1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

LINE と Google Apps Script で作成したBotの情報をkintoneに保存する

Last updated at Posted at 2020-06-15

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におうむ返しで返します。

  1. kintoneアプリを作成
  2. LINE Messaging APIを設定
  3. Google Apps Script でWebアプリを作成
  4. Google Apps Script の公開URLをLINE Messaging API のWebhookに設定します

1. kintoneアプリを作成

スクリーンショット 2020-06-15 19.22.32.png

文字列(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メッセージ画面
IMG_1158.PNG

kintoneレコード一覧
スクリーンショット 2020-06-15 20.57.46.png

参考

LINE Messaging API


Google Apps Script


今後の展開

  • kintoneからレコードを取得してLINEに返信する
  • GASの代わりにBotサーバーにHerokuを利用する
1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?