Here's what you can do with GCP's free tier in several parts. The content of the free tier is subject to change, and pay-as-you-go ones may be charged if the limit is exceeded, so Official Information Please use at your own risk while checking = ja).
This time, we will link ** Cloud Run ** and ** Datastore ** with LINE's ** Messaging API ** to create the following simple bot. At the end of the article, I'll also introduce a slightly more practical bot created in the same way, so please take a look there as well (I implemented it on App Engine, but it has a lot in common).
Cloud Run A GCP service that allows you to run stateless containers in a serverless environment. This time it's just running Flask's web server, so using App Engine may be the royal road, but Cloud Run seems to have fewer articles, so I'll introduce it.
Datastore GCP's scalable NoSQL database. Since it is currently built into Firestore, we will use Firestore in Datastore mode to be exact. By the way, Official explains how to use Datastore mode and Native mode properly as follows.
For new server projects, use Cloud Firestore in Datastore mode.
Messaging API You can create a bot that runs on LINE. The created bot is linked to the LINE official account, so people who have registered as friends can use it.
The following 3 files are prepared this time. Place them all in the same directory.
app.py First is app.py, which describes the main processing contents. The outline is based on here.
app.py
from flask import Flask, request, abort
from linebot import LineBotApi, WebhookHandler
from linebot.exceptions import InvalidSignatureError
from linebot.models import MessageEvent, TextMessage, TextSendMessage
import config #Messaging API access token, etc.
from google.cloud import datastore
import datetime
import os
app = Flask(__name__)
client = datastore.Client()
line_bot_api = LineBotApi(config.token)
handler = WebhookHandler(config.secret)
@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:
print("Invalid signature. Please check your channel access token/channel secret.")
abort(400)
return 'OK'
@handler.add(MessageEvent, message=TextMessage)
def handle_message(event):
user_id = event.source.user_id
user_key = client.key("TestTable", user_id) #Get Key with kind and id as arguments
user_entity = client.get(user_key) #Get Entity with Key as an argument
if user_entity is None:
user_entity = datastore.Entity(key=user_key, exclude_from_indexes=("timestamp",))
msg = "Nice to meet you!"
else:
timestamp = user_entity["timestamp"]
ts = datetime.datetime.fromtimestamp(timestamp/1000)
msg = "{}Year{}Month{}Day{}Time{}Since minutes!".format(ts.year, ts.month, ts.day, ts.hour, ts.minute)
user_entity.update({ #Entity update
"timestamp": event.timestamp
})
client.put(user_entity) #Save argument Entity in Datastore
line_bot_api.reply_message(
event.reply_token,
TextSendMessage(text=msg))
if __name__ == "__main__":
app.run(debug=True, host="0.0.0.0", port=int(os.environ.get("PORT", 8080)))
The handle_message
immediately after the @ handler.add
decorator is the function that corresponds to the message from the Messaging API. The argument event contains various information such as the user_id of the sender (listed in here). Can be seen). I'm not familiar with Datastore related functions, so I've made a brief comment, but please check the Documentation for details.
config.py This is the file read by ʻimport config` in app.py. Access token etc. are set to link with Messaging API (confirmation method will be described later). You can write it directly to app.py, but it is recommended to make it a separate file so that it can be easily managed with .gitignore.
config.py
token = "xxxxx"
secret = "xxxxx"
Dockerfile
Finally, the Dockerfile. The required Python packages are installed with RUN pip install ...
.
# Use the official Python image.
# https://hub.docker.com/_/python
FROM python:3.7
# Copy local code to the container image.
ENV APP_HOME /app
WORKDIR $APP_HOME
COPY . .
# Install production dependencies.
RUN pip install Flask gunicorn line-bot-sdk google-cloud-datastore
# Run the web service on container startup. Here we use the gunicorn
# webserver, with one worker process and 8 threads.
# For environments with multiple CPU cores, increase the number of workers
# to be equal to the cores available.
CMD exec gunicorn --bind :$PORT --workers 1 --threads 8 app:app
When you reach this point, deploy with the following command. Please read the project name and region as appropriate. On the way, you will be asked ʻAllow unauthenticated invocations to [qiita-sample](y / N)?, But this time it is a test, so set it to
y`. When you're done, check the URL from the GCP console.
gcloud builds submit --tag gcr.io/$gcp_project/qiita-sample
gcloud beta run deploy qiita-sample --image gcr.io/$gcp_project/qiita-sample --platform managed --region us-west1
First, log in to LINE Developers, go to Console, and select Provider (if not). Create).
If there is no channel yet, the screen below will be displayed. Go to the Create a Messaging API channel and fill in the required information.
Next is the setting change and confirmation.
--Check Channel secret
from Basic Settings and Channel access token
from Messaging API settings (issue with Issue if not issued) and describe in config.py.
--Set Webhooks in Messaging API settings. This time, add / callback
to the end of the URL confirmed on the Cloud Run console, and the URL as shown in the image below. After inputting, turn on ʻUse webhook. --Similarly, set ʻAuto-reply Messages
to Disabled in Messaging API settings.
The setting is completed up to this point.
Add it to your LINE friends with the QR code or ID on the settings screen, and talk to them. If you have already deployed Cloud Run, you will get a reply as shown in the image at the beginning. You can also confirm that the latest response time is recorded normally from the Datastore console.
Actually, it was my first post, so I think there were many parts that were difficult to read, but I hope it will be helpful as much as possible. Finally, I would like to introduce the bot that I created as described in this article.
The park is closed due to Corona, but it is a convenient bot at a theme park that I made dreaming of going to Disney again. If you invite with a QR code or ID (@ 541rhynx
), you can ** split the bill ** or ** pair the vehicle ** in the LINE talk. This implementation is App Engine, but you should be able to do the same just by rewriting the app.py of the bot I made this time. The code and instructions are available on github.
Recommended Posts