MessagingAPI + GASでメッセージ送信（+定期実行設定）

# はじめに
MessagingAPI + GAS で簡単なBotを作る過程で学んだことについてまとめる。

# push送信
```js:main.gs
const TOKEN = "自分のアクセストークン";
const LINE_PUSH_ENDPOINT = "https://api.line.me/v2/bot/message/push";

const HEADERS = {
  "Content-Type": "application/json; chrset=UTF-8",
  "Authorization": "Bearer " + TOKEN //Bearerの後ろの半角スペースを忘れずに！
}

//pushメッセージ用処理
function postMessage() {
  const postData = {
    "to": "自分のuserId",
    "messages": [{
      "type": "text",
      "text": "送信するメッセージ"
    }]
  }

  const params = {
    "methods": "POST",
    "headers": HEADERS,
    "payload": JSON.stringify(postData)
  };

  UrlFetchApp.fetch(LINE_PUSH_ENDPOINT, params);
}

```

アクセストークンは、LINE DevelopersのMessaging　API設定に記載の「チャンネルアクセストークン」。userIdは、チャンネル基本設定にある「あなたのユーザID」より取得できます。

プッシュメッセージとは、***任意のタイミング***でユーザーに送信できるメッセージのこと。

https://developers.line.biz/ja/reference/messaging-api/#send-push-message


## 不明点を調べる

### UrlFetchApp.fetch()
GASのUrlFetchAppクラスのメソッド。リソースを取得し、インターネットを介して他のホストと通信する。

***fetch(url, params)***

オプションの詳細パラメータを使用してURLをフェッチするよう要求する。それぞれの形式は以下の通り。paramsに指定するObjectの詳細は公式ドキュメントに記載されています。
url: String
params: Object


https://developers.google.com/apps-script/reference/url-fetch/url-fetch-app


### JSON.stringify()
JSON.stringify()は、JavaScriptのオブジェクトや値をJSON文字列に変換する。
これを用いて、postDataをJSON文字列に変換してAPIに渡している。

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify


# オウム返し処理

```js:main.gs
const TOKEN = "自分のアクセストークン";
const LINE_ENDPOINT = "https://api.line.me/v2/bot/message/reply";
const HEADERS = {
  "Content-Type": "application/json; chrset=UTF-8",
  "Authorization": "Bearer " + TOKEN //Bearerの後ろの半角スペースを忘れずに！
}

//オウム返し処理
function doPost(e) {
  const responseLine = e.postData.getDataAsString();
  const event = JSON.parse(responseLine).events[0];
  const replyToken = event.replyToken;
  let userMessage = event.message.text;
  
  const replyBody = {
    "replyToken": replyToken,
    "messages": [{
      "type": "text",
      "text": userMessage
    }]
  };
  const params = {
    "method": "POST",
    "headers": HEADERS,
    "payload": JSON.stringify(replyBody)
  };
  UrlFetchApp.fetch(LINE_ENDPOINT, params);
}
```

## Webhookイベントオブジェクト
以下は、LINEプラットフォームで生成されるイベントを含むJSONオブジェクトです。

```json:Webhookイベントオブジェクトの例
{
    "destination": "xxxxxxxxxx",
    "events": [
        {
            "type": "message",
            "message": {
                "type": "text",
                "id": "14353798921116",
                "text": "Hello, world"
            },
            "timestamp": 1625665242211,
            "source": {
                "type": "user",
                "userId": "U80696558e1aa831..."
            },
            "replyToken": "757913772c4646b784d4b7ce46d12671",
            "mode": "active"
        },
        {
            "type": "follow",
            "timestamp": 1625665242214,
            "source": {
                "type": "user",
                "userId": "Ufc729a925b3abef..."
            },
            "replyToken": "bb173f4d9cf64aed9d408ab4e36339ad",
            "mode": "active"
        },
        {
            "type": "unfollow",
            "timestamp": 1625665242215,
            "source": {
                "type": "user",
                "userId": "Ubbd4f124aee5113..."
            },
            "mode": "active"
        }
    ]
}
```

イベントオブジェクトを見つつ、実装した処理を見ていくと以下の流れになります。

1. getDataAsString()で受け取ったデータを文字列として取得
2. JSON.parseでデータ文字列をJavaScriptオブジェクトに変換 
3. イベントオブジェクトのeventsの最初のオブジェクト（LINEから届いたテキストデータ含む）を取得
4. 応答する際に必要なリプライトークンと、オウム返しをするために受け取ったテキストを取得
5. リプライ  


### 参考
https://developers.line.biz/ja/reference/messaging-api/#webhooks

## 不明点を調べる


### getDataAsString()
blobのデータを、指定されたエンコーディングの文字列として取得する。

https://developers.google.com/apps-script/reference/base/blob

### JSON.parse()
JSON.parse() メソッドは文字列を JSON として解析し、文字列によって記述されている JavaScript の値やオブジェクトを構築する。

LINEから受け取ったデータをgetDataAsString()でJSON文字列に変換し、JSON.parse()でオブジェクト形式にパースしている。

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse


# JavaScriptオブジェクトとJSONの違い
## JavaScriptオブジェクト
JavaScriptのオブジェクトは、オブジェクトという形式の型の値。

keyはシングル、ダブルクォーテーションどちらでも可、囲わなくても良い。
文字列もシングル、ダブルクォーデーションどちらも可。
末尾のカンマは使用できる。

オブジェクトであるため、オブジェクト内の値の参照や代入もできる。


## JSON
JSONは、`JavaScriptオブジェクトの構文に従ったテキストベースのデータ形式`である。
プロパティのみを含むことができ、メソッドを含むことはできない。

keyはダブルクォーテーションで囲む必要がある。
文字列もダブルクォーテーションで囲む必要がある。
末尾のカンマは使用できない。

```javascript:sample.js
let object = {
    key1: '値1',
    key2: '値2'
}
//JSON文字列に変換
let json = JSON.stringify(object);

console.log(object);         // { key1: '値1', key2: '値2' }
console.log(json);           // {"key1":"値1","key2":"値2"}

console.log(object['key1']); // 値1
console.log(json['key1']);   // undefined（文字列であるため参照できない）
```


## 参考
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/JSON

https://qiita.com/rasedevapp/items/e83125b4fddd1230d4c6

https://developer.mozilla.org/ja/docs/Learn/JavaScript/Objects/Basics

https://techplay.jp/column/611

https://qiita.com/shinka401/items/f470674c5c8dbe468c3e


# GASで毎日決まった時間にメッセージを送信する
定期実行する設定は、GASの左メニューにある「トリガー」を選択し、右下の「トリガーを追加する」から追加できる。
定期実行したい関数を選択し、実行間隔等の設定をするだけ。とても簡単。

![スクリーンショット 2022-02-19 18.49.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/381376/7c62b08c-576c-bccb-5966-2d9737493a66.png)

# まとめ
今回は、MessagingAPIの中でもプッシュ送信やオウム返し処理についてまとめつつ、使用したメソッドやJSON等についても軽く触れた。

MessagingAPI + GASで簡単なbotを作るだけであればたくさん参考記事があるので作ることは簡単でした。
なので、実際にどういった処理を行なっているかをきちんと理解することが重要だと思いました。
公式のドキュメントを読んで引き続き学習を進めていきたいと思います。

以上。