【LINE DC 2021】 Azure Functions と SSSAPI（スプレッドシートの API化）を組み合わせて作る LINE Bot

この記事は、2021年の [LINE DC のアドベントカレンダー](https://qiita.com/advent-calendar/2021/linedc) の 23日目の記事です。

## 今回の内容
以下の「Azure FunctionsでLINE Bot作成」という記事と、「簡単設定で Googleスプレッドシートの記載内容を API化してくれる SSSAPI」の情報を見かけていたのですが、「これらを組み合わせてみたいな」とふと思ったのが、この記事を書くことになった発端です。

●Azure FunctionsでLINE Bot作成 - Qiita
　https://qiita.com/RyogaTakao/items/a86522d560178f83652c
●Azure FunctionsでLINE Bot作成 -アレンジ編vol.1- - Qiita
　https://qiita.com/RyogaTakao/items/041fa30e967aa73b5c18

●GoogleスプレッドシートのAPI化サービス -SSSAPI-
　https://sssapi.app/

## 今回利用する仕組み・サービスについて
今回利用する仕組み・サービスは、冒頭にも書いた以下が主になります。

- LINE Bot（Messaging API）
- Azure Functions
- SSSAPI（Googleスプレッドシートを利用）

## 実際に作っていく
### LINE Bot のベースを作る
まずは、オウム返しをするLINE Bot を作ります。

LINE側の設定や、Azure Functions 上で Node.js を使った開発をする話は、冒頭に書いていた「[Azure FunctionsでLINE Bot作成](https://qiita.com/RyogaTakao/items/a86522d560178f83652c)」という記事をご参照ください。
画面キャプチャをたくさん使った分かりやすい説明がありますのでそれを見つつ、オウム返しができる、というところまで進めてください。

#### 環境変数の利用
その際、「Channel secret」と「Channel access token」の設定については、上記の記事に書いているソースコードの中に含める形ではなく、以下の記事に書いている「環境変数」を利用することにします。

●Azure Functions と LINE Notify の組み合わせ（Node.js を利用、ポータルで開発） - Qiita
　https://qiita.com/youtoy/items/1f4dcd6dca2ea3a2fd97

具体的には、Azure Portal上で、以下のように 2つの環境変数を設定しました。
![環境変数の利用.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/32ac83d2-6bd1-d977-31f6-614ff55821b0.jpeg)
※ 設定をした後は、忘れずに保存をしておいてください

環境変数からの読み込みをするために、元のソースコードに手を加えた部分のみ抜粋して以下に記載します。

```javascript
const config = {
    channelAccessToken: process.env["CHANNEL_ACCESS_TOKEN"],
    channelSecret: process.env["CHANNEL_SECRET"],
};
```

#### オウム返しの動作確認
とりあえず、この時点での動作確認。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">LINE Bot の動作確認 <a href="https://t.co/Aq1S5ebsFc">pic.twitter.com/Aq1S5ebsFc</a></p>&mdash; you (@youtoy) <a href="https://twitter.com/youtoy/status/1472513506901905411?ref_src=twsrc%5Etfw">December 19, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

### SSSAPI との連携
#### SSSAPI の準備
ここから、Googleスプレッドシートの内容を API で取得できるようにしてくれるサービスである SSSAPI を使った内容を試していきます。

SSSAPI を使うための準備・基本的な使い方は、以下の公式のページを見ていただくのが分かりやすいかと思います。

●APIの追加方法
　https://sssapi.app/help/add_api/
●APIの利用方法
　https://sssapi.app/help/api_call/

自分が今回用に準備したものは以下のとおりです。
![SSSAPIの設定.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/15f4dd77-b860-0528-19f3-0f3dd1465fa1.jpeg)

API で呼び出す Googleスプレッドシートの内容はこちらになります。
買い物リストっぽいものを適当に作ってみました。
![スプレッドシート.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/40f0e44a-db85-e17a-863c-f7a5bb8e5349.jpeg)

#### 呼び出し用の URL を環境変数で保持する
また、この API を呼び出すための URL は、先ほどの LINE Bot用のトークン等と同様に Azure Portal上で環境変数として登録することにします。
![SSSAPIのURL.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/17e5bab5-3ca8-83f9-3006-74f8d5acad37.jpeg)

これで、SSSAPI関連の準備は一通り完了です。

#### Azure Functions で axios を利用する
Azure Functions で、SSSAPI を使う場合に HTTPリクエストを行う必要があります。
前に以下の記事を書いたことがあるのですが、その際に利用した axios を使うことにします。

●Azure Functions と LINE Notify の組み合わせ（Node.js を利用、ポータルで開発） - Qiita
　https://qiita.com/youtoy/items/1f4dcd6dca2ea3a2fd97

そのために、Azure Portal上のコンソールで `npm install axios` というコマンドを実行して、axios を追加しいます。

#### 特定の言葉に反応してリストを返す
あとは、Azure Portal上で Azure Functions を使ったプログラムを書いていきます。
具体的には、以下のような内容です。

```javascript
const line = require("@line/bot-sdk");
const axios = require("axios");

const config = {
  channelAccessToken: process.env["CHANNEL_ACCESS_TOKEN"],
  channelSecret: process.env["CHANNEL_SECRET"],
};
const url = process.env["SSSAPI_URL"];

const client = new line.Client(config);

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

  if (req.query.message || (req.body && req.body.events)) {
    if (req.body && req.body.events[0]) {
      const text = req.body.events[0].message.text;
      // context.log(text);
      let output;
      if(text==="リスト") {
        const res = await axios.get(url);
        // context.log(res.data);
        output = `【リスト】`;
        for (const element of res.data) {
          output += `\n「${element.item}」 ${element.num}個`;
        }
      } else {
        output = text;
      }
      context.log(output);  

      message = {
        type: "text",
        text: output,
      };
      context.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",
    };
  }
};
```

実装は単純で、LINEアプリ上で入力されたテキストが「リスト」だった場合は、SSSAPI を使って取得した Googleスプレッドシート上の情報を送ります。
また、それ以外のテキストが入力されていた場合はオウム返しをするという動作です。

##### 動作確認
上記のプログラムの動作を確認してみます。
試しに、LINEアプリ上で「リスト」という言葉と、それ以外の言葉をそれぞれ入力してみました。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr"><a href="https://twitter.com/hashtag/AzureFunctions?src=hash&amp;ref_src=twsrc%5Etfw">#AzureFunctions</a> 上で実装した LINE Bot。<br>基本はオウム返しだけど、特定の言葉が送られた時は <a href="https://twitter.com/hashtag/SSSAPI?src=hash&amp;ref_src=twsrc%5Etfw">#SSSAPI</a> から取得したリスト（スプレッドシート上に用意したリスト）を返す、というのをテストしてみた。<br><br>とりあえず、想定通りに動いた感じがする。<br><br>（ <a href="https://twitter.com/hashtag/LINEDC?src=hash&amp;ref_src=twsrc%5Etfw">#LINEDC</a> のアドベントカレンダー用の記事の準備） <a href="https://t.co/sNvtaPXThQ">pic.twitter.com/sNvtaPXThQ</a></p>&mdash; you (@youtoy) <a href="https://twitter.com/youtoy/status/1472557380412280836?ref_src=twsrc%5Etfw">December 19, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

上記の画像から分かるように、想定通りに動作しているのが確認できました。

## おわりに
今回、SSSAPI から取得したデータを返す LINE Bot を、Azure Functions を作ってみました。
まだ、SSSAPI で利用できる機能を活用しきれていない状況でもあるので、その辺りは今後の検討内容にできればと思っています。