GoogleAppsScriptでGmailのデータを取得してSlackに投稿する

お仕事でGoogleAppsScript(GAS)を書くことになったので手順をメモ。

  1. Gmailの受信ボックス内に特定のラベルがついているメールをGAS取得
  2. GASで取得したメールから必要な情報を取り出す
  3. メールのラベルを処理済みみたいなラベルに付け替える
  4. Slackの指定したチャンネルに成形したデータを投稿する

という流れ。

Slackアプリの作成準備

Create an app

まずはSlackに投稿するために必要な準備をしておきます。slack api ページを開き、「Create an app」という白いボタンを押します。

Slack API 公式サイト

クリックすると以下のような画面が出ます。 From scratch を選択して1から作成することにします。

Create an app

アプリの名前(任意)を入力して、どのSlackワークスペース用に作成するか、管理しているSlackのワークスペースを選択して「Create App」をクリックしてアプリを作成します。

Slack API Name

OAuth & Permissions

アプリの作成が完了すると、アプリの基本情報が表示されるページへ遷移します。次にやることは、この作成したアプリにSlackワークスペースを操作するために必要な権限を設定します。左側のメニューの「Features」の中にある「OAuth & Permissions」をクリックすると権限設定ページが開きます。

Slack OAuth & Permissions

少し下の方にScopesのセクションがあるので、「Bot Token Scopes」に設定を追加します。 「Add an OAuth Scope」のボタンをクリックして、chat:write の権限を追加します。これで、チャンネルへのメッセージ送信(チャットへの書込み)権限が付与されました。

Slack Bot Token Scopes

権限を付与するとページの上に戻って、「OAuth Tokens for Your Workspace」のセクションの「Install to Workspace」を押すとアプリがSlackにアクセスする権限の許可をもとめてきます。許可してあげましょう。

Slack Add an OAuth Scope

許可すると前の画面に戻ってきて、トークンが発行されているはずです。そのトークンをGASで使用しますので取っておきましょう。Slack側の準備はひとまずここまでです。

Slack OAuth Tokens for Your Workspace

Gmailの情報を取得してラベルの削除と追加

現在ログインしているGmailアカウントの受信トレイから指定したラベルのデータを取得して、プログラムで加工したいわけで。ひとまずサンプル書きます。

function getMail() {
  const label1 = GmailApp.getUserLabelByName('取りたいラベル');  // 取得するラベル名
  const label2 = GmailApp.getUserLabelByName('削除後のラベル');  // 変更するラベル名
  let threads  = GmailApp.search('label:取りたいラベル', 0, 1);  // ひとまず1件取得

  for(let thread of threads) {
    let msgs = thread.getMessages();

    if (msgs[0]) {
      let msg = msgs[0];
      let date = msg.getDate();
      let subject = msg.getSubject();
      // 何かしら情報を成形
    }
    thread.removeLabel(label1);  // ラベルを削除
    thread.addLabel(label2);     // ラベルを新規追加
  }
}

ポイントはまずは2行目から4行目のGmailAppクラスオブジェクト。これで取得するラベル名・変更するラベル名・指定したラベルのメールを取得します。4行目でメールを取得できれば、threads配列に受信メール情報(GmailThreadクラスのインスタンス)が格納されます。そこからgetMessagesメソッドで取得したメッセージ(GmailMessageクラスのインスタンス)を元に情報を加工します。

最後に取得に使用したラベル名を受信メールから削除(15行目)してラベルを新たに追加(16行目)して処理完了です。

GASでSlackの指定チャンネルに投稿

GASにSlackAppライブラリを導入

まずはGASでSlack APIを使用できるようにするためにライブラリを追加します。GASを記述している所の左側に「ライブラリ」と「サービス」があるのでライブラリをクリックして追加します。

Slackライブラリ追加

スクリプトIDの入力を求められるので、
スクリプトID:1on93YOYfSmV92R5q59NpKmsyWIQD8qnoLYk-gkQBI92C58SPyA2x1-bq
を貼り付けて検索ボタンを押すとSlackAppが出てくるので追加してあげます。

Slack APIをコールして指定チャンネルにメッセージを投稿する

これまたサンプルを書きます。
初回実行時に「承認が必要です」と確認を求められますので、権限を確認して許可をしてください。

function postSlack() {
  let token = 'xoxb-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx';  // Slack APIで発行したtoken
  let slackApp = SlackApp.create(token);
  let channelId = '#general';
 
  slackApp.postMessage(channelId, 'test\nmessage');
}

Slack側でチャンネルにアプリ追加

Slackの左側のメニュー「App」にアプリが追加されているはずですので、アプリを使用するチャンネルを指定します。アプリをクリックして画面上部のアプリ名をクリックすると以下の画面が表示されるので使用するチャンネルを指定します。

Slackアプリをチャンネルに追加

GASのトリガーを設定

最後のこれを定期実行するためにトリガーを設定します。プログラムを書いている画面の一番左の時計アイコンをクリックするとトリガーの追加ができます(追加ボタンは画面右下)

GASトリガー設定

これを設定してトリガー通りのサイクルで動作すればOKです。最初はテストするために即時実行で試してみましょう。

Slack API 実行結果

できた!\(^o^)/
2023年最初の記事を箱根駅伝を見ながら書くっていうね。

追記:メッセージにメンションをつける場合

SlackAppのライブラリではメンションのつけ方がちょっと特殊なのでメモ。

チャンネル<!channel>
アクティブユーザー<!here>
ユーザー<@メンバーID>
グループ<!subteam^取得したID|グループ名>