~ChatWork API × GAS~ Google スプレッドシートのボタンを押したら任意のセルの内容を ChatWork へ送信する。
ビーズクリエイトでも業務になくてはならないチャットワーク。お客様との連絡、社内通知、担当内の情報共有など、様々な連絡手段として活用しています。先日チャットワークが数分間ダウンしただけでも、社内で多少の混乱が起きたほどです。
弊社では業務日報でも、チャットワークを利用しています。その報告の仕方なのですが、あとから集計しやすいように各社員が Google スプレッドシートに業務内容を記入し、その後チャットワークに同じ内容を手動投稿しています。・・・二度手間ですね。こういうところを改善したいのがエンジニアの性。(問題に気づいたあと1年ほど放置していたのは内緒です)
chatwork API と GAS の連携でなんとかならないものか・・・
ググってみたところ、Google スプレッドシート と チャットワーク API の連携については以下のような記事が見つかりました。
・最終行が更新されたら追加分を投稿
・スプレッドシートが修正されたら該当スプレッドシートのURLを通知
今回やりたいことと似ていますが、スプレッドシート内の任意の範囲を投稿するという記事は見つかりませんでした。
じゃあ作ってしまおう
というわけで、作ってみました。そんなにハマることなくやりたい事が実現できましたので、その成果物の作成方法について共有いたします。似たような事を実現したいエンジニアさん、どうぞ参考になさってくださいな。
まずはシートの雛形を作成
日報スプレッドシートのフォーマットはこんな感じにしてみました。
(クリックで別タブで拡大表示されます)
弊社の日報文化を元に作成していますが、要点としては
・A1セルにチャットワークの送信ボタンを作成
・B1セルにチャットワークへ送信する日付をセレクトボックスから選択可能
・G1に日報報告者の名前を記入
・E列にその日の所感などを記入
・案件名は別シートから選択式
・各案件ごとに業務内容とかかった時間を記入
・D列でその日に携わった業務の合計時間を自動計算
といったところです。
セレクトボックス作成の仕方(データの入力規則)や合計時間の作成方法は割愛します。
簡単ですのでググッてみてください。
スクリプトエディタの準備
GAS (Google Apps Script) の編集画面を開きます。
スプレッドシートの上部メニューより、[ツール] → [スクリプトエディタ] をクリックします。そうすると、無題のプロジェクトというタイトルで GAS のエディタが開き、デフォルトでは myfunction() という名前の何も記述されていない関数が入っています。この関数名を、daily_report() とでも変更しておきます。
変更後、GAS エディタ上部メニューより、[ファイル] → [保存] をクリックします。初回のみプロジェクト名入力ダイアログが開きますので、”chatwork日報送信”とでもして [OK] をクリックします。
ボタンの作成
スプレッドシートにボタンを設置し、クリックすると daily_report() を実行するようにします。スプレッドシート上部メニューより、[挿入] → [図形描画] とすすみ、ボタンとなる画像を作成します。今回はこんな感じにしてみました。
ボタンを適当な大きさ・適当な場所に配置した後、ボタンを右クリックします。そうすると右上のほうに ▼ マークが表示されますので、クリックし “スクリプトを割り当て” を選択します。スクリプトの割り当てダイアログが開きますので、今回は “daily_report” と入力し、[OK] をクリックします。
これでボタンをクリックすると daily_report() 関数が走るようになりました。この段階では daily_report() の内容を記述していませんので、クリックすると [スクリプトが終了しました] といった通知のみがスプレッドシート上部に表示されます。
ChatWorkClient ライブラリの追加
チャットワーク API を GAS で利用するには、ChatWork API ライブラリを設定しなければいけません。GAS エディタ上部メニューの [リソース] → [ライブラリ] を開き、ライブラリを検索欄に “M6TcEyniCs1xb3sdXFF_FhI-MNonZQ_sT” と入力し、[選択] ボタンをクリックします。ChatWorkClient ライブラリが表示されますので、バージョンに最新のものに選択し、[保存] をクリックします。
これでチャットワーク API を保存する準備ができました。
チャットワーク送信用コードを書こう
こんなかんじで gas にコードをかきます。セル番地などは、最初の画像にあわせたものになっています。セルを整形した方は、コードの方もあわせて変更してくださいね。
function daily_report() {
var mySs=SpreadsheetApp.getActiveSpreadsheet(); //スプレッドシートを取得
var mySheet=SpreadsheetApp.getActiveSheet(); //シートを取得
var lastRow=mySheet.getDataRange().getLastRow(); //対象となるシートの最終行を取得
var employeeName=mySheet.getRange(1,7).getValue(); //記入者の名前を取得
var Date = mySheet.getRange(1,2).getValue(); //チャットワークへ送信する日付
for(var i=3;i<=lastRow;i++){ //B列の3行目から最終行目までチェック
if(mySheet.getRange(i,2).getValue() === Date){ //B1の送信日付が同じ場合
var Impression = mySheet.getRange(i,5).getValue(); //所感取得
for (var j=1,k=5;j<8;j++,k+=2){ //業務内容取得
var col = j + k;
var Project = mySheet.getRange(i,col).getValue();
var Detail = mySheet.getRange(i,col+1).getValue();
var Hour = mySheet.getRange(i,col+2).getValue();
eval("var Project_" + j + " = Project");
eval("var Detail_" + j + " = Detail");
eval("var Hour_" + j + " = Hour");
}
var strBody = Date + "の" + employeeName + "の業務日報です。" + "\n\n";
for (var l=1;l<8;l++){ //業務内容を元にchatworkへ送信するメッセージを整形
eval("var chkProject = Project_" + l);
eval("var chkDetail = Detail_" + l);
eval("var chkHour = Hour_" + l);
if(chkProject != ''){
strBody += chkProject + "\n";
strBody += chkDetail + "\n";
strBody += chkHour + "時間" + "\n\n" ;
}
}
if(Impression != ''){
strBody += "~所感など~" + "\n";
strBody += Impression + "\n";
}
var cwClient = ChatWorkClient.factory({token: 'XXXXXXXX'}); //チャットワークAPI
cwClient.sendMessage({
room_id:XXXXXXXX, //ルームID
body:strBody
});
Browser.msgBox("チャットワークへ送信しました。本日もお疲れ様でした。");
return i;
}
}
return 0;
}
簡単な解説
冒頭の変数宣言では、
mySs にスプレッドシートファイル、mySheet にシート名、lastRow にシートの最終行を代入しています。employeeName は G1 セルの記入者の名前、Date は B1 セルの報告する日付です。(コメントそのままですね・・・)
for(var i=3;i<=lastRow;i++){
if(mySheet.getRange(i,2).getValue() === Date){ //B1の送信日付が同じ場合
//大抵の処理はここに記述
}
}
にて、3行目以降の B列から B1 の日付と一致するセルを検索し、ヒットした場合は //大抵の処理はここに記述 の箇所にかいていきます。
今回のフォーマットでは所感、案件名1~7、詳細1~7、かかった時間1~7 を記入しますので、一旦 Impression、Project_1 (~7)、Detail_1 (~7)、Hour_1 (~7) にそれぞれを代入します。
for (var j=1,k=5;j<8;j++,k+=2){ //業務内容取得
var col = j + k;
var Project = mySheet.getRange(i,col).getValue();
var Detail = mySheet.getRange(i,col+1).getValue();
var Hour = mySheet.getRange(i,col+2).getValue();
eval("var Project_" + j + " = Project");
eval("var Detail_" + j + " = Detail");
eval("var Hour_" + j + " = Hour");
}
今回の場合は、カウンタ変数 j に Project_1~7 の 1~7 の部分を入れています。
カウンタ変数 k は各入力項目の番地取得用です。今回のフォーマットにあわせて 5 から始まりループごとに 2 ずつ加算しています。
案件名1 は F列 (6番目の列) ですので j (1) + k (5) で算出できるわけですね。
案件名2 も I列 (9番目の列) ですので j (2) + k (7) というふうに算出できます。
案件名3 以降も同様です。
また、変数名を動的に定義したいので、Project_1~7、Detail_1~7、Hour_1~7 は eval()関数で定義します。セキュリティ面の懸念点もあるけれど、eval 超便利。
変数 strBody には、チャットワークへ送信するメッセージを入れていきます。
また、後半のAPIトークン {token: ‘XXXXXXXX’} に自分(発言者)のトークンを設定し、
room_id には発言させたいチャットワークのルームIDを記入します。
実行してみよう
コードを修正したら、[ファイル] → [保存] より一旦保存します。
それではスプレッドシートに戻り、日報記入後、作成したボタンをクリックしてみましょう。
初回のみ、以下の承認ダイアログが表示されますので、[続行] ボタンをクリックし、
Google の許可のリクエストで [許可] をクリックします。
チャットワークにも、指定した日付の記入内容が送信されました!
YATTA!
ビーズクリエイトではエンジニアを募集しています。
ビーズクリエイトのエンジニア職に興味のある方は、ぜひご連絡ください