【webhook】Slackの高度なワークフローが便利なことに気づいた


Slackワークフローの「高度な設定」として、webhookがあります。
![コメント.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666457/10c9bc56-b9b8-a308-af2d-283b97f9d7d3.png)


ワークフロー自体はけっこう組織内でもみんな気軽に使ってたのですが、
webhookのボタンは押したことがありませんでした。ワークフロー登場時には記事もなかった気がするし。

https://qiita.com/yuji_saito/items/5dc2b079d4e43bd381d8

ですが、↑こちらの記事を拝見して、「エッ、もしかしてすごい便利…！？」と思ったので、使ってみることにしました。

# 実際に使ってみた
今回は、自組織で使っているClickUpというタスク管理ツールでタスクを作成すると、Slackに通知がされるという仕組みを構築します。
ClickUpのAutomationという機能と、Slackワークフローを組み合わせて作ります。

ClickUpには元々SlackIntegrationがあるのですが、ClickUpのチームとSlackワークスペースが1:1の関係でしか設定ができない欠点があり、
Slackワークスペースを複数持って運用している自組織では、やりたいことがやり切れていない状態だったのです。

## Slackワークフローを準備する

公式ドキュメントはこちら↓

https://slack.com/intl/ja-jp/help/articles/360041352714-Webhook-%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%9F%E9%AB%98%E5%BA%A6%E3%81%AA%E3%83%AF%E3%83%BC%E3%82%AF%E3%83%95%E3%83%AD%E3%83%BC%E3%82%92%E4%BD%9C%E6%88%90%E3%81%99%E3%82%8B

文字列で入力されてきたメールアドレスをSlackユーザーのメールアドレスと照合してくれるの助かります。
数年前、スプレッドシート上で照合させて…とかいう泥臭いGASを組んだこともある身としては、涙が出そうです…！:sob:笑

冒頭で紹介した記事や、公式ドキュメントを見れば簡単に設定できるのでやり方は省略。

## ClickUpのAutomationを準備する

公式ドキュメントはこちら↓

https://docs.clickup.com/en/articles/3904933-automation-actions

ClickUpにはAutomationという、GUIでZapierのようなことができる機能があります。
これも便利だと思うのですが、特定条件のタスクが作られたら特定の誰かをアサインする、ぐらいにしか使ったことがありませんでした。
でもよく見たら公式ドキュメントにwebhookがCallできるよって書いてあった。これ使える！

![コメント.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666457/c021d35a-8b4a-c321-66b7-af7014994ff0.png)

あんまり詳しく公式ドキュメントに書いてなくて、フィールドが選べるけどこれはどう使うのかな？って思ったのですが、
（たぶんクエリパラメータとして使えるとかなのかな…）
右側のCallWebhookの下のURLの欄にwebhookURLを入れるだけで
持っているデータを全て送ってくれるようなので、あまり深く考えずそのまま使うことにします。

ClickUp側の設定次第で、タスクの作成以外にも、タスク期日が来たら、とか、タスクのステータスを変えたら、とか、
柔軟に対応できるので、今回作ったもので色々応用ができそう！

## 実際に走らせてみると…あれ？
あれ？走らないな？となってから、公式ドキュメントを再度読んで気づいたのですが、
Slackワークフローのwebhookは、**ネストしているjsonには現時点では対応していません。**
（ClickUpのAutomationで吐き出されるjsonはバリバリネストしまくっている…）

しかしここで諦めるのは悔しいので、jsonをフラット化する処理を間に挟んであげることにします。

## Lambda+API Gatewayを準備する

### Lambdaを書く
flatten_jsonライブラリを使えばラクラクでした！

外部ライブラリはLayerで導入しました。
requestsはこちらのリポジトリを利用させてもらいました。ARNs入れるだけで導入できて最高
（今回は使わなかったけど、よく使うPandasもなぜかAWS公式Layerからは仲間はずれされてるので、このリポジトリにはまたお世話になりそうです）

https://github.com/keithrozario/Klayers

```python
import requests
import json
from flatten_json import flatten

def lambda_handler(event, context):
 flatjson = flatten(event['body'])

 url = "<slackワークフローのwebhookURL>"
 headers = {'content-type': 'application/json'}
 
 requests.post(url, data=json.dumps(flatjson), headers=headers)
 print(flatjson)
 return flatjson
```

### API Gatewayを準備する
POSTメソッドを作ります。

1. 統合リクエストでLambda関数を選び、先ほど作ったLambda関数を選びます。
1. マッピングテンプレートで「Content-type:application/json」を指定して、以下を設定しておきます。

```js
{
  "body" : $input.json('$')
}
```


公式ドキュメントに記載されているサンプルjsonでテストしてみると…

```json:リクエスト
{ 
 body: { 
 date: "2020-04-28T17:12:12.408Z",
 id: "61826c6c-f5db-4cb8-8227-5ad1a3165883",
 payload: {
  archived: false,
  assignees: [],
  checklists: [],
  creator: {
   id: 123456,
   username: "Josh",
   color: "#08c7e0",
   email: "user@clickup.com",
   profilePicture: "https://website.com/Pictures/123456_HHK.jpg"
   },
  custom_fields: [],
  date_closed: null,
  date_created: "1588051179885",
  date_updated: "1588093930834",
  dependencies: [], 
  description: null, 
  due_date: null, 
  folder: {
   id: "55200004",
   name: "Automations",
   hidden: false,
   access: true 
   },
  id: "p1u1x0",
  linked_tasks: [],
  list: {
   id: "12345678",
   name: "Automation Webhooks",
   access: true 
   }, 
  name: "Webhooks!", 
  orderindex: "-0.0234354635389856960000000000000000", 
  parent: null, 
  priority: null, 
  project: {
   id: "12345678",
   name: "Test",
   hidden: false,
   access: true
   },
  space: {
   id: "12345678"
   }, 
  start_date: null,
  status: {
   status: "active",
   color: "#000000",
   orderindex: 1,
   type: "custom"
   }, 
  tags: [], 
  team_id: "123456", 
  text_content: null,
  time_estimate: null, 
  url: "https://app.clickup.com/t/p1u1x0", 
  watchers: [] 
   }, 
 trigger_id: "61826c6c-f5db-4cb8-8227-5ad1a3165883" 
 } 
}
```
```json:レスポンス
{
"date": "2020-04-28T17:12:12.408Z",
"id": "61826c6c-f5db-4cb8-8227-5ad1a3165883",
"payload_archived": false,
"payload_assignees":[],
"payload_checklists":[],
"payload_creator_id": 123456,
"payload_creator_username": "Josh",
"payload_creator_color": "#08c7e0",
"payload_creator_email": "user@clickup.com",
"payload_creator_profilePicture": "https://website.com/Pictures/123456_HHK.jpg",
"payload_custom_fields":[],
"payload_date_closed": null,
"payload_date_created": "1588051179885",
"payload_date_updated": "1588093930834",
"payload_dependencies":[],
"payload_description": null,
"payload_due_date": null,
"payload_folder_id": "55200004",
"payload_folder_name": "Automations",
"payload_folder_hidden": false,
"payload_folder_access": true,
"payload_id": "p1u1x0",
"payload_linked_tasks":[],
"payload_list_id": "12345678",
"payload_list_name": "Automation Webhooks",
"payload_list_access": true,
"payload_name": "Webhooks!",
"payload_orderindex": "-0.0234354635389856960000000000000000",
"payload_parent": null,
"payload_priority": null,
"payload_project_id": "12345678",
"payload_project_name": "Test",
"payload_project_hidden": false,
"payload_project_access": true,
"payload_space_id": "12345678",
"payload_start_date": null,
"payload_status_status": "active",
"payload_status_color": "#000000",
"payload_status_orderindex": 1,
"payload_status_type": "custom",
"payload_tags":[],
"payload_team_id": "123456",
"payload_text_content": null,
"payload_time_estimate": null,
"payload_url": "https://app.clickup.com/t/p1u1x0",
"payload_watchers":[],
"trigger_id": "61826c6c-f5db-4cb8-8227-5ad1a3165883"
}
```
こんなかんじにフラット化されました！やった～！

## 再度走らせてみる

- slackワークフローで指定しているkey名をフラット化されたjsonに合わせて変更
- ClickUpAutomationでCallするURLをAPIGatewayで生成したものに変更

したうえで、ClickUpでタスクを作成！ 
無事にslackワークフローで受け止めてもらえ、Slackでメッセージ通知がされました！
ちゃんとメンションもされてます:smile:
![form.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666457/ad9603cb-36dc-c3df-f638-fe626c6be1cc.png)


# やってみた感想
今回の例では、完全ノーコードとはいきませんでしたが、
**インプット・アウトプット共に、カスタマイズがしやすい構造になった** のが本当に良かったなと思います。

今回作ったもの全てをLambdaとかGASでやっちゃうこともできるとは思いますが、カスタマイズ・メンテナンスのたびにコードをいじるのは手間です。
ClickUpのAutomationも、SlackのワークフローもGUIの直感的操作で設定変更ができるので、エンジニア以外にも気軽に使ってもらいやすい！ :raised_hands:

SlackワークフローのWebhookトリガー、入力されてくるjsonが元々フラットなものであれば、lambdaを噛ませる必要もないので、
ノーコードで各種ツールからとSlackを連携できるステキな機能だなと思いました。
公式ドキュメントの書きっぷりから見て、今後ネストjsonも対応してくれそうな予感もするし。

今後、自動化の選択肢に積極的に入れていきたいと思います！ :muscle: