【LINE Messaging API】公式LINEから様々なメッセージを送信してみる

# 概要
LINE Messaging APIを使用した様々な形式のメッセージを送信してみたいと思います。

LINEで普段使用している形式としては、テキストメッセージやスタンプ、画像、動画などが挙げられると思います。今回は、テキストメッセージ、スタンプに加え、位置情報メッセージとテンプレートメッセージにフォーカスを当てて実装していきます！

https://developers.line.biz/ja/reference/messaging-api/

実行環境は、cloud functionsを使用して、定期実行されるようにバッチで実装します！実行したい時は、強制実行できるので便利です！

# 各種初期設定
LINE Messaging APIとcloud functionsの初期設定、実行環境の整備から始めましょう。
2つとも過去の記事で初期設定等を紹介しているので、その記事を参考に設定してみてください！
### LINE Messaging API

https://qiita.com/yappi-dev/items/21dd4a40f3e44672969a

※記事では、LINEログインについても設定してますが、今回は、LINE Messaging APIだけでOKです！

### cloud functions

https://qiita.com/yappi-dev/items/807040e7c71dccc91b97

# 実装
LINE Messaging APIの初期設定とcloud functionsの始めのデプロイが完了したら、実装に移っていきます！

初めに、LINE Messaging APIのメソッド等を使用できるようにパッケージをインストールします。
```
npm i @line/bot-sdk
```

次に、LINE Messaging APIが使用できるように、アクセストークンなどを環境変数に格納しておきます！
functionsフォルダ直下に`.env`ファイルを作成して、下記のように設定しておきます。
```
# LINE developers
LINE_CHANNEL_SECRET='{LINE Messaging APIのチャネルアクセストークン}'
LINE_ACCESS_TOKEN='{LINE Messaging APIのチャネルシークレット}'
```

これで、functionsでトークンが使用することができます。
ここまでできたら、functionsの実装に移っていきます！

### LINE Messaging APIのconfig
先ほど環境変数で設定したトークンを使って`config`を定義しておきます。初期化時に使用します。
```typescript: src/index.ts
import * as functions from 'firebase-functions'

import * as line from '@line/bot-sdk'

const lineConfig = {
  channelAccessToken: process.env.LINE_CHANNEL_SECRET!,
  channelSecret: process.env.LINE_ACCESS_TOKEN!,
}
```

### テキストメッセージ
```typescript: src/index.ts
/** テキストメッセージ */
const sendTextMessageBatch = functions
  .region('asia-northeast1')
  .pubsub.schedule('0 18 * * *')
  .onRun(async () => {
    try {
      const client = new line.Client(lineConfig)
      const postMessage: line.Message = {
        type: 'text',
        text: 'これはcloud functionsからのメッセージです',
      }
      await client.broadcast(postMessage)
    } catch (error) {
      console.log(error)
    }
  })

module.exports = {
  sendTextMessageBatch,
}
```

テキストメッセージは、下記のように設定します。
```typescript
const postMessage: line.Message = {
    type: 'text',
    text: 'これはcloud functionsからのメッセージです',
}
```
`type`を`text`に設定することでメッセージ形式がテキストとして設定されます。`text`がメッセージの本文になるので、送信したい文言に修正してみてください！
メッセージを送信するのは、一律`broadcast`メソッドを使用します。これは、公式ラインを追加しているユーザ全員に対してメッセージを送信するメソッドです。メソッドは他にもありますので、公式ドキュメントを参考にして仕様に合わせて実装してみてください。

それでは、このコードをデプロイして、強制実行してみます！結果を確認してみましょう！
![スクリーンショット 2023-09-02 13.59.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/746815/ef9ebe7a-2f18-b3a2-13f9-a9d02ed60d51.png)
強制実行したので、バッチの意味はありませんが、これでテキストメッセージが送信されました！

### スタンプメッセージ
次は、スタンプメッセージです！
先ほどのテキストメッセージの下に下記のコードを追加していきます！
```typescript: src/index.ts
/** スタンプメッセージ */
const sendStampMessageBatch = functions
  .region('asia-northeast1')
  .pubsub.schedule('0 18 * * *')
  .onRun(async () => {
    try {
      const client = new line.Client(lineConfig)
      const postMessage: line.Message = {
        type: 'sticker',
        packageId: '446',
        stickerId: '1988',
      }
      await client.broadcast(postMessage)
    } catch (error) {
      console.log(error)
    }
  })
```
スタンプメッセージは、下記で設定します。
```typescript
const postMessage: line.Message = {
    type: 'sticker',
    packageId: '446',
    stickerId: '1988',
}
```
テキストメッセージと似ていますが、`type`によって、指定する項目が違うので注意してください。
スタンプの指定は、`packageId`と`stickerId`で指定することができます。
スタンプの種類については、LINE Messaging APIで送信できるものが決まっているので、公式から使用したいスタンプを探してみてください！

https://developers.line.biz/ja/docs/messaging-api/sticker-list/

テキストメッセージと同様にfunctionsにデプロイして、強制実行します！
すると、下記の画像のようにスタンプが送信されます！
![スクリーンショット 2023-09-02 14.03.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/746815/5c773bcb-24ec-0885-80e7-521020fb5e7c.png)

### 位置情報メッセージ
次は位置情報です！これも同様に`index.ts`の下にコードを追加していきます。
住所はLINE Messaging APIのサンプルコードにあったものをそのまま使用していますので、指定したい場所に変更してみてください！
```typescript: src/index.ts
/** 位置情報メッセージ */
const sendLocationInfoMessageBatch = functions
  .region('asia-northeast1')
  .pubsub.schedule('0 18 * * *')
  .onRun(async () => {
    try {
      const client = new line.Client(lineConfig)
      const postMessage: line.Message = {
        type: 'location',
        title: 'my location',
        address: '〒160-0004 東京都新宿区四谷一丁目6番1号',
        latitude: 35.687574,
        longitude: 139.72922,
      }
      await client.broadcast(postMessage)
    } catch (error) {
      console.log(error)
    }
  })
```
位置情報では、`type`を`location`に設定します。
```typescript
const postMessage: line.Message = {
    type: 'location',
    title: 'my location',
    address: '〒160-0004 東京都新宿区四谷一丁目6番1号',
    latitude: 35.687574,
    longitude: 139.72922,
}
```
メッセージに表示する、タイトルと住所を指定、マップで表示ができるように経度、緯度を指定します。

再度、デプロイして、強制実行してみましょう！位置情報が送信させると思います！
![スクリーンショット 2023-09-02 20.36.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/746815/eb863eb0-371b-c2a5-f3c7-cab4b9f83d61.png)

### テンプレートメッセージ
これが最後のメッセージ形式です！これも同様に`index.ts`に追加します！
```typescript: src/index.ts
/** ボタンメッセージ */
const sendButtonMessageBatch = functions
  .region('asia-northeast1')
  .pubsub.schedule('0 18 * * *')
  .onRun(async () => {
    try {
      const client = new line.Client(lineConfig)
      const postMessage: line.Message = {
        type: 'template',
        altText: '今日の問題',
        template: {
          type: 'buttons',
          title: '今日の1問',
          text: 'パンはパンでも食べられないパンは？',

          actions: [
            {
              type: 'message',
              label: 'フライパン',
              text: '正解',
            },
            {
              type: 'message',
              label: 'メロンパン',
              text: '不正解',
            },
          ],
        },
      }
      await client.broadcast(postMessage)
    } catch (error) {
      console.log(error)
    }
  })
```
テンプレートメッセージは以下で指定します！
項目が少し多いので、コード内に説明書きをします！
```typescript
const postMessage: line.Message = {
    type: 'template',
    altText: '今日の問題', // トーク一覧に表示される
    template: {
        type: 'buttons', // ボタンメッセージ
        title: '今日の1問', // メッセージのタイトル
        text: 'パンはパンでも食べられないパンは？', // メッセージの本文
        
        actions: [
            {
                type: 'message', // ボタンを押したらmessageが送信
                label: 'フライパン', // ボタンのラベル
                text: 'フライパン', // ボタンを押したら送信されるメッセージ
            },
            {
                type: 'message',
                label: 'メロンパン',
                text: 'メロンパン',
            },
        ],
    },
},
```
最後に、デプロイをして結果を確認してみましょう。
送信されたメッセージの`フライパン`を押下したら、「フライパン」という単語を自動で送信されます！
![スクリーンショット 2023-09-02 20.52.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/746815/b8cfdef1-2d06-7c25-72df-f30eedbf577d.png)

`template`項目の`type`は他にもあるようなので、公式ドキュメントを確認して、仕様にあった形式を実装してみてください！
また、`actions`についてもいろいろ使用方法があるみたいなので、今後勉強してみようと思います！

https://developers.line.biz/ja/docs/messaging-api/message-types/#template-messages

# さいごに
今回は、LINE Messaging APIとcloud functinosを使用して、様々な形式のメッセージを送信してみました。
意外といろんな形式があって、応用できそうだなと感じました！何かのお役に立てれば幸いです！！