LINE botをVS Codeで開発してAzure Functionsへデプロイするメモ (Node.js版)(※動作確認でcloudflaredを使用する手順を追加)

# はじめに

LINE botをmacOS上のVS Codeで開発してAzure Functionsへデプロイする手順です。
Azure FunctionsでNode.js版LINE botを動かします。

# 手順(準備)

### 1. VS Codeをインストールする

執筆時点のバージョンは1.53でした。
https://code.visualstudio.com/

![スクリーンショット 2021-02-07 14.45.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/766be49c-eb4f-2ed8-92d3-dcb7572a46ae.png)

### 2. VS CodeにAzure Functions拡張機能を追加する

https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-azurefunctions

![スクリーンショット 2021-02-07 14.46.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/30393a16-0ba1-13ef-91dc-6a147c92a3a9.png)

### 3. Node.jsをインストールする

執筆時点のバージョンは14.15.4 LTSでした。
https://nodejs.org/

![スクリーンショット 2021-02-07 14.47.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/cb87092e-38b8-f482-eaeb-95b9b77abf7b.png)

### 4. ローカル環境でLINE Botを動作確認するための準備

ngrokを使用する方法とcloudflaredを使用する方法があります。

### 4-1. ngrokをインストールする

ダウンロードしてzipを解凍する。
https://ngrok.com/download

![スクリーンショット 2021-02-07 14.56.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/ef167e33-d4b0-3a4f-0c1e-b789834d8abd.png)

サインアップ(または、ログイン)して、authtokenの値を確認する。

![スクリーンショット 2021-02-07 15.07.31.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/5ee44ccf-ce29-5018-d887-07c8c42f2341.jpeg)

コマンドを実行してauthtokenを登録する。

```bash
$ ./ngrok authtoken <authtokenの値>
```

### 4-2. cloudflaredをインストールする

サインアップの必要はありません。

```bash
$ brew install cloudflare/cloudflare/cloudflared
```

### 5. LINE Developers Consoleでアカウントを作成する

新規チャンネル(Messaging API)を作成します。
https://developers.line.biz/console/

# 手順(LINE botの作成)

### 1. VS CodeのAzure Functionsで新規プロジェクトを作成する

![azure_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/5b8e6f90-f174-5b63-5095-57388a5c9ceb.jpeg)

フォルダを選択する
![スクリーンショット 2021-02-07 15.25.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/96f2a3cd-f6a6-cbc6-7fd0-8900f8ea8790.png)

言語(JavaScript)を選択する
![スクリーンショット 2021-02-07 15.26.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/f148b25f-4c0d-adb3-168b-0e288d26eb90.png)

テンプレート(HTTP trigger)を選択する
![スクリーンショット 2021-02-07 15.27.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/f4400feb-2f4e-fc5c-9495-d26aef82e2c7.png)

functionに名前(HTTP trigger1)をつける (そのまま改行でOK)
![スクリーンショット 2021-02-07 15.28.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/0ad61713-80b3-dbb0-8fcb-673f4161c07b.png)

Authorization level(Function)を選択する
![スクリーンショット 2021-02-07 15.28.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/11162d3e-2f09-5ce9-f0be-3619289fdd81.png)

プロジェクトを開く (Open in current windowを選択する)
![スクリーンショット 2021-02-07 15.29.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/56383483-62aa-7b27-839e-6421bc6e9d8b.png)

### 2. サンプルコードを実行する

サンプルコードをStart Debugging[F5]で実行する。
![sample_code.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/45c1d84e-c08c-39d4-75dc-5ee5dcf6e2ce.jpeg)

TERMINAL画面に表示されるURLをクリックしてブラウザで表示確認する。
![スクリーンショット 2021-02-07 16.03.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/7a6402f7-4ca9-6c3d-38ac-54d98ef9d47d.png)

ブラウザのURLの最後にパラメータ(?name=test)を追加して、表示が変わることを確認する。
![スクリーンショット 2021-02-07 16.04.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/990424c8-cfba-9732-9a65-0ea6194a2704.png)
![スクリーンショット 2021-02-07 16.04.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/2b052cd8-cb2b-239a-0b44-656b53d4bb3e.png)

### 3. チャンネルアクセストークンを設定する

LINE Developers ConsoleのMessaging API設定からチャンネルアクセストークンの値をコピーする。
![スクリーンショット 2021-02-07 15.50.58.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/cab47265-6ab2-7038-ad38-734c39975ab0.jpeg)

ローカル実行用の環境変数を設定する。(local.settings.jsonに環境変数を追加)
"ACCESS_TOKEN": "<チャンネルアクセストークンの値>",

![スクリーンショット 2021-02-07 16.11.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/d1d99e8b-3d39-b581-9365-d25276ded3aa.png)

### 4. index.jsの内容をLINE botに変更する。

![スクリーンショット 2021-02-07 16.16.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/b63c72ab-cc0e-ff4a-6eb4-b4b07eaa82e2.png)

ソースコードはこちらです。
https://raw.githubusercontent.com/kitazaki/azure_functions_nodejs_line_bot/main/index.js

```js:index.js
const line = require('@line/bot-sdk');

const client = new line.Client({
    channelAccessToken: process.env.ACCESS_TOKEN
    
});

module.exports = async function (context, req) {
    context.log('JavaScript HTTP trigger function processed a request.');
    console.log(req);

    if (req.query.message || (req.body && req.body.events)) {
        if (req.body && req.body.events[0]) {
            message = {
                type: "text",
                text: req.body.events[0].message.text
            }
            console.log(message);
            if (req.body.events[0].replyToken) {
                client.replyMessage(req.body.events[0].replyToken, message);
            }
        }
        else {
            context.res = {
                status: 200,
                body: req.query.message
            };
        }
    }
    else {
        context.res = {
            status: 200,
            body: "Please check the query string in the request body"
        };
    };
};
```

### 5. LINE botを実行する

TERMINALからline bot sdkをインストールする。

```bash
$ npm i @line/bot-sdk
```

![スクリーンショット 2021-02-07 16.22.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/adcc64ef-dd56-9366-875e-bf6637026818.png)

Start Debugging[F5]で実行する。

![スクリーンショット 2021-02-07 19.49.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/5711bea5-ee47-cfea-daa2-93b6f32628c1.png)


### (参考)脆弱性の対応

執筆時点でline bot sdkに脆弱性が1件含まれていました。
脆弱性を解消するためにはLINE botを停止して、手動で対応する必要があります。

```bash
$ npm audit
```

![スクリーンショット 2021-02-07 16.25.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/d1347c2a-f7cb-6172-e885-2b593a13c417.png)

bot-sdkに含まれるaxiosのバージョンが低いため、手動で更新します。

```bash
$ cd node_modules/\@line/bot-sdk
$ vi package.json
```

```json:package.json
(変更前)
"axios": "^0.20.0",
(変更後)
"axios": "^0.21.1",
```

```bash
$ npm i
$ npm audit fix
$ cd ../../..
$ npm i
```

脆弱性が0件になったことを確認します。

```bash
$ npm audit
found 0 vulnerabilities
```

### 6. ngrokまたはcloudflaredを実行する

### 6-1. ngrokを実行する

ターミナルを開いてngrokを実行します。

```bash
$ ./ngrok http 7071
```

![スクリーンショット 2021-02-07 19.53.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/ea5ef9f2-9eb8-8ffd-bfd0-1df23592b723.png)

### 6-2. cloudflaredを実行する

ターミナルを開いてcloudflaredを実行します。

```bash
$ cloudflared tunnel --url localhost:7071
```

![EyQNoswUcAE0S5r.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/d1a5bbe4-b0ac-a360-45d3-d3d88bd68f60.jpeg)

### 7. LINE developers consoleでWebhookの設定をする

LINE developers consoleのMessaging API設定からWebhookの設定をします。
URLはngrokまたはcloudflaredを実行する毎に変わります。

ngrokの例.

```text
https://c174833025ae.ngrok.io/api/HttpTrigger1
```

![スクリーンショット 2021-02-07 19.55.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/aec9b9d8-aa28-cfa7-95e0-e48cec5826c1.png)

cloudflaredの例.

```text
https://dh-lost-prefer-por.trycloudflare.com/api/HttpTrigger1
```

![EyQNKImU8AMgaTJ.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/74d28695-adf4-eb68-ebd6-768b5eb5589a.jpeg)


「検証」ボタンを押して成功(OK)が表示されれば問題ありません。
ngrokを実行したターミナルとVS CodeのTERMINAL画面にログが表示されます。

![スクリーンショット 2021-02-07 19.55.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/3e683cff-aaf6-0682-5593-da315f6b8479.png)
![スクリーンショット 2021-02-07 19.56.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/d71a70b5-5476-13c9-0b15-3acfefbe895f.png)

cloudflaredの場合、VS CodeのTERMINAL画面にのみログが表示されます。

![EyQNplnU4AAP9v-.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/81741eba-418f-3f46-3113-ad0ed4095d99.jpeg)

# 手順(Azure Functionsへデプロイ)

### 1. Azureへログインする

![スクリーンショット 2021-02-07 20.38.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/676e7799-2924-aca5-f397-f4e2bde19bb3.png)

### 2. Azure Functionsへデプロイする

デプロイアイコン(上向きの矢印)を押して、「＋Create new Function App in Azure...」を選択します。

![deploy_0.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/5b00eab7-c88b-35aa-4599-15ee7ab5879b.jpeg)

アプリ名を入力します。(以降はline-bot02を例に説明します。)

![スクリーンショット 2021-02-07 20.19.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/9eee1263-cba3-8ab3-c38a-fce46fabdbc9.png)

Node.jsのバージョンを選択します。(ここではNode.js 14 LTSを選択します。)

![deploy_3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/6e56bc1f-7e81-a68d-7bc3-38246e2123cf.jpeg)

デプロイ先を選択します。(ここではJapan Eastを選択します。)

![deploy_4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/973774bd-b374-d0c8-ec3a-803ada27159c.jpeg)

デプロイが完了するまで少し時間がかかります。

### 3. チャンネルアクセストークンを設定する

Application Settingsで「Add New Settings...」を選択してチャンネルアクセストークンを設定します。

![deploy_5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/41940adf-cc7d-8329-3abf-5b2b2d20e000.jpeg)

キーの名前(ACCESS_TOKEN)を入力します。

![スクリーンショット 2021-02-07 20.26.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/85a09ef2-d63a-1ea0-80f8-4d37648787d5.png)

キーの値(LINE developers consoleのチャンネルアクセストークンの値)を入力します。

![スクリーンショット 2021-02-07 20.29.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/314d0a1d-2e3f-0a6f-7f01-54e34764f931.png)

### 4. Webhook URLを確認する

FunctionsのHttpTrigger1から「Copy Function Url」を選択します。

![deploy_6.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/2bcd63e0-1a2e-bdc5-7867-d98b90d9a3df.jpeg)

LINE developers consoleのMessaging API設定からWebhookの設定をします。

![スクリーンショット 2021-02-07 20.34.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/cef3d89f-5fee-0e4e-2551-8dd7842eae76.png)

### 5. ログを確認する

Logsの「Connect to Log Stream...」を選択します。

![スクリーンショット 2021-02-07 20.35.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/fc5ef153-3079-1c8c-30ec-c34a5e6af0a7.png)