業務の隙間を埋める技術メモ。

「それ、作れるか?」より 「それ、作って大丈夫か?」を考えたい。 業務で“ちゃんと使える”かどうかを、 実際に手を動かして確かめたログを残しています。

Power Automate → Slack連携を“そのままやらない”という選択をしてみた話(GAS経由で安定させる)

はじめに

「Power AutomateからSlackに通知飛ばしたい」

これ、やろうと思えばすぐできそうに見えるんですが、実際にやってみると意外と詰まります。
自分も最初は「公式コネクタあるし余裕でしょ」と思っていました。

…が、結論から言うと、

  • 直接連携はできることが少ない

  • スレッド周りが弱すぎる

  • 運用していくと破綻しやすい

という壁にぶつかり、「GAS(Google Apps Script)を挟む構成」に落ち着きました。

この記事では、

👉 実際にハマったポイント
👉 なぜGASを挟むとラクになるのか
👉 実装手順(やってみたベース)

を、同じ目線で整理していきます。


まずやってみた:Power Automate → Slack 直接連携

やったこと

  • Power Automateでフロー作成

  • Slackコネクタで「メッセージ投稿」

一見うまくいく

普通にチャンネルに投稿はできます。

👉 ここまでは5分でできる


でもすぐ限界がくる

業務で使おうとすると、ここが一気に効いてきます。


① スレッドに投稿できない(ほぼ詰みポイント)

  • 投稿はできる

  • でも「既存メッセージへの返信」ができない

👉 つまり
通知が全部バラバラに散らかる


② スレッドを“動的に作れない”のが地味に致命的

これが今回一番言いたいポイントです。

やりたかったこと👇

  • 案件ごとにスレッドを作る

  • 同じ案件の更新は同じスレッドにぶら下げる

  • 新規なら新スレッド、既存なら返信

👉 こういう“普通の使い方”ができない

Power Automateの標準コネクタだと:

  • 最初の投稿のts(スレッドID)を取得できない

  • その結果、スレッドを起点にした制御ができない

👉 「スレッド運用そのもの」が設計できない


③ メッセージの柔軟性が低い

  • リッチな構造が組みにくい

  • JSONを直接扱いづらい


④ ロジックがつらい

  • ちょっとした整形が面倒

  • 分岐が増えると破綻気味


じゃあどうしたか → GASを挟んでみた

構成をこう変えました👇

Power Automate → GAS(Webhook)→ Slack API

GASを挟むと何が変わるか

① スレッドを“ちゃんと扱える”

ここが一番デカいです。

できるようになること👇

  • 新規投稿 → tsを取得

  • tsを保存(スプレッドシート等)

  • 次回以降 → thread_tsとして指定

👉 「動的にスレッドを作って、継続利用する」が実現できる


② スレッドの有無で分岐できる

スレッドIDある?
  YES → 返信
  NO  → 新規投稿+ID保存

👉 この当たり前の制御がようやく可能になる


③ Slack APIをフルで使える

  • chat.postMessage

  • thread_ts指定

  • blocks

👉 もはや別物レベル


④ Power Automateが軽くなる

  • ただデータを投げるだけ

  • ロジックは全部GAS

👉 フローが壊れにくい


実装手順(やってみた)


Step1:Slack側準備

  • App作成

  • chat:write権限付与

  • Botトークン取得


Step2:GASでWebhook

function doPost(e) {
  const data = JSON.parse(e.postData.contents);
  const token = "xoxb-xxxx";

  // スレッドID管理(例:スプレッドシートでもOK)
  let threadTs = data.thread_ts;

  if (!threadTs) {
    // 新規投稿
    const res = postToSlack(data.channel, data.text, null);
    threadTs = JSON.parse(res).ts;

    // ここでthreadTsを保存(案件IDと紐付けるなど)
  } else {
    // 既存スレッドに返信
    postToSlack(data.channel, data.text, threadTs);
  }

  return ContentService.createTextOutput("ok");
}

function postToSlack(channel, text, thread_ts) {
  const payload = {
    channel: channel,
    text: text,
    thread_ts: thread_ts || undefined
  };

  const options = {
    method: "post",
    headers: {
      Authorization: "Bearer xoxb-xxxx",
      "Content-Type": "application/json"
    },
    payload: JSON.stringify(payload)
  };

  const res = UrlFetchApp.fetch(
    "https://slack.com/api/chat.postMessage",
    options
  );

  return res.getContentText();
}

Step3:Power Automate

HTTPでGASに投げるだけ

{
  "channel": "#general",
  "text": "案件更新",
  "thread_ts": ""
}

👉 thread_tsは空でOK(GAS側で判断)


実際に使ってみた感想

スレッド運用が成立するようになった

これが本当に大きい。

  • 案件単位でまとまる

  • 更新が追いやすい

  • ノイズが減る

👉 「通知」から「業務ツール」に変わる


むしろ最初からこれでよかった

直接連携で頑張るより:

👉 GAS1枚挟んだ方が圧倒的にシンプル


まとめ

Power Automate → Slack連携は

👉 「投稿するだけ」なら直接でもOK
👉 「運用する」ならGAS必須レベル

特に、

👉 スレッドを動的に作れない問題

これがある限り、直接連携はかなり厳しいです。


最後に

今回の学び👇

👉 「できる」と「使える」は別

そして、

👉 GASは“制御レイヤー”としてめちゃくちゃ優秀


もし次にやるなら、

👉 最初から「スレッド管理前提」で設計する

これを強くおすすめします。