鯛’s PG blog

プログラミングに関するあれこれを書きます

LINEのチャットボットを作ってみた 〜Google Apps Script のコード〜

別記事「LINEのチャットボットを作ってみた 〜導入〜」
taiyaki-dos.hatenablog.com

で省略した、Google Apps Script(以降GAS) のコードを載せていこうと思う。

 

GAS側で行いたい処理は以下

1. 受け取ったメッセージを元にGoogle スプレッドシート内を検索
2. 該当の「名前」「住所」「Google MapのURL+住所」を取得
3. 結果を返す


事前作業として、以下を済ませておくこと。

  • LINE Developers の Channel基本設定 で 「アクセストークン」を発行
  • 住所が記載されているスプレッドシートのファイルキーを取得


ファイルキーはスプレッドシートを開いたときのURLのうち△の部分
例)https://docs.google.com/spreadsheets/d/△△△/edit#gid=0

var CHANNEL_ACCESS_TOKEN = 'xxxxxx';
var ADDRESS_FILE_KEY = 'ooooooo';

function doPost(e) {
  var reply_token= JSON.parse(e.postData.contents).events[0].replyToken;
  if (typeof reply_token === 'undefined') {
    return;
  }
  // レスポンスメッセージの設定
  var response_message = setResponseMessage(e);

  // メッセージ送信のための設定
  var url = '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': reply_token,
      'messages': [{ 
        'type': 'text',
        'text': response_message,
      }],
    }),
  });
  return ContentService.createTextOutput(JSON.stringify({'content': 'post ok'})).setMimeType(ContentService.MimeType.JSON);
}

 
事前作業で取得しておいた「アクセストークン」「ファイルキー」を上記ソース内の"CHANNEL_ACCESS_TOKEN"、"ADDRESS_FILE_KEY"に設定する。

送り返すメッセージを生成しているのは、

  // レスポンスメッセージの設定
  var response_message = setResponseMessage(e);


で、setResponseMessage() の中で受け取ったメッセージを元に住所検索を行う。

/*
 * レスポンスメッセージ設定処理
 */
function setResponseMessage(req) {
  var res = '';

  // ユーザーの入力文字列を取得
  var user_message = JSON.parse(req.postData.contents).events[0].message.text;

  // 入力文字列から住所を検索
  var address_str = getAddress(user_message);

  // 〜中略〜

  var count = address_str.length;

  if (count < 3) {
    for (var i=0; i<count; i++) {
      // 住所をURIエンコード
      e_url = encodeURIComponent(address_str[i][1]);
      res = res + address_str[i][0] + '\n' + address_str[i][1] + '\n' + google_map_url + e_url + '\n';
    }
  } else {
    for (var i=0; i<count; i++) {
      // 社寺名だけをレスポンスメッセージにセット
      res = res + address_str[i][0] + '\n';
      if (i >= 19) {
        res = res + '他多数...';
        break;
      }
    }
  }
  // メッセージの返却  
  return res;
}

/*
 * スプレッドシート内の検索
 */
function getAddress(str) {
  // スプレッドシートの取得
  var spreadsheet = SpreadsheetApp.openById(ADDRESS_FILE_KEY);
  // 取得したシートのデータを二次元配列に格納
  var dat = spreadsheet.getDataRange().getValues();
  // 返却用配列
  var result = [];
  
  // 検索
  for (var i=1,len=dat.length; i<len; i++) {
    if (dat[i][0].indexOf(str) !== -1) {
    //  return dat[i][1];
      result.push([dat[i][0], dat[i][1]]);
    }
  }
  return result;
}


スプレッドシート内の検索を行っているのは getAddress() 内。
直接スプレッドシートを参照、検索しても良いのだが、一度配列に入れてからループで回したほうが処理速度が早いらしいのでこんなことをしている。

  // 取得したシートのデータを二次元配列に格納
  var dat = spreadsheet.getDataRange().getValues();