見出し画像

電話代行(fondesk)のChatwork通知から自動でkintoneアプリにレコード追加するGAS

タイトルを考えながら、一瞬「なんてニッチなGASをつくってしまったんだ…w」と思いましたが、とりあえず弊社ではニーズがあったので記事にしました。
誰かの役に立つと幸いです。

前提

・fondeskの電話代行を利用している(かつ、Chatworkに通知している)
・kintoneを利用している
・電話の件数が多い

背景・経緯

ドクターメイトは社内に電話がなく、代表電話はすべてChatwork電話代行に繋がります。
Chatwork 電話代行 powered by fondesk
https://lp.chatwork.com/ja/reception/

電話代行の担当者がすべての電話を受けてくれて、その内容をChatworkで通知してくれる便利なサービスです。

これまではChatwork上でタスクを立てるなどして対応できていたのですが、ありがたいことに全国の介護事業所からの問合せが急増していまして、Chatwork上だけで管理できなくなってきました。

このままだと対応漏れしそうということで、社内で利用しているkintoneに問合せアプリをつくって管理しようということになりました。

準備1. kintoneのアプリをつくる

■アプリを作成し、フォームをつくる
アプリを作成し、以下のフィールドコードで項目をつくります。
・お名前 (文字列(1行))
・電話番号 (文字列(1行))
・あて先 (文字列(1行))
・内容 (文字列(複数行))

以下の項目は任意ですが、管理用につくっておくと良いと思います。
・ステータス(ドロップダウン)
  → 項目:「未対応」(初期値)、「対応済み」など
・担当者(ユーザー選択)

■APIトークンを生成する
アプリ管理画面の「設定」タブ を開き、中央部にある APIトークン をクリック。

画像2

生成するボタンを押すとトークンが生成されます。(後ほど使用します)
アクセス権の「レコード追加」にチェックして「保存」します。

画像3

最後に「アプリを更新」または「アプリを作成」ボタンを押してアプリの設定を保存します。

画像4

準備2. Chatwork の情報を集める

次に、Chatwork側の情報を集めます。
以下の3つをGASの初期設定で使用します。

■Chatwork APIトークン
Chatworkにログインした状態で、
https://www.chatwork.com/service/packages/chatwork/subpackages/api/token.php
にアクセスし、Chatworkのパスワードを入力すると取得できます。
当然ですが、電話代行のグループチャットにアクセスできるアカウントでトークンを取得してくださいね。

画像5

■fondeskアカウントのChatworkID
電話代行のグループチャットでfondeskをTo指定してみましょう。
メッセージ入力欄に[To:777777] のような文字が入力されます。この場合、777777がfondeskアカウントのChatworkIDです。

画像6

■ChatworkルームID
電話代行のグループチャットのURLを確認してください。
https://www.chatwork.com/#!rid6666666 だったら、6666666がルームIDです。

画像7

準備3. Google Apps Scriptを作成する

Googleドライブを開き、任意のフォルダでGoogle Apps Scriptを作成します。
下のスクリプトをコピペして、上部の初期設定欄を準備1〜2で取得した情報に書き換えます。

コピペするスクリプト

/*---- 初期設定ここから ----*/
// kintoneサブドメイン(https://xxxxxx.cybozu.com/k/99/だったら、xxxxxx)
const SUB_DOMAIN = "xxxxxx";
// kintoneアプリ番号(https://xxxxxx.cybozu.com/k/99/だったら、99)
const APP_ID = 99;
// kintoneアプリの名前
const APP_NAME = "問合せ管理";
// kintone アプリのAPIトークン(レコード追加権限があればOK)
const APP_TOKEN = "xxxxxxxxxxxxxxxxxxxx";
// Chatwork APIトークン ( https://www.chatwork.com/service/packages/chatwork/subpackages/api/token.php で取得)
const CHATWORK_TOKEN = "xxxxxxxxxxxxxxxxxx";
// FONDESKアカウントのChatworkID(fondeskをTo指定したとき[To:777777] だったら、777777)
const FONDESK_ID = "777777";
// ChatworkルームID(https://www.chatwork.com/#!rid6666666 だったら、6666666)
const ROOM_ID = "6666666";
/*---- 初期設定ここまで ----*/

function myFunction() {
 // 最終のメッセージIDを読み込む
 let lastMessageId = PropertiesService.getScriptProperties().getProperty("lastMessageId") || "1399309536560435200";
 // Chatworkメッセージ読込み
 const messages = getMessages();
 // メッセージがなければ終了
 if( messages.length == 0 ) return false;
 // 正規表現で指定の場所から内容を取得する関数
 const getContent = ( body, regExp ) => {
   const ary = body.match(regExp);
   const value = (ary)? ary[1] : "不明";
   return value;
 };
 // 作成用のレコード配列
 const records = [];
 // メッセージの数だけ繰り返し
 for( let msg of messages ){
   // 投稿者がfondesk以外かメッセージIDが古ければ次へ
   if( msg.account.account_id != FONDESK_ID || msg.message_id < lastMessageId ) continue;
   // bodyに含まれる特定の内容をそれぞれ抜き出す
   const body = msg.body; 
   const callerName = getContent(body,/【発信者】\s(.+)/);
   const callerPhone = getContent(body,/《電話連絡を希望》(.+)/);
   const toName = getContent(body,/【あて先】\s(.+)/);
   const message = getContent(body,/\[hr\]([\s\S]+?)\n*\[/);
   // kintoneに作成するレコードの内容をオブジェクトにする( keyはアプリのフィールドコードに合わせる )
   // ※「フィールド名」ではなく「フィールドコード」なので注意
   const record = {
     "お名前": {
       "value": callerName
     },
     "電話番号": {
       "value": callerPhone
     },
     "あて先": {
       "value": toName
     },
     "内容": {
       "value": message
     }
   };
   // 最後のメッセージIDを上書き
   lastMessageId = msg.message_id;
   // 配列recordsにオブジェクトrecordを追加する
   records.push(record);
 };
 // 配列recordsがあればkintoneレコードを作成
 if( records.length > 0 ) postRecords(records);
 // 最後のメッセージIDを記録
 PropertiesService.getScriptProperties().setProperty("lastMessageId",lastMessageId);
}

// チャットワークからメッセージを取得する関数
function getMessages(){
 var params = {
   headers : {"X-ChatworkToken" : CHATWORK_TOKEN},
   method : "get"
 };
 // forceを1にすると強制的に100件読込める( 0なら前回の続きのみ )
 const force = 0; //1;
 const url = `https://api.chatwork.com/v2/rooms/${ROOM_ID}/messages?force=${force}`;
 try {
   const response = UrlFetchApp.fetch(url, params);
   if(response.getContentText()) return JSON.parse(response.getContentText());
   else return '';
 } catch (e) {
   // エラーの場合
   console.log(e);
   return '';
 }
}

// kintoneのレコードを一括作成する関数
function postRecords(records) {
 const limit = 100; //上限100;
 const apps = {
   APPLICATION: { appid: APP_ID, name: APP_NAME, token: APP_TOKEN },
 };
 // 作成するレコードを上限数まで抜き出す
 const recordsLimited = records.slice(0, limit);
 // 作成してレスポンス取得
 var kintone_manager = new KintoneManager(SUB_DOMAIN, apps);
 var response = kintone_manager.create("APPLICATION", recordsLimited);
 // ステータスコード取得(成功すれば200)
 const code = response.getResponseCode();
 // 200でなければ終了
 if( code != 200 ){ Logger.log(code); return false; }
 // 作成済みのレコードを削除
 records.splice(0, limit);
 // レコードが残っていれば次の処理へ(繰り返し)
 if(records.length > 0) postRecords(records);
}

// kintone処理 ( https://qiita.com/Arahabica/items/063877b0da439020d2c2 より引用 )
var KintoneManager = (function() {
   "use strict";
   // user, passが指定されれば、パスワード認証
   // 指定されなければ、APIトークン認証
   function KintoneManager(subdomain, apps, user, pass){
       this.subdomain = subdomain;
       this.authorization = null;
       this.apps = apps;

       if (arguments.length > 3) {
           this.authorization = Utilities.base64Encode(user + ":" + pass);
       } else if (arguments.length > 2) {
           // 引数が3つの場合はエンコード済みの認証情報として処理
           this.authorization = user;
       }        
   }
   // レコードの作成
   KintoneManager.prototype.create = function(app_name, records) {
       var app = this.apps[app_name];
       var payload = {
         app: app.appid,
         records: records
       };
       var response = UrlFetchApp.fetch(
           "@1/records.json".replace(/@1/g,this._getEndpoint(app.guestid)),
          this._postOption(app, payload)
       );
       return response;
   };
   // POSTメソッドの時のオプション情報
   KintoneManager.prototype._postOption = function(app,payload) {
      var option = {
              method: "post",
              contentType: "application/json",
              headers: this._authorizationHeader(app),
              muteHttpExceptions: true,
              payload: JSON.stringify(payload)
      };
      return option;
   };
   // エンドポイントの取得
   KintoneManager.prototype._getEndpoint = function(guest_id) {
     var endpoint = "https://@1.cybozu.com".replace(/@1/g,this.subdomain);
     if (guest_id == null) {
       return endpoint + "/k/v1";
     } else {
       return endpoint + "/k/guest/@1/v1".replace(/@1/g, guest_id);
     }
   };
   // ヘッダーの認証情報
   KintoneManager.prototype._authorizationHeader = function(app) {
     if (this.authorization) {
        // パスワード認証
        return { "X-Cybozu-Authorization": this.authorization };
     } else if (app.token) {
        // APIトークン認証
        return { "X-Cybozu-API-Token": app.token };
     } else {
       throw new Error("kintone APIを呼ぶための認証情報がありません。");
     }
   };
   return KintoneManager;
})();

テスト実行してみる

一度 myFunction を実行してみてテストしてみましょう。(初回実行時は許可画面が表示されるので許可してください。)

kintoneアプリにレコードが追加されていれば成功です。

トリガーを設定する

最後に、5分おきにmyFunctionが実行されるようトリガーを設定します。

時計のマークのトリガー設定を開き、右下の「トリガーを追加」ボタンをクリック。
以下のとおり設定して保存します。

・実行する関数: myFunction
・イベントのソース: 時間主導型
・トリガーのタイプ: 分ベースのタイマー
・時間の間隔: 5分おき

画像8

これでfondeskから通知が来たら(5分おきのタイミングで)kintoneアプリにレコードが作成されるようになりました。

kintoneアプリの担当者やステータスの項目を使って、電話問合せを管理していきましょう。

最後に宣伝です

初心者向けのGoogle Apps Scriptの書籍を販売中です。
すぐに仕事で使える9つの自動化サンプルスクリプトを収録。
よろしければぜひお買い求めください!


この記事が気に入ったらサポートをしてみませんか?