【非エンジニア向け】Slackで一定時間リアクションが無い投稿を自動でリマインドさせる方法（Zapier使用）

# はじめに

Slackで一定時間が経っても絵文字リアクション（私は勝手にスタンプと呼んでしまっています）が無い場合に自動でリマインドさせたいと思ったのですが、調べてもあまり同様の例がなく、愛用しているZapierでも簡単には実装できなそうでした。
※[Zapier](https://zapier.com)とは、様々なWebサービスやアプリ（例えばGmailやSlack、Googleスプレッドシートなど）を連携し、ノーコードで自動化できるアメリカ発のサービスです。例えば「スプレッドシートの内容が更新されたらSlackでメッセージを送信する」といったワークフローを、プログラミングの知識がなくても実装することができます。

そこで色々と工夫した結果、Zapierで2本のワークフローを組み合わせる方法で実現できたため、この記事ではそのやり方について説明しています。

ちなみに筆者はコードをまったく書けない/分からない非エンジニア人材です！
なるべく非エンジニアの方がそのまま真似しやすいように、スクショ多め・手順を詳細めに記載しています。
なお、Zapierで単純なワークフローが作成できる方を想定して説明しますが、説明通り設定すれば初めての方でも完コピしていただけると思います。

# このワークフローでできること

Slackで特定の投稿に一定時間特定のリアクションが無い場合、BotがSlackにメッセージを送信してくれます。
![2212qiita_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530171/176a30e0-ed6f-937e-c865-28e25b3deaf7.png)
![2212qiita_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530171/7c48fb68-762a-8209-d93c-f51a1135d8db.png)
- 特定の投稿＝「特定のチャンネル内の投稿」を前提に説明しますが、「特定のチャンネル内で特定のワードを含む投稿」「特定のチャンネル内で特定の人からの投稿」や、特定のチャンネルに限らず全チャンネル内といった条件でも可能です。
- 一定時間＝スクショのように「15分」「1時間」のような設定のほか、「○日」「○週間」も可能です。
- 特定の絵文字リアクション＝ワークスペースに追加された組織独自のカスタム絵文字のみ設定できます（デフォルトの絵文字は設定できません）。また、ワークスペースのメンバー全員ではなく、特定の誰かがリアクションした場合のみを条件とすることも可能です。

# 構築に必要なもの

- Zapier
    - アカウント（Multi-step Zaps を作成できるStarterプラン以上）
- Slack
    - アカウント
    - ワークフローに使うカスタム絵文字
- Googleスプレッドシート
    - 以下が転記される列を用意します。（列順や表記は自由でOK / 必須以外は推奨項目）
        - リアクションした日時
        - リアクションした人のSlackユーザー名
        - リアクションした投稿の内容
        - リアクションした投稿のURL（必須）
        ![2212qiita_14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530171/b91c9882-2002-24e6-348d-d0fe5c550455.png)

# ワークフローの構成

Zapierで以下2つのワークフローを稼働させます。

1. 特定のチャンネル内で特定のリアクションがあったら、その情報をスプレッドシートに転記するワークフロー
2. 特定のチャンネル内で条件に一致する投稿があったら、一定時間経過後にスプレッドシートで当該投稿へのリアクションの有無を確認し、リアクションが無い場合のみメッセージを送信するワークフロー

# ワークフローの作り方

## 1 特定のチャンネル内で特定のリアクションがあったら、その情報をスプレッドシートに転記するワークフロー

### 【全体の構成】
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530171/cab5a040-7177-a071-c07d-5e2aa883535d.png" width=70%>

### 【各ステップの設定】

#### 1-1. New Reaction Added in Slack
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530171/565dfd9d-d049-b561-a3a1-0efc07c218e4.png" width=70%>

- App : Slack
- Event : New Reaction Added
- Account : 対象の投稿やリアクションを見れる権限のアカウントであればOK
- Trigger
    - Reaction : リアクションを検出したいカスタム絵文字を指定
    - Channel : 特定のチャンネル内でのリアクションでのみワークフローを起動させたい場合は、ここでチャンネルを指定
        - 特定の複数チャンネル内で起動させたい場合はここで指定せず、ステップ1と2の間にFilterアクションを追加して「1のチャンネル名が○○ or ××と一致する場合のみ」等と設定することで実現できます
        - 全チャンネル内で起動させたい場合は指定不要です
    - User : 特定の誰かがリアクションした場合のみワークフローを起動させたい場合は、ここでSlackユーザーを指定
        - 特定の複数人のリアクションで起動させたい場合はここで指定せず、ステップ1と2の間にFilterアクションを追加して「1のSlackユーザー名が○○ or ××と一致する場合のみ」等と設定することで実現できます
        - 誰がリアクションした場合でも起動させたい場合も、指定不要です
- Test : テストを行うと、上の設定に関わらず直近そのAccountで押したカスタム絵文字が検出されますが、仕様なのでそのまま進んでOKです

#### 1-2. Create Spreadsheet Row in Google Sheets
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530171/e33e3501-5bda-6876-1ee4-d0ced0cc0fc4.png" width=70%>

- App : Google Sheets
- Event : Create Spreadsheet Row
- Account : このスプレッドシートへの編集権限を持つアカウントであればOK
- Action
    - Drive : スプレッドシートが所属する共有/マイドライブを指定（任意）
    - Spreadsheet : スプレッドシートのIDを指定（プルダウンで指定するか、以下でIDを抽出して直接記入）
        - IDはスプレッドシートのURLの`d/`と`/edit`の間の英数字（スクショ赤枠箇所）で確認できます
        <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530171/d3aa0332-a590-ce95-adf5-cefb156c1698.png" width=70%>
    - Worksheet : スプレッドシートの対象シート名を指定
    - タイムスタンプ : 1のMessage Ts Time（Slackの投稿時間）を指定（任意）
    - スタンプ追加者：1のUser Name（リアクションした人のSlackユーザー名）を指定（任意）
    - 内容 : 1のMessage Text（Slackの投稿内容）を指定（任意）
    - Thread Ts : 1のMessage Ts（Slackの投稿のスレッド識別番号のようなもの）を指定（任意）
    - URL : 1のMessage Permalink（Slackの投稿URL）を指定
    ※タイムスタンプ～URLの項目はスプレッドシートの各列の1行目が自動展開されているものなので、ご自身のスプレッドシートによって異なります
    ※タイムスタンプ～URLの項目をスプレッドシートに用意していますが、このワークフローでは実質URLしか使用しません。他の項目はあくまで私の管理用に用意していて、推奨ではありますが必須の項目ではありません
    - Test : テストを行うと、1のテストで取得した内容がスプレッドシートに転記されるので、想定通りの転記となっているか確認してください

## 2. 特定のチャンネル内で条件に一致する投稿があったら、一定時間経過後にスプレッドシートで当該投稿へのリアクションの有無を確認し、リアクションが無い場合のみメッセージを送信するワークフロー

### 【全体の構成】
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530171/c2fa48eb-890c-3b57-884c-826e6fcd0efa.png" width=70%>


### 【各ステップの設定】

#### 2-1. New Message Posted to Channel in Slack
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530171/59345f5c-05c7-f2ed-5a53-058f99f7874e.png" width=70%>

- App : Slack
- Event : New Message Posted
- Account : 対象の投稿やリアクションを見れる権限のアカウントであればOK
- Trigger
    - Channel : 特定のチャンネル内での投稿でのみワークフローを起動させたい場合は、ここでチャンネルを指定
        - 特定の複数チャンネル内で起動させたい場合はここで指定せず、ステップ2のFilterアクションで「1のチャンネル名が○○ or ××と一致する場合のみ」といった条件を加えることで実現できます
        - 全チャンネル内で起動させたい場合は指定不要です
        - ここの設定は、[1-1 > Trigger](https://qiita.com/sophia38/items/63463eeb160ecf2dbc4c#1-new-reaction-added-in-slack) と一致するはずです
    - Trigger for Bot Messages? : Botによる投稿でもワークフローを起動させたい場合はYes
        - Yesにすると、例えばチャンネルに新しいメンバーが追加された場合のSlackbotの通知などもトリガーと認定してワークフローが起動します
- Test : テストを行うと、上の設定に関わらずそのワークスペース内の直近の投稿が検出されることがありますが、仕様なのでそのまま進んでOKです

#### 2-2. Only continue if…
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530171/f7e39bb5-701e-ed95-0d6f-3e6211b33cc1.png" width=70%>

- App : Filter by Zapier
- Filter : 特定の条件に一致する投稿のみでワークフローを起動させたい場合、その条件を指定
    - 例えば、1で設定したチャンネル内で「○○」を本文に含む投稿のみ起動させたい場合は「`1.Text` `(Text)Contains` `○○`」と設定
    - 1で設定したチャンネル内のすべての投稿で起動させたい場合は、このステップはまるごと不要です
- Continueを押すと、1でテストした投稿がFilterを通過するか否か判定してくれるので、想定通りの判定となっているか確認してください

#### 2-3. Delay For in Delay by Zapier
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530171/b7ed62bb-b5e3-6f96-35f2-15136761f6aa.png" width=70%>

- App : Delay by Zapier
- Event : Delay For
- Action
    - Time Delayed For (value) / (unit) : 投稿後にリアクションの有無を確認するまでの時間と単位を指定
        - 投稿の1時間後にリマインドしたい場合は「(value) `1`  / (unit) `hours`」と指定
- Test : テストすると、現在時刻から指定した経過時間後の時刻を返してくれます

#### 2-4. Lookup Spreadsheet Rows (output as Line Items) in Google Sheets
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530171/8bef3f63-d10e-7fb2-9e4c-6c1687fca705.png" width=70%>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530171/4d8f88ce-f757-082c-c995-f52b8ba0c1fe.png" width=70%>

- App : Google Sheets
- Event : Lookup Spreadsheet Rows (output as Line Items)
- Account : このスプレッドシートへの編集権限を持つアカウントであればOK
- Action
    - Drive ～ Worksheet : [1-2 > Action](https://qiita.com/sophia38/private/63463eeb160ecf2dbc4c#2-create-spreadsheet-row-in-google-sheets) と同様
    - Lookup Column : スプレッドシートのURL列を指定
    - Lookup Value : 1のMessage Permalink（Slackの投稿URL）を指定
    - Supporting Lookup Column / Value : 上記URLでの検索以外でサブの検索キーを設定したい場合はここで指定
    - Bottom-Up : スプレッドシートの上行から検索するのではなく、下行から検索したい場合はTrueで指定
    - Row Count : Lookup Valueに一致する行が複数ある場合に抽出する行数を指定
        - 今回は1投稿に1リアクションしかつかない運用を想定しており、何行でもOK
    - Should this step be considered a "success" when nothing is found? : Yes
        - Noにすると、一致するURLが見つからなかった場合ワークフローがここで終了する
        - 一致するURLが見つからなかった場合（＝投稿にリアクションが無い場合）にメッセージを送りたいので、Yesにしてワークフローが終了しないようにする
- Test : テストすると、1の投稿URLと一致するスプレッドシートの行を返してくれるので、想定通りの判定となっているか確認してください

#### 2-5. Only continue if…
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530171/ec6046b4-c432-a1bc-aa36-afa1adff0a63.png" width=70%>

- App : Filter by Zapier
- Filter : 「`4. Zap Search Was Found Status` `(Text) Does not exactly matches` `true`」と設定
    - 2-4で一致するURLが見つからなかった場合（＝検索結果がFalse）の場合のみワークフローを続けさせる判定文です
- Continueを押すと、4でテストした行がFilterを通過するか否か判定してくれるので、想定通りの判定となっているか確認してください

#### 2-6. Send Channel Message in Slack
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530171/70210e95-c8dd-4c9b-cc1f-c179640abf97.png" width=70%>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530171/2ffaa05e-a010-7a6c-13da-f30c1dc41540.png" width=70%>

- App : Slack
- Event : Send Channel Message
- Account : メッセージを送信したいチャンネルに入れる権限のアカウントであればOK
- Action
    - Channel : メッセージを送信したいチャンネルを指定
    - Message Text : 送信したいメッセージを指定
        - [このワークフローでできること](https://qiita.com/sophia38/private/63463eeb160ecf2dbc4c#%E3%81%93%E3%81%AE%E3%83%AF%E3%83%BC%E3%82%AF%E3%83%95%E3%83%AD%E3%83%BC%E3%81%A7%E3%81%A7%E3%81%8D%E3%82%8B%E3%81%93%E3%81%A8)　のスクショのような文章をここで指定する
        - メンションなどの表記方法については以下の記事が大変参考になります
            - **[Zapier から Slack にメッセージを投稿するときの設定まとめ](https://blog.pirox.dev/2020/04/27/071145)**
        - このメッセージ内に1のMessage Permalinkを挿入すると、リアクションすべき投稿へワンクリックで飛べて便利なのでおすすめです
    - Send as a bot? : Botからのメッセージに見せたければYes、Account で指定したユーザーからのメッセージに見せたければNoを選択
    - Bot Name / Bot Icon : Botからのメッセージに見せる場合、Botの名前 / アイコンを自由に設定可能
    
    ※Include a link to this Zap? ～ Broadcast To Channel? の設定はスクショ内容を推奨しますが、自由にカスタマイズいただいて問題ありません
    
- Test : テストすると設定どおりにメッセージが送信されるので、想定通りの判定となっているか確認してください

### 以上2つのワークフローをPublish → Onに設定すれば、完了です！

# おわりに

もともとはSlack上で依頼されるタスクの対応漏れを防ぎたいと考えて、このようなワークフローを開発してみました。

人間の注意力にはどうしても限界がある中で、このような自動リマインダーはとても心強い味方となってくれます。メンバーに負荷がかからない形で、業務の品質を上げることができました。

このワークフローは想定以上に汎用性が高く、既に社内でも様々な形に応用して活用されており、嬉しい限りです。

例えば同じ仕組みをアレンジして、リアクションではなくスレッドへのコメントが一定時間無い場合のリマインダー等も実現可能です。

ぜひ試してみてください！