Slackの投稿を1ヶ月単位でスプレッドシートに書き込む【GoogleAppsScript】


現状・やりたいこと

  • プライベートで使ってるSlackがフリープラン
  • 過去の投稿を残しておきたい
  • 保存する投稿はDMのやりとり

やること

1. Slackでユーザーbotの作成

試してないけどアプリbotだとできなさそうだからユーザーbotにした
(てかDMにアプリbotって追加できないよね。。。?)

メッセージ取得に必要な権限を設定してユーザーbotの作成

2. SlackAPIでSlackに投稿した1ヶ月分の投稿の取得

エンドポイントは https://api.slack.com/api/conversations.history

最初channelにDM相手のユーザーIDを指定しててずっとchannel_not_foundが返ってきてハマった。。。
↓DMにもチャンネルIDあるの知らんかった

SlackチャンネルID

メッセージ取得件数がデフォルトで100件ほどだからresponse_metadata.next_cursorが空になるまでfetchMessages()を実行する

function fetchMessages(results = [], cursor = "") {
  const res = UrlFetchApp.fetch(
    "https://api.slack.com/api/conversations.history?channel=" +
      CHANNEL_NAME +
      "&oldest=" +
      oldest +
      "&latest=" +
      latest +
      "&cursor=" +
      cursor,
    {
      method: "get",
      payload: {
        token: USER_TOKEN,
      },
    }
  );

  const src = JSON.parse(res);
  if (!src.ok) {
    Logger.log(src);
    throw new Error("レスポンス不正");
  }

  results.push(...src.messages);
  // response_metadata.next_cursorがある場合は再帰処理
  if (src?.response_metadata?.next_cursor) {
    return fetchMessages(results, src.response_metadata.next_cursor);
  }
  return results;
}

3. スプレッドシートにシートの作成と書き込み

function myFunction() {
  const ss = SpreadsheetApp.openById(SHEET_ID);
  const sheet = ss.insertSheet();
  const dt = new Date();
  // 前月分の投稿を取得するため-1ヶ月にする
  dt.setMonth(dt.getMonth() + 1 - 2)
  const dateArray = dt.toLocaleDateString().split("/"); // toLocaleDateString()のformatがMM/DD/YYYYになるのはなんで...??
  // 年月毎にシートの作成
  sheet.setName(dateArray[2] + "-" + (dateArray[0].length === 1 ? "0" + dateArray[0] : dateArray[0]));

  const src = fetchMessages();
  // 日付の昇順で登録したいからsort
  src.sort((a, b) => a.ts - b.ts);
  const results = [];
  src.map((row) => {
    const dt = new Date(row.ts * 1000).toLocaleString("JP");
    results.push([dt, USERS[row.user], row.text]); // 時間・ユーザー名・メッセージ
  });

  sheet.getRange(1, 1, results.length, 3).setValues(results); // 一括書き込み
}

4. GASのトリガー設定

トリガーの設定を毎月1日に設定する

GoogleAppsScriptのトリガー設定

あとはスプレッドシートに書き込まれればOK

Googleスプレッドシート

コード全文

感想

UrlFetchApp.fetchparams指定できんの知らんかった
文字列連結むりすぎ

developers.google.com

参考

api.slack.com developers.google.com


株式会社エイルシステムではWebエンジニア・モバイルアプリエンジニアを募集しています。
実務経験がなくてもOKです。ご興味のある方は弊社HPよりご連絡ください。