Slackワークフローの「高度な設定」として、webhookがあります。
ワークフロー自体はけっこう組織内でもみんな気軽に使ってたのですが、
webhookのボタンは押したことがありませんでした。ワークフロー登場時には記事もなかった気がするし。
ですが、↑こちらの記事を拝見して、「エッ、もしかしてすごい便利…!?」と思ったので、使ってみることにしました。
実際に使ってみた
今回は、自組織で使っているClickUpというタスク管理ツールでタスクを作成すると、Slackに通知がされるという仕組みを構築します。
ClickUpのAutomationという機能と、Slackワークフローを組み合わせて作ります。
ClickUpには元々SlackIntegrationがあるのですが、ClickUpのチームとSlackワークスペースが1:1の関係でしか設定ができない欠点があり、
Slackワークスペースを複数持って運用している自組織では、やりたいことがやり切れていない状態だったのです。
Slackワークフローを準備する
公式ドキュメントはこちら↓
文字列で入力されてきたメールアドレスをSlackユーザーのメールアドレスと照合してくれるの助かります。
数年前、スプレッドシート上で照合させて…とかいう泥臭いGASを組んだこともある身としては、涙が出そうです…!笑
冒頭で紹介した記事や、公式ドキュメントを見れば簡単に設定できるのでやり方は省略。
ClickUpのAutomationを準備する
公式ドキュメントはこちら↓
ClickUpにはAutomationという、GUIでZapierのようなことができる機能があります。
これも便利だと思うのですが、特定条件のタスクが作られたら特定の誰かをアサインする、ぐらいにしか使ったことがありませんでした。
でもよく見たら公式ドキュメントにwebhookがCallできるよって書いてあった。これ使える!
あんまり詳しく公式ドキュメントに書いてなくて、フィールドが選べるけどこれはどう使うのかな?って思ったのですが、
(たぶんクエリパラメータとして使えるとかなのかな…)
右側のCallWebhookの下のURLの欄にwebhookURLを入れるだけで
持っているデータを全て送ってくれるようなので、あまり深く考えずそのまま使うことにします。
ClickUp側の設定次第で、タスクの作成以外にも、タスク期日が来たら、とか、タスクのステータスを変えたら、とか、
柔軟に対応できるので、今回作ったもので色々応用ができそう!
実際に走らせてみると…あれ?
あれ?走らないな?となってから、公式ドキュメントを再度読んで気づいたのですが、
Slackワークフローのwebhookは、ネストしているjsonには現時点では対応していません。
(ClickUpのAutomationで吐き出されるjsonはバリバリネストしまくっている…)
しかしここで諦めるのは悔しいので、jsonをフラット化する処理を間に挟んであげることにします。
Lambda+API Gatewayを準備する
Lambdaを書く
flatten_jsonライブラリを使えばラクラクでした!
外部ライブラリはLayerで導入しました。
requestsはこちらのリポジトリを利用させてもらいました。ARNs入れるだけで導入できて最高
(今回は使わなかったけど、よく使うPandasもなぜかAWS公式Layerからは仲間はずれされてるので、このリポジトリにはまたお世話になりそうです)
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メソッドを作ります。
- 統合リクエストでLambda関数を選び、先ほど作ったLambda関数を選びます。
- マッピングテンプレートで「Content-type:application/json」を指定して、以下を設定しておきます。
{
"body" : $input.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"
}
}
{
"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でメッセージ通知がされました!
ちゃんとメンションもされてます
やってみた感想
今回の例では、完全ノーコードとはいきませんでしたが、
インプット・アウトプット共に、カスタマイズがしやすい構造になった のが本当に良かったなと思います。
今回作ったもの全てをLambdaとかGASでやっちゃうこともできるとは思いますが、カスタマイズ・メンテナンスのたびにコードをいじるのは手間です。
ClickUpのAutomationも、SlackのワークフローもGUIの直感的操作で設定変更ができるので、エンジニア以外にも気軽に使ってもらいやすい!
SlackワークフローのWebhookトリガー、入力されてくるjsonが元々フラットなものであれば、lambdaを噛ませる必要もないので、
ノーコードで各種ツールからとSlackを連携できるステキな機能だなと思いました。
公式ドキュメントの書きっぷりから見て、今後ネストjsonも対応してくれそうな予感もするし。
今後、自動化の選択肢に積極的に入れていきたいと思います!