Skip to content

Commit d187bb9

Browse files
koonwenKoonwen Lee
andauthored
support upload snippets + refactor (#14)
* remove unused + update file param name * upload_file: support snippets * upload_file: alpha equivalent renaming * fix upload snippet and test --------- Co-authored-by: Koonwen Lee <koonwen.lee@ahrefs.com>
1 parent 73432ce commit d187bb9

6 files changed

Lines changed: 48 additions & 52 deletions

File tree

examples/examples.ml

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,14 @@ let text =
3737
let doc = "text to send" in
3838
Arg.(value & opt string "" & info [ "t"; "text" ] ~docv:"TEXT" ~doc)
3939

40+
let content =
41+
let doc = "content/snippet to send" in
42+
Arg.(value & opt (some string) None & info [ "ct"; "content" ] ~docv:"CONTENT" ~doc)
43+
44+
let filename =
45+
let doc = "filename identifier" in
46+
Arg.(required & opt (some string) None & info [ "f"; "filename" ] ~docv:"FILENAME" ~doc)
47+
4048
let update =
4149
let doc = "text to update first message" in
4250
Arg.(value & opt string "" & info [ "u"; "update" ] ~docv:"UPDATE" ~doc)
@@ -75,9 +83,9 @@ let send =
7583
Cmd.v info term
7684

7785
let send_file =
78-
let doc = "upload a file using Slack APIs example" in
86+
let doc = "upload a file or snippet using Slack APIs example" in
7987
let info = Cmd.info "send_file" ~doc in
80-
let term = Term.(const Sender.send_file $ channels_opt $ text) in
88+
let term = Term.(const Sender.send_file $ content $ channels_opt $ filename) in
8189
Cmd.v info term
8290

8391
let send_update =

examples/sender.ml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,11 @@ let send icon_url icon_emoji username channel text =
3232
in
3333
Lwt_main.run run
3434

35-
let send_file channels content =
35+
let send_file content channels filename =
3636
let run =
3737
let ctx = Common_example.get_ctx_example in
38-
let file = Slack_j.make_files_upload_req ?channels ~content () in
39-
match%lwt Api_remote.upload_file ~ctx ~file with
38+
let req = Slack_j.make_files_upload_req ?channels ?content ~filename () in
39+
match%lwt Api_remote.upload_file ~ctx ~req with
4040
| Ok res ->
4141
printf "file uploaded: %s" res.file.id;
4242
( match res.file.permalink with

lib/api.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ module type S = sig
88
val send_message : ctx:Context.t -> msg:post_message_req -> post_message_res slack_response Lwt.t
99
val send_message_webhook : ctx:Context.t -> url:string -> msg:post_message_req -> unit slack_response Lwt.t
1010
val update_message : ctx:Context.t -> msg:update_message_req -> update_message_res slack_response Lwt.t
11-
val upload_file : ctx:Context.t -> file:files_upload_req -> files_upload_res slack_response Lwt.t
11+
val upload_file : ctx:Context.t -> req:files_upload_req -> files_upload_res slack_response Lwt.t
1212
val get_permalink : ctx:Context.t -> req:get_permalink_req -> get_permalink_res slack_response Lwt.t
1313

1414
(* conversations *)

lib/api_local.ml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,9 @@ let update_message ~ctx:_ ~msg =
5959
printf "%s\n" json;
6060
Lwt.return_ok { default_update_message_res with channel = msg.channel }
6161

62-
let upload_file ~ctx:_ ~file =
63-
let json = file |> Slack_j.string_of_files_upload_req |> Yojson.Basic.from_string |> Yojson.Basic.pretty_to_string in
64-
match file.channels with
62+
let upload_file ~ctx:_ ~req =
63+
let json = req |> Slack_j.string_of_files_upload_req |> Yojson.Basic.from_string |> Yojson.Basic.pretty_to_string in
64+
match req.channels with
6565
| Some channels ->
6666
printf "will update #%s\n" channels;
6767
printf "%s\n" json;

lib/api_remote.ml

Lines changed: 29 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -78,20 +78,6 @@ let update_message ~(ctx : Context.t) ~(msg : Slack_t.update_message_req) =
7878
~name:(sprintf "chat.update (%s,%s)" msg.ts msg.channel)
7979
~ctx ~body `POST "chat.update" Slack_j.read_update_message_res
8080

81-
let www_form_of_files_upload_req (file : Slack_t.files_upload_req) =
82-
let fields =
83-
[
84-
string_field_val file.channels "channels";
85-
string_field_val file.content "content";
86-
string_field_val file.filename "filename";
87-
string_field_val file.filetype "filetype";
88-
string_field_val file.initial_comment "initial_comment";
89-
string_field_val file.thread_ts "thread_ts";
90-
string_field_val file.title "title";
91-
]
92-
in
93-
list_filter_opt fields
94-
9581
let get_permalink ~(ctx : Context.t) ~(req : Slack_t.get_permalink_req) =
9682
log#info "getting permalink for channel %s, message_ts %s" req.channel req.message_ts;
9783
let args = Web.make_url_args [ "channel", req.channel; "message_ts", req.message_ts ] in
@@ -100,26 +86,22 @@ let get_permalink ~(ctx : Context.t) ~(req : Slack_t.get_permalink_req) =
10086
~name:(sprintf "chat.getPermalink (%s, %s)" req.channel req.message_ts)
10187
~ctx `GET api_path Slack_j.read_get_permalink_res
10288

103-
let www_form_of_get_upload_url_ext (req : Slack_t.get_upload_url_ext_req) =
104-
let fields =
89+
let get_upload_url_external ~(ctx : Context.t) ~(req : Slack_t.get_upload_url_ext_req) =
90+
log#info "getting upload url for %s" req.filename;
91+
let args =
10592
[
10693
Some ("filename", req.filename);
10794
Some ("length", Int.to_string req.length);
10895
string_field_val req.alt_txt "alt_txt";
10996
string_field_val req.snippet_type "snippet_type";
11097
]
98+
|> list_filter_opt
11199
in
112-
list_filter_opt fields
113-
114-
let get_upload_url_external ~(ctx : Context.t) ~(req : Slack_t.get_upload_url_ext_req) =
115-
log#info "getting upload url for %s" req.filename;
116-
let args = www_form_of_get_upload_url_ext req in
117-
let data = Web.make_url_args args in
118-
let body = `Raw ("application/x-www-form-urlencoded", data) in
119-
log#info "data to upload req: %s" data;
100+
let args = Web.make_url_args args in
101+
let api_path = sprintf "files.getUploadURLExternal?%s" args in
120102
request_token_auth ~ctx
121103
~name:(sprintf "files.getUploadURLExternal (%s)" req.filename)
122-
~body `POST "files.getUploadURLExternal" Slack_j.read_get_upload_url_ext_res
104+
`POST api_path Slack_j.read_get_upload_url_ext_res
123105

124106
let complete_upload_external ~(ctx : Context.t) ~(req : Slack_t.complete_upload_ext_req) =
125107
log#info "completing upload url for %s" @@ Slack_j.string_of_files_v2 req.files;
@@ -130,27 +112,33 @@ let complete_upload_external ~(ctx : Context.t) ~(req : Slack_t.complete_upload_
130112
~name:(sprintf "files.completeUploadExternal (%s)" @@ Slack_j.string_of_files_v2 req.files)
131113
~body `POST "files.completeUploadExternal" Slack_j.read_complete_upload_ext_res
132114

133-
(** [upload_file ctx file] upload [file] to channels noted in [file.channels]
134-
with content [file.content]; Not supporting file upload through form using
135-
`file` currently
136-
uses web API with access token *)
137-
let upload_file ~(ctx : Context.t) ~(file : Slack_t.files_upload_req) =
138-
match file.filename, file.content with
139-
| None, _ | _, None -> Exn.fail "need to supply both filename and content"
140-
| Some filename, Some content ->
141-
let length = String.length content in
142-
let req = Slack_j.make_get_upload_url_ext_req ~filename ~length () in
143-
( match%lwt get_upload_url_external ~ctx ~req with
115+
(** [upload_file ctx file] upload [file] to channels noted in
116+
[file.channels] with content [file.content]; Not supporting file
117+
upload through form using `file` currently uses web API with
118+
access token. Snippet can also be sent instead by filling the
119+
content value *)
120+
let upload_file ~(ctx : Context.t) ~(req : Slack_t.files_upload_req) =
121+
match req.filename with
122+
| None -> Exn.fail "need to supply filename"
123+
| Some filename ->
124+
let contents, length =
125+
match req.content with
126+
| Some v -> v, String.length v
127+
| None ->
128+
let raw_file_contents = In_channel.with_open_bin filename (fun ic -> input_all ic) in
129+
raw_file_contents, String.length raw_file_contents
130+
in
131+
let req' = Slack_j.make_get_upload_url_ext_req ~filename ~length () in
132+
( match%lwt get_upload_url_external ~ctx ~req:req' with
144133
| Error e -> Lwt.return_error e
145134
| Ok { upload_url; file_id; _ } ->
146-
let raw_file_contents = In_channel.with_open_bin filename (fun ic -> input_all ic) in
147-
let body = `Raw ("", raw_file_contents) in
135+
let body = `Raw ("text/plain", contents) in
148136
( match%lwt http_request ~ua:ctx.ua ~body `POST upload_url with
149137
| Error e -> slack_lib_fail "upload file failed with: %s" e
150138
| Ok _ ->
151-
let files : Slack_t.files_v2 = [ { id = file_id; title = file.title } ] in
152-
let req = Slack_j.make_complete_upload_ext_req ~files ?channels:file.channels ?thread_ts:file.thread_ts () in
153-
( match%lwt complete_upload_external ~ctx ~req with
139+
let files : Slack_t.files_v2 = [ { id = file_id; title = req.title } ] in
140+
let req' = Slack_j.make_complete_upload_ext_req ~files ?channels:req.channels ?thread_ts:req.thread_ts () in
141+
( match%lwt complete_upload_external ~ctx ~req:req' with
154142
| Error e -> Lwt.return_error e
155143
| Ok { files; _ } ->
156144
let f =

lib_test/test.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,8 @@ let file_list =
138138
let process_upload_file (channels, content) =
139139
Printf.printf "upload_file_to--------channels: %s--------\n" channels;
140140
let ctx = Context.empty_ctx () in
141-
let file : Slack_t.files_upload_req = Slack_j.make_files_upload_req ~channels ~content () in
142-
match%lwt Api.upload_file ~ctx ~file with
141+
let req : Slack_t.files_upload_req = Slack_j.make_files_upload_req ~channels ~content () in
142+
match%lwt Api.upload_file ~ctx ~req with
143143
| Ok res ->
144144
let json = res |> Slack_j.string_of_files_upload_res |> Yojson.Basic.from_string |> Yojson.Basic.pretty_to_string in
145145
print_endline json;

0 commit comments

Comments
 (0)