LoginSignup
2
1

More than 5 years have passed since last update.

Google Apps Script でドキュメントリンクを Slack に通知する

Posted at

はじめに

毎週行っている作業を自動化する Google Apps Script の、基本設計に示した4つ目のステップ「雛型ファイルのリンクを Slack に通知する」について説明します。

HTMLの雛型ファイル生成については、テンプレートを使って生成する方法を説明しました。サンプルコードのcreateHtmlTemplate()関数は File 型のオブジェクトを返しますので、この記事では File オブジェクトの URL を Slack に通知する関数を作成します。

関数仕様

関数名: slackSendTemplate

  • 引数
    • file : URL を通知する対象 File
  • 返り値: なし
  • 振る舞い
    • file の URL を Slack に通知する

シンプルですね。でも何か足りませんね。はい、一言に Slack と言いましても、どのワークスペースのどのチャネルに投稿するのかを示すパラメータが必要です。チャネルは開発中と本番運用で分けたいので、このパラメータはデプロイ時に決まると考えられます。こちらでも説明したように、このようなパラメータはプロジェクトのプロパティとして定義するのがよいです。

Slack の Webhook

外部アプリと連携して Slack にメッセージを送信する最も簡単なインターフェイスは Webhook です。Slack が提供するエンドポイントに対して、JSON 形式のデータをポストするだけで、Slack に通知を流すことができます。

Webhook の設定

こちらのドキュメントに簡単なチュートリアルがありますので、それを見て設定して下さい。英語がしんどいですか? では、簡単に手順を書いておきます。

  • 上記リンク先の右上 "Your Apps" というリンクをクリックします
  • "Create New App" をクリックします
  • 表示されたダイアログにアプリ名を入力し(この記事では AirBot とします)、Slack のワークスペースを選択します(サインインしているワークスペースを選択するか、ここでワークスペースにサインインします)
    image.png

  • "Create App" をクリックします

  • "Incoming Webhooks" をクリックします
    image.png

  • Webhook を有効化します(Off → On)
    image.png

  • On にすると以下が表示されますので、"Add New Webhook to Workspace" をクリックします
    image.png

  • 開いた画面で投稿先のチャネルを選択して、"許可する" をクリックします

  • 前の画面に戻りますが、Webhook URL の表示が増えていますので、"Copy" ボタンをクリックして URL をコピーします(必要な時にいつでもコピーできます)

  • サンプルコードもこの URL が挿入されたコードに変わっていますので、"Copy" ボタンをクリックしてコピーし、curlがインストールされた環境のターミナルに貼り付けて実行してみて下さい(感動の瞬間です!)

以上で完了です。Slack に投稿するのに必要なのはこの Webhook URL だけです。つまり、URL を知っていれば誰でも投稿できてしまいますので、URL をソースコードに埋め込むようなことはしないで下さいね。万一漏洩してしまった場合は、一旦ゴミ箱のアイコンをクリックして削除し、作り直して下さい。

プロパティ: SLACK_WEBHOOK

先にも書きましたように、Webhook URL はデプロイ時に決まるものと考えるとよいので、プロパティを作成します。プロパティ名は SLACK_WEBHOOK とします。

  • Google Apps Script のスクリプトエディタで、メニューの「ファイル」→「プロジェクトのプロパティ」を選択します
  • 開いたダイアログの「スクリプトのプロパティ」タブをクリックします
  • 「+行を追加」をクリックします
  • (名前)に SLACK_WEBHOOK を、(値)に Webhook URL を入力し、「保存」をクリックします image.png

テストコード

マイドライブに HTML ファイルを作成して、その URL を Slack に通知するテストです。

test.gs
function testSlackSendTemplate() {
  const file = DriveApp.createFile('template.html', '<h1>This is a template file.</h1>', MimeType.HTML);
  slackSendHtml(file);
}

関数コード

シンプルなメッセージ

まずは、何の飾り気もなく、ただ作成したファイルの URL を Slack に通知するコードです。Webhook URL に JSON形式のデータを POST するだけです。簡単ですね。

main.gs
function slackSendTemplate(file) {
  Logger.log('雛型ファイルのリンクを Slack に通知する');

  //スクリプトプロパティを取得する
  const url = PropertiesService.getScriptProperties().getProperty('SLACK_WEBHOOK');

  const params = {
    method: 'post',
    contentType: 'application/json',
    payload: JSON.stringify({ text: '雛型ファイルを生成しました ' + file.getUrl() })
  }
  UrlFetchApp.fetch(url, params);  
}

初めてテストコードtestSlackSendTemplateを実行した時に、Google ドライブ操作と、外部サービス接続のアクセス許可を求められます。アクセス許可については、こちらを参照して下さい。めでたく実行が完了すると、以下のように Slack にメッセージが表示されます!

image.png

リッチなメッセージ

Webhook の説明ページには、Attachment を使ってリッチなメッセージを作成するサンプルがあります。しかし、Attachment の説明ページを見ると、outmoded approach(時代遅れなやり方)なので Layout Blockを使いなさいと書かれています。以下は、Layout Block を使って、テキスト1、水平ライン、ファイルへのリンク、テキスト2 というメッセージを送るコードです。

slack.gs
function slackSendSimpleMessage(url, text) {
  const message = { text: text };
  slackSend(url, message);
}

function slackSendRichMessage(url, text1, fileName, fileUrl, text2) {
  const message = {
    blocks: [
      {
        type: 'section',
        text: { type: 'mrkdwn', text: text1 }
      },
      {
        type: 'divider'
      },
      {
        type: 'section',
        text: {
          type: 'mrkdwn',
          text: Utilities.formatString('<%s|_*%s*_>\n%s', fileUrl, fileName, text2)
        }
      }
    ]
  };
  slackSend(url, message);
}

function slackSend(url, message) {
  const params = {
    method: 'post',
    contentType: 'application/json',
    payload: JSON.stringify(message)
  };
  Logger.log(JSON.stringify(message));
  UrlFetchApp.fetch(url, params);  
}

Slack 関連の関数は汎用性が高いので、別のスクリプトファイル slack.gsに分けて定義しました。先ほどの例のシンプルなメッセージを送る関数slackSendSimpleMessageと、リッチなメッセージを送る関数slackSendRichMessageを定義しています。メッセージ送信部分は共通なので、関数slackSendとしてくくり出しました。

リッチなメッセージを送信するメインの関数は以下のようになります。

main.gs
function slackSendTemplate(file) {
  Logger.log('雛型ファイルのリンクを Slack に通知する');
  const url = PropertiesService.getScriptProperties().getProperty('SLACK_WEBHOOK');
  slackSendRichMessage(url,
                       ':page_with_curl: <!channel> 今週の雛型ファイルを作成しました。',
                       file.getName(), file.getUrl(),
                       ':stars:リンクを開いてダウンロードして下さい。');
}

テキストのフォーマットについては、こちらを参照して下さい。テストコードtestSlackSendTemplateを実行すると、以下のようにリッチなメッセージが Slack に表示されます。

image.png

おわりに

実は記事を書いている途中に Attachment でなく Layout Block を使うべきだということに気づいてコードを書き直したので、随分書くのに時間がかかってしまいました。

おまけ

テキストのフォーマットに関する Slack のドキュメントには誤りがあります。問い合わせページから指摘しておいたので、いつか修正されると思いますが、念のためメモしておきます。ちなみに、問い合わせページが日本語のフォームだったので日本語で書いたら、英語でとんちんかんな返事が来ました。英語で説明したら理解して頂けたようでした。

Automatic parsingの説明に以下の記載がありますが、ここの true は false の誤りです。false がデフォルトです。

You can achieve this in different ways, depending on where the text is being placed:

  • For text in layout blocks set a verbatim attribute of your text objects to true. This is actually the default method of processing these text objects.

同じく、少し下の記載の false は true の誤りです。verbatim は「文字どおりに」という意味ですので、true にすると自動パースしてくれなくなるのですね。

If you want to disable automatic parsing, you have a couple of options depending on the type of text:

  • For text in layout blocks set a verbatim attribute of your text objects to false.
2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1