で、結局キャラクターBOTを作るには? ~LINEBOTオウム返し編~ #005
前回、LINEBOTの作成にGoogleのCloud Functionsを利用することに決めました。
”AI大谷翔平BOTをLINEで作る”を目標に色々やっております。
→これまでをまとめたマガジンはこちら
Cloud Functionsについての説明から続けたいと思います。
Cloud Functions
Cloud Functionsは前回述べたように”サーバーレス”と言われるサービスで
Googleの大きなサーバを使って、指定のプログラムだけを実行してもらう
みたいなイメージです。
自分でサーバを構築する必要がないのでサーバレスと言われています。
土地をたくさん持っているGoogleのサーバーの”間借り”と言ったところで、間借りの飲食店のように自分では建物・キッチンを持たずに営業ができます。(実際にサーバは存在しますが、構築・管理が不要ということです。)
ごちゃごちゃ言うより、使っているのを見てもらおうと思います。
今日は基本であるメッセージをそのまま返すオウム返しLINEBOTを作成してみます。(AI大谷BOT作成まで回りくどいですが、これを基本としてあとは肉付けするだけなのでお付き合いください。)
Cloud Functions 料金
使う前にまずCloud Functionsの料金について説明しておきます。結論から言うとほぼお金はかからないです。従量課金制となのですが、無料枠があります。
無料枠の条件をまとめると以下となります
200万回の呼び出し(1 か月あたり)
400,000 GB 秒、200,000 GHz 秒のコンピューティング時間
5 GB の下り(外向き)ネットワーク(1 か月あたり)
簡単に言うと、短い処理で重たいファイルさえ送信しなければ200万回呼び出しまで無料ということになります。200万回以上呼び出す…個人では中々ないと思いますが、可能性がある方は料金を計算してみてください。
1番気を付けるとすれば、ネットワークの5GBという条件で画像ファイルを頻繁に送信するものを作る場合は注意した方がいいと思います。
コンピューティング時間もよほどの長い処理をしなければ超えることもないかと思いますので、テキストだけのメッセージ処理だけなら無料枠で問題ないとご理解いただければと思います。
Google Cloud Platform登録
では始めたいと思うのですが、Cloud Functionsを利用するにはGoogle Cloud Platform(略してGCP)への利用登録が必要となります。
GCPはGoogleのクラウドサービスで、3大クラウドサービスの1つです。
90 日間 $300 分の無料クレジットがあり、敷居が低いですが支払い方法の設定が必須(クレジットカードの登録など)なので、忘れているうちに費用が発生していたなんてこともありえますので、そこだけ気を付けて下さい。
(必ず毎月の明細を確認してください。)
では登録していきます。
必要なのはGoogleアカウントとクレジットカード番号くらいです。
GCPのページにアクセス。無料で使って見るをクリック。
アカウントと国を選択して続行。(更新情報のチェックは任意)
支払い方法を設定。
アンケートがあるかもしれないですが、適当に答える。
これでGCPへの登録は完了です。
早速Cloud Functionsを作りたいと思いますが、その前にLINEBOTのための作業を行います。
LINE公式アカウントの作成
前回簡単に話した通り、LINE Messaging APIというものを使ってBOTを作成することになります。LINEの企業向けであるLINE Businessに登録が必要で、もちろんBOTは"公式アカウント"という位置づけになりますので、チャンネルアイコンなどの設定が必要となります。
登録方法は色んな方の記事で紹介されていますが、下記の記事が丁寧でわかりやすいのでこちらをご覧の上、ご登録してお願いします。
※テストのため、作ったアカウントはQRコードからご自身のスマホのLINEに登録してあげて下さい。
BOTに必要になるのは以下の2つのキーです。
LINE Developersページのコンソール内、チャネル基本設定にある"チャンネルアクセストークン"
Messaging API設定にある"チャンネルシークレット"
この2つがあればLINEをプログラムから操作ができます。
逆にこれを公開すると、メッセージが自由に送れてしまうので注意して下さい。(もし誤って公開してしまったら、再発行すれば大丈夫です。)
またMessaging APIの料金ですが、200通まで無料でそれ以上だと有料プランにする必要があります。
ただこれはこちらからメッセージを送った場合で、受け取ったメッセージを自動返信する場合はカウントされず、無料で送ることができます!
(旧TwitterAPIのようにこのまま無料だといいですが…)
もちろん宣伝など行いたい場合は、こちらから送る必要になりますので用途に応じてプランを選んで下さい。
ではGCP画面に戻って、Cloud Functionsの作成をします。
Cloud Functionsの作成
上部検索バーに「fu」など入力しCloud Functions管理画面を起動します。
ファンクション作成をクリック。
必要なAPIがあるため有効にするをクリックします。
ここからファンクションの作成となります。
最初に大事なのが構成を"第1世代"に変えてください。
”第2世代"が新しいバージョンではあるのですが、実態はCloud Runという別のサービスとなっており権限設定がややこしいです。ただパフォーマンスは上がっているとのことなので、GCPに慣れている人は第2世代を試してみてもいいかと思います。初めての人は必ず第1世代を選んで下さい。
関数名は適当に付けて、リージョンは東京が推奨。ただ他の地域の方が若干安かったりするので、費用がかかる恐れのある方は調べてみてください。
次にその下に行きます。トリガーは"HTTP"のままで、認証は"未認証の呼び出しを許可"、"HTTPSが必須"はチェックのまま"保存"を押して下さい。
"未認証の呼び出しを許可"しないとLINE側からCloud Functionを呼び出すことができません。「セキュリティ上大丈夫?」と思うかもしれませんが、コード側で対応を行います。(認証が必要にしてしまった場合も、後々権限設定で変更できます)
その他のランタイム、ビルドなどのタブ内の設定は基本的に何も変更しなくて大丈夫です。
ランタイムタブでランタイム環境変数だけ追加します。”変数を追加”をクリックし名前に”CHANNEL_SECRET”、値に先ほど取得したLINEのMessaging APIのチャンネルシークレットを設定します。
同じように”CHANNEL_ACCESS_TOKEN”と"チャンネルアクセストークン"の組み合わせも登録します。
”CHANNEL_SECRET”、”CHANNEL_ACCESS_TOKEN”はプログラムで使う変数名なのでなんでも構いません。これで”次へ”をクリック。
ここからがメインとなります。ファンクションの処理内容を記述するソースコードの入力となります。
最初にランタイムからPythonX.XXを選んで下さい。今回はPython3.10にし
ましたが、開発環境などに応じて変えて下さい。
基本はmain.pyとrequirements.txtの2つのファイルから構成されていて、main.pyにファンクションの処理、requirements.txtにインストールが必要なパッケージを記述します。ファイルは+ボタンで追加もできます。
今回はサンプルとして"オウム返し"をするので、main.pyの中を全て消して以下に変えてください。
import os
from flask import abort, jsonify
from linebot import (
LineBotApi, WebhookParser
)
from linebot.exceptions import (
InvalidSignatureError
)
from linebot.models import (
MessageEvent, TextMessage, TextSendMessage
)
def hello_world(request):
# 環境変数からAPI情報取得
channel_secret = os.environ.get('CHANNEL_SECRET')
channel_access_token = os.environ.get('CHANNEL_ACCESS_TOKEN')
# LineBotApi・WebhookParserインスタンス生成
line_bot_api = LineBotApi(channel_access_token)
parser = WebhookParser(channel_secret)
# 受け取ったrequestの中から本体と署名を取り出す
body = request.get_data(as_text=True)
signature = request.headers['X-Line-Signature']
try:
# 署名を検証しエラーなら終了
events = parser.parse(body, signature)
except InvalidSignatureError:
print("Invalid signature. Please check your channel access token/channel secret.")
return abort(405)
for event in events:
# メッセージイベントだけ取り出す
if not isinstance(event, MessageEvent):
continue
if not isinstance(event.message, TextMessage):
continue
# 受け取ったメッセージ内容をそのまま返す
line_bot_api.reply_message(
event.reply_token,
TextSendMessage(text=event.message.text)
)
return jsonify({ 'message': 'ok'})
いきなりこんなの見せられたも「?」だと思いますが、基本的にこれはLINEの公式のソースを少しCloud Functions用に変えたものなので、あまり深く考えなくて大丈夫です。要点だけお話しします。
3-13行目:必要なモジュール
利用するのはLINEが公式に提供するline-bot-sdk内のモジュールとWebアプリのための軽量フレームワークFlaskのモジュールです。
16行目:関数名(hello_world)
関数名はなんでもいいです。ただファンクション作成画面の"エントリポイント"と必ず同じにして下さい。(これで指定した関数が呼び出されます)
19-20行目:Messaging APIキー取得
環境変数からAPIキーを取得します。環境変数名は先ほどランタイム環境変数で指定したものと同じにして下さい。
32行目:署名との検証
このファンクションの起動元が作成したLINEアカウントであるか確認し、不整合ならエラーとします。
37-40行目:メッセージイベントの取り出し
公式アカウントは"誰かにフォローされたとき"など様々なイベントが起こった際、即時にその情報を受け取れます。ただ今回はテキストメッセージのイベントだけ受け付けるので、このように処理をしています。イベントは重複する場合もあるのでfor文としています。(イベントの詳細はこちら)
47-50行目:メッセージの送信(オウム返し)
メッセージイベントの場合、event.message.textに送られてきたメッセージがセットされています(テキストの場合)。これをTextSendMessageの引数にしてオウム返しします。もし、違う回答を送りたければここを変えてください。
※ちなみに公式ではlinebot.v3のモジュールを利用していますが、やや記述に面倒なことが多かったので、古いlinebotのものを利用しています。
Pythonはインデントが重要なので、貼り付けの際は気を付けて下さい。
次にrequirements.txtに以下を貼り付けてください。
flask
line-bot-sdk
requirementsには必要なパッケージ、いわいる"pip"がいるものを記載します。この2つは先ほど説明したモジュールのパッケージです。
※最初からある#から始まる2行はコメントなので消しても構いません。
これまで終わりましたらデプロイをクリックして、ファンクション完成となります。("関数をテスト"はしてもしなくても構いません)
以前言ったようにデプロイには時間がかかります。
完了し次のように緑チェックマークなら成功となります。
失敗した場合はログタグからエラーの内容を把握し、コードを修正して下さい。(requirements.txtに必要なパッケージ"line-bot-sdk"がない場合、ログは次のようになります。)
成功したらトリガータグを開き、トリガーURLをコピーして下さい。
あとはLINE DevelopersページのMessaging API設定にあるWebhook設定のWebhook URLを編集しこのトリガーURLを張り付けてください。
検証をクリックして接続確認。”成功”ならOKです。
(失敗した場合はまたログを見て下さい。)
あとはご自身のLINEからメッセージを送り、オウム返しされるか確認して下さい!
レスポンスの早さは…まずまずといったところでしょうか。
(偉そうですいません。無料では十分だと思います。)
ということで長くなってしまいましたが、Cloud Functionsを利用してのLINEBOTの作成はこんな感じです。何度も言いますがデプロイにかかる時間が長いので、エラーが出るとデバッグに時間がかかり結構大変です。
ですが、1度動いてしまえば、サーバにファイルを置く場合と違って管理もしやすいので、運用は楽だと思います。
あとはこれにこれまで作ったファインチューニングモデルを使ってGPTのAPIを動かせば完成となります!では次回もよろしくお願いします!
参考にさせて頂いた記事
※サムネイルはSDXLのdressed-animals Loraです。