kintone から LINE に投稿する

## 概要
先日に [LINE チャンネルの友達登録や投稿情報を kintone に保管](https://qiita.com/yukataoka/items/9356171cd350c465b745) で、LINEのチャンネル登録をして、友達登録や投稿情報を kintone に保管したり、AWS Lambda から返信できることまでは確認しました。
今回は、kintone から LINE チャンネルを友達登録した方に対して個別でメッセージを送る方法を試してみました。
![LINE2-04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75892/25dfbbdb-efc3-aa40-b5dd-9e5dcd6c1927.png)

## kintone アプリの項目追加
先ずは、前回作成した LINE の友達登録や投稿情報を保管する kintone アプリに、LINE に送信するメッセージ用のフィールドを追加します。
![LINE2-03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75892/c74a0613-66cf-70d0-167b-0d2ed7412790.png)

| フィールド名 | タイプ | フィードコート・要素ID |
|--------------|--------|----------------|
| lineユーザID | 文字列（1行） | lineUserId |
| 日時 | 日時 | lineDateTime |
| lineタイプ | 文字列（1行） | lineType |
| lineモード | 文字列（1行） | lineMode |
| lineメッセージ | 文字列（複数行） | lineMessage |
| __（追加）lineに送るメッセージ__ | __文字列（複数行）__ | __sendMessage__ |
| __（追加）__ | __スペース__ | __sendSubmit__ |

スペースは「LINEにメッセージ送信」ボタンを表示するために追加しています。

## kintone の JavaScript プログラム作成
kintone の 詳細画面を表示した時に「LINEにメッセージ送信」ボタンを表示し、クリックすると同時に LINE に、レコードのLINEユーザID宛てに「lineに送るメッセージ」フィールドの値を送る JavaScript プログラムを作成します。

LINE のユーザ宛てにメッセージを送るためには、Messaging API の https://api.line.me/v2/bot/message/push で以下のヘッダーで、JSON データを POST します。

__・ヘッダー__

```javascript
let headers = {
	'Authorization': ' Bearer ' + '{' + token + '}',
	'Content-Type' : 'application/json'
};
```

token の値は、 [LINE チャンネルの友達登録や投稿情報を kintone に保管](https://qiita.com/yukataoka/items/9356171cd350c465b745) で説明した__チャンネルアクセストークン__です。

__・POST データ__

```javascript
let json = {
	"to":userId,
	"messages":[
		{
			"type":"text",
			"text":message
		}
	]
};
```

message にLINEユーザに連絡するテキスト文書をセットしておきます。

__・CORS によるエラーに注意__

kinton の JavaScript で外部APIを利用する場合は、XMLHttpRequest() は使えません。ついつい私も最初 XMLHttpRequest() で実装しようとして後になって気づくのですが、 kintone.proxy() を利用します。うっかり XMLHttpRequest() で実装しようものなら、エラーでデバッグ画面で以下を確認することになります。また、うっかりやってしました、、、（汗）

```
Access to XMLHttpRequest at 'https://api.line.me/v2/bot/message/push' from origin 'https://yukataoka.cybozu.com' has been blocked by CORS policy: 
Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
```

__・今回実装したコード例__

今回は以下のように実装して、kintone から LINE にメッセージが送れるようになりました。
kintone.proxy()　は Promise でなくて良かったのですが、同期処理になっています。（汗）

```sendLineMessage.js
(function() {
	"use strict";
	
	const Protocol   = "https://";
	const LineHost   = "api.line.me";
	const LinePath   = "/v2/bot/message/push";
	const LineToken  = "LINEのチャンネルアクセストークン";
	
	// レコード詳細表示時イベント
	var eventsDetailShow = [
		'app.record.detail.show',
		'mobile.app.record.detail.show'];
	kintone.events.on(eventsDetailShow, function(event) {
		let sendButton  = makeSendButton(LineToken, event.record.lineUserId.value, event.record.sendMessage.value);
		if(event.type !== 'mobile.app.record.detail.show') {
			kintone.app.record.getSpaceElement('sendSubmit').appendChild(sendButton);
		}else{
			kintone.mobile.app.record.getSpaceElement('sendSubmit').appendChild(sendButton);
		}
	});
	
	// LINEにメッセージ送信ボタン作成
	function makeSendButton(token, userId, message) {
		let submitButton = document.createElement('div');
		let sendButton       = document.createElement('button');
		sendButton.innerText = ' LINEにメッセージ送信 ';
		sendButton.className = "gaia-ui-actionmenu-save";
		sendButton.onclick   = function() {
			let json = {
				"to":userId,
				"messages":[
					{
						"type":"text",
						"text":message
					}
				]
			};
			let url = Protocol + LineHost + LinePath;
			let res = funcPostLine(url, token, json);
		};
		submitButton.appendChild(sendButton);
		return submitButton;
	}
	
	// line にメッセージを送信
	function funcPostLine(url, token, json)
	{
		let headers = {
			'Authorization': ' Bearer ' + '{' + token + '}',
			'Content-Type' : 'application/json'
		};
		kintone.proxy(url, 'POST', headers, json).then(function(args) {
			if (args[1] === 200) {
				alert("LINEにメッセージを送信しました！");
				return true;
			}else{
				alert("LINEのメッセージ送信にエラーがありました！\n" + args[0]);
				return false;
			}
		}, function(error) {
			alert("LINEのメッセージ送信にエラーがありました！\n" + error);
			return false;
		});
	}	
})();
```

## 実行結果
kintone の詳細画面で「LINEにメッセージ送信」ボタンを押すと、即座に「LINEにメッセージを送信しました！」の alert() が表示され、LINEへのメッセージ送信を確認できました。
![LINE2-02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75892/9c958449-4734-6b9b-dbbb-6cedc6571b3c.png)
![IMG_7854-B.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75892/de4b41a5-c21d-55cb-9acb-a5d8ee03c2af.png)

## まとめ
先日の [LINE チャンネルの友達登録や投稿情報を kintone に保管](https://qiita.com/yukataoka/items/9356171cd350c465b745) から、今回の kintoe から LINE に投稿するまでで、以下を確認できました。

・LINE チャンネルを開設する
・LINE チャンネルの友達登録や投稿情報を kintone に保管
・LINE チャンネルの投稿に返信を送信
・kintone から LINE にメッセージを送信

特に kintone との連携の例が少なく相当な苦戦を予想していましたが、実際はわりと簡単に実装できました。実装のためのコストは以外とかからないと推測します。

ポイントとしては、チャンネルの友達登録時に LINE ユーザID を取得し、kintone で管理するアプリ(例えば顧客管理アプリ)のどう紐づけるかが鍵になりそうです。チャンネルの友達登録時や、その後でも kintone のアプリの情報と紐ずくしくみをどのように実装するかが、kintone と LINE を連携して活用するための鍵になりそうです。

## 参考情報
__line 送信設定__
https://developers.line.biz/ja/reference/messaging-api/#send-push-message
__外部APIの実行__
https://developer.cybozu.io/hc/ja/articles/202166320