Leoです。
この記事は Wanoグループ Advent Calendar 2019 の22日目の記事になります。
Telegramのアプリにserverless botの機能を追加しました。
現在僕は複数のメッセンジャを使っています。
Lineにはbotを簡単に追加できますが、今回初めてTelegramのアプリに入れる必要があったので、この記事をメモとしても書きました。
Telegramのbotの実装には基本的に4ステップがあります。
- Botの登録
- AWS lambdaの登録
- AWS API Gatewayのendpointを追加
- EndpointをTelegramにwebhookとして登録
Botの登録
Lineと違って、Telegramのbot登録やbotの操作はアプリ内でできます。(Lineの場合、Developerのページでやります)
TelegramのアプリにBotFatherっていうアカウントを検索します。
BotFatherとのチャットに'/newbot'のコマンドで新しいbotを登録します。
登録が始まったら、botの名前とかuser_idを登録します。
登録は完了したらbotのAPIにアクセスする時に必要なtokenが発行されます。secret tokenのため、安全なストレージに保存しましょう。
このチャットでbotの設定の更新もできます。
Lambdaの登録
Lambdaを登録します。今日はAWSのコンソールでの登録を説明します。
今回http requestしか使わないのでデフォルトのNodejs環境で実装しますが、GoやPythonなどの環境でも簡単に実装できます。
Lambdaの中に以下のことをやっています。
- Webhookのイベントを受け取っている
- Webhookのリクエストのパラメータからmessageのtextを取得している
- TelegramのAPIを叩いてチャネルに返信してる
上の3つの機能が含まれている以下のコードをLambdaのindex.jsに入れる。
const https = require('https');
const BOT_TOKEN = process.env.BOT_TOKEN
const URL = "https://api.telegram.org/bot" + BOT_TOKEN + "/sendMessage?";
exports.handler = function(event, context, callback) {
let text = 'Echo: ' + event.message.text;
let chatId = event.message.chat.id;
let replyUrl = URL + 'text=' + text + '&chat_id=' + chatId;
https.get(replyUrl, (res) => {
console.log("Got response: " + res.statusCode);
callback(null, res.statusCode)
}).on('error', (e) => {
console.log("Got error: " + e.message);
callback(Error(e))
})
};
Telegramのチャネルにメッセージの送信は単純なGETでできます。
LambdaのEnvironment variableにBOT_TOKENを定義する必要があります。
最後に'保存'押して、Lambdaの登録は完了です。
APIの登録
BotのWebhookになるAWS API GatewayのREST APIを登録します。
Resource/PathをCreate Resourceで指定します。
TelegramのWebhookはPOSTで通知するので、Create MethodでPOST指定します。
HTTP Methodを指定したら、APIと前に登録したLambdaを結びつくためにIntegrationに用意したLambda名を入れます。そうするとこのAPIはトリガーとして登録されます。
APIをデプロイしたらページの上に'Invoke API URL'が以下のように表示されます。
https://fiXXXX1oe.execute-api.us-east-2.amazonaws.com/test/
これはまだWebhookのURLではありません。最後の'test'はステージ名になります。
このURLの後ろにAPIのpath(今回は'bot-test')を付けるとWebhookのURLになります。
https://fiXXXX1oe.execute-api.us-east-2.amazonaws.com/test/bot-test
Webhookの登録
最後にAPI Gatewayに登録したURLをTelegramにWebhookとして登録しましょう。
そのために以下のTelegramのAPIを使えます。
https://api.telegram.org/bot<BOT_TOKEN>/setWebHook?url=<WEBHOOK_URL>
<>のところをそれぞれ入れてGETリクエストを叩きます(ブラウザからでもOK)
https://api.telegram.org/bot1001745750:AAFDXkXXXXXXXXXXXXXXXXXXX4kqp0Mto/setWebHook?url=https://fiXXXX1oe.execute-api.us-east-2.amazonaws.com/test/bot-test
以下の返信が来ます。
{"ok":true,"result":true,"description":"Webhook was set"}
これでBotの基本的な実装は終わりです。
Telegramでbotを検索して、チャネルに書いてみるとEchoされます。
## 終わりに
もちろんこのbotは例として作りました。LambdaがトリガとしてAWSの色々なサービスに広げることもできます。DBにアクセスやSFNをキックすることなどできます。
Lineのbotと比べてTelegramのbotのAPIはシンプルで、serverlessなbotは誰も作れるって感じでした。