Get mail from Gmail with Line Bot and send unread messages to the sender and subject to Line.
Check Gmail emails with Python --I used it as a reference to enable Google's API. Get mail from Gmail API using Python --I referred to how to use the Gmail API.
main.py
from flask import Flask, request, abort
from linebot import (
LineBotApi, WebhookHandler
)
from linebot.exceptions import (
InvalidSignatureError
)
from linebot.models import (
MessageEvent, TextMessage, TextSendMessage, LocationMessage, VideoMessage,
FollowEvent, UnfollowEvent, PostbackEvent, TemplateSendMessage,
ButtonsTemplate, CarouselTemplate, CarouselColumn, PostbackTemplateAction
)
from linebot.exceptions import LineBotApiError
import os
import json
import sys
import re
import Gmail
app = Flask(__name__)
YOUR_CHANNEL_ACCESS_TOKEN = os.environ["YOUR_CHANNEL_ACCESS_TOKEN"]
YOUR_CHANNEL_SECRET = os.environ["YOUR_CHANNEL_SECRET"]
line_bot_api = LineBotApi(YOUR_CHANNEL_ACCESS_TOKEN)
handler = WebhookHandler(YOUR_CHANNEL_SECRET)
@app.route("/callback", methods=['POST'])
def callback():
signature = request.headers['X-Line-Signature']
body = request.get_data(as_text=True)
app.logger.info("Request body: " + body)
try:
handler.handle(body, signature)
except InvalidSignatureError:
abort(400)
return 'OK'
@handler.add(MessageEvent, message=TextMessage)
def handle_message(event):
text = event.message.text
user_id = event.source.user_id
if 'Email' in text:
mail = Gmail.GmailAPI()
# get the reply message
messages = mail.process_message()
# reply
line_bot_api.reply_message(
event.reply_token,
TextSendMessage(text=str(messages))
)
if __name__ == "__main__":
port = int(os.getenv("PORT", 5000))
app.run(host="0.0.0.0", port=port)
When the bot receives a message containing the string "mail", it gets an unread message from Gmail and replies.
Gmail.py
from googleapiclient.discovery import build
from httplib2 import Http
from oauth2client import file, client, tools
class GmailAPI:
def __init__(self):
# If modifying these scopes, delete the file token.json.
self._SCOPES = 'https://www.googleapis.com/auth/gmail.readonly'
def ConnectGmail(self):
store = file.Storage('token.json')
creds = store.get()
if not creds or creds.invalid:
flow = client.flow_from_clientsecrets('credentials.json', self._SCOPES)
creds = tools.run_flow(flow, store)
service = build('gmail', 'v1', http=creds.authorize(Http()))
return service
def GetMessageList(self):
# connect to API
service = self.ConnectGmail()
MessageList = []
query = 'is:unread'
# get all the messages (maximum=20)
messageIDlist = service.users().messages().list(userId='me',maxResults=20,q=query).execute()
# if no messages, stop return error
if messageIDlist['resultSizeEstimate'] == 0:
return 'error'
# Get information about the mails
for message in messageIDlist['messages']:
row = {}
MessageDetail = service.users().messages().get(userId='me',id=message['id']).execute()
for header in MessageDetail['payload']['headers']:
# get the senders of the messages
if header['name'] == 'From':
row['from'] = header['value']
# get the subject of the messages
elif header['name'] == 'Subject':
row['subject'] = header['value']
MessageList.append(row)
return MessageList
def process_message(self):
messagelist = self.GetMessageList()
# If there is no messages new, reply 'No message'
if messagelist == 'error':
reply = 'No message'
return reply
# make reply message
reply = ''
for mlist in messagelist:
from_name = mlist['from'].split('<')[0] + ':'
sub = '「' + mlist['subject'] + '」'
message = '{}\n{}'.format(from_name, sub)
reply += message
reply += '\n\n'
return reply
Using Gmail API, GetMessageList gets the sender and subject of unread mail, and process_message converts them to the character string when replying and returns it.
I have erased the sender's name, but I got the name and title and was able to reply!
I would like to implement the following two in the future.