Python으로 Linebot 만들기 및 파일 공유

소개



Python에서 DropboxAPI를 사용하고 Linebot에 파일 전송 기능을 추가하는 방법을 소개하고 싶습니다.
이번에는 월별 캘린더의 이미지를 Dropbox를 통해 보내주는 Linebot을 만듭니다.

↓이런 느낌


Linebot의 작성 그 자체에 대해서는, 참고가 되는 사이트가 많이 있으므로, 여기서는 생략합니다.

파이썬에서 LINEBot을 시작했습니다.
Flask에서 LINE bot을 구현하고 heroku에 deploy 할 때까지

무엇이 필요합니까?



언어: python 3.7.4
라이브러리(Linebot):Flask 1.1.1, line-bot-sdk 1.16.0,
라이브러리(Dropbox):dropbox 9.5.0

라이브러리 설치



아래의 3개 pip 명령으로 설치합니다.
pip install Flask
pip install line-bot-sdk
pip install dropbox

설치가 완료되면 실천입니다.

연습 (Dropbox 사용)



우선 DropboxAPI의 간단한 사용법에 대해 소개하겠습니다.
Dropbox의 개발자 등록, 액세스 토큰의 취득은, Dropbox API 앱 개발자 등록 절차 를 참고로 각자 실시해 주세요.

아래에서는 DropboxAPI를 이용한 이미지 업로드, 공유 링크 생성까지 수행합니다.
좋아하는 캘린더의 이미지를 인터넷에서 다운로드하고, 그들을 순서대로 1.jpg, 2.jpg, ...라고 이름을 바꾸어 주세요.
import dropbox
import os

#1.DropboxAPIの利用
DBX_ACCESS_TOKEN = ***********************
dbx = dropbox.Dropbox(DBX_ACCESS_TOKEN)

#2.Dropboxへのファイルアップロードと共有リンクの作成
for month in range(1,13):
  local_path = '%s.jpg' %month
  dbx_path = "/" + local_path
 
  #2-1.ファイルアップロード(解説1)
  f = open(local_path, 'rb')
  dbx.files_upload(f.read(),dbx_path, mode=dropbox.files.WriteMode.overwrite)
  f.close()

  #2-2.共有リンク作成(解説2)
  setting = dropbox.sharing.SharedLinkSettings(requested_visibility=dropbox.sharing.RequestedVisibility.public)
  try:       
    link = dbx.sharing_create_shared_link_with_settings(path=dbx_path, settings=setting)
  except:
    print("既に共有されています。")
 else:
    url = link[0].url
    print(url)

해설 1
files_upload의 모드는 기본적으로 WriteMode.add입니다.
이 경우 업로드 할 파일과 이름이 같은 파일이 이미있는 경우 파일 이름 (1). 확장명으로 저장됩니다.
덮어 쓰고 싶다면 mode를 overwirte로 설정하십시오.

해설 2
SharedLinkSettings에는 public, team_only, password (액세스에 암호가 필요)의 3 종류의 공유 ​​방법이 있습니다. 그 밖에 공유 기한, 비밀번호 등을 결정할 수 있습니다.

자세한 내용은 Dropbox for Python을 참조하십시오.

Linebot에 내장



위의 단계에서 만든 공유 링크를 사용하여 메시지에 따라 공유 링크를 반환하는 Linebot을 만듭니다.
아래 코드의 대부분은 GitHub line-bot-sdk-python examples에 설명된 것과 동일합니다.
from flask import Flask, request, abort
import os
import dropbox
from linebot import (
    LineBotApi, WebhookHandler
)
from linebot.exceptions import (
    InvalidSignatureError
)
from linebot.models import (
    MessageEvent, TextMessage, TextSendMessage,
)

app = Flask(__name__)

DBX_ACCESS_TOKEN = ***********************
dbx = dropbox.Dropbox(DBX_ACCESS_TOKEN)
#----------------------------ここから解説1
values = []
for month in range(1,13):
  local_path = '%s.jpg' %month
  dbx_path = "/" + local_path

  link = dbx.sharing_list_shared_links(path=dbx_path).links
  url = link[0].url
  url = url.replace('www.dropbox','dl.dropboxusercontent').replace('?dl=0','')
  values.append(url)

keys = [1,2,3,4,5,6,7,8,9,10,11,12]
pic_id = dict(zip(keys, values))
#----------------------------ここまで解説1

#環境変数取得
YOUR_CHANNEL_ACCESS_TOKEN = ***********************
YOUR_CHANNEL_SECRET = ***********************

line_bot_api = LineBotApi(YOUR_CHANNEL_ACCESS_TOKEN)
handler = WebhookHandler(YOUR_CHANNEL_SECRET)

@app.route("/")
def hello_world():
    return "hello world!"

@app.route("/callback", methods=['POST'])
def callback():
    # get X-Line-Signature header value
    signature = request.headers['X-Line-Signature']

    # get request body as text
    body = request.get_data(as_text=True)
    app.logger.info("Request body: " + body)

    # handle webhook body
    try:
        handler.handle(body, signature)
    except InvalidSignatureError:
        abort(400)

    return 'OK'

#----------------------------ここから解説2
@handler.add(MessageEvent, message=TextMessage)
def handle_message(event):
    words = [12,11,10,9,8,7,6,5,4,3,2,1]
    text = event.message.text
    for word in words:
        msg = 'カレンダー' + str(word)
        if msg in text:
            a = word - 1
            key = keys[a]
            line_bot_api.reply_message(
            event.reply_token,[
            TextSendMessage(text = key + '月のカレンダーだよ!'),
            TextSendMessage(text = pic_id[key])
            ])
#----------------------------ここまで解説2

if __name__ == "__main__":
#    app.run()
    port = int(os.getenv("PORT"))
    app.run(host="0.0.0.0", port=port)

해설 1
캘린더의 월과 URL을 연결한 사전을 만듭니다.
sharing_list_shared_links(path=dbx_path).links는 해당 경로의 링크 외에도 파일 정보를 포함하는 배열을 반환합니다. (링크는 가장 먼저 저장됩니다.)
url.replaced는 공유 링크에서 www.dropboxdl.dropboxusercontent로 변경하고 ?dl=0를 지우고 있습니다. 브라우저에서 공유 링크를 표시하는 데 필요한 프로세스입니다.

해설 2
Linebot이 메시지에 따라 이미지 링크를 보내도록 if 문으로 조건 분기합니다. (홈페이지 상단의 이미지 참조)
words에 1 월부터 순서대로 [1,2, ... 12]와 같이 저장하면 "캘린더 12 월"이라는 메시지를 보낼 때 "캘린더 1"이 먼저로드됩니다. 1월의 캘린더가 Linebot에서 돌아옵니다. 따라서 words는 [12,11,...1]과 같이 저장됩니다.

자세한 내용은 Dropbox for Python , line-bot-sdk-python을 참조하십시오.

참고



Linebot
파이썬에서 LINEBot을 시작했습니다.
Flask에서 LINE bot을 구현하고 heroku에 deploy 할 때까지

Dropbox
Dropbox API 앱 개발자 등록 절차
Dropbox API를 사용하여 파일 업로드 및 공유 링크 생성 및 공유 링크 획득

공식 문서
Dropbox for Python
line-bot-sdk-python

좋은 웹페이지 즐겨찾기