I made a Line Bot that uses Python to retrieve unread Gmail emails!

Purpose

Get mail from Gmail with Line Bot and send unread messages to the sender and subject to Line.

Development environment

reference

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.

Source code

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.

result

Screenshot_20200531-181629905 (1)_1.jpg I have erased the sender's name, but I got the name and title and was able to reply!

About the future

I would like to implement the following two in the future.

Recommended Posts

I made a Line Bot that uses Python to retrieve unread Gmail emails!
[Python] I made a Line bot that randomly asks English words.
I made a LINE BOT with Python and Heroku
[Python] I made a LINE Bot that detects faces and performs mosaic processing.
In Python, I made a LINE Bot that sends pollen information from location information.
I made a LINE BOT that returns parrots with Go
I want to send a message from Python to LINE Bot
I made a library that adds docstring to a Python stub file.
[Python] I made a decorator that doesn't seem to have any use.
I made a web application in Python that converts Markdown to HTML
I made a Discord bot in Python that translates when it reacts
I made a stamp substitute bot with line
I made a LINE Bot with Serverless Framework!
I made a Mattermost bot with Python (+ Flask)
[Python] I made a bot that tells me the current temperature when I enter a place name on LINE
I made a LINE BOT that returns a terrorist image using the Flickr API
I made a LINE Bot that sends recommended images every day on time
A story that I was addicted to when I made SFTP communication with python
[AWS] I made a reminder BOT with LINE WORKS
I made a Twitter BOT with GAE (python) (with a reference)
I made a household account book bot with LINE Bot
I made a VM that runs OpenCV for Python
I made a Python module to translate comment outs
I made a python library to do rolling rank
A Python beginner made a chat bot, so I tried to summarize how to make it.
I made a python text
I made a discord bot
I made a package to filter time series with python
[Python] I asked LINE BOT to answer the weather forecast.
I made a Chatbot using LINE Messaging API and Python
[AWS] I made a reminder BOT with LINE WORKS (implementation)
I made a toolsver that spits out OS, Python, modules and tool versions to Markdown
I made a program to collect images in tweets that I liked on twitter with Python
I made a Line-bot using Python!
I made a wikipedia gacha bot
I made a fortune with Python.
I made a daemon with Python
I made a library to easily read config files with Python
[Python3] I made a decorator that declares undefined functions and methods.
I made a package that can compare morphological analyzers with Python
I want to use a wildcard that I want to shell with Python remove
I want to know the weather with LINE bot feat.Heroku + Python
I created a Python library to call the LINE WORKS API
[Python] A memo that I tried to get started with asyncio
I made a Twitter bot that mutters Pokemon caught by #PokemonGO
I made a shuffle that can be reset (reverted) with Python
[LINE Messaging API] Create a BOT that connects with someone with Python
[Introduction] I want to make a Mastodon Bot with Python! 【Beginners】
I made a slack bot that notifies me of the temperature
I made a Chatbot using LINE Messaging API and Python (2) ~ Server ~
[python] I made a class that can write a file tree quickly
I made a Line bot that guesses the gender and age of a person from an image
I made a garbled generator that encodes favorite sentences from UTF-8 to Shift-JIS (cp932) in Python
[Python] I tried to make a simple program that works on the command line using argparse.
I made a Docker container to use JUMAN ++, KNP, python (for pyKNP).
I made a password generator to teach Python3 to children (bonus) * Completely remade
I started to work at different times, so I made a bot that tells me the time to leave
Python beginners decided to make a LINE bot with Flask (Flask rough commentary)
I made a tool to automatically browse multiple sites with Selenium (Python)
I made a character counter with Python
I made Othello to teach Python3 to children (2)