Node.jsでTelegramのチャットボットを作る

Ryo Igarashi

Node.js + Express + node-telegram-bot-apiでbotを制作します.実際に運用しているbotのソースコードはGitHubで公開していますのでご参考までにどうぞ.

Botアカウントの登録

はじめに,Telegram APIを利用するためのbotを登録します.Twitterなどとは異なり電話番号から登録する普通のアカウントとは別のbotアカウントを作成して,そちらにAPIを介してアクセスします.あくまでもbot専用のAPIというわけです.

Telegramのオフィシャルbotである@botfather/newbotと送信することでbotの登録が開始できます.はじめにbotの表示名を設定しますが,こちらは後から変更可能です.

Create a new bot

次に,botのユーザー名(@usernameの形式のもの)を設定します.こちらは残念ながら後から変更が出来ない上,末尾がbotで終了する必要があるため注意してください.

Naming the bot

Botアカウントが登録できると,最後にAPIにアクセスするためのトークンが送られてきます./tokenと送信することで再発行も可能ですが,安全性のために適切に保存してください.

Fetching a token

デフォルトではbotは/から始まるメッセージにしかアクセス出来ないようになっていますが,これは/setprivacyを利用することで無効化できます.必要であれば設定してください.

Setting privacy

APIのインストール

Axiosなどから直接APIにアクセスすることも可能ですが,npmでnode-telegram-bot-apiという優れたライブラリが公開されているのでこちらを利用します.

npm:

npm install --save node-telegram-bot-api

yarn:

yarn add node-telegram-bot-api

APIの利用: メッセージを受信する

トークンを取得し,ライブラリをインストールできたら早速botを動かし始めることができます.以下のコードを参考にメッセージを受信したらコンソールに受信したテキストを表示するbotを作ります.

const TelegramBot = require('node-telegram-bot-api');

// トークンを指定してインスタンス化
const bot = new TelegramBot('ここにアクセストークンを指定', { polling: true });

// Messageを受け取ったら実行
bot.on('message', (message) => {
	const { text } = message;
	console.log(`メッセージを受信: ${text}`);
});

メッセージの受信はon('message')で行えます.on()メソッドでは第二引数に受信するイベントの種類を指定でき,メッセージ以外にも様々なものがあるので試してみるといいかもしれません.イベントの一覧はこちらのドキュメントで確認できます

そして,on('message')で受信できるMessageエンティティは,textに生のテキストが格納されているので,それをconsole.logで出力することができます.

Botを起動

node bot.js

結果

Recieving message

APIの利用: メッセージを送信する

先程のコードを少し変更し,今度は受け取ったテキストをそのまま返信するbotを作ります.botからメッセージを送信するためにはsendMessage()というメソッドを利用します.以下が例です

const TelegramBot = require('node-telegram-bot-api');

// トークンを指定してインスタンス化
const bot = new TelegramBot('ここにアクセストークンを指定', { polling: true });

// Messageを受け取ったら実行
bot.on('message', (message) => {
	const { chat, text } = message;
	bot.sendMessage(chat.id, `メッセージを受信: ${text}`);
});

尚,利用可能な他のメソッドはTelegramの公式ドキュメントで詳しく解説されているのでカスタマイズしてみると面白いと思います.

結果

Response

Webhookの利用

Webhookを利用することも可能なので方法をご紹介します.上記のコードは全てpollingでイベントを受信していましたが,ここはExpressを使って受信用のアプリケーションを構築します.

まず追加で必要なライブラリをインストールします.

npm: 

npm install --save express body-parser

yarn:

yarn add express body-parser

証明書の発行

Webhookでのイベント受信には自己署名証明書(いわゆるオレオレ証明書)の発行が必要なのでOpenSSLを用いて発行します.Let’s encryptなどで発行したものでは正常にリクエストが送られてこないので注意してください.

openssl req -newkey rsa:2048 -sha256 -nodes -keyout key.pem -x509 -days 365 -out cert.pem

サンプル

Webhookでは,イベントが発生する度にTelegramのサーバーからPOSTリクエストが送信されるため,それをExpressで受信してbotに受け渡す必要があります.

以下のコードを参考に,ExpressとWebhookでbotを起動します.app.listen()で引数に指定したポート番号(例では8080)にリクエストが送信されるので,Webサーバー側で適切にプロキシの設定を行うことで運用が可能です.

const express     = require('express');
const bodyParser  = require('body-parser');
const TelegramBot = require('node-telegram-bot-api');

// トークンを指定してインスタンス化
const token = 'ここにアクセストークンを指定';
const bot   = new TelegramBot(token);

// Expressを起動
const app = express();

app.use(bodyParser.json());

app.post(`/bot${token}`, (req, res) => {
  api.processUpdate(req.body);
  res.sendStatus(200);
});

app.listen(8080);

// SSLの証明書とcallback用のURIを指定してイベントの受信をWebhookに
bot.setWebHook(`https://あなたのドメイン/bot${token}`, {
  certificate: '公開鍵のpath/crt.pem',
});

参考