|
50 | 50 | module Slack : Api.Slack = struct
|
51 | 51 | let log = Log.from "slack"
|
52 | 52 |
|
53 |
| - let send_notification ~(ctx : Context.t) ~msg = |
| 53 | + let bearer_token_header access_token = sprintf "Authorization: Bearer %s" access_token |
| 54 | + |
| 55 | + (** `send_notification ctx msg` notifies `msg.channel` with the payload `msg`; |
| 56 | + uses web API with access token if available, or with webhook otherwise *) |
| 57 | + let send_notification ~(ctx : Context.t) ~(msg : Slack_t.post_message_req) = |
| 58 | + let build_error e = fmt_error "%s\nfailed to send Slack notification" e in |
| 59 | + let build_query_error url e = build_error @@ sprintf "error while querying %s: %s" url e in |
54 | 60 | let secrets = Context.get_secrets_exn ctx in
|
55 |
| - match secrets.slack_access_token with |
56 |
| - | None -> Lwt.return @@ fmt_error "failed to retrieve Slack access token" |
57 |
| - | Some access_token -> |
58 |
| - let url = "https://slack.com/api/chat.postMessage" in |
| 61 | + let headers, url, webhook_mode = |
| 62 | + match secrets.slack_access_token with |
| 63 | + | Some access_token -> [ bearer_token_header access_token ], Some "https://slack.com/api/chat.postMessage", false |
| 64 | + | None -> [], Context.hook_of_channel ctx msg.channel, true |
| 65 | + in |
| 66 | + match url with |
| 67 | + | None -> Lwt.return @@ build_error @@ sprintf "no token or webhook configured to notify channel %s" msg.channel |
| 68 | + | Some url -> |
59 | 69 | let data = Slack_j.string_of_post_message_req msg in
|
60 |
| - let headers = [ sprintf "Authorization: Bearer %s" access_token ] in |
61 | 70 | let body = `Raw ("application/json", data) in
|
62 | 71 | log#info "sending to %s : %s" msg.channel data;
|
63 | 72 | ( match%lwt http_request ~body ~headers `POST url with
|
| 73 | + (* error detection in response: slack uses status codes for webhooks versus a 200 code w/ `error` field for web api *) |
64 | 74 | | Ok s ->
|
65 |
| - let res = Slack_j.post_message_res_of_string s in |
66 |
| - if res.ok then Lwt.return @@ Ok () |
| 75 | + if webhook_mode then Lwt.return @@ Ok () |
67 | 76 | else (
|
68 |
| - let msg = Option.value ~default:"an unknown error occurred" res.error in |
69 |
| - Lwt.return @@ fmt_error "%s\nfailed to send Slack notification" msg |
| 77 | + let res = Slack_j.post_message_res_of_string s in |
| 78 | + if res.ok then Lwt.return @@ Ok () |
| 79 | + else Lwt.return @@ build_query_error url (Option.value ~default:"an unknown error occurred" res.error) |
70 | 80 | )
|
71 |
| - | Error e -> Lwt.return @@ fmt_error "error while querying %s: %s\nfailed to send Slack notification" url e |
| 81 | + | Error e -> Lwt.return @@ build_query_error url e |
72 | 82 | )
|
73 | 83 | end
|
0 commit comments