這篇教學會延續「儲存使用者傳送的圖片或影片」範例,搭配 smtplib 和 email 標準函式庫,當收到使用者所傳送圖片或影片時,直接將檔案透過 Email 的方式寄出,就可以透過 Email 的附件保存檔案。
- 原文參考:串接 Email,寄送使用者的圖片或影片
- 完整教學:LINE BOT 教學
本篇教學延續「儲存使用者傳送的圖片或影片」教學範例程式碼。
參考「串接 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。
如果要使用 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()
因為透過 OAuth2.0 串接 Google 雲端硬碟相對來說比較麻煩,且對於初學者來說有一些安全性的疑慮,所以如果真的要保留圖片或影片,藉由 LINE BOT 接收後再串接 Email 發送,是相當不錯的保存檔案方式。
大家好,我是 OXXO,是個即將邁入中年的斜槓青年,我有個超過一千篇教學的 STEAM 教育學習網,有興趣可以參考下方連結呦~ ^_^