search
LoginSignup
0
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

Lisp Advent Calendar 2020 Day 3

posted at

CommonLispでIncoming Webhooksを使ってSlackへメッセージを投稿してみる

はじめに

今回は、Slackの Incoming Webhooks を使ったメッセージ送信をCommonLispでやってみようと思います
Incoming Webhooks は、他のアプリからSlackへメッセージを送信するための機能です
これを使うことで、外部からHTTPリクエストでメッセージをSlackへ送信できます

Incoming Webhooks の使い方の詳細は Sending messages using Incoming Webhooks を参照

Slack Appを作成する

まずは、Slack Appを作成する

Slack API のページを開き、Start Building ボタンをクリックしてアプリを作成する

App Name を入力(これは後からでも変更できる) し、 Development Slack Workspace でワークスペースを選択する

Add features and functionalityIncoming Webhooks を選択

Incoming Webhooks の設定ページに飛んだらトグルボタンを On にして有効化する

Add New Webhook to Workspace をクリックし、遷移したページの検索ボックスから投稿先のチャンネルを選択し、 許可する ボタンをクリックする

ここまできてようやく curl でSlackにメッセージを送信できるようになる

Incoming Webhooks の設定ページの下の方に Webhook URLs for Your Workspace という項目があるので、そこに記されたサンプル (Sample curl request to post to a channel) を試してみる

$ curl -X POST \
-H 'Content-type: application/json' \
--data '{"text":"Hello, World!"}' \
https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX

実際に送信された様子

curl でメッセージを簡単に送信できた

CommonLispで送信してみる

curl でできたので、CommonLispでも同じことができるはず

まずは、HTTPクライアントとして dexador を使用するのでロードしておく

(ql:quickload :dexador)

ベースURLは curl でやったときに使ったものをそのまま使用

(defparameter *base-url*
  "https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX")

POSTするデータはJSON形式で投稿する必要があるが、Lispプログラム中にJSON書くのはダルい(ダブルクォーテーションをエスケープして {\"text\" : \"Hello, world!\"} のように書く必要がある)ので、連想リストで作成してその後JSON形式に変換する
そのため、 jonathan をロードしておく

(ql:quickload :jonathan)

以下のように連想リストをJSON形式に変換

(defparameter *message*
  (jojo:to-json '(("text" . "Hello, Lisp")) :from :alist))

準備が整ったので、Slackへ送信する

(dex:post *base-url* :content *message*)

実際に送信された様子

CommonLispでもメッセージ送れた!

メッセージに装飾をつけて送ってみる

送信するメッセージを以下のように定義する

(defparameter *message2*
  (jojo:to-json
   '(("text" . "Danny Torrence left a 1 star review for your property.")
     ("blocks"
      (("type" . "section")
       ("text" . (("type" . "mrkdwn")
                  ("text" . "Danny Torrence left the following review for your property:"))))
      (("type" . "section")
       ("block_id" . "section567")
       ("text" . (("type" . "mrkdwn")
                  ("text" . "<https://example.com|Overlook Hotel>
:star:
Doors had too many axe holes, guest in room 237 was far too rowdy, whole place felt stuck in the 1920s.")))
       ("accessory" . (("type" . "image")
                       ("image_url" . "https://is5-ssl.mzstatic.com/image/thumb/Purple3/v4/d3/72/5c/d3725c8f-c642-5d69-1904-aa36e4297885/source/256x256bb.jpg")
                       ("alt_text" . "Haunted hotel image"))))
      (("type" . "section")
       ("block_id" . "section789")
       ("fields"
        (("type" . "mrkdwn")
         ("text" . "*Average Rating*
1.0"))))))
   :from :alist))

Slackへ送信する

(dex:post *base-url* :content *message2*)

実際に送信された様子

結構複雑なこともできるみたい
面白い

さいごに

これでCommonLispで作ったアプリケーションからSlackへメッセージを送ることができるようになりました
アプリケーションからの通知やログをSlackへ送信して表示するなど、様々なことに応用できそうです

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
0
Help us understand the problem. What are the problem?