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


はじめに

毎週行っている作業を自動化する 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.