# (チュートリアル)Node.jsを使ってサンプル応答ボットを作る
Messaging APIは、サービスとLINEユーザーとの間で双方向のコミュニケーションを可能にする機能です。
Messaging APIの機能を利用してユーザーとの交流を深めることができます。様々な種類のメッセージの送信、ユーザープロフィールの取得、ユーザーが送信したコンテンツの取得など、その機能は多岐にわたります。
このチュートリアル記事では、Node.jsを使ってMessaging APIでメッセージを送信する方法を説明します。
# チュートリアルのゴール
このチュートリアルを最後まで進めると、Messaging APIの使い方を実践的に学べるとともにユーザーが送信したメッセージに自動的に応答するアプリが作成できます。
# 始める前に
このチュートリアルを始める前に、いくつかのコンセプトやツールについて確認しておくとよりスムーズに進めることができます。
このチュートリアルではMessaging APIの仕様の理解やアプリのカスタム化を目的として、LINEが提供するSDKを使わずにNode.jsでMessaging APIを使用する方法を紹介します。Node.jsでMessaging APIをより少ないコード行数で素早く利用したい場合は、LINE Messaging API SDK for nodejs (opens new window)の利用をお勧めします。
# 想定される技術的知識
このチュートリアルは、JavaScriptとNode.jsの基本的な知識を必要とします。
# Messaging APIの概要
このチュートリアルをスムーズに進めるために、『Messaging APIドキュメント』の「Messaging APIの概要」を読んでおくことをお勧めします。
# 必要なツール
Herokuの無料プランは、2022年11月27日をもって廃止されました。このチュートリアルを無料で試したい場合は、他のプラットフォームを利用してください。詳しくは、「Heroku’s Next Chapter (opens new window)」を参照してください。
アプリを作成するには、以下のツールの登録およびインストールが必要です。
アカウント登録するもの
- LINE Developersコンソールのアカウント(LINE DevelopersコンソールにLINEアカウントまたはビジネスアカウントでログインし、まだお持ちでなければ開発者アカウントを作成してください。)
- Heroku (opens new window)アカウント
インストールするもの
# Herokuの設定
まずは、Herokuの環境を整えましょう。ターミナルまたはコマンドラインツールを開いてください。
まだHeroku CLIにログインしていない場合は、このコマンドを実行しログインします。
heroku login
このコマンドをアプリを作成したい場所で実行すると、新しいディレクトリが作成され、Gitが初期化され、Herokuを使った新しいアプリが作成されます。
mkdir sample-app
cd sample-app
git init
heroku create {Name of your app}
{Name of your app}
には、一意の名前を入力してください。たとえば次のような名前を推奨します。msg-api-tutorial-{YYYYMMDD}
アプリが問題なく作成されると、HerokuのURLがhttps://{Name of your app}.herokuapp.com/
のような形式で生成されます。このURLは後で必要になります。
生成されたHerokuのURLに、ブラウザでアクセスしてみてください。ウェルカムページが表示されます。
# package.json
ファイルを作成する
npm
がプロジェクトを識別やプロジェクトのメタデータを保持、依存関係を処理できるようにするために、package.json
ファイルを作成しましょう。プロジェクトのルートディレクトリで、次のように実行します。
npm init -y
npm init
は、npmパッケージを初期化します。このチュートリアルでは特別な設定は必要ないので、-y
コマンドを使用して、パッケージをセットアップするための質問をすべてスキップします。
以下のようなpackage.json
が作成されます。
{
"name": "sample-app",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
また、Herokuのようなサーバープラットフォームが、サーバーの起動時にどのファイルを使用するかを知るために、スタートスクリプトを追加する必要があります。このチュートリアルでは、サーバーの設定ファイルとしてindex.js
を指定します。
作成したpackage.json
ファイルをテキストエディタで開き、"start": "node index.js"
を追加しましょう。
{
"name": "sample-app",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "node index.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
このプロジェクトのために追加でインストールされたパッケージは、package.json
で管理されます。このアプリでは、以下のパッケージを使用します。
- Express.js (opens new window)(軽量なNode.jsのWebサーバーフレームワーク)
以下のコマンドを実行して、このパッケージをインストールしましょう。
npm install express
Express.jsをインストールすると、node_modules
というディレクトリが作成されます。このディレクトリにはローカルでインストールしたパッケージが保存されます。
このディレクトリがHerokuにプッシュされることを防ぐため、.gitignore
ファイルを作成します。
以下のコマンドを実行して.gitignore
ファイルを作成します。
touch .gitignore
作成した.gitignore
ファイルをテキストエディタで開きます。.gitignore
の中に、以下を追加します。
node_modules/
# 開発を始める
# グローバル設定
サーバー設定ファイルのindex.js
を作りましょう。
touch index.js
作成したindex.js
ファイルをテキストエディタで開きます。index.js
の中に、以下を追加します。
const https = require("https")
const express = require("express")
const app = express()
ここでは、先ほどインストールしたexpress
パッケージと、https
パッケージをインポートした上で、express
をインスタンス化しています。https
は、このアプリのHTTPリクエストを処理するために使用するパッケージです。このパッケージは、Node.jsにデフォルトで付属しているので、express
パッケージのようにインストールする必要はありません。
続いて、必要な環境変数を追加しましょう。
環境変数とは、プログラムの外部で値が設定される変数です。このチュートリアルでは、設定プロセスを簡素化し、機密情報が誤って公開されるのを防ぐために使用します。
index.js
で、インポートしたパッケージの下に、以下を追加します。
const PORT = process.env.PORT || 3000
const TOKEN = process.env.LINE_ACCESS_TOKEN
process.env.PORT
は、サーバーがどのポートにListenするかを指定します。process.env.LINE_ACCESS_TOKEN
は、Messaging APIを呼び出すために必要なチャネルアクセストークンを指定します。
# ミドルウェアの設定
Express.jsは、ミドルウェアのWebフレームワークです。ミドルウェア関数を使って、リクエストとレスポンスのサイクルを決めることができます。
このチュートリアルでは、Express.jsに付属するミドルウェア関数であるexpress.json()
とexpress.urlencoded()
を使用して、リクエストオブジェクトをそれぞれJSON、文字列、配列として扱います。
ミドルウェアの機能を使用するために、app.use()
を呼び出します。index.js
に、以下を追加します。
app.use(express.json())
app.use(express.urlencoded({
extended: true
}))
# ルーティングの設定
それでは、ボットサーバに基本的なルーティングロジックを追加してみましょう。ベストプラクティスとして、ヘルスチェック等の失敗を防ぐためにドメインのルート(/
)へのHTTP GETリクエストに対してステータス200
を送信しましょう。
index.js
ファイルに以下を追加します。
app.get("/", (req, res) => {
res.sendStatus(200)
})
それでは、ボットサーバーに基本的なルーティングロジックを追加してみましょう。app.listen()
関数を使って、サーバーがListenするポートを指定します。 環境変数PORT
を設定しているので、特に指定されていない限り、3000
をリッスンします。
index.js
に、以下の項目を追加します。
app.listen(PORT, () => {
console.log(`Example app listening at http://localhost:${PORT}`)
})
ユーザーがボットと対話すると、LINEプラットフォームのサーバーは、ボットのサーバーがホストするWebhook URLにHTTP POSTリクエストを送信します。
app.post()
は、指定されたパスへのHTTP POSTリクエストをルーティングします。この関数を使って、ボットサーバがこれらのリクエストにどのように応答するかを設定できます。
index.js
で、app.get()
とapp.listen()
関数の間に、以下を追加します。
app.post("/webhook", function(req, res) {
res.send("HTTP POST request sent to the webhook URL!")
})
これは、/webhook
エンドポイントにHTTP POSTリクエストが送られてきたときに、HTTP POST request sent to the webhook URL!
というHTTPレスポンスを返すようにボットサーバに指示するものです。
ここまでで、index.js
は以下のようになっているはずです。
const https = require("https")
const express = require("express")
const app = express()
const PORT = process.env.PORT || 3000
const TOKEN = process.env.LINE_ACCESS_TOKEN
app.use(express.json())
app.use(express.urlencoded({
extended: true
}))
app.get("/", (req, res) => {
res.sendStatus(200)
})
app.post("/webhook", function(req, res) {
res.send("HTTP POST request sent to the webhook URL!")
})
app.listen(PORT, () => {
console.log(`Example app listening at http://localhost:${PORT}`)
})
それでは、エンドユーザーがメッセージを送信した際の返信を設定しましょう。
ユーザーからのメッセージに対して返信をするために、ユーザーからメッセージを受信したことを識別する必要があります。 ユーザーがボットにメッセージを送信すると、メッセージイベントオブジェクトがWebhook URLに送信されます。メッセージイベントオブジェクトにはtype
プロパティが含まれており、値は message
に設定されています。このmessage
を使って、受け取ったWebhookイベントオブジェクトが message
タイプであることを識別できます。
ユーザーに返信を送るには、応答メッセージを送るエンドポイント(https://api.line.me/v2/bot/message/reply
)を使います。
index.js
のapp.post
に以下を追加しましょう。
app.post("/webhook", function(req, res) {
res.send("HTTP POST request sent to the webhook URL!")
// ユーザーがボットにメッセージを送った場合、返信メッセージを送る
if (req.body.events[0].type === "message") {
// 文字列化したメッセージデータ
const dataString = JSON.stringify({
replyToken: req.body.events[0].replyToken,
messages: [
{
"type": "text",
"text": "Hello, user"
},
{
"type": "text",
"text": "May I help you?"
}
]
})
// リクエストヘッダー
const headers = {
"Content-Type": "application/json",
"Authorization": "Bearer " + TOKEN
}
// リクエストに渡すオプション
const webhookOptions = {
"hostname": "api.line.me",
"path": "/v2/bot/message/reply",
"method": "POST",
"headers": headers,
"body": dataString
}
// リクエストの定義
const request = https.request(webhookOptions, (res) => {
res.on("data", (d) => {
process.stdout.write(d)
})
})
// エラーをハンドル
request.on("error", (err) => {
console.error(err)
})
// データを送信
request.write(dataString)
request.end()
}
})
このコードを読み解いてみましょう。
まず、APIサーバーに送信する返信トークンと返信メッセージデータをJSON形式で定義し、それをdataString
変数で文字列化します。
headers
は、リクエストヘッダーに必要なプロパティを指定します。
また、リクエストに渡すオプションをwebhookOptions
変数で定義します。webhookOptions
は、Node.jsドキュメントのhttps.request (opens new window)メソッドで定義されている仕様に従ったオプションを指定します。エンドポイントのホスト名とパス、HTTPリクエストメソッド、headers
とbodyを指定します。
const dataString = JSON.stringify({
replyToken: req.body.events[0].replyToken,
messages: [
{
"type": "text",
"text": "Hello, user"
},
{
"type": "text",
"text": "May I help you?"
}
]
})
const headers = {
"Content-Type": "application/json",
"Authorization": "Bearer " + TOKEN
}
const webhookOptions = {
"hostname": "api.line.me",
"path": "/v2/bot/message/reply",
"method": "POST",
"headers": headers,
"body": dataString
}
message
タイプのHTTP POSTリクエストが/webhook
エンドポイントに送信されると、返信を送信するためにhttps://api.line.me/v2/bot/message/reply
エンドポイントにHTTP POSTリクエストを送信します。
request
変数を定義して、リクエストを設定します。
const request = https.request(webhookOptions, (res) => {
res.on("data", (d) => {
process.stdout.write(d)
})
}
request.on
は、APIサーバーへのリクエスト送信時にエラーが発生した場合にコールバックされる関数です。
request.on("error", (err) => {
console.error(err)
})
最後に、このコードが実行されると、定義したリクエストが送信されます。
request.write(dataString)
request.end()
最終的なコードは以下のようになります。
const https = require("https")
const express = require("express")
const app = express()
const PORT = process.env.PORT || 3000
const TOKEN = process.env.LINE_ACCESS_TOKEN
app.use(express.json())
app.use(express.urlencoded({
extended: true
}))
app.get("/", (req, res) => {
res.sendStatus(200)
})
app.post("/webhook", function(req, res) {
res.send("HTTP POST request sent to the webhook URL!")
// ユーザーがボットにメッセージを送った場合、返信メッセージを送る
if (req.body.events[0].type === "message") {
// 文字列化したメッセージデータ
const dataString = JSON.stringify({
replyToken: req.body.events[0].replyToken,
messages: [
{
"type": "text",
"text": "Hello, user"
},
{
"type": "text",
"text": "May I help you?"
}
]
})
// リクエストヘッダー
const headers = {
"Content-Type": "application/json",
"Authorization": "Bearer " + TOKEN
}
// リクエストに渡すオプション
const webhookOptions = {
"hostname": "api.line.me",
"path": "/v2/bot/message/reply",
"method": "POST",
"headers": headers,
"body": dataString
}
// リクエストの定義
const request = https.request(webhookOptions, (res) => {
res.on("data", (d) => {
process.stdout.write(d)
})
})
// エラーをハンドル
request.on("error", (err) => {
console.error(err)
})
// データを送信
request.write(dataString)
request.end()
}
})
app.listen(PORT, () => {
console.log(`Example app listening at http://localhost:${PORT}`)
})
本番用として、不特定多数のユーザー向けにボットを公開する場合には署名の検証が必要です。HTTPリクエストがLINEプラットフォームから送られたことを確認するために、リクエストヘッダーのx-line-signature
に含まれる署名を検証してください。
署名の検証方法について詳しくは、『Messaging APIドキュメント』の「署名を検証する」を参照してください。
# Messaging APIチャネルを準備する
Messaging APIの機能を利用するには、Messaging APIチャネルを作成し、Webhook URLを登録する必要があります。
Messaging APIチャネルを作成するには、『Messaging APIドキュメント』の「LINE Developersコンソールでチャネルを作成する」の手順に従ってください。
作成したMessaging APIチャネルの[Messaging API設定]タブで、チャネルアクセストークンを発行します。
[Messaging API設定]タブで、[Webhook URL]に、「Herokuの設定」で取得したHerokuのURLをhttps://{Name of your app}.herokuapp.com/webhook
のURL形式で記入します。Webhook URLはhttps://{Name of your app}.herokuapp.com/
ではないので注意してください。
HerokuのURLを忘れてしまった場合は、Heroku Dashboard (opens new window)で確認できます。
[Webhookの利用]を有効にします。
[Messaging API設定]タブのQRコードを読み取って、ボットに紐づけられたLINE公式アカウントを友だちとして追加します。
[応答メッセージ]と[あいさつメッセージ]を無効にします。
これで、Messaging APIチャネルの準備が整いました。
# Herokuでアプリをデプロイする
「グローバル設定」で、チャネルアクセストークンとして環境変数LINE_ACCESS_TOKEN
の値を使うように設定しました。Herokuにデプロイしたアプリを正常に動作させるために、環境変数LINE_ACCESS_TOKEN
を登録する必要があります。
ターミナルまたはコマンドラインツールで、「Messaging APIチャネルを準備する」で取得したチャネルアクセストークンを使って、以下を実行してください。
heroku config:set LINE_ACCESS_TOKEN={チャネルアクセストークンをここに入力してください}
これで、アプリをデプロイする準備が整いました。
ターミナルまたはコマンドラインツールで、以下のコードをHerokuにプッシュします。
git add .
git commit -m "First commit"
git push heroku master
# Webhook URLを検証する
Webhookが正常に動作しているか確認しましょう。
「Messaging APIチャネルを準備する」で作成したチャネルの[Messaging API設定]タブをクリックします。
[Webhook URL]の[検証]をクリックします。
Webhook URLに問題がない場合、「成功」のメッセージが表示されます。問題があった場合、エラーメッセージが表示されますので、メッセージの内容に沿って対応してください。
「成功」のメッセージが表示されたらサンプルボットの完成です!
LINEでボットにメッセージを送ってみてください。このようなメッセージが届くはずです。
# トラブルシューティング
ボットが正常に動作していない場合は、以下のコマンドを実行することでHerokuのログを確認できます。
heroku logs --tail
# 次のステップ
このボットには、さまざまな機能を追加できます。その例をいくつかご紹介します。
リッチメニューを送信して、ユーザーにタップ可能なオプションを表示できます。
ユーザーが特定のアクションを実行したときに送信されるアクションオブジェクトを使って、レスポンスを送信できます。
ユーザープロフィールの取得で、カスタマイズしたメッセージを送信できます。
前述の通り、LINE Messaging API SDK for nodejs (opens new window)を使えば、より素早くボットを開発できます。こちらもぜひご検討ください。