LINEボットをGoogle Apps Scriptで動作させて、LINEからの情報をkintoneに保存してみました。
ボットのフロントにLINE Messaging API を利用して、kintoneはデータベースに使います。
前提条件や知識など
- LINEボットの設定が出来る
- Google Apps Scriptでコードが書ける
- kintoneでアプリが作成出来る
概要
LINE Messaging API のWebhookの設定に、Google Apps Script(GAS)をWebアプリで公開した際のURLを設定します。LINEのメッセージリクエストをGASのdoPost関数で取得して、リクエストの内容をkintoneにレコード追加して、同時にLINEにおうむ返しで返します。
- kintoneアプリを作成
- LINE Messaging APIを設定
- Google Apps Script でWebアプリを作成
- Google Apps Script の公開URLをLINE Messaging API のWebhookに設定します
1. kintoneアプリを作成

文字列(1行)フィールドを使って、LINE UserIdとメッセージを保存するフィールドを作成します。
2. LINE Messaging APIを設定
LINE Messaging API の設定方法に関しては特別な設定はありませんので、下記の公式リンクを参考にしてください。
3. Google Apps Script でWebアプリを作成
参考にコードを貼っておきます。
// 環境変数のセット
const scriptProperties = PropertiesService.getScriptProperties();
const DOMAIN = scriptProperties.getProperty('DOMAIN'); // kintone ドメイン名
const APP_ID = scriptProperties.getProperty('APP_ID'); // kintone ユーザーID
const API_TOKEN = scriptProperties.getProperty('API_TOKEN'); // kintone APIトークン
const SHEET_ID = scriptProperties.getProperty('SHEET_ID'); // デバッグ用 Spreadsheet ID
const CHANNEL_ACCESS_TOKEN = scriptProperties.getProperty('CHANNEL_ACCESS_TOKEN'); // LINEチャネルアクセストークン
function doPost(e: { postData: { contents: string; }; }) {
appendLogToSpreadsheet('--- debug start', SHEET_ID)
let lineEvents = []
const botUserId: string = JSON.parse(e.postData.contents).destination
lineEvents = JSON.parse(e.postData.contents).events
appendLogToSpreadsheet(botUserId, SHEET_ID)
appendLogToSpreadsheet(JSON.stringify(lineEvents), SHEET_ID)
if (!lineEvents.length) {
return ContentService.createTextOutput(JSON.stringify({'content': '200 ok'})).setMimeType(ContentService.MimeType.JSON);
}
lineEvents.forEach(event => appendLogToSpreadsheet(JSON.stringify(event), SHEET_ID))
let replyToken: string = ''
let userMessage: string = ''
const replyPackageId: string = '11537'
const replyStickerId: string = '52002740' // LINEスタンプID
let replyMessage = {}
let kintoneResult = {}
lineEvents.forEach( async (event) => {
if (event.type === 'message') {
if (event.message.type === 'text') { // テキストメッセージ
replyToken = event.replyToken
userMessage = event.message.text
replyMessage = {
type: 'text',
text: userMessage
}
kintoneResult = await LoggerTokintone (userMessage, event.source.userId)
} else if (event.message.type === 'sticker') { // LINEスタンプ
replyToken = event.replyToken
replyMessage = {
type: 'sticker',
packageId: replyPackageId,
stickerId: replyStickerId
}
kintoneResult = await LoggerTokintone (`sticker packageId: ${event.message.packageId}, stickerId: ${event.message.stickerId}`, event.source.userId)
} else {
replyToken = event.replyToken
userMessage = 'テキスト又はスタンプ以外が送信されました'
replyMessage = {
type: 'text',
text: userMessage
}
kintoneResult = await LoggerTokintone (userMessage, event.source.userId)
}
} else {
replyToken = event.replyToken
userMessage = 'メッセージ以外が送信されました'
replyMessage = {
type: 'text',
text: userMessage
}
kintoneResult = await LoggerTokintone (userMessage, event.source.userId)
}
appendLogToSpreadsheet('result', SHEET_ID)
appendLogToSpreadsheet(kintoneResult, SHEET_ID)
})
if (typeof replyToken === 'undefined') {
return ContentService.createTextOutput(JSON.stringify({'content': '200 ok'})).setMimeType(ContentService.MimeType.JSON);
}
const url: string = 'https://api.line.me/v2/bot/message/reply';
UrlFetchApp.fetch(url, {
'headers': {
'Content-Type': 'application/json; charset=UTF-8',
'Authorization': `Bearer ${CHANNEL_ACCESS_TOKEN}` ,
},
'method': 'post',
'payload': JSON.stringify({
'replyToken': replyToken,
'messages': [replyMessage],
}),
});
return ContentService.createTextOutput(JSON.stringify({'content': '200 ok'})).setMimeType(ContentService.MimeType.JSON);
}
// Spreadsheetにログを書き出す
function appendLogToSpreadsheet(log: string, sheetId: string, sheetName = 'sheet1') {
const spreadSheet = SpreadsheetApp.openById(sheetId)
spreadSheet.getSheetByName(sheetName).appendRow(
[new Date(), log]
);
SpreadsheetApp.flush()
}
// kintoneにユーザーIDをログとして追加する
function LoggerTokintone (message: string, lineId: string) {
const payload = {
app: APP_ID,
record: {
'message': {
'value': message
},
'lineId': {
'value': lineId
},
}
}
const option = {
method: "post",
contentType: "application/json",
headers: { "X-Cybozu-API-Token": API_TOKEN },
muteHttpExceptions: true,
payload: JSON.stringify(payload)
};
appendLogToSpreadsheet('option', SHEET_ID)
appendLogToSpreadsheet(JSON.stringify(option), SHEET_ID)
// kintoneにレコード追加
return new Promise((resolve, reject) => {
try {
const result = UrlFetchApp.fetch(
`https://${DOMAIN}.cybozu.com/k/v1/record.json`,
option
)
resolve(result)
} catch (error) {
reject(error)
}
})
}
デバッグログはSpreadsheetに出力しています。
4. Google Apps Script の公開URLをLINE Messaging API のWebhookに設定します
作成したLINE Messaging API チャネルの Webhook設定にGASの公開URLを設定して、Webhookの利用をONにします。
実行
LINE Messaging API のボット情報のQRコードを読み取って、友達追加します。
テキストメッセージを送るとおうむ返しでGASのBotサーバーからメッセージが送信されます。同時にkintoneにLINE UserIdとメッセージを追加します。
参考
LINE Messaging API
- Messaging APIの特徴
- 応答メッセージを送る
- Messaging APIの概要
- メッセージの送信方法
- 応答メッセージを送る
- Webhook
- Webhookイベントオブジェクト
- メッセージイベント
- LINE チャネルの作成
- ボットを作成する
Google Apps Script
- https://developers.google.com/apps-script/overview
- https://developers.google.com/apps-script/guides/v8-runtime
- https://developers.google.com/apps-script/guides/web
- https://developers.google.com/apps-script/guides/content
- https://codelabs.developers.google.com/codelabs/clasp/#0
- https://github.com/google/clasp
今後の展開
- kintoneからレコードを取得してLINEに返信する
- GASの代わりにBotサーバーにHerokuを利用する