Linebot creation & file sharing in Python

Introduction

I would like to introduce how to use the Dropbox API in Python and how to add a file transmission function to Linebot. This time, we will create a Linebot that will send you monthly calendar images via Dropbox.

↓ Like this Linebot参照.jpg

Regarding the creation of Linebot itself, there are many useful sites, so I will omit it here.

I started LINE Bot with Python [Until you implement LINE bot in Flask and deploy to heroku] (https://qiita.com/suigin/items/0deb9451f45e351acf92)

What do you need?

Language: python 3.7.4 Library (Linebot): Flask 1.1.1, line-bot-sdk 1.16.0, Library (Dropbox): dropbox 9.5.0

Library installation

Install with the following three pip commands.

pip install Flask
pip install line-bot-sdk
pip install dropbox

It is a practice when the installation is completed.

Practice (using Dropbox)

First, I will introduce how to use the Dropbox API easily. To register as a Dropbox developer and obtain an access token, please refer to Dropbox API app Developer Registration Procedure.

In the following, you can upload images and create shared links using the Dropbox API. Download your favorite calendar images from the internet and rename them to 1.jpg, 2.jpg, ... in order.

import dropbox
import os

#1.Using Dropbox API
DBX_ACCESS_TOKEN = ***********************
dbx = dropbox.Dropbox(DBX_ACCESS_TOKEN)

#2.Upload files to Dropbox and create shared links
for month in range(1,13):
  local_path = '%s.jpg' %month
  dbx_path = "/" + local_path
 
  #2-1.File upload (Explanation 1)
  f = open(local_path, 'rb')
  dbx.files_upload(f.read(),dbx_path, mode=dropbox.files.WriteMode.overwrite)
  f.close()
  
  #2-2.Creating a shared link (Explanation 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("Already shared.")
 else:
    url = link[0].url
    print(url)

Explanation 1 By default, the mode of files_upload is WriteMode.add. In that case, if a file with the same name as the file to be uploaded already exists, it will be saved with the file name (1) .extension. If you want to overwrite, set mode to overwrite.

Explanation 2 In SharedLinkSettings, there are three types of sharing methods: public, team_only, and password (a password is required for access). In addition, you can decide the sharing deadline, password, and so on.

If you want to know more, [Dropbox for Python] Please see (https://dropbox-sdk-python.readthedocs.io/en/latest/index.html).

Embedded in Linebot

Using the shared link created in the above procedure, create a Linebot that returns the shared link in response to the message. Most of the code below is GitHub line-bot-sdk-python examples Is the same as that described.

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)
#----------------------------Explanation from here 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))
#----------------------------Explanation up to here 1

#Get environment variables
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'

#----------------------------Explanation 2 from here
@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 = 'calendar' + str(word)
        if msg in text:
            a = word - 1
            key = keys[a]
            line_bot_api.reply_message(
            event.reply_token,[
            TextSendMessage(text = key + 'It's a monthly calendar!'),
            TextSendMessage(text = pic_id[key])
            ])
#----------------------------Explanation up to here 2

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

Explanation 1 Create a dictionary that links the month of the calendar with the URL. sharing_list_shared_links (path = dbx_path) .links returns an array containing file information in addition to the links in the corresponding path. (The link is stored first.) url.replaced changes www.dropbox in the shared link to dl.dropboxusercontent and deletes ? Dl = 0. This is the process required to display the shared link on the browser.

Explanation 2 The if statement is conditional so that Linebot sends an image link according to the message. (See the image at the top of the homepage) If you store [1,2, ... 12] in words in order from January, "Calendar 1" will be read first when you send the message "Calendar December". The January calendar is back from Linebot. Therefore, words are stored as [12,11, ... 1].

If you want to know more, [Dropbox for Python] (https://dropbox-sdk-python.readthedocs.io/en/latest/index.html),[line-bot-sdk-python] Please see (https://line-bot-sdk-python.readthedocs.io/en/stable/index.html).

reference

Linebot I started LINE Bot with Python [Until you implement LINE bot in Flask and deploy to heroku] (https://qiita.com/suigin/items/0deb9451f45e351acf92)

Dropbox Dropbox API app developer registration procedure [Use Dropbox API to upload files, create shared links, and get shared links] (https://qiita.com/Fortinbras/items/f77984e5a7c2b3045473)

** Official document ** [Dropbox for Python] (https://dropbox-sdk-python.readthedocs.io/en/latest/index.html) [line-bot-sdk-python] (https://line-bot-sdk-python.readthedocs.io/en/stable/index.html)

Recommended Posts

Linebot creation & file sharing in Python
LINE-Bot [0] in Python
File processing in Python
File operations in Python
File / folder path manipulation in Python
Save the binary file in Python
Create a binary file in Python
File creation
ORC, Parquet file operations in Python
GUI creation in python using tkinter 2
Exclusive control with lock file in Python
GUI creation in python using tkinter part 1
Convert psd file to png in Python
Write O_SYNC file in C and Python
Read the file line by line in Python
Read the file line by line in Python
Exclusive file access between processes in Python
[GPS] Create a kml file in Python
[Python] Read the specified line in the file
Quadtree in Python --2
Python in optimization
CURL in python
Script python file
Geocoding in python
SendKeys in Python
Meta-analysis in Python
Unittest in python
Epoch in Python
Discord in Python
Sudoku in Python
DCI in Python
Python file processing
quicksort in python
nCr in python
N-Gram in Python
Programming in python
Plink in Python
Constant in python
Lifegame in Python.
FizzBuzz in Python
Sqlite in python
StepAIC in Python
N-gram in python
Csv in python
Disassemble in Python
Reflection in Python
Constant in python
nCr in Python.
format in python
Scons in Python3
Puyo Puyo in python
python in virtualenv
PPAP in Python
Quad-tree in Python
Reflection in Python
Chemistry in Python
Hashable in python
DirectLiNGAM in Python
LiNGAM in Python
Flatten in python
flatten in python