「リッチメニュー」と「クイックリプライ」を利用した無料でできるLINEチャットボットアプリの作り方 (node.js + Heroku)
今回はクラウド環境Herokuを利用して無料でLINEチャットボットを作成してみました。
メッセージをそのまま返すサンプルはよくあるので、もう少し処理を加えて小学生低学年レベルの計算問題をやりとりするLINEチャットボット「バーチャル先生」を作成してみました。
LINE Messaging APIのリッチメニューやクイックリプライを利用していますので、これから使ってみようと思う方の参考になればと思います。
- 1. LINE チャットボットの完成イメージ
- 2. LINE チャットボットのシステム構成
- 3. LINE チャットボットの環境構築
- 4. GitHubの環境構築
- 5. Herokuの環境構築
- 6. LINEの環境構築
- 7. 開発環境の環境構築
- 8. LINE Official Accout Managerでリッチメニューを作成する
- 9. LINE Official Accout ManagerでDefaultの応答メッセージをOFFにする
- 10. node.js + express + @line/bot-sdkでチャットボットアプリを開発する
- 11. Herokuにデプロイ
- 12. LINE に作成したチャットボットを追加する
- 13. まとめ
LINE チャットボットの完成イメージ
スマホのLINEで表示したチャットボットの画面と各機能です。
画面イメージ
機能一覧
NO | ユーザ/チャットボット | 機能 | 内容 |
---|---|---|---|
1 | ユーザ | リッチメニュー | 「+」「-」「×」「÷」など計6つのボタンをクリックすると固定のメッセージを送信する (1) ピンクの「+」ボタン:「かんたんなたしざん」の文字列を送信 (2) 水色の「-」ボタン:「かんたんなひきざん」の文字列を送信 (3) 黄色の「×」ボタン:「かけざん(九九)」の文字列を送信 (4) 赤色の「+」ボタン:「難しい足し算」の文字列を送信 (5) 青色の「-」ボタン:「難しい引き算」の文字列を送信 (6) 白色の「÷」ボタン:「わりざん」の文字列を送信 |
2 | チャットボット | 問題作成 | (1)「かんたんなたしざん」の文字列を受信すると1~10の足し算の問題を送信 (2)「かんたんなひきざん」の文字列を受信すると1~10の引き算の問題を送信 (3)「かけざん(九九)」の文字列を受信すると九九の問題を送信 (4)「難しい足し算」の文字列を受信すると1~100の足し算の問題を送信 (5)「難しい引き算」の文字列を受信すると1~100の引き算の問題を送信 (6)「わりざん」の文字列を受信すると割り切れる割り算の問題を送信 全てクイックリプライを使って正解を4択で選ぶことができるようにする |
3 | ユーザ | 回答選択 | クイックリプライで表示された4択から回答を選ぶと、 「 ○ + ○ 」のこたえは『 ○』です。 の形式で回答を送信 |
4 | チャットボット | 回答確認 | ユーザから送信された 「 ○ + ○ 」のこたえは『 ○』です。 の文字列から正解か不正解かを判定し、結果を送信する 正解、不正解に合わせて送信するスタンプを分ける |
操作フローはNo 1~4の一連の動作を繰り返す続けることができるようになっています。
LINE チャットボットのシステム構成
構成要素 | 説明 |
---|---|
LINE Platform | ・Messaging APIを利用 |
LINE Official Accout Manager | ・応答メッセージ、プロフィール画像、リッチメニュー...等の設定 |
LINE Developers | ・Channel secret、Channel access tokenの取得(確認) ・Webhook URLの設定 |
Heroku(REST API) | ・Herokuはインフラストラクチャ管理が不要なクラウドベースの PaaS ・node.js(express)で作成したREST APIをデプロイできる ・無料で外部オリジン(ドメイン)からのリクエストに対応 |
Heroku(管理画面) | ・環境変数の設定 ・自動デプロイ設定(GitHubリポジトリとの紐づけ) ・デプロイ状態の確認 |
GitHub | ・HEROKUへのデプロイ対象とするリポジトリ ・HEROKUにもGitリポジトリがあるためそちらを利用する場合はGitHubは不要 ・masterブランチをデプロイ対象に設定 |
開発環境 | ・Visual Studio Code(VSCode) ・Gitクライアント ・Heroku CLI ・スマホ(LINEチャットボットの動作確認用) |
LINE チャットボットの環境構築
GitHub、Heroku、LINE、開発環境の4つを順番に設定していきます。
GitHubの環境構築
GitHubのアカウントを持っていない方は、Privateリポジトリも無料で作成できるので、この機会に取得してみましょう。
アカウントの作成は難しくはいですが、以下の記事を参考にしてみてください。
Herokuの環境構築
Herokuの環境構築で順です。
Herokuの環境変数の設定だけは、LINEの環境構築後に行う必要があります。
- Herokuのアカウント取得
- Herokuのアプリ作成
- GitHubのリポジトリから自動デプロイする設定
- Herokuの環境変数を設定(※LINEの環境構築後)
Herokuのアカウント取得
以下のURLにアクセスし、無料アカウントを作成しましょう。
Herokuのアプリ作成
Herokuのダッシュボード画面の「New」から「Create new app」を選択しアプリケーションを作成しましょう。
ダッシュボードのURLがわからない場合は以下のリンクで表示できます。
https://dashboard.heroku.com/apps
アプリ作成時に入力した「App name」が、ドメイン名の一部になります。
具体的にこのようになります。
https://[アプリ名].herokuapp.com/
GitHubのリポジトリから自動デプロイする設定
作成したアプリを選択し、「Develop」タブを表示します。
今回は、GitリポジトリにGitHubを利用しますので、「GitHub」を選択しましょう。
その後は、GitHubのログインとリポジトリの選択を行います。
忘れがちですが、「Enable Automatic Deploys」のボタンを押してデプロイの自動化を行っておきましょう。
Herokuの環境変数を設定(※LINEの環境構築後)
この後作成する、node.jsのチャットボットアプリでLINEの「Channel secret」と「Channel access token」を設定する必要があります。
今回はこの値をハートコーディングせずに、環境変数から取得できるようにします。
また、ポート番号も環境変数で切り替えたいため、以下の3つの環境変数をHerokuに設定しましょう。
環境変数名 | 設定値 |
---|---|
CHANNEL_ACCESS_TOKEN | LINE Developers – [Basic settings] – [Channel access token]の値(※) |
CHANNEL_SECRET | LINE Developers – [Basic settings] – [Channel secret]の値(※) |
PORT | 80 |
(※)の2項目はLINE環境構築後に設定するので、環境変数名のみを登録しておくとよいです。
LINEの環境構築
LINEの環境構築で行う作業内容です。
- LINE Developersのアカウント取得
- Providerの作成
- Channel(Messaging API)の作成
- Channel secretの取得
- Channel access tokenの取得
- Webhook URLの設定とUse webhookの設定をON
LINE Developersのアカウント取得
以下のURLにアクセスしLINE Developersカウントを取得しましょう。
https://developers.line.biz/ja
ビジネスアカウントがない方は「LINEアカウントでログイン」から普段利用しているLINEのアカウントでログインできます。
Providerの作成
LINE Developersにログインし、「Provider」を作成しましょう。
「Create」ボタンから作成できます。
複数のChannel(Messaging APIなど)を管理する箱のイメージです。
Channel(Messaging API)の作成
作成したProviderを選択するとChannelの一覧画面が表示されます。
画像の赤枠の部分をクリックし、Channelを作成しましょう。
今回はチャットボットアプリを開発したいので、「Messaging API」を選択します。
特に設定で迷うところはないですが、各項目を一覧にすると以下のようになります。
項目 | 説明 |
---|---|
Channel type | Messaging APIを選択する |
Provider | 作成したProviderを選択する |
Channel icon | 会話時にチャットボット側の表示される画像をアップロードする |
Channel name | LINEに友達追加するときに表示される名前です |
Channel description | このチャットボットの説明です |
Category | アプリにあったカテゴリを選択する |
Subcategory | アプリにあったサブカテゴリを選択する |
Email address | Messaging APIおUpdate情報などを受け取るメールアドレスを設定する |
Privacy policy URL | 任意項目なので入力しなくてもよい |
Terms of use URL | 任意項目なので入力しなくてもよい |
利用規約 | 読んでからチェックする |
最後に「Create」ボタンをクリックするとChannelが作成されます。
Channel secretの取得
作成したChannelの[Basic settings]に[Channel secret]という項目がるので、文字列をコピーする。
表示されていない場合は、「Issue」ボタンをクリックすると表示される。
この文字列をHerokuの環境変数(CHANNEL_SECRET)に設定する
Channel access tokenの取得
作成したChannelの[Messaging API]に[Channel access token]という項目がるので、文字列をコピーする。
Channel作成後は表示されていないため、「Issue」ボタンをクリックしてaccess tokenを取得する。
この文字列をHerokuの環境変数(CHANNEL_ACCESS_TOKEN)に設定する
Webhook URLの設定とUse webhookの設定をON
作成したChannelの[Messaging API]に[Webhook settings]という項目がある。
Webhook URLにはHerokuで作成したアプリ名を元に以下のようにURLを設定する
「http://[herokuで作成したアプリ名].herokuapp.com/webhook」
「/webhook」としているのは、後ほどnode.jsで作成するREST APIのパスを「/webhook」で作成するため
Use webhookをONにするのをお忘れなく。
開発環境の環境構築
開発環境をローカルPCに構築します。
- Visual Studio Code(VSCode)
- Node.js
- Gitクライアント
- Heroku CLI
- スマホ(LINEチャットボットの動作確認用)
Visual Studio Code(VSCode)
無料で高機能なVisual Studio Codeがおすすめですが、普段使い慣れたエディタで問題なしです。
Visual Studio Codeのインストールはこちらから
https://azure.microsoft.com/ja-jp/products/visual-studio-code/
Node.js
今回はアプリをNode.jsとexpressを利用して作成しますので、Node.jsをインストールされていない方は、以下のサイトからダウンロードしてインストールしてください。
特にこだわりがなければ安定したバージョンの「TLS」版をインストールしましょう。
Gitクライアント
MACの方は最初からインストールされていると思いますが、Windowsの方でGitをインストールされていない方は、以下のサイトからダウンロードしインストールしてください。
Heroku CLI
今回、GitHubを利用しているので必須のツールではありませんが、Herokuでうまく動作いない場合にログなどを確認することができますので、以下のサイトからインストールしておきましょう。
https://devcenter.heroku.com/articles/heroku-cli
スマホ(LINEチャットボットの動作確認用)
このページを見ている方はおそらくLINEを利用されている方なので、割愛します。
LINE Official Accout Managerでリッチメニューを作成する
LINE Official Accout Managerにアクセスし、[リッチメニュー] の [作成]ボタンをクリックします。
リッチメニューのタイトルと表示期間を設定
リッチメニューのテンプレート選択
「テンプレートを選択」から6つのアクションが選べる左上のメニューを選択します。
リッチメニューの背景画像のアップロード
リッチメニューに設定できる画像は6つのメニューの場合以下の条件を満たす必要があります。
ファイル形式:JPG、JPEG、PNG
ファイルサイズ:1MB以下
画像サイズ:2500px × 1686px、2500px × 843px、1200px × 810px、1200px × 405px、800px × 540px、800px × 270px
今回使用した画像です。
リッチメニューのアクションを設定
No | タイプ | メッセージ |
---|---|---|
A | テキスト | かんたんなたしざん |
B | テキスト | かんたんなひきざん |
C | テキスト | かけざん(九九) |
D | テキスト | 難しい足し算 |
E | テキスト | 難しい引き算 |
F | テキスト | わりざん |
「保存」ボタンをクリック
忘れずに保存する
LINE Official Accout ManagerでDefaultの応答メッセージをOFFにする
Channelを作成した初期状態ではデフォルトの応答メッセージが設定されているので、オフにしておく
node.js + express + @line/bot-sdkでチャットボットアプリを開発する
開発環境の初期設定
まずは、初期設定を行う。
- git cloneでGitHubに作成したリポジトリを取得する
- npm initでpakeage.json作成
- npm install express @line/bot-sdkでインストール
git clone https://github.com/[gitアカウント]/[リポジトリ名].git
cd [リポジトリ名]
npm init
npm install express @line/bot-sdk
最終的なフォルダ/ファイル構成
プロジェクトのディレクトリ
│ .env
│ .gitignore
│ index.js
│ package-lock.json
│ package.json
│ Procfile
│ README.md
│
└─message
constant.js
defaultMessage.js
mathAnswer.js
mathQuestion.js
resMessage.js
ファイル名 | 内容 |
---|---|
.env | herokuの環境変数に設定した値をローカル実行用に設定 |
.gitignore | gitの管理対象外としたいファイルがある場合に設定 例.「.env」ファイルを対象外にするなど |
index.js | 実行されるメインのファイル ・LINEのSDKを利用した認証 ・メッセージの送受信処理 ・REST APIサーバの実行 |
package-lock.json | 説明できるほどわかっていません。。。 |
package.json | インストールしたパッケージやnum runで実行できるコマンドの管理 |
Procfile | Herokuで実行するコマンドを記載するファイル |
README.md | アプリの内容などを記載しておく、GitHubのリポジトリにアクセスするとデフォルトで表示される |
constant.js | 定数管理用ファイル |
defaultMessage.js | 想定外のメッセージがユーザから送信された場合に変身するメッセージ |
mathAnswer.js | ユーザから送信された回答のチェックと正解/不正解に対応した回答メッセージの生成 |
mathQuestion.js | たしざん、ひきざん、かけざん、わりざんの問題と四択選択肢メッセージの生成 |
resMessage.js | 受信したメッセージに応じた各処理への割り振り処理 |
index.js
line/bot-sdkを利用すると認証回りは苦労なく実装できます。
const line = require('@line/bot-sdk');
const express = require('express');
const resMessage = require('./message/resMessage');
// 開発環境(.envファイルの読み込み)
require('dotenv').config();
// LINE Developersのページの値をherokuに環境変数に設定しておく
const config = {
channelAccessToken: process.env.CHANNEL_ACCESS_TOKEN,
channelSecret: process.env.CHANNEL_SECRET
};
const client = new line.Client(config);
const app = express();
// 認証回りはLINEのSDKに任せる
app.post('/webhook', line.middleware(config), (req, res) => {
const events = req.body.events;
// 受信メッセージを順番に処理
Promise.all(events.map((event) => {
return reqEvent(event).catch(() => { return null; });
}))
.then((result) => {
res.status(200).json({}).end();
});
});
// 受信メッセージに対応するメッセージを返信
function reqEvent(event) {
if (event.type === 'message' && event.message.type === 'text') {
return client.replyMessage(event.replyToken, resMessage(event.message.text));
} else {
return Promise.resolve(null);
}
}
// サーバ起動
const port = process.env.PORT || 80;
app.listen(port, () => {
console.log(`listening on port ${port}`);
});
constant.js
ユーザからの送信メッセージをまとめる
const Constant = {
ADDITION_EASY: 'かんたんなたしざん',
SUBTRACTION_EASY: 'かんたんなひきざん',
MULTIPLICATION_99: 'かけざん(九九)',
ADDITION_DIFFICULT: '難しい足し算',
SUBTRACTION_DIFFICULT: '難しい引き算',
DIVISION: 'わりざん'
}
module.exports = Constant;
defaultMessage.js
リッチメニューを利用せずに、ユーザが入力したメッセージを受信した場合の返信を用意しておく。
const defaultMessage = () => {
const initQuestion = {
type: 'text',
text: `もっとべんきょうする?`
}
return initQuestion;
}
module.exports = defaultMessage;
mathAnswer.js
ユーザが選択した回答が正解か不正解かを判定して、結果を送信してます。
typeに「sticker」を指定すると、LINEスタンプを送信することができます。
送信するスタンプの種類は「packageId」と「stickerId」で指定します。
const mathAnswer = (reqMessage) => {
// 数値3つを取得
const anss = reqMessage.match(/\d+/g);
// 演算子により正解を計算
let ans = 0;
switch (true) {
case /+/.test(reqMessage):
ans = parseInt(anss[0]) + parseInt(anss[1]);
break;
case /-/.test(reqMessage):
ans = parseInt(anss[0]) - parseInt(anss[1]);
break;
case /×/.test(reqMessage):
ans = parseInt(anss[0]) * parseInt(anss[1]);
break;
case /÷/.test(reqMessage):
ans = parseInt(anss[0]) / parseInt(anss[1]);
break;
}
if (ans === parseInt(anss[2])) {
// 正解
message = [
{
type: 'sticker',
packageId: '11537',
stickerId: '52002735',
stickerResourceType: 'STATIC'
},
{
type: 'text',
text: 'せいかい!\nやったー'
}
];
} else {
// 不正解
message = [
{
type: 'sticker',
packageId: '11537',
stickerId: '52002765',
stickerResourceType: 'STATIC'
},
{
type: 'text',
text: `ざんねん~\nこたえは『${ans}』だよ`
}
];
}
return message;
}
module.exports = mathAnswer;
mathQuestion.js
かなり冗長なコードですが、6パターンのリッチメニューに応じた問題を作成します。
クイックリプライはgetChoiceで作成しています。
const Constant = require('./constant');
const mathQuestion = (mathType) => {
switch (mathType) {
// 足し算(かんたん)
case Constant.ADDITION_EASY:
return mathQuestionADDITION_EASY();
break;
// 引き算(かんたん)
case Constant.SUBTRACTION_EASY:
return mathQuestionSUBTRACTION_EASY();
break;
// 掛け算(九九)
case Constant.MULTIPLICATION_99:
return mathQuestionMULTIPLICATION_99();
break;
// 足し算(むずかしい)
case Constant.ADDITION_DIFFICULT:
return mathQuestionADDITION_DIFFICULT();
break;
// 引き算(むずかしい)
case Constant.SUBTRACTION_DIFFICULT:
return mathQuestionSUBTRACTION_DIFFICULT();
break;
// 割り算
case Constant.DIVISION:
return mathQuestionDIVISION();
break;
default:
break;
}
}
// ADDITION_EASY
const mathQuestionADDITION_EASY = () => {
// 1-10の足し算
const num1 = Math.floor(Math.random() * 10 + 1);
const num2 = Math.floor(Math.random() * 10 + 1);
const ansOk = num1 + num2;
const ansNg = [ansOk - 1, ansOk + 1, ansOk + 2];
let ans = [ansOk, ...ansNg];
ans = shuffle(ans);
return makeMathQuestionMessage(num1, num2, ans, '+');
}
// SUBTRACTION_EASY
const mathQuestionSUBTRACTION_EASY = () => {
// 1-10の引き算
const tmp1 = Math.floor(Math.random() * 10 + 1);
const tmp2 = Math.floor(Math.random() * 10 + 2);
let num1 = 0;
let num2 = 0;
if (tmp1 > tmp2) {
num1 = tmp1;
num2 = tmp2;
} else if (tmp1 < tmp2) {
num1 = tmp2;
num2 = tmp1;
} else {
num1 = tmp1 + 2;
num2 = tmp2;
}
const ansOk = num1 - num2;
const ansNg = [ansOk - 1, ansOk + 1, ansOk + 2];
let ans = [ansOk, ...ansNg];
ans = shuffle(ans);
return makeMathQuestionMessage(num1, num2, ans, '-');
}
// MULTIPLICATION_99
const mathQuestionMULTIPLICATION_99 = () => {
// 九九
const num1 = Math.floor(Math.random() * 9 + 1);
const num2 = Math.floor(Math.random() * 9 + 1);
const ansOk = num1 * num2;
const ansNg = [ansOk - 1, ansOk + 1, ansOk + 2];
let ans = [ansOk, ...ansNg];
ans = shuffle(ans);
return makeMathQuestionMessage(num1, num2, ans, '×');
}
// ADDITION_DIFFICULT
const mathQuestionADDITION_DIFFICULT = () => {
// 1-10の足し算
const num1 = Math.floor(Math.random() * 100 + 1);
const num2 = Math.floor(Math.random() * 100 + 1);
const ansOk = num1 + num2;
const ansNg = [ansOk - 10, ansOk + 10, ansOk + 5];
let ans = [ansOk, ...ansNg];
ans = shuffle(ans);
return makeMathQuestionMessage(num1, num2, ans, '+');
}
// SUBTRACTION_DIFFICULT
const mathQuestionSUBTRACTION_DIFFICULT = () => {
// 1-100の引き算
const tmp1 = Math.floor(Math.random() * 100 + 1);
const tmp2 = Math.floor(Math.random() * 99 + 1);
let num1 = 0;
let num2 = 0;
if (tmp1 > tmp2) {
num1 = tmp1;
num2 = tmp2;
} else if (tmp1 < tmp2) {
num1 = tmp2;
num2 = tmp1;
} else {
num1 = tmp1 + 8;
num1 = tmp2;
}
const ansOk = num1 - num2;
const ansNg = [ansOk - 1, ansOk + 1, ansOk + 2];
let ans = [ansOk, ...ansNg];
ans = shuffle(ans);
return makeMathQuestionMessage(num1, num2, ans, '-');
}
// DIVISION
const mathQuestionDIVISION = () => {
// わりざん
const tmp1 = Math.floor(Math.random() * 9 + 1);
const tmp2 = Math.floor(Math.random() * 9 + 1);
const tmp3 = tmp1 * tmp2;
const num1 = tmp3;
const num2 = tmp1;
const ansOk = tmp2;
const ansNg = [ansOk - 1, ansOk + 1, ansOk + 2];
let ans = [ansOk, ...ansNg];
ans = shuffle(ans);
return makeMathQuestionMessage(num1, num2, ans, '÷');
}
// 問題用のメッセージの組み立て
const makeMathQuestionMessage = (num1, num2, ans, operator) => {
const getChoice = (i) => {
return (
{
type: 'action',
action: {
type: 'message',
label: ans[i].toString(),
text: `「 ${num1} ${operator} ${num2} 」のこたえは『 ${ans[i].toString()} 』です。`
}
}
)
}
const mathQuestion = {
type: 'text',
text: `「 ${num1} ${operator} ${num2} 」はなにかな?`,
quickReply: {
items: []
}
}
for (i = 0; i < ans.length; i++) {
mathQuestion.quickReply.items.push(getChoice(i));
}
return mathQuestion;
}
// 回答の選択肢をシャッフル
const shuffle = ([...array]) => {
for (let i = array.length - 1; i >= 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
return array;
}
module.exports = mathQuestion;
resMessage.js
index.jsから呼び出されるフロー制御用。
const Constant = require('./constant');
const mathQuestion = require('./mathQuestion');
const mathAnswer = require('./mathAnswer');
const defaultMessage = require('./defaultMessage');
const resMessage = (reqMessage) => {
// 返信用メッセージを組み立てる
let message;
if (
reqMessage === Constant.ADDITION_EASY ||
reqMessage === Constant.SUBTRACTION_EASY ||
reqMessage === Constant.MULTIPLICATION_99 ||
reqMessage === Constant.ADDITION_DIFFICULT ||
reqMessage === Constant.SUBTRACTION_DIFFICULT ||
reqMessage === Constant.DIVISION
) {
// 問題用メッセージを作成
message = mathQuestion(reqMessage);
} else if (/^「.+」.+『.+』.+$/g.test(reqMessage)) {
// 回答をチェックし正解/不正解のメッセージを作成
message = mathAnswer(reqMessage);
} else {
// 予想したメッセージ以外を受信した場合
message = defaultMessage();
}
return message;
}
module.exports = resMessage;
package.json
{
"name": "line-virtual-teacher",
"version": "1.0.0",
"description": "line-virtual-teacher",
"main": "index.js",
"scripts": {
"start": "node index.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/xxx/line-chatbot.git"
},
"keywords": [],
"author": "",
"license": "ISC",
"bugs": {
"url": "https://github.com/xxx/line-chatbot/issues"
},
"homepage": "https://github.com/xxx/line-chatbot#readme",
"dependencies": {
"@line/bot-sdk": "^6.8.4",
"dotenv": "^8.2.0",
"express": "^4.17.1"
}
}
“scripts" に "start": “node index.js" を追加しておきましょう
Procfile
web: node index.js
Herokuにデプロイ
デプロイはGitHubにPushするだけ
Herokuで自動デプロイの設定を行っているので、GitHubのmasterブランチにpushするだけでherokuがpushを検知し、デプロイを行います。
Heroku管理画面での確認方法
デプロイの実行結果の確認は「Activity」で確認できます。
LINE Developersでの確認方法
LINE Developersの[Messaging API]の[Webhook]の「検証」ボタンをクリックするとHerokuにデプロイしたREST APIが正常に稼働しているかを検証できます。
成功すると以下のようなメッセージが表示されます。
LINE に作成したチャットボットを追加する
いくつか方法はありますが、サクッと追加する方法として、LINE Developersの[Messaging API]の[QRコード]で読み込む方法です。
LINEの友達追加で表示されているQRコードで追加してみましょう。
正常に動作していれば、「LINE チャットボットの完成イメージ」の通りの動作になっているはずです。
まとめ
LINE Developersやherokuのアカウント取得から初めて、10時間ほどで作成することができましたので、javascriptの勉強をしていて、何か実際にスマホで動くものを作りたい方には、お手軽でおすすめです。
本当はherokuではなくfirebaesのfunctionsを利用したかったのですが、無料プランの場合は外部オリジンからのアクセスができないようでしたので、herokuを利用することにしました。
1記事で記載したため長文になってしました。
ここまで読んでくださって、ありがとうございました。