LINE Messaging APIのアクションを使用したメッセージ送信

# はじめに
はじめまして！

パーソルプロセス＆テクノロジー株式会社（以下パーソルP&T）、システムソリューション（SSOL）事業部所属の髙井です。

私はモビリティソリューションデザインチームに所属しており、 __モビリティ（ここでは移動手段全般）に関するサービスを考えたり、アプリを構築したりしております。__

いわゆる__「MaaS」__に取り組んでおります。

私たちが「MaaS」に取り組む中で、__現在活用している、もしくは活用する予定の技術やサービスやとりあえず発信したいこと__などなど、幅広くチームメンバーと共に執筆していきたいと思います。
メンバーごとに違った内容を発信していきますので、お楽しみに！

また、「MaaS」について詳しく知りたい方は、チームメンバーの吉田が記事を掲載しておりますので、
ぜひそちらをご覧ください。

[「MaaSとは」でたどり着いて欲しい記事　（1/3 前編）](https://note.com/ppt_msdg_maas/n/naae427dbc37c)
[「MaaSとは」でたどり着いて欲しい記事　（2/3 中編）](https://note.com/ppt_msdg_maas/n/na45c90b2f02f)
[「MaaSとは」でたどり着いて欲しい記事　（3/3 後編）](https://note.com/ppt_msdg_maas/n/n8fd724f7db6c)

# やること
__LINE上で日時選択ができるメニューを表示させ、選択した日時をレスポンスとしてメッセージ送信する__方法を共有していこうと思います。
### LINE上で日時選択
![954FDCF1-022A-4ABF-80A7-C17A53624071_1_105_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1457643/54169508-5c61-d6a9-8a72-42ecac513d3f.jpeg)
### 選択した日時をメッセージとして送信
![0B9AB2F9-9C5A-497D-B59D-04FFFB4317E6_1_105_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1457643/718528de-4076-a55b-c101-bf7a263bf1ca.jpeg)


今回はLINE Messaging APIの実装方法に専念するため、LINEアカウントの作成などは割愛させていただきます。


# Messaging API の概要
簡単にLINEで使用できるMessaging APIとは何かを公式ドキュメントから説明します。

>Messaging APIを使って、ユーザー個人に合わせた体験をLINE上で提>供するボットを作成できます。
>作成したボットはLINEプラットフォームのチャネルに紐付けます。チャネル>を作成すると生成されるLINE公式アカウントをボットモードで運用すると、>LINE公式アカウントがボットとして動作します。

公式ドキュメントから引用(https://developers.line.biz/ja/docs/messaging-api/overview/) 

つまりMessaging APIを使用すれば、ユーザー個人に合わせた様々なタイプのメッセージを送信したり、ユーザープロフィールを取得したりすることが可能です。
また、Messaging APIには各種アクションが備わっており、色々なイベントに対応することが可能になります。

例）
１．日時選択アクション
メニューから特定の日付、時刻、または日時を選択させ、選択した日時をWebhookを介してポストバックイベントで返される。

２．URIアクション
URIアクションを使って、LINE内ブラウザで指定のURLを開く。LINE URLスキームを組み合わせて使うと、通話アプリで指定の電話番号を開いたり、任意のLINE公式アカウントをシェアする画面を開いたりすることもできる。

３．ポストバックアクション
特定の文字列を含むポストバックイベントをサーバーに返却する。日時選択アクションで選択された日時をポストバックイベントとして受け取り、次のアクションを実行することができる。

今回は、**日時選択アクション＋ポストバックアクション**の実装方法および解説をしていきたいと思います。

# 事前準備
・LINE DevelopersでMessaging APIのチャンネルを作成していること。
・チャネルアクセストークンを取得していること。
参考：https://developers.line.biz/ja/docs/liff/getting-started/

# 実装方法
今回はサンプル作成のため、GAS(Google Apps Script)を使用してサーバーレスなAPIを試してみます。
GASは、Google ドライブ>新規>その他>Google Apps Script　でアクセスできます。

### 日時選択アクション用のサンプルボタンを送信
まずは日時選択ができるメニューボタンを送信するスクリプトを実装していきましょう。
GASのスクリプトプロパティにチャネルアクセストークンとユーザーIDを格納していますので、ご自身の割り当てられた値を記載してください。確認手順は※に記載しています。
内容の詳細は後述してますので、ご参考までに確認ください。

※1 __チャネルアクセストークン__：LINE DevelopersのMessaging API内の「メッセージングAPI」>画面下部の「チャネルアクセストークン」
※2 __ユーザーID__：LINE DevelopersのMessaging API内の「基本設定」>画面下部の「あなたのユーザーID」

```jsx
function datetime_picker_action() {

	// スクリプトプロパティのオブジェクトを格納
  PropertiesService.getScriptProperties().setProperties({
    "TOKEN": "{チャネルアクセストークン}",　// ※1
    "USERID": "{ユーザーID}", // ※2
    "PUSHURL": "https://api.line.me/v2/bot/message/push" // Push用URLをスクリプトプロパティに格納
  });
	// スクリプトプロパティのオブジェクトを取得
	const prop = PropertiesService.getScriptProperties().getProperties();

	// ボタンテンプレートメッセージを送る(datetime_picker) 
	UrlFetchApp.fetch(prop.PUSHURL, {
		'headers': {
			'Content-Type': 'application/json',
			'Authorization': 'Bearer ' + prop.TOKEN,
		},
		'method': 'POST',
		'payload': JSON.stringify({
			"to": prop.USERID,
			"messages": [
				{
					"type": "template",
					"altText": "datetime_picker",
					"template": {
						"type": "buttons",
						"thumbnailImageUrl": "https://placehold.jp/00dd82/ffffff/640x480.jpg?text=日時選択", // 画像のURL
						"imageAspectRatio": "rectangle", // 画像のアスペクト比、「rectangle: 1.51:1」・「square: 1:1」、デフォルト値はrectangle
						"imageSize": "cover", // 画像の表示形式
						"imageBackgroundColor": "#3a687e", // 画像の背景色
						"title": "メニュー",
						"text": "以下より選択してください。",
						"defaultAction": {
							"type": "uri",
							"label": "View detail",
							"uri": "https://line.me/ja/"
						},
						"actions": [
							{
								"type": "datetimepicker",
								"label": "日時を選択してください。",
								"data": "action=settime",
								"mode": "datetime",
								"initial": "2021-05-12t00:00",
								"max": "2022-05-12t23:59",
								"min": "2017-12-25t00:00"
							}
						]
					}
				}
			],
			"notificationDisabled": false // trueだとユーザーに通知されない
		}),
	});
}
```

### サンプルボタンのスクリプトをデプロイする
１．「デプロイ」>「新しいデプロイ」>歯車押下>「ウェブアプリ」>アクセスできるユーザーを「全員」に変更
→承認画面が表示されるので、リクエストを許可

２．デプロイが更新されましたというポップアップが表示されることを確認
→**ウェブアプリのURLをコピーしておきましょう**

３．LINE Developersの「WebhookのURL」に２でコピーしたURLを貼り付けし、成功という表示が出てくることを確認

４．「webhookを使用する」をオンにする

より詳細に確認したい場合は以下の記事を参考にしてください。
参考：[https://arukayies.com/gas/line_bot/line-bot-with-gas#URL](https://arukayies.com/gas/line_bot/line-bot-with-gas#URL)

### LINE上で日時選択メニューを操作
それでは対象のLINEbot を友だち追加していきましょう。すでに追加している場合は飛ばしてしまって問題ありません。
LINE Developersの「メッセージングAPI」タグを選択し、QRコードを読み取り友達追加。
上記で作成したスクリプトを実行。LINE上に日付選択のメニューボタンが送信されていることを確認。
__※この時点では、日付選択しても応答はありません。__

### 日時選択のボタンからPOSTデータを受け取ってメッセージを送信
次に日時選択した際に返答するスクリプトを記述していきましょう。
詳細については後述します。
__日時選択のボタンを送信するスクリプトと同様に、チャネルアクセストークンとユーザーIDはご自身の割り当てられた値を設定してください。__
記述完了しましたら以下の手順で再度デプロイをしていきましょう。
「デプロイ」>「デプロイを管理」>右上のペンアイコンの編集をクリック>バージョンを「新バージョン」に変更＞「デプロイ」押下

```jsx
function doPost(e) {
  	// スクリプトプロパティのオブジェクトを格納
  PropertiesService.getScriptProperties().setProperties({
    "TOKEN": "{チャネルアクセストークン}",
    "USERID": '{ユーザーID}',
    "REPLYURL": "https://api.line.me/v2/bot/message/reply"
  });
	// スクリプトプロパティのオブジェクトを取得
	const prop = PropertiesService.getScriptProperties().getProperties();
	// レスポンス取得
	const responseLine = e.postData.getDataAsString();
	// JSON形式に変換する
  var resDatetime = JSON.parse(responseLine).events[0].postback.params.datetime;
  var replyToken = JSON.parse(responseLine).events[0]['replyToken'];

	UrlFetchApp.fetch(prop.REPLYURL, {
		'headers': {
			'Content-Type': 'application/json',
			'Authorization': 'Bearer ' + prop.TOKEN, // スクリプトプロパティにトークンは事前に追加しておく
		},
		'method': 'POST',
		'payload': JSON.stringify({
      'replyToken': replyToken,
			"messages": [{
				"type": "text",
				"text": resDatetime // レスポンスを送る
			}],
			"notificationDisabled": false // trueだとユーザーに通知されない
		}),
	});
}
```

### 再度LINE上で日時選択メニューを操作
さきほど送信された日時選択メニューで任意の日付を選択し、送信してみましょう。
選択した日時がメッセージとして送信されていることが確認できましたでしょうか。
# 解説
LINE Botからメッセージを送信する方法としては2種類ありますが、今回使用したのは__応答メッセージ__です。

### 応答メッセージ
>ユーザーがLINE公式アカウントを友だち追加したり、LINE公式アカウントにメッセージを送ったりなど、ユーザーのアクションに応答するためのメッセージです。

以下の形式でリクエストデータを送信します。（公式ドキュメント参照）

```jsx
{
		'headers': {
			'Content-Type': 'application/json',
			'Authorization': 'Bearer ' + {channel access token}, // アクセストークンを記載
		},
		'replyToken': 'nHuyWiB7yP5Zw52FIkcQobQuGDXCTA', // Webhookで受信する応答トークン
		"messages": [{
				"type": "text",
				"text": "テキストメッセージの内容"
			}],
			"notificationDisabled": false // true：メッセージ送信時に、ユーザーに通知されない。 false:メッセージ送信時に、ユーザーに通知される。
		}),
}
```


実際に記述したコードは以下です。
流れとしては、__選択日時が入っているレスポンスを取得→取得したレスポンス内のデータから再度リクエストデータを送信__です。
まずはレスポンスを取得している箇所から説明します。
__選択した日時は postback の中に格納__されていることがわかります。これが**ポストバックアクション**のオブジェクトですね。
さらに__応答メッセージを送信する場合は、replyTokenを取得__する必要があります。

```jsx
 // レスポンス取得
  const responseLine = e.postData.getDataAsString();
 // JSON形式に変換する
  var resDatetime = JSON.parse(responseLine).events[0].postback.params.datetime;
  var replyToken = JSON.parse(responseLine).events[0]['replyToken'];
```

取得したレスポンス情報から再度リクエストを投げます。
__messageのtextに取得したレスポンスの日時を送信するよう値を設定__しています。
typeの値を変更するとスタンプや画像、動画を送信することも可能になります。

```jsx
	UrlFetchApp.fetch(prop.REPLYURL, {
		'headers': {
			'Content-Type': 'application/json',
			'Authorization': 'Bearer ' + prop.TOKEN, // スクリプトプロパティにトークンは事前に追加しておく
		},
		'method': 'POST',
		'payload': JSON.stringify({
      'replyToken': replyToken,
			"messages": [{
				"type": "text",
				"text": resDatetime // レスポンスを送る
			}],
			"notificationDisabled": false // trueだとユーザーに通知されない
		}),
	});
```


# 最後に
今回はLINE上でメッセージを送信する基本的な処理を説明しましたが、この使い方が理解できれば応用して様々な形式のLINE Botが作成できるかと思います。
ぜひ手を動かして試してみてください！

__最後まで読んでいただき、ありがとうございました！__