Googleフォームに記入されたらフォームの一部の内容を引用してTGのチャットに通知するBotを作ったよ(追記あり)

14 April 2021

GAS

t f B! P L

ちょっとしたBotを作るのに、アカウントさえあればサーバーレスかつ追加費用なしでもかなりのことができるという理由で、GAS(Google Apps Script)でガスガス書く界隈があります。

自分もGASでTGのBotを作ろう! と挑戦しましたが、まったく知識ゼロの初心者が書くには当時は参考にできる資料が少なすぎ、またGASはコードの管理とか実行ログ閲覧とかが本当にイケてないので、その時はGASで書くのは諦めました。ちなみにGASでガスガス書く人も「GASはデバックしづらい」とこぼしていましたので、やっぱそういうもんなんだと思います。

しかし「Googleフォームに記入されたらTGのチャットに通知を送るBot」を作ろう、もっと一般化して言うと、Googleドキュメント(総称)に対する何らかのアクションをトリガーにしたりドキュメントを操作したりしようと思ったらGASを使うのが当然便利なので、GASに舞い戻ってまいりました。

コードを書くにあたっては、Botや自分の表示名やサンプル文が2バイト文字だと、TGからのレスポンスでそれらが文字コードに変換されてしまって普通の人間には解読困難になるので、とりあえず英語で設定するのがおすすめです。以下コード。


//Botトークン var token = PropertiesService.getScriptProperties().getProperty("tokenIsabella");
//チャットID
var chatId = PropertiesService.getScriptProperties().getProperty("chatId");

var telegramUrl = "https://api.telegram.org/bot" + token;


//Installable Trigger; FormTriggerBilder
//実行するとトリガーがセットされる
function createFormSubmitTrigger() {
  var formId = PropertiesService.getScriptProperties().getProperty("formId");
  ScriptApp.newTrigger('fromGoogleFormToTelegram')
      .forForm(formId//トリガー対象のフォームを指定
      .onFormSubmit()
      .create();
}

//spreadsheetからデータを取得
function fromGoogleFormToTelegram(){
  var spreadSheetId = PropertiesService.getScriptProperties().getProperty("spreadSheetId");
  //フォームレスポンスのスプレッドシートを取得
  var activeSpreadsheet = SpreadsheetApp.openById(spreadSheetId);
  var activeSheet = activeSpreadsheet.getSheets()[0]; //アクティブシートを取得
  var row = activeSheet.getLastRow(); //行数
  var column = 3//シートC列目
  var range = activeSheet.getDataRange(); //データが入っている範囲を取得
  var value = range.getCell(row, column).getValue(); //最終行C列目の値を取得
  var message = "";

  message += value;
  Logger.log(message);
  sendToTelegram(chatId'@' + message + ' さんがフォームを送信しました!'token);
}

function sendToTelegram(chatIdtext){
  var payload = {
    'method''sendMessage',
    'chat_id'chatId,
    'text'text,
    'parse_mode''HTML'
  }
  var data = {
    'method''post',
    'payload'payload
  }
  var response = UrlFetchApp.fetch(telegramUrl + '/'data);
  Logger.log(response.getContentText());
}

(追記1) コードにAPIトークンやらスプシIDやらをベタ書きするのはよくないね、ということでベタ書きしていたBotトークンやらスプシIDやらをプロパティサービスを使って書き換えました。

(追記2) はじめはスクリプトをContainer-boundにしていたのですが(トリガー設定が楽なので)、これは元のGoogleドキュメントが編集可で共有されているとコードが書き換えられちゃう可能性があってあぶないね、ということでスクリプトをStandaloneにし、それに伴ってInstallable Triggerを導入しました。


[参考にしたサイト]

Telegram Bot Tutorial: How to connect your Telegram Bot to a Google Spreadsheet (Apps Script)
GoogleスプレッドシートとTGのBotを接続する方法で最初に見つけられたのこのYouTubeくらいなもんだった


GoogleAppsScriptでTelegram BOTを作る ~第1回 はじめてのTelegram BOT
とりあえずBotにしゃべらせるにはこうすればいいのか~というのがわかりやすく書いてあった


Googleフォームの回答内容をLINEで通知する
SlackとかLINEでGoogleフォームに記入した内容を受け取る方法はいくつかのサイトで解説されてたんだけど、ここのフォーム内容の取得方法が自分には一番アレンジしやすかった


【GAS】コードにAPIトークンやIDのベタ書きを避ける!(プロパティサービスの活用)
GASでのプロパティサービスの活用法。まぁベタ書きよりはよほどマシだけれども、Googleドキュメントの編集権限があればオーナーでなくても普通に書き換えできちゃうし、私の根本的な懸念はまったく払拭されていない


セキュリティに配慮しながらGASを書くTips
「Container-bound Scriptsだと権限も共有してしまう」これは特に、編集可で共有されることの多いGoogleスプレッドシートで大問題となり得るのだが、スクリプトをStandaloneにしてしまい、かつスクリプトの共有はしないことでその危険性はだいぶ低くなる。しかしそれでも私の根本的な懸念が完全に払拭された訳ではない、なぜならドキュメントの編集権限があればドキュメントにスクリプトくっつけて好き勝手にデプロイできてしまうことに変わりはないのだから……

Installable Triggers
スクリプトをStandaloneにしてしまうと、GoogleドキュメントとContainer-boundなスクリプトではデフォルトで使えたいくつかのトリガーが使えなくなるので、自分でトリガーを設定する必要が出てくる。使用にはトリガーの対象となるGoogleドキュメントの編集権限が必要

Search This Blog

History

2010年3月31日 再々移転・改題
2008年7月16日 再移転
2003年2月26日 移転・改題
1999年1月2日 開設

QooQ