Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions examples/examples.ml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,14 @@ let text =
let doc = "text to send" in
Arg.(value & opt string "" & info [ "t"; "text" ] ~docv:"TEXT" ~doc)

let content =
let doc = "content/snippet to send" in
Arg.(value & opt (some string) None & info [ "ct"; "content" ] ~docv:"CONTENT" ~doc)

let filename =
let doc = "filename identifier" in
Arg.(required & opt (some string) None & info [ "f"; "filename" ] ~docv:"FILENAME" ~doc)

let update =
let doc = "text to update first message" in
Arg.(value & opt string "" & info [ "u"; "update" ] ~docv:"UPDATE" ~doc)
Expand Down Expand Up @@ -75,9 +83,9 @@ let send =
Cmd.v info term

let send_file =
let doc = "upload a file using Slack APIs example" in
let doc = "upload a file or snippet using Slack APIs example" in
let info = Cmd.info "send_file" ~doc in
let term = Term.(const Sender.send_file $ channels_opt $ text) in
let term = Term.(const Sender.send_file $ content $ channels_opt $ filename) in
Cmd.v info term

let send_update =
Expand Down
6 changes: 3 additions & 3 deletions examples/sender.ml
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ let send icon_url icon_emoji username channel text =
in
Lwt_main.run run

let send_file channels content =
let send_file content channels filename =
let run =
let ctx = Common_example.get_ctx_example in
let file = Slack_j.make_files_upload_req ?channels ~content () in
match%lwt Api_remote.upload_file ~ctx ~file with
let req = Slack_j.make_files_upload_req ?channels ?content ~filename () in
match%lwt Api_remote.upload_file ~ctx ~req with
| Ok res ->
printf "file uploaded: %s" res.file.id;
( match res.file.permalink with
Expand Down
2 changes: 1 addition & 1 deletion lib/api.ml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ module type S = sig
val send_message : ctx:Context.t -> msg:post_message_req -> post_message_res slack_response Lwt.t
val send_message_webhook : ctx:Context.t -> url:string -> msg:post_message_req -> unit slack_response Lwt.t
val update_message : ctx:Context.t -> msg:update_message_req -> update_message_res slack_response Lwt.t
val upload_file : ctx:Context.t -> file:files_upload_req -> files_upload_res slack_response Lwt.t
val upload_file : ctx:Context.t -> req:files_upload_req -> files_upload_res slack_response Lwt.t
val get_permalink : ctx:Context.t -> req:get_permalink_req -> get_permalink_res slack_response Lwt.t

(* conversations *)
Expand Down
6 changes: 3 additions & 3 deletions lib/api_local.ml
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,9 @@ let update_message ~ctx:_ ~msg =
printf "%s\n" json;
Lwt.return_ok { default_update_message_res with channel = msg.channel }

let upload_file ~ctx:_ ~file =
let json = file |> Slack_j.string_of_files_upload_req |> Yojson.Basic.from_string |> Yojson.Basic.pretty_to_string in
match file.channels with
let upload_file ~ctx:_ ~req =
let json = req |> Slack_j.string_of_files_upload_req |> Yojson.Basic.from_string |> Yojson.Basic.pretty_to_string in
match req.channels with
| Some channels ->
printf "will update #%s\n" channels;
printf "%s\n" json;
Expand Down
70 changes: 29 additions & 41 deletions lib/api_remote.ml
Original file line number Diff line number Diff line change
Expand Up @@ -78,20 +78,6 @@ let update_message ~(ctx : Context.t) ~(msg : Slack_t.update_message_req) =
~name:(sprintf "chat.update (%s,%s)" msg.ts msg.channel)
~ctx ~body `POST "chat.update" Slack_j.read_update_message_res

let www_form_of_files_upload_req (file : Slack_t.files_upload_req) =
let fields =
[
string_field_val file.channels "channels";
string_field_val file.content "content";
string_field_val file.filename "filename";
string_field_val file.filetype "filetype";
string_field_val file.initial_comment "initial_comment";
string_field_val file.thread_ts "thread_ts";
string_field_val file.title "title";
]
in
list_filter_opt fields

let get_permalink ~(ctx : Context.t) ~(req : Slack_t.get_permalink_req) =
log#info "getting permalink for channel %s, message_ts %s" req.channel req.message_ts;
let args = Web.make_url_args [ "channel", req.channel; "message_ts", req.message_ts ] in
Expand All @@ -100,26 +86,22 @@ let get_permalink ~(ctx : Context.t) ~(req : Slack_t.get_permalink_req) =
~name:(sprintf "chat.getPermalink (%s, %s)" req.channel req.message_ts)
~ctx `GET api_path Slack_j.read_get_permalink_res

let www_form_of_get_upload_url_ext (req : Slack_t.get_upload_url_ext_req) =
let fields =
let get_upload_url_external ~(ctx : Context.t) ~(req : Slack_t.get_upload_url_ext_req) =
log#info "getting upload url for %s" req.filename;
let args =
[
Some ("filename", req.filename);
Some ("length", Int.to_string req.length);
string_field_val req.alt_txt "alt_txt";
string_field_val req.snippet_type "snippet_type";
]
|> list_filter_opt
in
list_filter_opt fields

let get_upload_url_external ~(ctx : Context.t) ~(req : Slack_t.get_upload_url_ext_req) =
log#info "getting upload url for %s" req.filename;
let args = www_form_of_get_upload_url_ext req in
let data = Web.make_url_args args in
let body = `Raw ("application/x-www-form-urlencoded", data) in
log#info "data to upload req: %s" data;
let args = Web.make_url_args args in
let api_path = sprintf "files.getUploadURLExternal?%s" args in
request_token_auth ~ctx
~name:(sprintf "files.getUploadURLExternal (%s)" req.filename)
~body `POST "files.getUploadURLExternal" Slack_j.read_get_upload_url_ext_res
`POST api_path Slack_j.read_get_upload_url_ext_res

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

(** [upload_file ctx file] upload [file] to channels noted in [file.channels]
with content [file.content]; Not supporting file upload through form using
`file` currently
uses web API with access token *)
let upload_file ~(ctx : Context.t) ~(file : Slack_t.files_upload_req) =
match file.filename, file.content with
| None, _ | _, None -> Exn.fail "need to supply both filename and content"
| Some filename, Some content ->
let length = String.length content in
let req = Slack_j.make_get_upload_url_ext_req ~filename ~length () in
( match%lwt get_upload_url_external ~ctx ~req with
(** [upload_file ctx file] upload [file] to channels noted in
[file.channels] with content [file.content]; Not supporting file
upload through form using `file` currently uses web API with
access token. Snippet can also be sent instead by filling the
content value *)
let upload_file ~(ctx : Context.t) ~(req : Slack_t.files_upload_req) =
match req.filename with
| None -> Exn.fail "need to supply filename"
| Some filename ->
let contents, length =
match req.content with
| Some v -> v, String.length v
| None ->
let raw_file_contents = In_channel.with_open_bin filename (fun ic -> input_all ic) in
raw_file_contents, String.length raw_file_contents
in
let req' = Slack_j.make_get_upload_url_ext_req ~filename ~length () in
( match%lwt get_upload_url_external ~ctx ~req:req' with
| Error e -> Lwt.return_error e
| Ok { upload_url; file_id; _ } ->
let raw_file_contents = In_channel.with_open_bin filename (fun ic -> input_all ic) in
let body = `Raw ("", raw_file_contents) in
let body = `Raw ("text/plain", contents) in
( match%lwt http_request ~ua:ctx.ua ~body `POST upload_url with
| Error e -> slack_lib_fail "upload file failed with: %s" e
| Ok _ ->
let files : Slack_t.files_v2 = [ { id = file_id; title = file.title } ] in
let req = Slack_j.make_complete_upload_ext_req ~files ?channels:file.channels ?thread_ts:file.thread_ts () in
( match%lwt complete_upload_external ~ctx ~req with
let files : Slack_t.files_v2 = [ { id = file_id; title = req.title } ] in
let req' = Slack_j.make_complete_upload_ext_req ~files ?channels:req.channels ?thread_ts:req.thread_ts () in
( match%lwt complete_upload_external ~ctx ~req:req' with
| Error e -> Lwt.return_error e
| Ok { files; _ } ->
let f =
Expand Down
4 changes: 2 additions & 2 deletions lib_test/test.ml
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,8 @@ let file_list =
let process_upload_file (channels, content) =
Printf.printf "upload_file_to--------channels: %s--------\n" channels;
let ctx = Context.empty_ctx () in
let file : Slack_t.files_upload_req = Slack_j.make_files_upload_req ~channels ~content () in
match%lwt Api.upload_file ~ctx ~file with
let req : Slack_t.files_upload_req = Slack_j.make_files_upload_req ~channels ~content () in
match%lwt Api.upload_file ~ctx ~req with
| Ok res ->
let json = res |> Slack_j.string_of_files_upload_res |> Yojson.Basic.from_string |> Yojson.Basic.pretty_to_string in
print_endline json;
Expand Down