Skip to content

Commit fa92c93

Browse files
committed
slack: add auth.test endpoint with atd adapter
1 parent c9fa0d4 commit fa92c93

File tree

5 files changed

+63
-0
lines changed

5 files changed

+63
-0
lines changed

lib/api.ml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,6 @@ module type Slack = sig
1616
val send_notification : ctx:Context.t -> msg:post_message_req -> (unit, string) Result.t Lwt.t
1717

1818
val send_chat_unfurl : ctx:Context.t -> chat_unfurl_req -> (unit, string) Result.t Lwt.t
19+
20+
val send_auth_test : ctx:Context.t -> unit -> auth_test_res slack_response Lwt.t
1921
end

lib/api_local.ml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ module Slack_base : Api.Slack = struct
2828
let send_notification ~ctx:_ ~msg:_ = Lwt.return @@ Error "undefined for local setup"
2929

3030
let send_chat_unfurl ~ctx:_ _ = Lwt.return @@ Error "undefined for local setup"
31+
32+
let send_auth_test ~ctx:_ () = Lwt.return @@ Error "undefined for local setup"
3133
end
3234

3335
module Slack : Api.Slack = struct

lib/api_remote.ml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,11 @@ end
6767
module Slack : Api.Slack = struct
6868
let log = Log.from "slack"
6969

70+
let slack_http_request ?headers ?body meth url read =
71+
match%lwt http_request ?headers ?body meth url with
72+
| Error e -> Lwt.return @@ Error (sprintf "error while querying %s: %s" url e)
73+
| Ok s -> Lwt.return @@ Slack_j.slack_response_of_string read s
74+
7075
let bearer_token_header access_token = sprintf "Authorization: Bearer %s" (Uri.pct_encode access_token)
7176

7277
(** `send_notification ctx msg` notifies `msg.channel` with the payload `msg`;
@@ -123,4 +128,17 @@ module Slack : Api.Slack = struct
123128
)
124129
| Error e -> Lwt.return @@ fmt_error "error while querying %s: %s\nfailed to unfurl Slack links" url e
125130
)
131+
132+
let send_auth_test ~(ctx : Context.t) () =
133+
log#info "retrieving bot information";
134+
let secrets = Context.get_secrets_exn ctx in
135+
match secrets.slack_access_token with
136+
| None -> Lwt.return @@ Error "failed to retrieve Slack access token"
137+
| Some access_token ->
138+
let url = "https://slack.com/api/auth.test" in
139+
let headers = [ bearer_token_header access_token ] in
140+
( match%lwt slack_http_request ~headers `GET url Slack_j.read_auth_test_res with
141+
| Ok res -> Lwt.return @@ Ok res
142+
| Error e -> Lwt.return @@ Error (sprintf "%s\nfailed to retrieve Slack auth info" e)
143+
)
126144
end

lib/atd_adapters.ml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,28 @@ module Branch_filters_adapter = List_or_default_field.Make (struct
4646

4747
let default_value = `List []
4848
end)
49+
50+
module Slack_response_adapter : Atdgen_runtime.Json_adapter.S = struct
51+
let normalize (x : Yojson.Safe.t) =
52+
match x with
53+
| `Assoc fields ->
54+
begin
55+
match List.assoc "ok" fields with
56+
| `Bool true -> `List [ `String "Ok"; x ]
57+
| `Bool false ->
58+
begin
59+
match List.assoc "error" fields with
60+
| `String msg -> `List [ `String "Error"; `String msg ]
61+
| _ -> x
62+
end
63+
| _ | (exception Not_found) -> x
64+
end
65+
| _ -> x
66+
67+
let restore (x : Yojson.Safe.t) =
68+
let mk_fields ok fields = ("ok", `Bool ok) :: List.filter (fun (k, _) -> k <> "ok") fields in
69+
match x with
70+
| `List [ `String "Ok"; `Assoc fields ] -> `Assoc (mk_fields true fields)
71+
| `List [ `String "Error"; `String msg ] -> `Assoc (mk_fields false [ "error", `String msg ])
72+
| _ -> x
73+
end

lib/slack.atd

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,3 +118,19 @@ type chat_unfurl_res = {
118118
ok: bool;
119119
?error: string option;
120120
}
121+
122+
type auth_test_res = {
123+
url: string;
124+
team: string;
125+
user: string;
126+
team_id: string;
127+
user_id: string;
128+
}
129+
130+
type ('ok, 'err) http_response <ocaml predef module="Base.Result" t="t"> = [
131+
| Ok of 'ok
132+
| Error of 'err
133+
] <ocaml repr="classic">
134+
135+
type 'ok slack_response = ('ok, string) http_response
136+
<json adapter.ocaml="Atd_adapters.Slack_response_adapter">

0 commit comments

Comments
 (0)