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