iT邦幫忙

2023 iThome 鐵人賽

0
Software Development

跟著 OXXO 一起學 Python系列 第 93

( Day 44.2 ) Python LINE BOT 串接 Email,寄送使用者的圖片或影片

  • 分享至 

  • xImage
  •  

這篇教學會延續「儲存使用者傳送的圖片或影片」範例,搭配 smtplib 和 email 標準函式庫,當收到使用者所傳送圖片或影片時,直接將檔案透過 Email 的方式寄出,就可以透過 Email 的附件保存檔案。

本篇教學延續「儲存使用者傳送的圖片或影片」教學範例程式碼。

本機環境串接 Email

參考「串接 Gmail 寄送電子郵件」教學內容,先申請 Google 應用程式密碼,並閱讀「附加檔案的 email」範例程式,將發送 Email 的程式碼獨立成一個 sendEmail 函式,並與原本接收圖片與影片的程式碼結合。

from flask import Flask, request

# 載入 json 標準函式庫,處理回傳的資料格式
import json

# 載入 LINE Message API 相關函式庫
from linebot import LineBotApi, WebhookHandler
from linebot.exceptions import InvalidSignatureError
from linebot.models import MessageEvent, TextMessage, TextSendMessage

# 載入 smtplib 和 email 函式庫
import smtplib
from email.mime.application import MIMEApplication
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

app = Flask(__name__)

# 寄送 Email 的函式,包含五個參數
# txt:Email 的標題
# source:要傳送的附件 ( 二進位格式 )
# fileName:附件檔案名稱
# email:寄件者的 Email
# pwd:應用程式密碼
def sendEmail(txt, source, fileName, email, pwd):
    msg = MIMEMultipart()
    attach_file = MIMEApplication(source, Name=fileName)  # 附加檔案
    msg.attach(attach_file)
    msg['Subject'] = txt   # 標題
    msg['From'] = email    # 給誰 ( 通常是給自己 )
    msg['To'] = email      # 寄件者
    smtp = smtplib.SMTP('smtp.gmail.com', 587)
    smtp.ehlo()
    smtp.starttls()
    smtp.login(email, pwd) # 使用應用程式密碼登入
    status = smtp.send_message(msg)
    print(status)
    smtp.quit()

@app.route("/", methods=['POST'])
def linebot():
    body = request.get_data(as_text=True)                    # 取得收到的訊息內容
    try:
        json_data = json.loads(body)                         # json 格式化訊息內容
        access_token = ''                                    # 你的 Token
        secret = ''                                          # 你的 Secret
        line_bot_api = LineBotApi(access_token)              # 確認 token 是否正確
        handler = WebhookHandler(secret)                     # 確認 secret 是否正確
        signature = request.headers['X-Line-Signature']      # 加入回傳的 headers
        handler.handle(body, signature)                      # 綁定訊息回傳的相關資訊
        tk = json_data['events'][0]['replyToken']            # 取得回傳訊息的 Token
        type = json_data['events'][0]['message']['type']     # 取得 LINe 收到的訊息類型
        if type=='text':
            msg = json_data['events'][0]['message']['text']  # 取得 LINE 收到的文字訊息
            print(msg)                                       # 印出內容
            reply = msg
        elif type=='image':
            print(json_data['events'][0])
            msgID = json_data['events'][0]['message']['id']
            message_content = line_bot_api.get_message_content(msgID)
            # 收到圖片後寄送 Email
            sendEmail('LINE 傳圖片來囉!', message_content.content, f'{msgID}.jpg', '你的 Email', '你申請的應用程式密碼')
            reply = '圖片儲存完成!'
        elif type=='video':
            print(json_data['events'][0])
            msgID = json_data['events'][0]['message']['id']
            message_content = line_bot_api.get_message_content(msgID)
            # 收到影片後寄送 Email
            sendEmail('LINE 傳影片來囉!', message_content.content, f'{msgID}.mp4', '你的 Email', '你申請的應用程式密碼')
            reply = '影片儲存完成!'
        else:
            reply = '你傳的不是文字或圖片呦~'
        print(reply)
        line_bot_api.reply_message(tk,TextSendMessage(reply))# 回傳訊息
    except:
        print(body)                                          # 如果發生錯誤,印出收到的內容
    return 'OK'                                              # 驗證 Webhook 使用,不能省略

if __name__ == "__main__":
    app.run()

完成後執行程式 ( 記得先使用 ngrok 產生 webhook 網址並提交至 LINE Developer ),傳送圖片或影片到 LINE BOT,該圖片或影片就會自動轉寄到 Email。

LINE BOT 教學 ( Python ) - 串接 Email,寄送使用者上傳的圖片或影片

Colab 串接 Email

如果要使用 Colab 作為開發環境,將上述的程式碼額外 import run_with_ngrok,並於程式碼中使用 run_with_ngrok(app),就可以將使用者傳送的圖片或影片,轉傳到指定的 Email。

from flask import Flask, request
from flask_ngrok import run_with_ngrok    # 額外 import run_with_ngrok

# 載入 json 標準函式庫,處理回傳的資料格式
import json

# 載入 LINE Message API 相關函式庫
from linebot import LineBotApi, WebhookHandler
from linebot.exceptions import InvalidSignatureError
from linebot.models import MessageEvent, TextMessage, TextSendMessage

import smtplib
from email.mime.application import MIMEApplication
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

app = Flask(__name__)
run_with_ngrok(app)     # 串接 ngrok

def sendEmail(txt, source, fileName, email, pwd):
    msg = MIMEMultipart()
    attach_file = MIMEApplication(source, Name=fileName)
    msg.attach(attach_file)
    msg['Subject'] = txt
    msg['From'] = email
    msg['To'] = email
    smtp = smtplib.SMTP('smtp.gmail.com', 587)
    smtp.ehlo()
    smtp.starttls()
    smtp.login(email, pwd)
    status = smtp.send_message(msg)
    print(status)
    smtp.quit()

@app.route("/", methods=['POST'])
def linebot():
    body = request.get_data(as_text=True)                    # 取得收到的訊息內容
    try:
        json_data = json.loads(body)                         # json 格式化訊息內容
        access_token = ''                                    # 你的 Token
        secret = ''                                          # 你的 Secret
        line_bot_api = LineBotApi(access_token)              # 確認 token 是否正確
        handler = WebhookHandler(secret)                     # 確認 secret 是否正確
        signature = request.headers['X-Line-Signature']      # 加入回傳的 headers
        handler.handle(body, signature)                      # 綁定訊息回傳的相關資訊
        tk = json_data['events'][0]['replyToken']            # 取得回傳訊息的 Token
        type = json_data['events'][0]['message']['type']     # 取得 LINe 收到的訊息類型
        if type=='text':
            msg = json_data['events'][0]['message']['text']  # 取得 LINE 收到的文字訊息
            print(msg)                                       # 印出內容
            reply = msg
        elif type=='image':
            print(json_data['events'][0])
            msgID = json_data['events'][0]['message']['id']
            message_content = line_bot_api.get_message_content(msgID)
            sendEmail('LINE 傳圖片來囉!', message_content.content, f'{msgID}.jpg', '你的 Email', '你申請的應用程式密碼')
            reply = '圖片儲存完成!'
        elif type=='video':
            print(json_data['events'][0])
            msgID = json_data['events'][0]['message']['id']
            message_content = line_bot_api.get_message_content(msgID)
            sendEmail('LINE 傳影片來囉!', message_content.content, f'{msgID}.mp4', '你的 Email', '你申請的應用程式密碼')
            reply = '影片儲存完成!'
        else:
            reply = '你傳的不是文字或圖片呦~'
        print(reply)
        line_bot_api.reply_message(tk,TextSendMessage(reply))# 回傳訊息
    except:
        print(body)                                          # 如果發生錯誤,印出收到的內容
    return 'OK'                                              # 驗證 Webhook 使用,不能省略

if __name__ == "__main__":
    app.run()

LINE BOT 教學 ( Python ) - 串接 Email,寄送使用者上傳的圖片或影片

小結

因為透過 OAuth2.0 串接 Google 雲端硬碟相對來說比較麻煩,且對於初學者來說有一些安全性的疑慮,所以如果真的要保留圖片或影片,藉由 LINE BOT 接收後再串接 Email 發送,是相當不錯的保存檔案方式。

更多教學

大家好,我是 OXXO,是個即將邁入中年的斜槓青年,我有個超過一千篇教學的 STEAM 教育學習網,有興趣可以參考下方連結呦~ ^_^


上一篇
( Day 44.1 ) Python LINE BOT 儲存使用者傳送的圖片或影片
下一篇
( Day 45.1 ) Python LINE BOT 串接 Dialogflow ( 基本串接 )
系列文
跟著 OXXO 一起學 Python101
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言