Help us understand the problem. What is going on with this article?

1時間でLINE BOTを作るハンズオン (資料+レポート) in Node学園祭2017 #nodefest

1時間でLINE BOTを作るハンズオン (資料+レポート) in Node学園祭2017 #nodefest

by n0bisuke
1 / 45

last updated 2020/4/4

この資料について

  • この資料をハンズオンなどに活用してNode.js普及を促進させてもらえたら幸いです。
    • 使うときにコメント欄にコメント貰えると嬉しいです!
    • ハンズオン進めてみた感想などもコメント貰えると嬉しいです!
  • 会の流れとしてはハンズオン -> もくもく会 -> (可能な人は)もくもく会で作ったBOTを発表という流れです。
  • どこまでやるか
    • 手元で確認するだけであればSTEP3まででOK
    • ホスティングしてハンズオン後も使いたいならSTEP4まで
  • アップデート
    • 2018/3/14 ngrokのインストールをnpm経由に変更
    • 2018/8/28 本体のディベロッパー画面が更新されてるので変更
    • 2018/11/24 nowのバージョンアップに伴ってnow.jsonの記述を追加
    • 2019/5/14 LINE@アカウントのLINE公式アカウントへの統合に伴ったフロー変更などを適用、事例に市川市追加、nowのデプロイ方法の更新
    • 2019/6/11 疎通確認でエラーが出るのは問題ないですが、そこで接続できないと問い合わせが多いためserver.jsに疎通確認用のコードを追加。
    • 2019/6/14 nowをv2に対応
    • 2019/7/31 ngrokでのトンネリング箇所をserveoにも対応
    • 2019/8/24 Webhookの設定方法を公式アカウントマネージャー側へ
    • 2020/4/4 nowのデプロイ手順更新、サンプルコード更新
    • 2020/5/22 デプロイの部分をVercelに変更かつ、外部記事へ
    • 2020/6/14 天気APIのコードを微修正


はじめに

  • 対象者: Node.js初心者向け
  • 目的: LINE BOTを作ってNode.jsに触れる
  • ゴール目標: LINE BOTを作ってデプロイする
  • 性質上、Node.js以外の話の方が多いかも
  • 1Hしかないのでコード理解よりも動くものを
  • 早く終わった人はもくもくタイム

自己紹介


LINE BOT

  • LINE上で動作するBOT
  • 様々なプログラムと連携させることができる
  • LINE自体のユーザー数が多いことで、追加でアプリインストールがほぼ不要なことが利点
  • LINEがUIになるのでUIを考える手間が少なく、サーバーサイドエンジニア的に嬉しい

事例: みずほ、出前館


事例: ヤマト運輸


行政事例: 市川市

https://linecorp.com/ja/pr/news/ja/2019/2642


LINE Messaging API

LINE BOTを作るためのAPIです。

Messaging APIを利用することで、あなたのサービスをLINEのトークルーム上で提供することができます。
LINEユーザー一人一人に合わせたユーザー体験を提供できます。


スクリーンショット 2017-02-05 9.10.01.png


Push APIとReply API

スクリーンショット 2017-02-05 9.09.22.png

基本的にPushとReplyの二つのAPIがあります。

PushはBotアプリケーション側が起点となってユーザーにアクションします。
Replyはユーザーの発言を起点としてBotアプリケーションを呼び出します。


作ってみよう


1. Botアカウントを作成する

LINEのBotはTwitterなどと違い、通常のユーザーのアカウントをBot化することは出来ず、専用のアカウントを作る必要があります。


LINEディベロッパーサイトへログイン

まずはLINE developersのサイトにアクセスし、ログインしましょう。

スクリーンショット 2019-05-14 15.32.42.png

LINEアカウントでのログインを求められます。メールアドレスとパスワードもしくはQRコードでログインできます。ログインできない場合はLINEのスマートフォンアプリ側で設定を確認しましょう。

設定がまだの方はLINEのスマートフォンアプリ画面から 設定>アカウントでメールアドレスを設定できます。
LINEでメールアドレスを新規登録・確認・変更・登録解除(削除)する方法


プロバイダーの作成

ログインしたらプロバイダーの作成を行います。プロバイダーは自分が作るLINE BOTなどの開発者名やチーム名、企業名になります。初回だけディベロッパー登録で個人情報を聞かれると思うので回答してから進めましょう。

スクリーンショット 2019-05-14 15.38.42.png

新規プロバイダー作成ボタンを押して進み、プロバイダー名を入力して進めましょう。

スクリーンショット 2019-05-14 15.41.04.png


Messaging APIの新規チャンネルを作成

チャンネルを作成します。今回はLINE BOTを作るMessaging APIを選択します。

スクリーンショット 2019-05-14 15.42.03.png

Messaging APIの「チャンネル作成する」を選択しましょう。


BOTの情報入力

BOTの情報を入力していきます。

スクリーンショット 2019-05-14 15.48.52.png

  • アプリアイコン画像(任意): BOTのアイコンになる画像を選びましょう。
  • アプリ名(必須): BOTの名前を入力しましょう。LINEという文字列は使えなかった気がします。
  • アプリ説明(必須): BOTの説明を入力しましょう。取り急ぎは適当でも大丈夫。
  • 大業種/小業種(必須): BOTのカテゴリを選択します。取り急ぎは適当でも大丈夫。
  • メールアドレス(必須): BOTの開発者にLINE側からお知らせがあるときに受け取るメールアドレス。
  • プライバシーポリシーURL/サービス利用規約URL(任意):これも取り急ぎはなくても大丈夫です。

※昔はここでプラン設定(Developer Trial or FREE)をしていましたが、公式アカウントへの統合に伴って選択肢がなくなりました。

同意にチェックと確認して作成

同意にチェック/確認して作成


Botの設定確認

作ったBOTを選択しましょう。

こんな感じの基本設定画面になります。

スクリーンショット 2020-04-03 1.51.31.png

ここで設定を変更していきます。

忘れがちなのがWebhook送信を「利用する」にするところです。
その他は以下の設定にしておくことをオススメします。

  • Webhook送信: 利用する
  • Botのグループトーク参加: 利用する
  • 自動応答メッセージ: 利用しない
  • 友達追加時あいさつ: 利用する

2019年4月以降はLINE公式アカウントマネージャーに遷移して設定する形になっています。


Botと友達になろう

画面下部にあるLINEアプリへのQRコードを確認します。

ここで表示されるQRコードを使って、自分が作成したBotアカウントと友達になりましょう。

ここからはスマートフォン画面のキャプチャになります。

QRコードリーダーを開きBotを友達追加しましょう。

「追加」を選択します。

「同意する」を選択します。

Botが友達に追加されました。


2. Node.jsでBot開発

ここからは手元のターミナルなどでの作業がメインになります。
Node.jsのインストールがまだの方は参考記事などをもとに準備をして下さい。


ちなみに、筆者の環境は以下になります。 (2019/5/14時点)

  • Node.js v12.2.0
  • npm v6.9.0
  • macOS Mojave 10.14

プロジェクトを作成とハローワールド

Node.jsのプロジェクトはpackage.jsonがあるディレクトリが起点となります。
まずはnpm initコマンドpackage.jsonを作成します。

$ mkdir mylinebot
$ cd mylinebot
$ npm init -y
Wrote to /Users/n0bisuke/dotstudio/2_events/20171125_nodefest/linebot/mylinebot/package.json:

{
  "name": "mylinebot",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

次に依存モジュールを追加します。 今回はこちらのSDKを利用します。

ちなみに以前は公式のNode.js SDKが無かったので依存なしでも書いてました。

$ npm i @line/bot-sdk express

次にプログラムのメインとなるserver.jsをmylinebotフォルダ内に作成します。

  • Macだとtouchコマンド
$ touch server.js
  • windowsだとnulコマンド(らしい)
$ type nul > server.js

コマンドじゃなくてもエディタの新規作成などで大丈夫です。

ディレクトリ内は現状こんな感じです。 (Windowsの人はlsが使えないのでdirを使いましょう)

$ ls
server.js            node_modules      package-lock.json package.json

エディタでserver.jsを編集します。
以下をコピー&ペーストしましょう。

server.js
'use strict';

const express = require('express');
const line = require('@line/bot-sdk');
const PORT = process.env.PORT || 3000;

const config = {
    channelSecret: '作成したBOTのチャンネルシークレット',
    channelAccessToken: '作成したBOTのチャンネルアクセストークン'
};

const app = express();

app.get('/', (req, res) => res.send('Hello LINE BOT!(GET)')); //ブラウザ確認用(無くても問題ない)
app.post('/webhook', line.middleware(config), (req, res) => {
    console.log(req.body.events);

    //ここのif分はdeveloper consoleの"接続確認"用なので削除して問題ないです。
    if(req.body.events[0].replyToken === '00000000000000000000000000000000' && req.body.events[1].replyToken === 'ffffffffffffffffffffffffffffffff'){
        res.send('Hello LINE BOT!(POST)');
        console.log('疎通確認用');
        return; 
    }

    Promise
      .all(req.body.events.map(handleEvent))
      .then((result) => res.json(result));
});

const client = new line.Client(config);

async function handleEvent(event) {
  if (event.type !== 'message' || event.message.type !== 'text') {
    return Promise.resolve(null);
  }

  return client.replyMessage(event.replyToken, {
    type: 'text',
    text: event.message.text //実際に返信の言葉を入れる箇所
  });
}

app.listen(PORT);
console.log(`Server running at ${PORT}`);

後ほどの書き換えに備えてfunction handleEvent()の箇所はasyncにしました。 (2020/4/4)


Channel Secretとアクセストークンの確認

先ほどの「LINE developers」の画面でChannel SecretChannel Access Tokenを確認します。

  • Channel Secret確認

  • アクセストークン発行


server.jsのソースコードのchannelAccessTokenchannelSecretの部分に値を指定しましょう。

アプリケーションを起動してみます。

$ node server.js

起動すると以下がターミナルに表示されることを確認しましょう。

Server running at 3000

ここで問題なければブラウザでhttp://localhost:3000にアクセスすると`Hello LINE BOT!`と表示されると思います。


3. ngrokでトンネリング


LINE Botを作るためにはWebhookURLをLINE developersに登録する必要があります。


この際SSLが必須になるのですが証明書取得などの手間もありますし、PaaSなどにホスティングして試すのはデバッグが大変なので、手元のPCのlocalhostにグローバルからアクセスできるようにするトンネリングツールを利用しましょう。

などが有名です。今回はngrokを利用します。


まずはngrokのサイトにいき、本体をダウンロードして解凍します。

この辺の手順を更新しました。(2018/3/14)

npm経由でngrokをインストールできます。

https://www.npmjs.com/package/ngrok

$ npm i -g ngrok

次にトンネリングサーバーを起動します。 ngrok http ポート名と指定します。
今回はNode.jsアプリケーションを3000番ポートで利用するので3000を指定しましょう。

$ ngrok http 3000

ngrok by @inconshreveable                                    (Ctrl+C to quit)

Session Status                online
Account                       n0bisuke (Plan: Free)
Version                       2.1.18
Region                        United States (us)
Web Interface                 http://127.0.0.1:4040
Forwarding                    http://1148cbd9.ngrok.io -> localhost:3000
Forwarding                    https://1148cbd9.ngrok.io -> localhost:3000

Connections                   ttl     opn     rt1     rt5     p50     p90
                              0       0       0.00    0.00    0.00    0.00

起動すると表示されるhttps://で始まるアドレスを利用します。
この場合はhttps://1148cbd9.ngrok.ioです。このアドレスは起動の度に変わるため、ngrokは起動し続けて開発を行うことをおススメします。


以下のように、ngrokのプロセスとNode.jsアプリケーションのプロセスを並行して実行しての開発になります。


Webhook URLの更新

https://1148cbd9.ngrok.io/webhookがWebhook URLになります。

LINE developers画面のWebhook URLを更新します。

2019年4月以降は公式アカウントマネージャー側で更新しないといけない模様です。

スクリーンショット 2019-08-24 3.28.44.png

スクリーンショット 2019-08-24 3.26.15.png

ここに先ほどのアドレスを指定しましょう。 URLの末尾に/webhookをつけるのを忘れずに


この状態でBotに話しかけてみて下さい。

Botがおうむ返ししてくれます。

補足: serveoの利用 - ngrokのインストールがうまくいかない場合など

2019年7月頃、ngrokよりserveoがすごい。0秒で localhostを固定URLで公開
の記事がバズってました。

serveoでのやり方も紹介します。そのうちこの記事もngrokから差し替えるかもしれません。

ポリシー的にどうなん?みたいな会話もあるのでとりまこれくらいの追記で......笑

serveoはインストールなど不要です。利用したいドメイン名を指定してngrokを立ち上げるようにNode.jsのプロセスとは別タブや別ウィンドウを新規に立ち上げて以下を実行しましょう。

$ ssh -o ServerAliveInterval=60 -R <利用したいドメイン名>:80:localhost:<Node.jsなどのプログラムを立ち上げてるポート> serveo.net

例えばlocalhost:3000https://n0bisuke.serveo.netで利用したい。とかであれば以下のように実行します。

$ ssh -o ServerAliveInterval=60 -R n0bisuke:80:localhost:3000 serveo.net
Forwarding HTTP traffic from https://n0bisuke.serveo.net
Press g to start a GUI session and ctrl-c to quit.

あとは今回のプログラムだとhttps://n0bisuke.serveo.net/webhookをLINEの管理画面に設定すればOKです。


4. プログラムをデプロイして永続化する

ngrokだと、手元のパソコン上でプログラムが動作するため、パソコンを閉じると動作しなくなってしまいます。

永続的にLINE BOTを動かすために何かしらのサーバーにデプロイしましょう。

Vercelにデプロイ (2020/5/22更新)

今回は、Vercelを使ってみます。

Vercelとは

  • Node.js向けのPaaS / FaaS
    • RubyやGoなども使える
    • Docker対応した模様なのでかなり色々使える
  • 旧名称はnow.sh
  • CLIからコマンド一つでデプロイできる
  • Herokuなどよりもデプロイ手順が簡単

こちらの手順↓で進めてみましょう。

VercelでLINE BOTを動かす 2020年5月版


補足資料

補足内容です。

補足資料その1 - if文で条件分岐

  • event.message.textがユーザーから送られてきた文字列
  • こんにちはとBOTに送るとこんばんわの時間ですよと言われて、それ以外だとうざと返されるプログラムが以下になります。
  • client.replyMessage()でBOTのリプライになります。
server.js

省略


async function handleEvent(event) {
  if (event.type !== 'message' || event.message.type !== 'text') {
    return Promise.resolve(null);
  }

  let replyText = '';
  if(event.message.text === 'こんにちは'){
    replyText = 'こんばんわの時間ですよ';
  }else{
    replyText = 'うざ';
  }

  return client.replyMessage(event.replyToken, {
    type: 'text',
    text: replyText
  });
}

省略



補足資料その2 - 天気APIを使う応用 (2020/4/4更新)

天気を教えてくれるBOTを作ってみましょう。

ライブドアの天気APIを利用してみます。

http://weather.livedoor.com/weather_hacks/webservice

  • axiosのインストール

外部のAPIにアクセスするためにaxiosをmylinebotのプロジェクトにインストールします。

npm i axios
  • server.jsの冒頭箇所にconst axios = require('axios');を追記します。
server.js
'use strict';

const axios = require('axios'); //追記
const express = require('express');
const line = require('@line/bot-sdk');
const PORT = process.env.PORT || 3000;



(省略)
  • server.jsの該当箇所(async function hendleEvent(){}の中)を書き換えます。
server.js


省略



async function handleEvent(event) {
  if (event.type !== 'message' || event.message.type !== 'text') {
    return Promise.resolve(null);
  }

  //"天気教えて"以外の場合は反応しない
  if(event.message.text !== '天気教えて') {
    return client.replyMessage(event.replyToken, {
      type: 'text',
      text: '"天気教えて"と言ってね'
    });
  }

  let replyText = '';
  replyText = 'ちょっと待ってね'; //"ちょっと待ってね"ってメッセージだけ先に処理
  await client.replyMessage(event.replyToken, {
      type: 'text',
      text: replyText
  });

  //axiosを使って天気APIにアクセス
  const CITY_ID = `400040`; //ライドアのAPIから取得したいシティのIDを
  const URL = `http://weather.livedoor.com/forecast/webservice/json/v1?city=${CITY_ID}`;
  const res = await axios.get(URL);
  const pushText = res.data.description.text;
  return client.pushMessage(event.source.userId, {
      type: 'text',
      text: pushText,
  });
}



省略



補足資料その3 - スクレイピングと組み合わせる

APIが無いサイトでもスクレイピングすると情報を取得できます。
が、ご利用は自己責任でお願いします。

花粉ボットと実装サンプル


応用


応用回答例: Node.jsの最新を教えてくれるBOT 答え合わせ

  • Node.jsの最新バージョン教えて!と言われたらとりあえずちょっと待ってねとリプライメッセージ
  • https://nodejs.org/ja/ にスクレイピングしにいって、完了したらプッシュメッセージで教えてくれる
  • async/awaitでaxiosのHTTPリクエストとLINE MASSAGING APIへのリクエストを同期処理的に記述

axiosを追加インストール

npm i axios
server.js
'use strict';

const express = require('express');
const line = require('@line/bot-sdk');
const axios = require('axios');
const PORT = process.env.PORT || 3000;

const config = {
    channelSecret: '',
    channelAccessToken: ''
};

const app = express();

app.post('/webhook', line.middleware(config), (req, res) => {
    console.log(req.body.events);
    Promise
      .all(req.body.events.map(handleEvent))
      .then((result) => res.json(result));
});

const client = new line.Client(config);

function handleEvent(event) {
  if (event.type !== 'message' || event.message.type !== 'text') {
    return Promise.resolve(null);
  }

  let mes = ''
  if(event.message.text === 'Node.jsの最新バージョン教えて!'){
    mes = 'ちょっとまってね'; //待ってねってメッセージだけ先に処理
    getNodeVer(event.source.userId); //スクレイピング処理が終わったらプッシュメッセージ
  }else{
    mes = event.message.text;
  }

  return client.replyMessage(event.replyToken, {
    type: 'text',
    text: mes
  });
}

const getNodeVer = async (userId) => {
    const res = await axios.get('https://nodejs.org/ja/');
    const item = res.data;
    const version = item.match(/最新版"  data-version="(.*?)">/)[1]; //正規表現で(無理やり)取得
    console.log(version);

    await client.pushMessage(userId, {
        type: 'text',
        text: `今の最新は${version}だよ!`,
    });
}

app.listen(PORT);
console.log(`Server running at ${PORT}`);

レポート: 参加者の方々が作ったBOTを紹介(ハンズオン後に追記)

もくもくタイムは20min程度でしたが、皆さんすごいです。

1. Node.jsの最新バージョン+ヤフー検索ができるBOT

応用課題で出していたNode.jsのバージョンを教えてくれる機能もLTSと最新版の両方に対応してくれました。
スクレイピングの勢いでヤフー検索まで繋いでいます。

2. 調べたい単語を入れるとWikipediaの検索結果を返してくれるBOT

これめっちゃ便利です。
Wikipediaまでわざわざ調べに行かなくても色々な言葉の概要を知ることができます。

3. URLを入れると話題のdev.toとどっちが速いかを教えてくれるBOT

話題ですね。

dev.toと阿部寛のホームページについてちゃんと計測させてくれ

dev.toと入力したサイトのどちらが早いか計測してくれます。
トレンドを捉えるアイディアの柔軟性がすごい。

4. 今日のご飯何にするかを絵文字で提案してくれるBOT!

ご飯何にしようか迷いますよね。
絵文字で推薦してくれるのでもう迷わない......!

コード指定すればNode.jsからも絵文字扱えるんだよっていう良い例だと思います。

5. 何でも人に聞く人にググらせるBOT

「調べる前になんでも人に聞く人を駆逐したい」らしいです笑

検索ワードを入れるとググれってことでGoogleに飛ばされます。
ハンズオンで触れていないリッチメニューまで活用してくれました。

6. Polymerと会話?できるBOT

Polymerが好きすぎてPolymerちゃんと会話できるBOTを作ったそうです笑

7.検索ワードを入れるとunsplash.comから画像を取得してくるBOT

画像検索も出て来ました。
画像扱えるとビジュアルが圧倒的に良くなりますね。


まとめと所感

Node.jsとNowを使うと爆速でLINE BOTを作れますし、細かいものを作るときにこの組み合わせはかなり使えます。 (デバッグの際はngrokがおすすめ)

応用してどんどん開発していきましょう。

見て回った限り、大半の人がデプロイまでたどり着くことができて、7人もオリジナルBOTを作って発表までできるのはさすがの学園祭的なレベルの高さを感じます。

時間内に終わらなかった人もこの記事を見直してチャレンジしてもらえたら幸いです。

参加してくださった皆さんありがとうございました!

n0bisuke
プロトタイピング専門スクール「プロトアウトスタジオ」で教えたりしてます。 プロフ -> https://dotstud.io/members/n0bisuke
https://protoout.studio
dotstudio
全ての人がモノづくりを楽しむ世界を目指して活動しています。
https://dotstud.io
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした