チャットワークの自動予約送信機能をGASで作ろう

みなさん、こんにちは!
現役エンジニアの”ます”です。

今回はChatworkの予約送信のプログラムの作り方を紹介していきます。
Google Apps Scriptを用いてChatwork APIを活用した予約送信です。

個人や法人などのビジネスの連絡でよく用いられるチャットワークですが、定期連絡や決まった時刻にメッセージを送信したいときってありませんか?
私自身、本業での連絡ツールがチャットワークのため、「いついつの何時に送信したい内容がある」と不便に思ったことがありました。

そこで、自分用のチャットワーク自動送信予約のスプレッドシートを作成したところ、
かなり便利になりましたし、社内でも評判がよく、様々な人が活用するようになりました。

本記事を実践して30分以内に、チャットワークのタイマー送信が可能になっていることでしょう!

今回は私がカスタマイズして作成したチャットワークの自動送信を簡易化し、紹介していきます。

スプレッドシートを作成する

まずはスプレッドシートを作成していきます。
今回、チャットワークの送信予約に必要な情報はスプレッドシートで管理する設定にします。

Googleドライブにスプレッドシートが作成できたら「予約送信」と「設定」のシートを作成しましょう。

予約送信シートのヘッダーを作成する

予約送信に必要なヘッダーを設定していきます。
今回は下記4つの項目を記入します。

  • 予約日時
  • 送信先ルームID
  • 送信内容
  • 送信完了日時

予約日時は今回は「年月日および時分」までを指定していく想定で設定しようと思います。
また、送信先ルームIDは後ほど詳しく説明しますが、こちらで誰に送るか、どのトークルームに送信するかを判別します。

送信内容はメッセージ内容で、送信完了日時は送信された際に入力していく項目とします。

設定シートのヘッダーを作成する

チャットワークのトークンを記入していきましょう。
こちらをプログラムから読み取る設定にしていきます。

※添付画像のトークンはダミーです。

チャットワークトークンの取得方法、参照方法に関してはこちらをご参照ください。

 

Chatwork APIの利用申請方法

次にGoogle Apps Scriptを導入してきます。

Google Apps Scriptの導入

スプレッドシートの「拡張機能」タブから「Apps Script」をクリックしてスプレッドシートに紐付けたプロジェクトを作成します。

仕組みや方法は詳しくこちらで紹介しているため、よろしければご参照ください。

Google Apps Scriptの導入方法

プログラムを必要な処理の順番に記入していく

さて、ここからのプログラムはどのような処理が必要なのか丁寧に考えていく方がスムーズに開発できます。

現在日時を取得

const NOW = new Date();

まず、予約送信というのが機能になりますから、現在日時と予約送信日時が一致しているかの判定が必要になります。
つまり、実行されている日時の取得は必須です。

スプレッドシートを取得

次にスプレッドシートを取得していきます。
今回、コンテナバインド方式でスクリプトを作成したため、こちらの取得は簡単です。

const SS = SpreadsheetApp.getActiveSpreadsheet();

チャットワークAPIトークンを取得

メッセージ送信時に必要となるチャットワークトークンを取得していきます。
設定シートに設定したA2セルの値を取得しますが、少々長くなるので後ほど関数として外だしします。

const TOKEN = getCwToken(SS);

run関数の外にgetCwToken()関数を作成していきます。

設定シートからA2セルの範囲を指定して値を取得して返却する関数です。

function run() {
  // 中略
}

/**
* 設定シートA2セルからチャットワークAPIトークンを取得
* SS : スプレッドシート型
* return string
*/
function getCwToken(SS) {
  const SHEET = SS.getSheetByName("設定");
  const API_TOKEN = SHEET.getRange("A2").getValue();
  return API_TOKEN;
}

予約送信シートを取得

さて、いろいろと準備ができたので予約送信シートから予約送信に設定しているデータを取得してきましょう。

const SHEET = SS.getSheetByName("予約送信");

予約送信シートのデータを取得(1行目のヘッダーを除外)

取得したSHEETから入力されているすべてのデータを取得します。
この際、ヘッダーの値は無視したいので、slice(1)として除外しています。

const VALUES = SHEET.getDataRange().getValues().slice(1);

取得範囲は1行目から記入した最後の行までです。
添付画像だとA2セル(slice(1)で1行目を除外しているため)からD5セルまでの範囲が対象となります。

取得したデータをループ(行、インデックス番号)

取得したデータは2次元配列になるため、1行ずつ取り出して送信予約日時と一致しているかを見ていきます。
その際に配列内のすべてのデータを取り出すforEach文を活用していきます。

forEach文では第1引数を配列から1つずつ取り出した値の引数名を記入し、
第2引数にインデックス番号が割り振られます。

この第2引数は行番号を取得する際に使いますので今回は指定していきます。

VALUES.forEach((row, i) => {
  // ここにこの後の説明内容を追記していきます。
});

予約日時、送信先ルームID、送信内容、送信完了日時を取得

取り出した行は一次元配列になっているため、それぞれスプレッドシートの予約送信シートに指定したA,B,C,Dを取得していきます。

※上記、forEarch文の{}の中に追記していく内容です。

// 予約日時
let reserve_time = row[0]; // A列
// 送信先ルームID
let room_id = row[1]; // B列
// 送信内容
let message = row[2]; // C列
// 送信完了日時
let sent_time = row[3]; // D列

予約日時が現在時刻と一致しているかつ、送信完了日時が入力されてない場合

ここで、すべてのメッセージをチャットワークに送信してしまうのでは予約送信になりません。
現在時刻とスプレッドシートに記入した予約時刻が一致している場合、
かつ、送信完了をしていない場合にのみチャットワークにメッセージを送信するように設定していきましょう。

※上記、forEarch文の{}の中に追記していく内容です。

if(isSameTime(NOW, reserve_time) && !sent_time) {
  // ここに、下記の説明を追加します。
}

isSameTime関数は自作の関数です。
第1引数と第2引数を比較し、年月日と時分の一致を確かめます。

この関数はrun()関数の{}の外に記入するようにしてください。

function run() {
  // 中略
}

/**
* 年月日、時分が一致しているかをチェック
* time1 : datetime
* time2 : datetime
* return boolean
*/
function isSameTime(time1, time2) {
  return time1.getFullYear() === time2.getFullYear()
    && time1.getMonth() === time2.getMonth()
    && time1.getDate() === time2.getDate()
    && time1.getHours() === time2.getHours()
    && time1.getMinutes() === time2.getMinutes();
}

チャットワークにメッセージを送信

現在時刻が予約送信時刻と一致していた場合、かつ、送信完了日時が入力されていなかった場合に
sendMessage()関数を実行します。

sendMessage()関数も自作の関数です。
チャットワークトークンと送信先のルームID、送信内容を引数に設定しています。

※if文の{}内に記入するように注意してください。

if(isSameTime(NOW, reserve_time) && !sent_time) {
  sendMessage(TOKEN, room_id, message);
}

sendMessage()関数ではチャットワークAPIを活用し、外部との通信を行っています。
UrlFetchAppというGoogle Apps Scriptの機能でチャットワークに送信を依頼しています。

当ブログの他の記事ではGoogle Apps Scriptのライブラリ「Chatwork Client」を活用している記事もございますが、
今回は自分の手でAPIを叩くための設定を行っています。

※この関数はrun()関数の{}の外に記入するようにしてください。

function run() {
  // 中略
}

/**
* チャットワークへメッセージを送信する
* https://developer.chatwork.com/reference/post-rooms-room_id-messages
* TOKEN : チャットワークAPIトークン
* room_id : 送信先ID
* message : 送信内容
*/
function sendMessage(TOKEN, room_id, message) {
  const options = {
    method: 'POST',
    headers: {
      'Accept': 'application/json',
      'Content-Type': 'application/x-www-form-urlencoded',
      'X-ChatWorkToken': TOKEN
    },
    payload: {
      'body': message
    }
  };

  UrlFetchApp.fetch('https://api.chatwork.com/v2/rooms/' + room_id + '/messages', options);
}

スプレッドシートへ送信日時を記入

チャットワークへのメッセージ送信が完了したらスプレッドシートへ完了日時を記入しましょう。
insertSentTime()関数を実行します。

insertSentTime()関数も自作の関数です。
記入先のシート(予約送信)と行番号、現在時刻を渡しています。

行番号は「i+2」となっていますが、forEachのindex番号は0から始まるのに対し、
スプレッドシートの行数は1から始めるため、+1します。

さらに、ヘッダーの1行をslice(1)で除外していたため、+1する必要があり、「i+2」となっています。

※if文の{}内に記入するように注意してください。

if(isSameTime(NOW, reserve_time) && !sent_time) {
  sendMessage(TOKEN, room_id, message);

  // スプレッドシートへ送信日時を記入
  insertSentTime(SHEET, i+2, NOW);
}

insertSentTime()関数は送信予約シートのD列(送信完了日時)に時間を入力するための関数です。
※この関数はrun()関数の{}の外に記入するようにしてください。

function run() {
// 中略
}

/**
* 指定のシートの指定行にデータを入力する関数
* SHEET : 入力先のシート
* row_num : 入力行
* insert_value : 入力する文字列
*/
function insertSentTime(SHEET, row_num, insert_value) {
  SHEET.getRange("D"+row_num).setValue(insert_value);
}

 

簡単にコードを分けて説明してきましたが、いちどまとめたものを参照ください。

コードまとめ

/**
 * 実行関数
 */
function run() {
  // 現在日時を取得
  const NOW = new Date();

  // スプレッドシートを取得
  const SS = SpreadsheetApp.getActiveSpreadsheet();

  // チャットワークAPIトークンを取得
  const TOKEN = getCwToken(SS);

  // 予約送信シートを取得
  const SHEET = SS.getSheetByName("予約送信");

  // 予約送信シートのデータを取得 1行目のヘッダーを除外
  const VALUES = SHEET.getDataRange().getValues().slice(1);

  // 取得したデータをループ(行、行番号)
  VALUES.forEach((row, i) => {
    // 予約日時
    let reserve_time = row[0]; // A列
    // 送信先ルームID
    let room_id = row[1]; // B列
    // 送信内容
    let message = row[2]; // C列
    // 送信完了日時
    let sent_time = row[3]; // D列

    // 予約日時が現在時刻と一致している場合
    if(isSameTime(NOW, reserve_time) && !sent_time) {

      // チャットワークにメッセージを送信
      sendMessage(TOKEN, room_id, message);

      // スプレッドシートへ送信日時を記入
      insertSentTime(SHEET, i+2, NOW);

    }
  });

}

/**
 * 設定シートA2セルからチャットワークAPIトークンを取得
 * SS : スプレッドシート型
 * return string
 */
function getCwToken(SS) {
  const SHEET = SS.getSheetByName("設定");
  const API_TOKEN = SHEET.getRange("A2").getValue();
  return API_TOKEN;
}

/**
 * 年月日、時分が一致しているかをチェック
 * time1 : datetime
 * time2 : datetime
 * return boolean
 */
function isSameTime(time1, time2) {
  return time1.getFullYear() === time2.getFullYear()
    && time1.getMonth() === time2.getMonth()
    && time1.getDate() === time2.getDate()
    && time1.getHours() === time2.getHours()
    && time1.getMinutes() === time2.getMinutes();
}

/**
 * 指定のシートの指定行にデータを入力する関数
 * SHEET : 入力先のシート
 * row_num : 入力行
 * insert_value : 入力する文字列
 */
function insertSentTime(SHEET, row_num, insert_value) {
  SHEET.getRange("D"+row_num).setValue(insert_value);
}

/**
 * チャットワークへメッセージを送信する
 * https://developer.chatwork.com/reference/post-rooms-room_id-messages
 * TOKEN : チャットワークAPIトークン
 * room_id : 送信先ID
 * message : 送信内容
 */
function sendMessage(TOKEN, room_id, message) {

  const options = {
    method: 'POST',
    headers: {
      'Accept': 'application/json',
      'Content-Type': 'application/x-www-form-urlencoded',
      'X-ChatWorkToken': TOKEN
    },
    payload: {
      'body': message
    }
  };

  UrlFetchApp.fetch('https://api.chatwork.com/v2/rooms/' + room_id + '/messages', options);
}

手動で実行して試してみる

 

スプレッドシートに現在時刻を記入してrun()関数を実行してみます。

スプレッドシートに現在時刻を記入する

チャットワークの送信先ルームIDはURLで分かります。

スクリプトでrun()関数を実行する

実行ログに「実行完了」と出れば成功です。

チャットワークを確認する

チャットワークにもうまく送信できていました。

自動で毎分チェックしてくれるトリガー設定

Google Apps Scriptのプロジェクトに戻り、左サイドバーをご覧ください。

「トリガー」というのがあります。
こちらは手動でボタンや関数の実行を命令せずとも何らかのイベントをもとに自動で関数を実行してくれる設定になります。

今回は毎分、「時間」をベースに自動実行の設定にします。

トリガーを開く

トリガーを追加

画面右下に「トリガーを追加」というボタンがあるため、そちらをクリック。

トリガーの詳細設定

トリガーの詳細設定をします。
今回は毎分チェックをしたいのでこのように設定してください。

実行する関数:run

実行するデプロイを選択:Head

イベントのソースを選択:時間主導型

時間ベースのトリガーのタイプを選択:分ベースのタイマー

時間間隔を選択(分):1分おき

トリガーが設定されてることを確認する

 

これで設定は以上になります。

予約送信を使うことで業務が効率化、または削減されましたら幸いです。

私個人としてはこの他に定期メッセージの設定だとか、第1何曜日の設定、月初、月末の設定など、様々な機能を開発して活用しております。
また、チャットワークAPIも頻繁に活用しているため、ルーム名やルームIDを自動で取得することなども可能です。

より便利に、よりカスタマイズしたいなおご要望がございましたら問い合わせくださいましたらサポートします!

お問い合わせ

まとめ

最後までお読みいただきありがとうございます。

Google Apps Scriptと外部APIの連携は柔軟性も高く、導入コストも安いため、かなり有効活用しております。
今回は実務でも大活躍のチャットワークの自動予約送信機能の開発を紹介しました。

実際にゼロから簡易的なものを作ってみましたが、30分以内で完了しました。

本ブログではこれまでもこれからもGoogle Apps Scriptを紹介していきますので、
ぜひまたご覧になってくださいましたら幸いです。

Google Workspaceを活用している場合はGoogle Apps Scriptを覚えると業務の効率化および自動化ができます。
Google Apps Scriptが学べるスクールはコチラで紹介しています。よかったら見てみてください。

Google Apps Scriptを学べるスクール3選

Google Apps Scriptが学べたらコチラの記事で収益化してみてはいかがでしょうか?

Google Apps Scriptのプロが教える!成功するGAS副業完全ガイド

また次の記事でお会いしましょう!

最新情報をチェックしよう!