diff options
| author | Adelyn Breelove <[email protected]> | 2019-01-17 09:47:39 -0700 |
|---|---|---|
| committer | Adelyn Breelove <[email protected]> | 2019-01-17 09:47:39 -0700 |
| commit | 8760c74b63eb44acad13829ef41b2e705f031ecb (patch) | |
| tree | 90240eaaafc8f033c707fa00fdb3837ba485c0b9 /lib | |
| parent | Member methods are here (diff) | |
| parent | new event dispatching (diff) | |
| download | disml-8760c74b63eb44acad13829ef41b2e705f031ecb.tar.xz disml-8760c74b63eb44acad13829ef41b2e705f031ecb.zip | |
Resolve non-ff merge
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/client.ml | 42 | ||||
| -rw-r--r-- | lib/config.ml | 37 | ||||
| -rw-r--r-- | lib/config.mli | 37 | ||||
| -rw-r--r-- | lib/dispatch.ml | 9 | ||||
| -rw-r--r-- | lib/dune | 2 | ||||
| -rw-r--r-- | lib/endpoints.mli | 61 | ||||
| -rw-r--r-- | lib/event.ml | 53 | ||||
| -rw-r--r-- | lib/http.ml | 502 | ||||
| -rw-r--r-- | lib/http.mli | 185 | ||||
| -rw-r--r-- | lib/models.ml | 10 | ||||
| -rw-r--r-- | lib/models/ban.ml | 4 | ||||
| -rw-r--r-- | lib/models/ban.mli | 1 | ||||
| -rw-r--r-- | lib/models/channel.ml | 116 | ||||
| -rw-r--r-- | lib/models/channel.mli | 22 | ||||
| -rw-r--r-- | lib/models/guild.ml | 254 | ||||
| -rw-r--r-- | lib/models/guild.mli | 34 | ||||
| -rw-r--r-- | lib/models/member.ml | 55 | ||||
| -rw-r--r-- | lib/models/member.mli | 10 | ||||
| -rw-r--r-- | lib/models/message.ml | 82 | ||||
| -rw-r--r-- | lib/models/message.mli | 12 | ||||
| -rw-r--r-- | lib/models/reaction.ml | 7 | ||||
| -rw-r--r-- | lib/models/reaction.mli | 5 | ||||
| -rw-r--r-- | lib/models/role.ml | 34 | ||||
| -rw-r--r-- | lib/models/role.mli | 10 | ||||
| -rw-r--r-- | lib/models/user.ml | 34 | ||||
| -rw-r--r-- | lib/models/user.mli | 7 | ||||
| -rw-r--r-- | lib/opcode.mli | 18 | ||||
| -rw-r--r-- | lib/rl.mli | 19 | ||||
| -rw-r--r-- | lib/s.ml | 396 | ||||
| -rw-r--r-- | lib/sharder.ml | 606 | ||||
| -rw-r--r-- | lib/sharder.mli | 57 |
31 files changed, 1398 insertions, 1323 deletions
diff --git a/lib/client.ml b/lib/client.ml index 45b6d54..49d01dc 100644 --- a/lib/client.ml +++ b/lib/client.ml @@ -1,30 +1,22 @@ -module Make(T : S.ClientOptions)(H : S.Handler_f) = struct - open Async +open Async +include Config - module Http = Http.Make(T) - module Models = Models.Make(Http) - module Handler = H.Make(Models) - module Dispatch = Dispatch.Make(Handler) - module Sharder = Sharder.Make(Http)(Dispatch) +type t = { + sharder: Sharder.t; + token: string; +} - type t = { - sharder: Sharder.t; - token: string; - } +let start ?count token = + Config.token := token; + Sharder.start ?count () + >>| fun sharder -> + { sharder; token = !Config.token; } - let token = T.token +let set_status ~status client = + Sharder.set_status ~status client.sharder - let start ?count () = - Sharder.start ?count () - >>| fun sharder -> - { sharder; token; } +let set_status_with ~f client = + Sharder.set_status_with ~f client.sharder - let set_status ~status client = - Sharder.set_status ~status client.sharder - - let set_status_with ~f client = - Sharder.set_status_with ~f client.sharder - - let request_guild_members ~guild ?query ?limit client = - Sharder.request_guild_members ~guild ?query ?limit client.sharder -end
\ No newline at end of file +let request_guild_members ~guild ?query ?limit client = + Sharder.request_guild_members ~guild ?query ?limit client.sharder
\ No newline at end of file diff --git a/lib/config.ml b/lib/config.ml new file mode 100644 index 0000000..99018ea --- /dev/null +++ b/lib/config.ml @@ -0,0 +1,37 @@ +let token = ref "" + + let hello = ref (fun (_:Yojson.Safe.json) -> ()) + let ready = ref (fun (_:Yojson.Safe.json) -> ()) + let resumed = ref (fun (_:Yojson.Safe.json) -> ()) + let invalid_session = ref (fun (_:Yojson.Safe.json) -> ()) + let channel_create = ref (fun (_:Channel_t.t) -> ()) + let channel_update = ref (fun (_:Channel_t.t) -> ()) + let channel_delete = ref (fun (_:Channel_t.t) -> ()) + let channel_pins_update = ref (fun (_:Yojson.Safe.json) -> ()) + let guild_create = ref (fun (_:Guild_t.t) -> ()) + let guild_update = ref (fun (_:Guild_t.t) -> ()) + let guild_delete = ref (fun (_:Guild_t.t) -> ()) + let member_ban = ref (fun (_:Ban_t.t) -> ()) + let member_unban = ref (fun (_:Ban_t.t) -> ()) + let guild_emojis_update = ref (fun (_:Yojson.Safe.json) -> ()) + let integrations_update = ref (fun (_:Yojson.Safe.json) -> ()) + let member_join = ref (fun (_:Member_t.t) -> ()) + let member_leave = ref (fun (_:Member_t.member_wrapper) -> ()) + let member_update = ref (fun (_:Member_t.member_update) -> ()) + let members_chunk = ref (fun (_:Member_t.t list) -> ()) + let role_create = ref (fun (_:Role_t.t) -> ()) + let role_update = ref (fun (_:Role_t.t) -> ()) + let role_delete = ref (fun (_:Role_t.t) -> ()) + let message_create = ref (fun (_:Message_t.t) -> ()) + let message_update = ref (fun (_:Message_t.message_update) -> ()) + let message_delete = ref (fun (_:Snowflake.t) (_:Snowflake.t) -> ()) + let message_bulk_delete = ref (fun (_:Snowflake.t list) -> ()) + let reaction_add = ref (fun (_:Reaction_t.reaction_event) -> ()) + let reaction_remove = ref (fun (_:Reaction_t.reaction_event) -> ()) + let reaction_bulk_remove = ref (fun (_:Reaction_t.t list) -> ()) + let presence_update = ref (fun (_:Presence.t) -> ()) + let typing_start = ref (fun (_:Yojson.Safe.json) -> ()) + let user_update = ref (fun (_:Yojson.Safe.json) -> ()) + let voice_state_update = ref (fun (_:Yojson.Safe.json) -> ()) + let voice_server_update = ref (fun (_:Yojson.Safe.json) -> ()) + let webhooks_update = ref (fun (_:Yojson.Safe.json) -> ())
\ No newline at end of file diff --git a/lib/config.mli b/lib/config.mli new file mode 100644 index 0000000..681e9ce --- /dev/null +++ b/lib/config.mli @@ -0,0 +1,37 @@ +val token : string ref + +val hello : (Yojson.Safe.json -> unit) ref +val ready : (Yojson.Safe.json -> unit) ref +val resumed : (Yojson.Safe.json -> unit) ref +val invalid_session : (Yojson.Safe.json -> unit) ref +val channel_create : (Channel_t.t -> unit) ref +val channel_update : (Channel_t.t -> unit) ref +val channel_delete : (Channel_t.t -> unit) ref +val channel_pins_update : (Yojson.Safe.json -> unit) ref +val guild_create : (Guild_t.t -> unit) ref +val guild_update : (Guild_t.t -> unit) ref +val guild_delete : (Guild_t.t -> unit) ref +val member_ban : (Ban_t.t -> unit) ref +val member_unban : (Ban_t.t -> unit) ref +val guild_emojis_update : (Yojson.Safe.json -> unit) ref +val integrations_update : (Yojson.Safe.json -> unit) ref +val member_join : (Member_t.t -> unit) ref +val member_leave : (Member_t.member_wrapper -> unit) ref +val member_update : (Member_t.member_update -> unit) ref +val members_chunk : (Member_t.t list -> unit) ref +val role_create : (Role_t.t -> unit) ref +val role_update : (Role_t.t -> unit) ref +val role_delete : (Role_t.t -> unit) ref +val message_create : (Message_t.t -> unit) ref +val message_update : (Message_t.message_update -> unit) ref +val message_delete : (Snowflake.t -> Snowflake.t -> unit) ref +val message_bulk_delete : (Snowflake.t list -> unit) ref +val reaction_add : (Reaction_t.reaction_event -> unit) ref +val reaction_remove : (Reaction_t.reaction_event -> unit) ref +val reaction_bulk_remove : (Reaction_t.t list -> unit) ref +val presence_update : (Presence.t -> unit) ref +val typing_start : (Yojson.Safe.json -> unit) ref +val user_update : (Yojson.Safe.json -> unit) ref +val voice_state_update : (Yojson.Safe.json -> unit) ref +val voice_server_update : (Yojson.Safe.json -> unit) ref +val webhooks_update : (Yojson.Safe.json -> unit) ref
\ No newline at end of file diff --git a/lib/dispatch.ml b/lib/dispatch.ml deleted file mode 100644 index 4a9b791..0000000 --- a/lib/dispatch.ml +++ /dev/null @@ -1,9 +0,0 @@ -module Make(H : sig val handle_event : Event.t -> unit end) : S.Dispatch = struct - let dispatch ~ev contents = - (* Printf.printf "Dispatching %s\n%!" ev; *) - (* print_endline (Yojson.Safe.prettify contents); *) - try - Event.event_of_yojson ~contents ev - |> H.handle_event - with Event.Invalid_event ev -> Printf.printf "Unknown event: %s%!" ev -end
\ No newline at end of file @@ -17,7 +17,7 @@ role role_t snowflake user user_t - client dispatch endpoints event http models opcode rl s sharder + client config endpoints event http opcode rl sharder ) (libraries core async_ssl cohttp-async yojson websocket-async zlib ppx_deriving_yojson.runtime) (preprocess (pps ppx_jane ppx_deriving_yojson)) diff --git a/lib/endpoints.mli b/lib/endpoints.mli new file mode 100644 index 0000000..aba0eb7 --- /dev/null +++ b/lib/endpoints.mli @@ -0,0 +1,61 @@ +val gateway : string +val gateway_bot : string +val channel : int -> string +val channel_messages : int -> string +val channel_message : int -> int -> string +val channel_reaction_me : int -> int -> string -> string +val channel_reaction : int -> int -> string -> int -> string +val channel_reactions_get : int -> int -> string -> string +val channel_reactions_delete : int -> int -> string +val channel_bulk_delete : int -> string +val channel_permission : int -> int -> string +val channel_permissions : int -> string +val channels : string +val channel_call_ring : int -> string +val channel_invites : int -> string +val channel_typing : int -> string +val channel_pins : int -> string +val channel_pin : int -> int -> string +val guilds : string +val guild : int -> string +val guild_channels : int -> string +val guild_members : int -> string +val guild_member : int -> int -> string +val guild_member_role : int -> int -> int -> string +val guild_bans : int -> string +val guild_ban : int -> int -> string +val guild_roles : int -> string +val guild_role : int -> int -> string +val guild_prune : int -> string +val guild_voice_regions : int -> string +val guild_invites : int -> string +val guild_integrations : int -> string +val guild_integration : int -> int -> string +val guild_integration_sync : int -> int -> string +val guild_embed : int -> string +val guild_emojis : int -> string +val guild_emoji : int -> int -> string +val webhooks_guild : int -> string +val webhooks_channel : int -> string +val webhook : int -> string +val webhook_token : int -> string -> string +val webhook_git : int -> string -> string +val webhook_slack : int -> string -> string +val user : int -> string +val me : string +val me_guilds : string +val me_guild : int -> string +val me_channels : string +val me_connections : string +val invite : string -> string +val regions : string +val application_information : string +val group_recipient : int -> int -> string +val guild_me_nick : int -> string +val guild_vanity_url : int -> string +val guild_audit_logs : int -> string +val cdn_embed_avatar : string -> string +val cdn_emoji : string -> string -> string +val cdn_icon : int -> string -> string -> string +val cdn_avatar : int -> string -> string -> string +val cdn_default_avatar : int -> string
\ No newline at end of file diff --git a/lib/event.ml b/lib/event.ml index d6a6372..1c0bcc2 100644 --- a/lib/event.ml +++ b/lib/event.ml @@ -22,9 +22,9 @@ type t = | GUILD_MEMBER_REMOVE of Member_t.member_wrapper | GUILD_MEMBER_UPDATE of Member_t.member_update | GUILD_MEMBERS_CHUNK of Member_t.t list -| GUILD_ROLE_CREATE of Role_t.t (* * Guild_t.t *) -| GUILD_ROLE_UPDATE of Role_t.t (* * Guild_t.t *) -| GUILD_ROLE_DELETE of Role_t.t (* * Guild_t.t *) +| GUILD_ROLE_CREATE of Role_t.t +| GUILD_ROLE_UPDATE of Role_t.t +| GUILD_ROLE_DELETE of Role_t.t | MESSAGE_CREATE of Message_t.t | MESSAGE_UPDATE of Message_t.message_update | MESSAGE_DELETE of Snowflake.t * Snowflake.t @@ -75,4 +75,49 @@ let event_of_yojson ~contents t = match t with | "VOICE_STATE_UPDATE" -> VOICE_STATE_UPDATE contents | "VOICE_SERVER_UPDATE" -> VOICE_SERVER_UPDATE contents | "WEBHOOKS_UPDATE" -> WEBHOOKS_UPDATE contents - | s -> raise @@ Invalid_event s
\ No newline at end of file + | s -> raise @@ Invalid_event s + +let dispatch ev = match ev with +| HELLO d -> !Config.hello d +| READY d -> !Config.ready d +| RESUMED d -> !Config.resumed d +| INVALID_SESSION d -> !Config.invalid_session d +| CHANNEL_CREATE d -> !Config.channel_create d +| CHANNEL_UPDATE d -> !Config.channel_update d +| CHANNEL_DELETE d -> !Config.channel_delete d +| CHANNEL_PINS_UPDATE d -> !Config.channel_pins_update d +| GUILD_CREATE d -> !Config.guild_create d +| GUILD_UPDATE d -> !Config.guild_update d +| GUILD_DELETE d -> !Config.guild_delete d +| GUILD_BAN_ADD d -> !Config.member_ban d +| GUILD_BAN_REMOVE d -> !Config.member_unban d +| GUILD_EMOJIS_UPDATE d -> !Config.guild_emojis_update d +| GUILD_INTEGRATIONS_UPDATE d -> !Config.integrations_update d +| GUILD_MEMBER_ADD d -> !Config.member_join d +| GUILD_MEMBER_REMOVE d -> !Config.member_leave d +| GUILD_MEMBER_UPDATE d -> !Config.member_update d +| GUILD_MEMBERS_CHUNK d -> !Config.members_chunk d +| GUILD_ROLE_CREATE d -> !Config.role_create d +| GUILD_ROLE_UPDATE d -> !Config.role_update d +| GUILD_ROLE_DELETE d -> !Config.role_delete d +| MESSAGE_CREATE d -> !Config.message_create d +| MESSAGE_UPDATE d -> !Config.message_update d +| MESSAGE_DELETE (d,e) -> !Config.message_delete d e +| MESSAGE_BULK_DELETE d -> !Config.message_bulk_delete d +| MESSAGE_REACTION_ADD d -> !Config.reaction_add d +| MESSAGE_REACTION_REMOVE d -> !Config.reaction_remove d +| MESSAGE_REACTION_REMOVE_ALL d -> !Config.reaction_bulk_remove d +| PRESENCE_UPDATE d -> !Config.presence_update d +| TYPING_START d -> !Config.typing_start d +| USER_UPDATE d -> !Config.user_update d +| VOICE_STATE_UPDATE d -> !Config.voice_state_update d +| VOICE_SERVER_UPDATE d -> !Config.voice_server_update d +| WEBHOOKS_UPDATE d -> !Config.webhooks_update d + +let handle_event ~ev contents = + (* Printf.printf "Dispatching %s\n%!" ev; *) + (* print_endline (Yojson.Safe.prettify contents); *) + try + event_of_yojson ~contents ev + |> dispatch + with Invalid_event ev -> Printf.printf "Unknown event: %s%!" ev
\ No newline at end of file diff --git a/lib/http.ml b/lib/http.ml index 58bdd4e..5f8e4e6 100644 --- a/lib/http.ml +++ b/lib/http.ml @@ -1,345 +1,341 @@ -module Make(T : S.ClientOptions) = struct - open Core - open Async - open Cohttp - - let token = T.token - - module Base = struct - exception Invalid_Method - exception Bad_response_headers - - let rl = ref Rl.empty - - let base_url = "https://discordapp.com/api/v7" - - let process_url path = - Uri.of_string (base_url ^ path) - - let process_request_body body = - body - |> Yojson.Safe.to_string - |> Cohttp_async.Body.of_string - - let process_request_headers () = - let h = Header.init () in - Header.add_list h [ - "User-Agent", "Dis.ml v0.1.0"; - "Authorization", ("Bot " ^ token); - "Content-Type", "application/json"; - ] - - let process_response path ((resp:Response.t), body) = - (match Response.headers resp - |> Rl.rl_of_header with - | Some r -> Mvar.put (Rl.find_exn !rl path) r - | None -> raise Bad_response_headers) - >>= fun () -> - match resp |> Response.status |> Code.code_of_status with - | 200 -> body |> Cohttp_async.Body.to_string >>| Yojson.Safe.from_string >>= Deferred.Or_error.return - | code -> - body |> Cohttp_async.Body.to_string >>= fun body -> - Deferred.Or_error.errorf "Unsuccessful response received: %d - %s" code body - - let request ?(body=`Null) m path = - rl := Rl.update ~f:(function - | None -> - let r = Mvar.create () in - Mvar.set r Rl.default; - r - | Some r -> r - ) !rl path; - let limit = Rl.find_exn !rl path in - Mvar.take limit >>= fun limit -> - let process () = - let uri = process_url path in - let headers = process_request_headers () in - let body = process_request_body body in - (match m with - | `DELETE -> Cohttp_async.Client.delete ~headers ~body uri - | `GET -> Cohttp_async.Client.get ~headers uri - | `PATCH -> Cohttp_async.Client.patch ~headers ~body uri - | `POST -> Cohttp_async.Client.post ~headers ~body uri - | `PUT -> Cohttp_async.Client.put ~headers ~body uri - | _ -> raise Invalid_Method) - >>= process_response path - in if limit.remaining > 0 then process () - else Clock.at (Core.Time.(Span.of_int_sec limit.reset |> of_span_since_epoch)) >>= process - end +open Core +open Async +open Cohttp + +module Base = struct + exception Invalid_Method + exception Bad_response_headers + + let rl = ref Rl.empty + + let base_url = "https://discordapp.com/api/v7" + + let process_url path = + Uri.of_string (base_url ^ path) + + let process_request_body body = + body + |> Yojson.Safe.to_string + |> Cohttp_async.Body.of_string + + let process_request_headers () = + let h = Header.init () in + Header.add_list h [ + "User-Agent", "Dis.ml v0.1.0"; + "Authorization", ("Bot " ^ !Config.token); + "Content-Type", "application/json"; + ] + + let process_response path ((resp:Response.t), body) = + (match Response.headers resp + |> Rl.rl_of_header with + | Some r -> Mvar.put (Rl.find_exn !rl path) r + | None -> raise Bad_response_headers) + >>= fun () -> + match resp |> Response.status |> Code.code_of_status with + | 200 -> body |> Cohttp_async.Body.to_string >>| Yojson.Safe.from_string >>= Deferred.Or_error.return + | code -> + body |> Cohttp_async.Body.to_string >>= fun body -> + Deferred.Or_error.errorf "Unsuccessful response received: %d - %s" code body + + let request ?(body=`Null) ?(query=[]) m path = + rl := Rl.update ~f:(function + | None -> + let r = Mvar.create () in + Mvar.set r Rl.default; + r + | Some r -> r + ) !rl path; + let limit = Rl.find_exn !rl path in + Mvar.take limit >>= fun limit -> + let process () = + let uri = Uri.add_query_params' (process_url path) query in + let headers = process_request_headers () in + let body = process_request_body body in + (match m with + | `DELETE -> Cohttp_async.Client.delete ~headers ~body uri + | `GET -> Cohttp_async.Client.get ~headers uri + | `PATCH -> Cohttp_async.Client.patch ~headers ~body uri + | `POST -> Cohttp_async.Client.post ~headers ~body uri + | `PUT -> Cohttp_async.Client.put ~headers ~body uri + | _ -> raise Invalid_Method) + >>= process_response path + in if limit.remaining > 0 then process () + else Clock.at (Core.Time.(Span.of_int_sec limit.reset |> of_span_since_epoch)) >>= process +end - let get_gateway () = - Base.request `GET Endpoints.gateway +let get_gateway () = + Base.request `GET Endpoints.gateway - let get_gateway_bot () = - Base.request `GET Endpoints.gateway_bot +let get_gateway_bot () = + Base.request `GET Endpoints.gateway_bot - let get_channel channel_id = - Base.request `GET (Endpoints.channel channel_id) +let get_channel channel_id = + Base.request `GET (Endpoints.channel channel_id) - let modify_channel channel_id body = - Base.request ~body `PATCH (Endpoints.channel channel_id) +let modify_channel channel_id body = + Base.request ~body `PATCH (Endpoints.channel channel_id) - let delete_channel channel_id = - Base.request `DELETE (Endpoints.channel channel_id) +let delete_channel channel_id = + Base.request `DELETE (Endpoints.channel channel_id) - let get_messages channel_id limit (kind, id) = - Base.request `GET (Printf.sprintf "%s?%s=%d&limit=%d" (Endpoints.channel_messages channel_id) kind id limit) +let get_messages channel_id limit (kind, id) = + Base.request ~query:[(kind, string_of_int id); ("limit", string_of_int limit)] `GET (Endpoints.channel_messages channel_id) - let get_message channel_id message_id = - Base.request `GET (Endpoints.channel_message channel_id message_id) +let get_message channel_id message_id = + Base.request `GET (Endpoints.channel_message channel_id message_id) - let create_message channel_id body = - Base.request ~body:body `POST (Endpoints.channel_messages channel_id) +let create_message channel_id body = + Base.request ~body:body `POST (Endpoints.channel_messages channel_id) - let create_reaction channel_id message_id emoji = - Base.request `PUT (Endpoints.channel_reaction_me channel_id message_id emoji) +let create_reaction channel_id message_id emoji = + Base.request `PUT (Endpoints.channel_reaction_me channel_id message_id emoji) - let delete_own_reaction channel_id message_id emoji = - Base.request `DELETE (Endpoints.channel_reaction_me channel_id message_id emoji) +let delete_own_reaction channel_id message_id emoji = + Base.request `DELETE (Endpoints.channel_reaction_me channel_id message_id emoji) - let delete_reaction channel_id message_id emoji user_id = - Base.request `DELETE (Endpoints.channel_reaction channel_id message_id emoji user_id) +let delete_reaction channel_id message_id emoji user_id = + Base.request `DELETE (Endpoints.channel_reaction channel_id message_id emoji user_id) - let get_reactions channel_id message_id emoji = - Base.request `GET (Endpoints.channel_reactions_get channel_id message_id emoji) +let get_reactions channel_id message_id emoji = + Base.request `GET (Endpoints.channel_reactions_get channel_id message_id emoji) - let delete_reactions channel_id message_id = - Base.request `DELETE (Endpoints.channel_reactions_delete channel_id message_id) +let delete_reactions channel_id message_id = + Base.request `DELETE (Endpoints.channel_reactions_delete channel_id message_id) - let edit_message channel_id message_id body = - Base.request ~body `PATCH (Endpoints.channel_message channel_id message_id) +let edit_message channel_id message_id body = + Base.request ~body `PATCH (Endpoints.channel_message channel_id message_id) - let delete_message channel_id message_id = - Base.request `DELETE (Endpoints.channel_message channel_id message_id) +let delete_message channel_id message_id = + Base.request `DELETE (Endpoints.channel_message channel_id message_id) - let bulk_delete channel_id body = - Base.request ~body `POST (Endpoints.channel_bulk_delete channel_id) +let bulk_delete channel_id body = + Base.request ~body `POST (Endpoints.channel_bulk_delete channel_id) - let edit_channel_permissions channel_id overwrite_id body = - Base.request ~body `PUT (Endpoints.channel_permission channel_id overwrite_id) +let edit_channel_permissions channel_id overwrite_id body = + Base.request ~body `PUT (Endpoints.channel_permission channel_id overwrite_id) - let get_channel_invites channel_id = - Base.request `GET (Endpoints.channel_invites channel_id) +let get_channel_invites channel_id = + Base.request `GET (Endpoints.channel_invites channel_id) - let create_channel_invite channel_id body = - Base.request ~body `POST (Endpoints.channel_invites channel_id) +let create_channel_invite channel_id body = + Base.request ~body `POST (Endpoints.channel_invites channel_id) - let delete_channel_permission channel_id overwrite_id = - Base.request `DELETE (Endpoints.channel_permission channel_id overwrite_id) +let delete_channel_permission channel_id overwrite_id = + Base.request `DELETE (Endpoints.channel_permission channel_id overwrite_id) - let broadcast_typing channel_id = - Base.request `POST (Endpoints.channel_typing channel_id) +let broadcast_typing channel_id = + Base.request `POST (Endpoints.channel_typing channel_id) - let get_pinned_messages channel_id = - Base.request `GET (Endpoints.channel_pins channel_id) +let get_pinned_messages channel_id = + Base.request `GET (Endpoints.channel_pins channel_id) - let pin_message channel_id message_id = - Base.request `PUT (Endpoints.channel_pin channel_id message_id) +let pin_message channel_id message_id = + Base.request `PUT (Endpoints.channel_pin channel_id message_id) - let unpin_message channel_id message_id = - Base.request `DELETE (Endpoints.channel_pin channel_id message_id) +let unpin_message channel_id message_id = + Base.request `DELETE (Endpoints.channel_pin channel_id message_id) - let group_recipient_add channel_id user_id = - Base.request `PUT (Endpoints.group_recipient channel_id user_id) +let group_recipient_add channel_id user_id = + Base.request `PUT (Endpoints.group_recipient channel_id user_id) - let group_recipient_remove channel_id user_id = - Base.request `DELETE (Endpoints.group_recipient channel_id user_id) +let group_recipient_remove channel_id user_id = + Base.request `DELETE (Endpoints.group_recipient channel_id user_id) - let get_emojis guild_id = - Base.request `GET (Endpoints.guild_emojis guild_id) +let get_emojis guild_id = + Base.request `GET (Endpoints.guild_emojis guild_id) - let get_emoji guild_id emoji_id = - Base.request `GET (Endpoints.guild_emoji guild_id emoji_id) +let get_emoji guild_id emoji_id = + Base.request `GET (Endpoints.guild_emoji guild_id emoji_id) - let create_emoji guild_id body = - Base.request ~body `POST (Endpoints.guild_emojis guild_id) +let create_emoji guild_id body = + Base.request ~body `POST (Endpoints.guild_emojis guild_id) - let edit_emoji guild_id emoji_id body = - Base.request ~body `PATCH (Endpoints.guild_emoji guild_id emoji_id) +let edit_emoji guild_id emoji_id body = + Base.request ~body `PATCH (Endpoints.guild_emoji guild_id emoji_id) - let delete_emoji guild_id emoji_id = - Base.request `DELETE (Endpoints.guild_emoji guild_id emoji_id) +let delete_emoji guild_id emoji_id = + Base.request `DELETE (Endpoints.guild_emoji guild_id emoji_id) - let create_guild body = - Base.request ~body `POST Endpoints.guilds +let create_guild body = + Base.request ~body `POST Endpoints.guilds - let get_guild guild_id = - Base.request `GET (Endpoints.guild guild_id) +let get_guild guild_id = + Base.request `GET (Endpoints.guild guild_id) - let edit_guild guild_id body = - Base.request ~body `PATCH (Endpoints.guild guild_id) +let edit_guild guild_id body = + Base.request ~body `PATCH (Endpoints.guild guild_id) - let delete_guild guild_id = - Base.request `DELETE (Endpoints.guild guild_id) +let delete_guild guild_id = + Base.request `DELETE (Endpoints.guild guild_id) - let get_guild_channels guild_id = - Base.request `GET (Endpoints.guild_channels guild_id) +let get_guild_channels guild_id = + Base.request `GET (Endpoints.guild_channels guild_id) - let create_guild_channel guild_id body = - Base.request ~body `POST (Endpoints.guild_channels guild_id) +let create_guild_channel guild_id body = + Base.request ~body `POST (Endpoints.guild_channels guild_id) - let modify_guild_channel_positions guild_id body = - Base.request ~body `PATCH (Endpoints.guild_channels guild_id) +let modify_guild_channel_positions guild_id body = + Base.request ~body `PATCH (Endpoints.guild_channels guild_id) - let get_member guild_id user_id = - Base.request `GET (Endpoints.guild_member guild_id user_id) +let get_member guild_id user_id = + Base.request `GET (Endpoints.guild_member guild_id user_id) - let get_members guild_id = - Base.request `GET (Endpoints.guild_members guild_id) +let get_members guild_id = + Base.request `GET (Endpoints.guild_members guild_id) - let add_member guild_id user_id body = - Base.request ~body `PUT (Endpoints.guild_member guild_id user_id) +let add_member guild_id user_id body = + Base.request ~body `PUT (Endpoints.guild_member guild_id user_id) - let edit_member guild_id user_id body = - Base.request ~body `PATCH (Endpoints.guild_member guild_id user_id) +let edit_member guild_id user_id body = + Base.request ~body `PATCH (Endpoints.guild_member guild_id user_id) - let remove_member guild_id user_id body = - Base.request ~body `DELETE (Endpoints.guild_member guild_id user_id) +let remove_member guild_id user_id body = + Base.request ~body `DELETE (Endpoints.guild_member guild_id user_id) - let change_nickname guild_id body = - Base.request ~body `PATCH (Endpoints.guild_me_nick guild_id) +let change_nickname guild_id body = + Base.request ~body `PATCH (Endpoints.guild_me_nick guild_id) - let add_member_role guild_id user_id role_id = - Base.request `PUT (Endpoints.guild_member_role guild_id user_id role_id) +let add_member_role guild_id user_id role_id = + Base.request `PUT (Endpoints.guild_member_role guild_id user_id role_id) - let remove_member_role guild_id user_id role_id = - Base.request `DELETE (Endpoints.guild_member_role guild_id user_id role_id) +let remove_member_role guild_id user_id role_id = + Base.request `DELETE (Endpoints.guild_member_role guild_id user_id role_id) - let get_bans guild_id = - Base.request `GET (Endpoints.guild_bans guild_id) +let get_bans guild_id = + Base.request `GET (Endpoints.guild_bans guild_id) - let get_ban guild_id user_id = - Base.request `GET (Endpoints.guild_ban guild_id user_id) +let get_ban guild_id user_id = + Base.request `GET (Endpoints.guild_ban guild_id user_id) - let guild_ban_add guild_id user_id body = - Base.request ~body `PUT (Endpoints.guild_ban guild_id user_id) +let guild_ban_add guild_id user_id body = + Base.request ~body `PUT (Endpoints.guild_ban guild_id user_id) - let guild_ban_remove guild_id user_id body = - Base.request ~body `DELETE (Endpoints.guild_ban guild_id user_id) +let guild_ban_remove guild_id user_id body = + Base.request ~body `DELETE (Endpoints.guild_ban guild_id user_id) - let get_roles guild_id = - Base.request `GET (Endpoints.guild_roles guild_id) +let get_roles guild_id = + Base.request `GET (Endpoints.guild_roles guild_id) - let guild_role_add guild_id body = - Base.request ~body `POST (Endpoints.guild_roles guild_id) +let guild_role_add guild_id body = + Base.request ~body `POST (Endpoints.guild_roles guild_id) - let guild_roles_edit guild_id body = - Base.request ~body `PATCH (Endpoints.guild_roles guild_id) +let guild_roles_edit guild_id body = + Base.request ~body `PATCH (Endpoints.guild_roles guild_id) - let guild_role_edit guild_id role_id body = - Base.request ~body `PATCH (Endpoints.guild_role guild_id role_id) +let guild_role_edit guild_id role_id body = + Base.request ~body `PATCH (Endpoints.guild_role guild_id role_id) - let guild_role_remove guild_id role_id = - Base.request `DELETE (Endpoints.guild_role guild_id role_id) +let guild_role_remove guild_id role_id = + Base.request `DELETE (Endpoints.guild_role guild_id role_id) - let guild_prune_count guild_id days = - Base.request `GET ((Endpoints.guild_prune guild_id) ^ "?days=" ^ Int.to_string days) +let guild_prune_count guild_id days = + Base.request ~query:[("days", Int.to_string days)] `GET (Endpoints.guild_prune guild_id) - let guild_prune_start guild_id days = - Base.request `POST ((Endpoints.guild_prune guild_id) ^ "?days=" ^ Int.to_string days) +let guild_prune_start guild_id days = + Base.request ~query:[("days", Int.to_string days)] `POST (Endpoints.guild_prune guild_id) - let get_guild_voice_regions guild_id = - Base.request `GET (Endpoints.guild_voice_regions guild_id) +let get_guild_voice_regions guild_id = + Base.request `GET (Endpoints.guild_voice_regions guild_id) - let get_guild_invites guild_id = - Base.request `GET (Endpoints.guild_invites guild_id) +let get_guild_invites guild_id = + Base.request `GET (Endpoints.guild_invites guild_id) - let get_integrations guild_id = - Base.request `GET (Endpoints.guild_integrations guild_id) +let get_integrations guild_id = + Base.request `GET (Endpoints.guild_integrations guild_id) - let add_integration guild_id body = - Base.request ~body `POST (Endpoints.guild_integrations guild_id) +let add_integration guild_id body = + Base.request ~body `POST (Endpoints.guild_integrations guild_id) - let edit_integration guild_id integration_id body = - Base.request ~body `POST (Endpoints.guild_integration guild_id integration_id) +let edit_integration guild_id integration_id body = + Base.request ~body `POST (Endpoints.guild_integration guild_id integration_id) - let delete_integration guild_id integration_id = - Base.request `DELETE (Endpoints.guild_integration guild_id integration_id) +let delete_integration guild_id integration_id = + Base.request `DELETE (Endpoints.guild_integration guild_id integration_id) - let sync_integration guild_id integration_id = - Base.request `POST (Endpoints.guild_integration_sync guild_id integration_id) +let sync_integration guild_id integration_id = + Base.request `POST (Endpoints.guild_integration_sync guild_id integration_id) - let get_guild_embed guild_id = - Base.request `GET (Endpoints.guild_embed guild_id) +let get_guild_embed guild_id = + Base.request `GET (Endpoints.guild_embed guild_id) - let edit_guild_embed guild_id body = - Base.request ~body `PATCH (Endpoints.guild_embed guild_id) +let edit_guild_embed guild_id body = + Base.request ~body `PATCH (Endpoints.guild_embed guild_id) - let get_vanity_url guild_id = - Base.request `GET (Endpoints.guild_vanity_url guild_id) +let get_vanity_url guild_id = + Base.request `GET (Endpoints.guild_vanity_url guild_id) - let get_invite invite_code = - Base.request `GET (Endpoints.invite invite_code) +let get_invite invite_code = + Base.request `GET (Endpoints.invite invite_code) - let delete_invite invite_code = - Base.request `DELETE (Endpoints.invite invite_code) +let delete_invite invite_code = + Base.request `DELETE (Endpoints.invite invite_code) - let get_current_user () = - Base.request `GET Endpoints.me +let get_current_user () = + Base.request `GET Endpoints.me - let edit_current_user body = - Base.request ~body `PATCH Endpoints.me +let edit_current_user body = + Base.request ~body `PATCH Endpoints.me - let get_guilds () = - Base.request `GET Endpoints.me_guilds +let get_guilds () = + Base.request `GET Endpoints.me_guilds - let leave_guild guild_id = - Base.request `DELETE (Endpoints.me_guild guild_id) +let leave_guild guild_id = + Base.request `DELETE (Endpoints.me_guild guild_id) - let get_private_channels () = - Base.request `GET Endpoints.me_channels +let get_private_channels () = + Base.request `GET Endpoints.me_channels - let create_dm body = - Base.request ~body `POST Endpoints.me_channels +let create_dm body = + Base.request ~body `POST Endpoints.me_channels - let create_group_dm body = - Base.request ~body `POST Endpoints.me_channels +let create_group_dm body = + Base.request ~body `POST Endpoints.me_channels - let get_connections () = - Base.request `GET Endpoints.me_connections +let get_connections () = + Base.request `GET Endpoints.me_connections - let get_user user_id = - Base.request `GET (Endpoints.user user_id) +let get_user user_id = + Base.request `GET (Endpoints.user user_id) - let get_voice_regions () = - Base.request `GET Endpoints.regions +let get_voice_regions () = + Base.request `GET Endpoints.regions - let create_webhook channel_id body = - Base.request ~body `POST (Endpoints.webhooks_channel channel_id) +let create_webhook channel_id body = + Base.request ~body `POST (Endpoints.webhooks_channel channel_id) - let get_channel_webhooks channel_id = - Base.request `GET (Endpoints.webhooks_channel channel_id) +let get_channel_webhooks channel_id = + Base.request `GET (Endpoints.webhooks_channel channel_id) - let get_guild_webhooks guild_id = - Base.request `GET (Endpoints.webhooks_guild guild_id) +let get_guild_webhooks guild_id = + Base.request `GET (Endpoints.webhooks_guild guild_id) - let get_webhook webhook_id = - Base.request `GET (Endpoints.webhook webhook_id) +let get_webhook webhook_id = + Base.request `GET (Endpoints.webhook webhook_id) - let get_webhook_with_token webhook_id token = - Base.request `GET (Endpoints.webhook_token webhook_id token) +let get_webhook_with_token webhook_id token = + Base.request `GET (Endpoints.webhook_token webhook_id token) - let edit_webhook webhook_id body = - Base.request ~body `PATCH (Endpoints.webhook webhook_id) +let edit_webhook webhook_id body = + Base.request ~body `PATCH (Endpoints.webhook webhook_id) - let edit_webhook_with_token webhook_id token body = - Base.request ~body `PATCH (Endpoints.webhook_token webhook_id token) +let edit_webhook_with_token webhook_id token body = + Base.request ~body `PATCH (Endpoints.webhook_token webhook_id token) - let delete_webhook webhook_id = - Base.request `DELETE (Endpoints.webhook webhook_id) +let delete_webhook webhook_id = + Base.request `DELETE (Endpoints.webhook webhook_id) - let delete_webhook_with_token webhook_id token = - Base.request `DELETE (Endpoints.webhook_token webhook_id token) +let delete_webhook_with_token webhook_id token = + Base.request `DELETE (Endpoints.webhook_token webhook_id token) - let execute_webhook webhook_id token body = - Base.request ~body `POST (Endpoints.webhook_token webhook_id token) +let execute_webhook webhook_id token body = + Base.request ~body `POST (Endpoints.webhook_token webhook_id token) - let execute_slack_webhook webhook_id token body = - Base.request ~body `POST (Endpoints.webhook_slack webhook_id token) +let execute_slack_webhook webhook_id token body = + Base.request ~body `POST (Endpoints.webhook_slack webhook_id token) - let execute_git_webhook webhook_id token body = - Base.request ~body `POST (Endpoints.webhook_git webhook_id token) +let execute_git_webhook webhook_id token body = + Base.request ~body `POST (Endpoints.webhook_git webhook_id token) - let get_audit_logs guild_id body = - Base.request ~body `GET (Endpoints.guild_audit_logs guild_id) -end
\ No newline at end of file +let get_audit_logs guild_id body = + Base.request ~body `GET (Endpoints.guild_audit_logs guild_id)
\ No newline at end of file diff --git a/lib/http.mli b/lib/http.mli new file mode 100644 index 0000000..c2a50b8 --- /dev/null +++ b/lib/http.mli @@ -0,0 +1,185 @@ +open Async + +module Base : sig + exception Invalid_Method + + val base_url : string + + val process_url : string -> Uri.t + val process_request_body : Yojson.Safe.json -> Cohttp_async.Body.t + val process_request_headers : unit -> Cohttp.Header.t + + val process_response : + string -> + Cohttp_async.Response.t * Cohttp_async.Body.t -> + Yojson.Safe.json Deferred.Or_error.t + + val request : + ?body:Yojson.Safe.json -> + ?query:(string * string) list -> + [> `DELETE | `GET | `PATCH | `POST | `PUT ] -> + string -> + Yojson.Safe.json Deferred.Or_error.t +end + +(* Auto-generated signatures *) +val get_gateway : unit -> Yojson.Safe.json Deferred.Or_error.t +val get_gateway_bot : unit -> Yojson.Safe.json Deferred.Or_error.t +val get_channel : int -> Yojson.Safe.json Deferred.Or_error.t +val modify_channel : + int -> Yojson.Safe.json -> Yojson.Safe.json Deferred.Or_error.t +val delete_channel : int -> Yojson.Safe.json Deferred.Or_error.t +val get_messages : int -> int -> string * int -> Yojson.Safe.json Deferred.Or_error.t +val get_message : int -> int -> Yojson.Safe.json Deferred.Or_error.t +val create_message : + int -> Yojson.Safe.json -> Yojson.Safe.json Deferred.Or_error.t +val create_reaction : + int -> int -> string -> Yojson.Safe.json Deferred.Or_error.t +val delete_own_reaction : + int -> int -> string -> Yojson.Safe.json Deferred.Or_error.t +val delete_reaction : + int -> int -> string -> int -> Yojson.Safe.json Deferred.Or_error.t +val get_reactions : + int -> int -> string -> Yojson.Safe.json Deferred.Or_error.t +val delete_reactions : + int -> int -> Yojson.Safe.json Deferred.Or_error.t +val edit_message : + int -> + int -> Yojson.Safe.json -> Yojson.Safe.json Deferred.Or_error.t +val delete_message : + int -> int -> Yojson.Safe.json Deferred.Or_error.t +val bulk_delete : + int -> Yojson.Safe.json -> Yojson.Safe.json Deferred.Or_error.t +val edit_channel_permissions : + int -> + int -> Yojson.Safe.json -> Yojson.Safe.json Deferred.Or_error.t +val get_channel_invites : int -> Yojson.Safe.json Deferred.Or_error.t +val create_channel_invite : + int -> Yojson.Safe.json -> Yojson.Safe.json Deferred.Or_error.t +val delete_channel_permission : + int -> int -> Yojson.Safe.json Deferred.Or_error.t +val broadcast_typing : int -> Yojson.Safe.json Deferred.Or_error.t +val get_pinned_messages : int -> Yojson.Safe.json Deferred.Or_error.t +val pin_message : int -> int -> Yojson.Safe.json Deferred.Or_error.t +val unpin_message : int -> int -> Yojson.Safe.json Deferred.Or_error.t +val group_recipient_add : + int -> int -> Yojson.Safe.json Deferred.Or_error.t +val group_recipient_remove : + int -> int -> Yojson.Safe.json Deferred.Or_error.t +val get_emojis : int -> Yojson.Safe.json Deferred.Or_error.t +val get_emoji : int -> int -> Yojson.Safe.json Deferred.Or_error.t +val create_emoji : + int -> Yojson.Safe.json -> Yojson.Safe.json Deferred.Or_error.t +val edit_emoji : + int -> + int -> Yojson.Safe.json -> Yojson.Safe.json Deferred.Or_error.t +val delete_emoji : int -> int -> Yojson.Safe.json Deferred.Or_error.t +val create_guild : + Yojson.Safe.json -> Yojson.Safe.json Deferred.Or_error.t +val get_guild : int -> Yojson.Safe.json Deferred.Or_error.t +val edit_guild : + int -> Yojson.Safe.json -> Yojson.Safe.json Deferred.Or_error.t +val delete_guild : int -> Yojson.Safe.json Deferred.Or_error.t +val get_guild_channels : int -> Yojson.Safe.json Deferred.Or_error.t +val create_guild_channel : + int -> Yojson.Safe.json -> Yojson.Safe.json Deferred.Or_error.t +val modify_guild_channel_positions : + int -> Yojson.Safe.json -> Yojson.Safe.json Deferred.Or_error.t +val get_member : int -> int -> Yojson.Safe.json Deferred.Or_error.t +val get_members : int -> Yojson.Safe.json Deferred.Or_error.t +val add_member : + int -> + int -> Yojson.Safe.json -> Yojson.Safe.json Deferred.Or_error.t +val edit_member : + int -> + int -> Yojson.Safe.json -> Yojson.Safe.json Deferred.Or_error.t +val remove_member : + int -> + int -> Yojson.Safe.json -> Yojson.Safe.json Deferred.Or_error.t +val change_nickname : + int -> Yojson.Safe.json -> Yojson.Safe.json Deferred.Or_error.t +val add_member_role : + int -> int -> int -> Yojson.Safe.json Deferred.Or_error.t +val remove_member_role : + int -> int -> int -> Yojson.Safe.json Deferred.Or_error.t +val get_bans : int -> Yojson.Safe.json Deferred.Or_error.t +val get_ban : int -> int -> Yojson.Safe.json Deferred.Or_error.t +val guild_ban_add : + int -> + int -> Yojson.Safe.json -> Yojson.Safe.json Deferred.Or_error.t +val guild_ban_remove : + int -> + int -> Yojson.Safe.json -> Yojson.Safe.json Deferred.Or_error.t +val get_roles : int -> Yojson.Safe.json Deferred.Or_error.t +val guild_role_add : + int -> Yojson.Safe.json -> Yojson.Safe.json Deferred.Or_error.t +val guild_roles_edit : + int -> Yojson.Safe.json -> Yojson.Safe.json Deferred.Or_error.t +val guild_role_edit : + int -> + int -> Yojson.Safe.json -> Yojson.Safe.json Deferred.Or_error.t +val guild_role_remove : + int -> int -> Yojson.Safe.json Deferred.Or_error.t +val guild_prune_count : + int -> int -> Yojson.Safe.json Deferred.Or_error.t +val guild_prune_start : + int -> int -> Yojson.Safe.json Deferred.Or_error.t +val get_guild_voice_regions : + int -> Yojson.Safe.json Deferred.Or_error.t +val get_guild_invites : int -> Yojson.Safe.json Deferred.Or_error.t +val get_integrations : int -> Yojson.Safe.json Deferred.Or_error.t +val add_integration : + int -> Yojson.Safe.json -> Yojson.Safe.json Deferred.Or_error.t +val edit_integration : + int -> + int -> Yojson.Safe.json -> Yojson.Safe.json Deferred.Or_error.t +val delete_integration : + int -> int -> Yojson.Safe.json Deferred.Or_error.t +val sync_integration : + int -> int -> Yojson.Safe.json Deferred.Or_error.t +val get_guild_embed : int -> Yojson.Safe.json Deferred.Or_error.t +val edit_guild_embed : + int -> Yojson.Safe.json -> Yojson.Safe.json Deferred.Or_error.t +val get_vanity_url : int -> Yojson.Safe.json Deferred.Or_error.t +val get_invite : string -> Yojson.Safe.json Deferred.Or_error.t +val delete_invite : string -> Yojson.Safe.json Deferred.Or_error.t +val get_current_user : unit -> Yojson.Safe.json Deferred.Or_error.t +val edit_current_user : + Yojson.Safe.json -> Yojson.Safe.json Deferred.Or_error.t +val get_guilds : unit -> Yojson.Safe.json Deferred.Or_error.t +val leave_guild : int -> Yojson.Safe.json Deferred.Or_error.t +val get_private_channels : + unit -> Yojson.Safe.json Deferred.Or_error.t +val create_dm : + Yojson.Safe.json -> Yojson.Safe.json Deferred.Or_error.t +val create_group_dm : + Yojson.Safe.json -> Yojson.Safe.json Deferred.Or_error.t +val get_connections : unit -> Yojson.Safe.json Deferred.Or_error.t +val get_user : int -> Yojson.Safe.json Deferred.Or_error.t +val get_voice_regions : unit -> Yojson.Safe.json Deferred.Or_error.t +val create_webhook : + int -> Yojson.Safe.json -> Yojson.Safe.json Deferred.Or_error.t +val get_channel_webhooks : int -> Yojson.Safe.json Deferred.Or_error.t +val get_guild_webhooks : int -> Yojson.Safe.json Deferred.Or_error.t +val get_webhook : int -> Yojson.Safe.json Deferred.Or_error.t +val get_webhook_with_token : + int -> string -> Yojson.Safe.json Deferred.Or_error.t +val edit_webhook : + int -> Yojson.Safe.json -> Yojson.Safe.json Deferred.Or_error.t +val edit_webhook_with_token : + int -> + string -> Yojson.Safe.json -> Yojson.Safe.json Deferred.Or_error.t +val delete_webhook : int -> Yojson.Safe.json Deferred.Or_error.t +val delete_webhook_with_token : + int -> string -> Yojson.Safe.json Deferred.Or_error.t +val execute_webhook : + int -> + string -> Yojson.Safe.json -> Yojson.Safe.json Deferred.Or_error.t +val execute_slack_webhook : + int -> + string -> Yojson.Safe.json -> Yojson.Safe.json Deferred.Or_error.t +val execute_git_webhook : + int -> + string -> Yojson.Safe.json -> Yojson.Safe.json Deferred.Or_error.t +val get_audit_logs : + int -> Yojson.Safe.json -> Yojson.Safe.json Deferred.Or_error.t
\ No newline at end of file diff --git a/lib/models.ml b/lib/models.ml deleted file mode 100644 index bfcc428..0000000 --- a/lib/models.ml +++ /dev/null @@ -1,10 +0,0 @@ -module Make(H : S.Http) = struct - module Ban = Ban.Make(H) - module Channel = Channel.Make(H) - module Guild = Guild.Make(H) - module Member = Member.Make(H) - module Message = Message.Make(H) - module Reaction = Reaction.Make(H) - module Role = Role.Make(H) - module User = User.Make(H) -end
\ No newline at end of file diff --git a/lib/models/ban.ml b/lib/models/ban.ml index f84fe62..45f7679 100644 --- a/lib/models/ban.ml +++ b/lib/models/ban.ml @@ -1,3 +1 @@ -module Make(Http : S.Http) = struct - type t = Ban_t.t -end
\ No newline at end of file +include Ban_t
\ No newline at end of file diff --git a/lib/models/ban.mli b/lib/models/ban.mli new file mode 100644 index 0000000..d1050b0 --- /dev/null +++ b/lib/models/ban.mli @@ -0,0 +1 @@ +type t = Ban_t.t
\ No newline at end of file diff --git a/lib/models/channel.ml b/lib/models/channel.ml index 3fab452..c3524ef 100644 --- a/lib/models/channel.ml +++ b/lib/models/channel.ml @@ -1,59 +1,57 @@ -module Make(Http : S.Http) = struct - open Async - open Core - include Channel_t - - exception Invalid_message - exception No_message_found - - let say ~content ch = - Http.create_message (get_id ch) (`Assoc [("content", `String content)]) - >>| Result.map ~f:Message_t.of_yojson_exn - - let send_message ?embed ?content ?file ?(tts=false) ch = - let embed = match embed with - | Some e -> e - | None -> `Null in - let content = match content with - | Some c -> `String c - | None -> `Null in - let file = match file with - | Some f -> `String f - | None -> `Null in - let () = match embed, content with - | `Null, `Null -> raise Invalid_message - | _ -> () in - Http.create_message (get_id ch) (`Assoc [ - ("embed", embed); - ("content", content); - ("file", file); - ("tts", `Bool tts); - ]) >>| Result.map ~f:Message_t.of_yojson_exn - - let delete ch = - Http.delete_channel (get_id ch) >>| Result.map ~f:ignore - - let get_message ~id ch = - Http.get_message (get_id ch) id >>| Result.map ~f:Message_t.of_yojson_exn - - let get_messages ?(mode=`Around) ?id ?(limit=50) ch = - let kind = match mode with - | `Around -> "around", limit - | `Before -> "before", limit - | `After -> "after", limit - in - let id = match id with - | Some id -> id - | None -> raise No_message_found in - Http.get_messages (get_id ch) id kind >>| Result.map ~f:(fun l -> - Yojson.Safe.Util.to_list l - |> List.map ~f:Message_t.of_yojson_exn) - - let broadcast_typing ch = - Http.broadcast_typing (get_id ch) >>| Result.map ~f:ignore - - let get_pins ch = - Http.get_pinned_messages (get_id ch) >>| Result.map ~f:(fun l -> - Yojson.Safe.Util.to_list l - |> List.map ~f:Message_t.of_yojson_exn) -end
\ No newline at end of file +open Async +open Core +include Channel_t + +exception Invalid_message +exception No_message_found + +let say ~content ch = + Http.create_message (get_id ch) (`Assoc [("content", `String content)]) + >>| Result.map ~f:Message_t.of_yojson_exn + +let send_message ?embed ?content ?file ?(tts=false) ch = + let embed = match embed with + | Some e -> e + | None -> `Null in + let content = match content with + | Some c -> `String c + | None -> `Null in + let file = match file with + | Some f -> `String f + | None -> `Null in + let () = match embed, content with + | `Null, `Null -> raise Invalid_message + | _ -> () in + Http.create_message (get_id ch) (`Assoc [ + ("embed", embed); + ("content", content); + ("file", file); + ("tts", `Bool tts); + ]) >>| Result.map ~f:Message_t.of_yojson_exn + +let delete ch = + Http.delete_channel (get_id ch) >>| Result.map ~f:ignore + +let get_message ~id ch = + Http.get_message (get_id ch) id >>| Result.map ~f:Message_t.of_yojson_exn + +let get_messages ?(mode=`Around) ?id ?(limit=50) ch = + let kind = match mode with + | `Around -> "around", limit + | `Before -> "before", limit + | `After -> "after", limit + in + let id = match id with + | Some id -> id + | None -> raise No_message_found in + Http.get_messages (get_id ch) id kind >>| Result.map ~f:(fun l -> + Yojson.Safe.Util.to_list l + |> List.map ~f:Message_t.of_yojson_exn) + +let broadcast_typing ch = + Http.broadcast_typing (get_id ch) >>| Result.map ~f:ignore + +let get_pins ch = + Http.get_pinned_messages (get_id ch) >>| Result.map ~f:(fun l -> + Yojson.Safe.Util.to_list l + |> List.map ~f:Message_t.of_yojson_exn)
\ No newline at end of file diff --git a/lib/models/channel.mli b/lib/models/channel.mli new file mode 100644 index 0000000..4d67e94 --- /dev/null +++ b/lib/models/channel.mli @@ -0,0 +1,22 @@ +open Async + +type t = Channel_t.t +val say : content:string -> t -> Message_t.t Deferred.Or_error.t +val send_message : + ?embed:Yojson.Safe.json -> + ?content:string -> + ?file:string -> + ?tts:bool -> + t -> + Message_t.t Deferred.Or_error.t +val delete : t -> unit Deferred.Or_error.t +val get_message : id:Snowflake.t -> t -> Message_t.t Deferred.Or_error.t +val get_messages : + ?mode:[ `Before | `After | `Around ] -> + ?id:Snowflake.t -> + ?limit:int -> + t -> + Message_t.t list Deferred.Or_error.t +val broadcast_typing : t -> unit Deferred.Or_error.t +val get_pins : t -> Message_t.t list Deferred.Or_error.t +(* TODO more things related to guild channels *)
\ No newline at end of file diff --git a/lib/models/guild.ml b/lib/models/guild.ml index 60652df..c1b9925 100644 --- a/lib/models/guild.ml +++ b/lib/models/guild.ml @@ -1,129 +1,127 @@ -module Make(Http : S.Http) = struct - open Core - open Async - include Guild_t - - let ban_user ~id ?(reason="") ?(days=0) guild = - Http.guild_ban_add guild.id id (`Assoc [ - ("delete-message-days", `Int days); - ("reason", `String reason); - ]) >>| Result.map ~f:ignore - - let create_emoji ~name ~image guild = - Http.create_emoji guild.id (`Assoc [ - ("name", `String name); - ("image", `String image); - ("roles", `List []); - ]) >>| Result.map ~f:Emoji.of_yojson_exn - - let create_role ~name ?colour ?permissions ?hoist ?mentionable guild = - let payload = ("name", `String name) :: [] in - let payload = match permissions with - | Some p -> ("permissions", `Int p) :: payload - | None -> payload - in let payload = match colour with - | Some c -> ("color", `Int c) :: payload - | None -> payload - in let payload = match hoist with - | Some h -> ("hoist", `Bool h) :: payload - | None -> payload - in let payload = match mentionable with - | Some m -> ("mentionable", `Bool m) :: payload - | None -> payload - in Http.guild_role_add guild.id (`Assoc payload) - >>| Result.map ~f:(fun r -> Role_t.role_of_yojson_exn r |> Role_t.wrap ~guild_id:guild.id) - - let create_channel ~mode ~name guild = - let kind = match mode with - | `Text -> 0 - | `Voice -> 2 - | `Category -> 4 - in Http.create_guild_channel guild.id (`Assoc [ - ("name", `String name); - ("type", `Int kind); - ]) >>| Result.map ~f:Channel_t.of_yojson_exn - - let delete guild = - Http.delete_guild guild.id >>| Result.map ~f:ignore - - let get_ban ~id guild = - Http.get_ban guild.id id >>| Result.map ~f:Ban_t.of_yojson_exn - - let get_bans guild = - Http.get_bans guild.id >>| Result.map ~f:(fun bans -> - Yojson.Safe.Util.to_list bans - |> List.map ~f:Ban_t.of_yojson_exn) - - let get_channel ~id guild = - match List.find ~f:(fun c -> Channel_t.get_id c = id) guild.channels with - | Some c -> Deferred.Or_error.return c - | None -> Http.get_channel id >>| Result.map ~f:(fun c -> Channel_t.(channel_wrapper_of_yojson_exn c |> wrap)) - - let get_emoji ~id guild = - Http.get_emoji guild.id id >>| Result.map ~f:Emoji.of_yojson_exn - - (* TODO add invite abstraction? *) - let get_invites guild = - Http.get_guild_invites guild.id - - let get_member ~id guild = - match List.find ~f:(fun m -> m.user.id = id) guild.members with - | Some m -> Deferred.Or_error.return m - | None -> Http.get_member guild.id id >>| Result.map ~f:Member_t.of_yojson_exn - - let get_prune_count ~days guild = - Http.guild_prune_count guild.id days >>| Result.map ~f:(fun prune -> - Yojson.Safe.Util.(member "pruned" prune |> to_int)) - - (* TODO add HTTP fallback *) - let get_role ~id guild = - List.find ~f:(fun r -> r.id = id) guild.roles - - (* TODO add webhook abstraction? *) - let get_webhooks guild = - Http.get_guild_webhooks guild.id - - let kick_user ~id ?reason guild = - let payload = match reason with - | Some r -> `Assoc [("reason", `String r)] - | None -> `Null - in Http.remove_member guild.id id payload >>| Result.map ~f:ignore - - let leave guild = - Http.leave_guild guild.id - - (* TODO Voice region abstractions? *) - let list_voice_regions guild = - Http.get_guild_voice_regions guild.id - - let prune ~days guild = - Http.guild_prune_start guild.id days >>| Result.map ~f:(fun prune -> - Yojson.Safe.Util.(member "pruned" prune |> to_int)) - - let request_members guild = - Http.get_members guild.id >>| Result.map ~f:(fun members -> - Yojson.Safe.Util.to_list members - |> List.map ~f:Member_t.of_yojson_exn) - - let set_afk_channel ~id guild = Http.edit_guild guild.id (`Assoc [ - ("afk_channel_id", `Int id); - ]) >>| Result.map ~f:of_yojson_exn - - let set_afk_timeout ~timeout guild = Http.edit_guild guild.id (`Assoc [ - ("afk_timeout", `Int timeout); - ]) >>| Result.map ~f:of_yojson_exn - - let set_name ~name guild = Http.edit_guild guild.id (`Assoc [ +open Core +open Async +include Guild_t + +let ban_user ~id ?(reason="") ?(days=0) guild = + Http.guild_ban_add guild.id id (`Assoc [ + ("delete-message-days", `Int days); + ("reason", `String reason); + ]) >>| Result.map ~f:ignore + +let create_emoji ~name ~image guild = + Http.create_emoji guild.id (`Assoc [ ("name", `String name); - ]) >>| Result.map ~f:of_yojson_exn - - let set_icon ~icon guild = Http.edit_guild guild.id (`Assoc [ - ("icon", `String icon); - ]) >>| Result.map ~f:of_yojson_exn - - let unban_user ~id ?reason guild = - let payload = match reason with - | Some r -> `Assoc [("reason", `String r)] - | None -> `Null - in Http.guild_ban_remove guild.id id payload >>| Result.map ~f:ignore -end
\ No newline at end of file + ("image", `String image); + ("roles", `List []); + ]) >>| Result.map ~f:Emoji.of_yojson_exn + +let create_role ~name ?colour ?permissions ?hoist ?mentionable guild = + let payload = ("name", `String name) :: [] in + let payload = match permissions with + | Some p -> ("permissions", `Int p) :: payload + | None -> payload + in let payload = match colour with + | Some c -> ("color", `Int c) :: payload + | None -> payload + in let payload = match hoist with + | Some h -> ("hoist", `Bool h) :: payload + | None -> payload + in let payload = match mentionable with + | Some m -> ("mentionable", `Bool m) :: payload + | None -> payload + in Http.guild_role_add guild.id (`Assoc payload) + >>| Result.map ~f:(fun r -> Role_t.role_of_yojson_exn r |> Role_t.wrap ~guild_id:guild.id) + +let create_channel ~mode ~name guild = + let kind = match mode with + | `Text -> 0 + | `Voice -> 2 + | `Category -> 4 + in Http.create_guild_channel guild.id (`Assoc [ + ("name", `String name); + ("type", `Int kind); + ]) >>| Result.map ~f:Channel_t.of_yojson_exn + +let delete guild = + Http.delete_guild guild.id >>| Result.map ~f:ignore + +let get_ban ~id guild = + Http.get_ban guild.id id >>| Result.map ~f:Ban_t.of_yojson_exn + +let get_bans guild = + Http.get_bans guild.id >>| Result.map ~f:(fun bans -> + Yojson.Safe.Util.to_list bans + |> List.map ~f:Ban_t.of_yojson_exn) + +let get_channel ~id guild = + match List.find ~f:(fun c -> Channel_t.get_id c = id) guild.channels with + | Some c -> Deferred.Or_error.return c + | None -> Http.get_channel id >>| Result.map ~f:(fun c -> Channel_t.(channel_wrapper_of_yojson_exn c |> wrap)) + +let get_emoji ~id guild = + Http.get_emoji guild.id id >>| Result.map ~f:Emoji.of_yojson_exn + +(* TODO add invite abstraction? *) +let get_invites guild = + Http.get_guild_invites guild.id + +let get_member ~id guild = + match List.find ~f:(fun m -> m.user.id = id) guild.members with + | Some m -> Deferred.Or_error.return m + | None -> Http.get_member guild.id id >>| Result.map ~f:Member_t.of_yojson_exn + +let get_prune_count ~days guild = + Http.guild_prune_count guild.id days >>| Result.map ~f:(fun prune -> + Yojson.Safe.Util.(member "pruned" prune |> to_int)) + +(* TODO add HTTP fallback *) +let get_role ~id guild = + List.find ~f:(fun r -> r.id = id) guild.roles + +(* TODO add webhook abstraction? *) +let get_webhooks guild = + Http.get_guild_webhooks guild.id + +let kick_user ~id ?reason guild = + let payload = match reason with + | Some r -> `Assoc [("reason", `String r)] + | None -> `Null + in Http.remove_member guild.id id payload >>| Result.map ~f:ignore + +let leave guild = + Http.leave_guild guild.id + +(* TODO Voice region abstractions? *) +let list_voice_regions guild = + Http.get_guild_voice_regions guild.id + +let prune ~days guild = + Http.guild_prune_start guild.id days >>| Result.map ~f:(fun prune -> + Yojson.Safe.Util.(member "pruned" prune |> to_int)) + +let request_members guild = + Http.get_members guild.id >>| Result.map ~f:(fun members -> + Yojson.Safe.Util.to_list members + |> List.map ~f:Member_t.of_yojson_exn) + +let set_afk_channel ~id guild = Http.edit_guild guild.id (`Assoc [ + ("afk_channel_id", `Int id); + ]) >>| Result.map ~f:of_yojson_exn + +let set_afk_timeout ~timeout guild = Http.edit_guild guild.id (`Assoc [ + ("afk_timeout", `Int timeout); + ]) >>| Result.map ~f:of_yojson_exn + +let set_name ~name guild = Http.edit_guild guild.id (`Assoc [ + ("name", `String name); + ]) >>| Result.map ~f:of_yojson_exn + +let set_icon ~icon guild = Http.edit_guild guild.id (`Assoc [ + ("icon", `String icon); + ]) >>| Result.map ~f:of_yojson_exn + +let unban_user ~id ?reason guild = + let payload = match reason with + | Some r -> `Assoc [("reason", `String r)] + | None -> `Null + in Http.guild_ban_remove guild.id id payload >>| Result.map ~f:ignore
\ No newline at end of file diff --git a/lib/models/guild.mli b/lib/models/guild.mli new file mode 100644 index 0000000..daedc3c --- /dev/null +++ b/lib/models/guild.mli @@ -0,0 +1,34 @@ +open Async + +type t = Guild_t.t +val ban_user : id:Snowflake.t -> ?reason:string -> ?days:int -> t -> unit Deferred.Or_error.t +val create_emoji : name:string -> image:string -> t -> Emoji.t Deferred.Or_error.t +val create_role : + name:string -> + ?colour:int -> + ?permissions:int -> + ?hoist:bool -> + ?mentionable:bool -> + t -> + Role_t.t Deferred.Or_error.t +val create_channel : mode:[ `Text | `Voice | `Category ] -> name:string -> t -> Channel_t.t Deferred.Or_error.t +val delete : t -> unit Deferred.Or_error.t +val get_ban : id:Snowflake.t -> t -> Ban_t.t Deferred.Or_error.t +val get_bans : t -> Ban_t.t list Deferred.Or_error.t +val get_channel : id:Snowflake.t -> t -> Channel_t.t Deferred.Or_error.t +val get_emoji : id:Snowflake.t -> t -> Emoji.t Deferred.Or_error.t +val get_invites : t -> Yojson.Safe.json Deferred.Or_error.t +val get_member : id:Snowflake.t -> t -> Member_t.t Deferred.Or_error.t +val get_prune_count : days:int -> t -> int Deferred.Or_error.t +val get_role : id:Snowflake.t -> t -> Role_t.t option +val get_webhooks : t -> Yojson.Safe.json Deferred.Or_error.t +val kick_user : id:Snowflake.t -> ?reason:string -> t -> unit Deferred.Or_error.t +val leave : t -> Yojson.Safe.json Deferred.Or_error.t +val list_voice_regions : t -> Yojson.Safe.json Deferred.Or_error.t +val prune : days:int -> t -> int Deferred.Or_error.t +val request_members : t -> Member_t.t list Deferred.Or_error.t +val set_afk_channel : id:Snowflake.t -> t -> t Deferred.Or_error.t +val set_afk_timeout : timeout:int -> t -> t Deferred.Or_error.t +val set_name : name:string -> t -> t Deferred.Or_error.t +val set_icon : icon:string -> t -> t Deferred.Or_error.t +val unban_user : id:Snowflake.t -> ?reason:string -> t -> unit Deferred.Or_error.t
\ No newline at end of file diff --git a/lib/models/member.ml b/lib/models/member.ml index 40e82c2..881586b 100644 --- a/lib/models/member.ml +++ b/lib/models/member.ml @@ -1,45 +1,10 @@ -module Make(Http : S.Http) = struct - open Async - open Core - include Member_t - - let add_role ~(role:Role_t.t) member = - Http.add_member_role member.guild_id member.user.id role.id - >>| Result.map ~f:ignore - - let remove_role ~(role:Role_t.t) member = - Http.remove_member_role member.guild_id member.user.id role.id - >>| Result.map ~f:ignore - - let ban ?(reason="") ?(days=0) member = - Http.guild_ban_add member.guild_id member.user.id (`Assoc [ - ("delete-message-days", `Int days); - ("reason", `String reason); - ]) >>| Result.map ~f:ignore - - let kick ?reason member = - let payload = match reason with - | Some r -> `Assoc [("reason", `String r)] - | None -> `Null - in Http.remove_member member.guild_id member.user.id payload >>| Result.map ~f:ignore - - let mute member = - Http.edit_member member.guild_id member.user.id (`Assoc [ - ("mute", `Bool true); - ]) >>| Result.map ~f:ignore - - let deafen member = - Http.edit_member member.guild_id member.user.id (`Assoc [ - ("deaf", `Bool true); - ]) >>| Result.map ~f:ignore - - let unmute member = - Http.edit_member member.guild_id member.user.id (`Assoc [ - ("mute", `Bool false); - ]) >>| Result.map ~f:ignore - - let undeafen member = - Http.edit_member member.guild_id member.user.id (`Assoc [ - ("deaf", `Bool false); - ]) >>| Result.map ~f:ignore -end
\ No newline at end of file +include Member_t +(* val add_role : Member_t.t -> Role_t.t -> Yojson.Safe.json Deferred.t +val remove_role : Member_t.t -> Role_t.t -> Yojson.Safe.json Deferred.t +val ban : ?reason:string -> ?days:int -> Member_t.t -> Yojson.Safe.json Deferred.t +val ban : ?reason:string -> Member_t.t -> Yojson.Safe.json Deferred.t +val kick : ?reason:string -> Member_t.t -> Yojson.Safe.json Deferred.t +val mute : Member_t.t -> Yojson.Safe.json Deferred.t +val deafen : Member_t.t -> Yojson.Safe.json Deferred.t +val unmute : Member_t.t -> Yojson.Safe.json Deferred.t +val undeafen : Member_t.t -> Yojson.Safe.json Deferred.t *) diff --git a/lib/models/member.mli b/lib/models/member.mli new file mode 100644 index 0000000..627e903 --- /dev/null +++ b/lib/models/member.mli @@ -0,0 +1,10 @@ +type t = Member_t.t +(* val add_role : Member_t.t -> Role_t.t -> Yojson.Safe.json Deferred.Or_error.t +val remove_role : Member_t.t -> Role_t.t -> Yojson.Safe.json Deferred.Or_error.t +val ban : ?reason:string -> ?days:int -> Member_t.t -> Yojson.Safe.json Deferred.Or_error.t +val ban : ?reason:string -> Member_t.t -> Yojson.Safe.json Deferred.Or_error.t +val kick : ?reason:string -> Member_t.t -> Yojson.Safe.json Deferred.Or_error.t +val mute : Member_t.t -> Yojson.Safe.json Deferred.Or_error.t +val deafen : Member_t.t -> Yojson.Safe.json Deferred.Or_error.t +val unmute : Member_t.t -> Yojson.Safe.json Deferred.Or_error.t +val undeafen : Member_t.t -> Yojson.Safe.json Deferred.Or_error.t *)
\ No newline at end of file diff --git a/lib/models/message.ml b/lib/models/message.ml index bce361c..6cb54b4 100644 --- a/lib/models/message.ml +++ b/lib/models/message.ml @@ -1,42 +1,40 @@ -module Make(Http : S.Http) = struct - open Async - include Message_t - - let add_reaction msg (emoji:Emoji.t) = - let e = match emoji.id with - | Some i -> Printf.sprintf "%s:%d" emoji.name i - | None -> emoji.name - in - Http.create_reaction msg.channel_id msg.id e - - let remove_reaction msg (emoji:Emoji.t) (user:User_t.t) = - let e = match emoji.id with - | Some i -> Printf.sprintf "%s:%d" emoji.name i - | None -> emoji.name - in - Http.delete_reaction msg.channel_id msg.id e user.id - - let clear_reactions msg = - Http.delete_reactions msg.channel_id msg.id - - let delete msg = - Http.delete_message msg.channel_id msg.id - - let pin msg = - Http.pin_message msg.channel_id msg.id - - let unpin msg = - Http.unpin_message msg.channel_id msg.id - - let reply msg cont = - let rep = `Assoc [("content", `String cont)] in - Http.create_message msg.channel_id rep - - let set_content msg cont = - to_yojson { msg with content = cont; } - |> Http.edit_message msg.channel_id msg.id - - let set_embed msg embed = - to_yojson { msg with embeds = [embed]; } - |> Http.edit_message msg.channel_id msg.id -end
\ No newline at end of file +open Async +include Message_t + +let add_reaction msg (emoji:Emoji.t) = + let e = match emoji.id with + | Some i -> Printf.sprintf "%s:%d" emoji.name i + | None -> emoji.name + in + Http.create_reaction msg.channel_id msg.id e + +let remove_reaction msg (emoji:Emoji.t) (user:User_t.t) = + let e = match emoji.id with + | Some i -> Printf.sprintf "%s:%d" emoji.name i + | None -> emoji.name + in + Http.delete_reaction msg.channel_id msg.id e user.id + +let clear_reactions msg = + Http.delete_reactions msg.channel_id msg.id + +let delete msg = + Http.delete_message msg.channel_id msg.id + +let pin msg = + Http.pin_message msg.channel_id msg.id + +let unpin msg = + Http.unpin_message msg.channel_id msg.id + +let reply msg cont = + let rep = `Assoc [("content", `String cont)] in + Http.create_message msg.channel_id rep + +let set_content msg cont = + to_yojson { msg with content = cont; } + |> Http.edit_message msg.channel_id msg.id + +let set_embed msg embed = + to_yojson { msg with embeds = [embed]; } + |> Http.edit_message msg.channel_id msg.id
\ No newline at end of file diff --git a/lib/models/message.mli b/lib/models/message.mli new file mode 100644 index 0000000..c8c2155 --- /dev/null +++ b/lib/models/message.mli @@ -0,0 +1,12 @@ +open Async + +type t = Message_t.t +val add_reaction : t -> Emoji.t -> Yojson.Safe.json Deferred.Or_error.t +val remove_reaction : t -> Emoji.t -> User_t.t -> Yojson.Safe.json Deferred.Or_error.t +val clear_reactions : t -> Yojson.Safe.json Deferred.Or_error.t +val delete : t -> Yojson.Safe.json Deferred.Or_error.t +val pin : t -> Yojson.Safe.json Deferred.Or_error.t +val unpin : t -> Yojson.Safe.json Deferred.Or_error.t +val reply : t -> string -> Yojson.Safe.json Deferred.Or_error.t +val set_content : t -> string -> Yojson.Safe.json Deferred.Or_error.t +val set_embed : t -> Embed.t -> Yojson.Safe.json Deferred.Or_error.t
\ No newline at end of file diff --git a/lib/models/reaction.ml b/lib/models/reaction.ml index 3134bc3..c4ab326 100644 --- a/lib/models/reaction.ml +++ b/lib/models/reaction.ml @@ -1,6 +1 @@ -module Make(Http : S.Http) = struct - type t = Reaction_t.t - - (* let delete reaction user = - Http.delete_reaction *) -end
\ No newline at end of file +include Reaction_t
\ No newline at end of file diff --git a/lib/models/reaction.mli b/lib/models/reaction.mli new file mode 100644 index 0000000..08572df --- /dev/null +++ b/lib/models/reaction.mli @@ -0,0 +1,5 @@ +type t = Reaction_t.t +(* val delete : Reaction_t.t -> Yojson.Safe.json Deferred.Or_error.t +val get_users : Reaction_t.t -> int -> User_t.t list Deferred.Or_error.t +val get_users_after : Reaction_t.t -> Snowflake.t -> int -> User_t.t list Deferred.Or_error.t +val get_users_before : Reaction_t.t -> Snowflake.t -> int -> User_t.t list Deferred.Or_error.t *)
\ No newline at end of file diff --git a/lib/models/role.ml b/lib/models/role.ml index 1d641cb..ee6bb0a 100644 --- a/lib/models/role.ml +++ b/lib/models/role.ml @@ -1,27 +1,23 @@ -module Make(Http : S.Http) = struct - type role = Role_t.role - type role_update = Role_t.role_update - type t = Role_t.t +include Role_t - let edit_role ~body (role:t) = Http.guild_role_edit role.guild_id role.id body +let edit_role ~body (role:t) = Http.guild_role_edit role.guild_id role.id body - let allow_mention role = - edit_role ~body:(`Assoc [("mentionable", `Bool true)]) role +let allow_mention role = + edit_role ~body:(`Assoc [("mentionable", `Bool true)]) role - let delete (role:t) = Http.guild_role_remove role.guild_id role.id +let delete (role:t) = Http.guild_role_remove role.guild_id role.id - let disallow_mention role = - edit_role ~body:(`Assoc [("mentionable", `Bool false)]) role +let disallow_mention role = + edit_role ~body:(`Assoc [("mentionable", `Bool false)]) role - let hoist role = - edit_role ~body:(`Assoc [("hoist", `Bool true)]) role +let hoist role = + edit_role ~body:(`Assoc [("hoist", `Bool true)]) role - let set_colour ~colour role = - edit_role ~body:(`Assoc [("color", `Int colour)]) role +let set_colour ~colour role = + edit_role ~body:(`Assoc [("color", `Int colour)]) role - let set_name ~name role = - edit_role ~body:(`Assoc [("name", `String name)]) role +let set_name ~name role = + edit_role ~body:(`Assoc [("name", `String name)]) role - let unhoist role = - edit_role ~body:(`Assoc [("hoist", `Bool false)]) role -end
\ No newline at end of file +let unhoist role = + edit_role ~body:(`Assoc [("hoist", `Bool false)]) role
\ No newline at end of file diff --git a/lib/models/role.mli b/lib/models/role.mli new file mode 100644 index 0000000..5eca8c1 --- /dev/null +++ b/lib/models/role.mli @@ -0,0 +1,10 @@ +open Async + +type t = Role_t.t +val allow_mention : t -> Yojson.Safe.json Deferred.Or_error.t +val delete : t -> Yojson.Safe.json Deferred.Or_error.t +val disallow_mention : t -> Yojson.Safe.json Deferred.Or_error.t +val hoist : t -> Yojson.Safe.json Deferred.Or_error.t +val set_colour : colour:int -> t -> Yojson.Safe.json Deferred.Or_error.t +val set_name : name:string -> t -> Yojson.Safe.json Deferred.Or_error.t +val unhoist : t -> Yojson.Safe.json Deferred.Or_error.t
\ No newline at end of file diff --git a/lib/models/user.ml b/lib/models/user.ml index 8edcea1..bd6583c 100644 --- a/lib/models/user.ml +++ b/lib/models/user.ml @@ -1,22 +1,20 @@ -module Make(Http : S.Http) = struct - open Core - include User_t +open Core +include User_t - let tag user = - Printf.sprintf "%s#%s" user.username user.discriminator +let tag user = + Printf.sprintf "%s#%s" user.username user.discriminator - let mention user = - Printf.sprintf "<@%d>" user.id +let mention user = + Printf.sprintf "<@%d>" user.id - let default_avatar user = - let avatar = Int.of_string user.discriminator % 5 in - Endpoints.cdn_default_avatar avatar +let default_avatar user = + let avatar = Int.of_string user.discriminator % 5 in + Endpoints.cdn_default_avatar avatar - let face user = match user.avatar with - | Some avatar -> - let ext = if String.is_substring ~substring:"a_" avatar - then "gif" - else "png" in - Endpoints.cdn_avatar user.id avatar ext - | None -> default_avatar user -end
\ No newline at end of file +let face user = match user.avatar with + | Some avatar -> + let ext = if String.is_substring ~substring:"a_" avatar + then "gif" + else "png" in + Endpoints.cdn_avatar user.id avatar ext + | None -> default_avatar user
\ No newline at end of file diff --git a/lib/models/user.mli b/lib/models/user.mli new file mode 100644 index 0000000..af873e1 --- /dev/null +++ b/lib/models/user.mli @@ -0,0 +1,7 @@ +type t = User_t.t +val tag : t -> string +val mention : t -> string +val default_avatar : t -> string +val face : t -> string +(* val private_channel : t -> Channel_t.t *) +(* val send : t -> Yojson.Safe.json Deferred.Or_error.t *)
\ No newline at end of file diff --git a/lib/opcode.mli b/lib/opcode.mli new file mode 100644 index 0000000..e07f82e --- /dev/null +++ b/lib/opcode.mli @@ -0,0 +1,18 @@ +type t = + | DISPATCH + | HEARTBEAT + | IDENTIFY + | STATUS_UPDATE + | VOICE_STATE_UPDATE + | RESUME + | RECONNECT + | REQUEST_GUILD_MEMBERS + | INVALID_SESSION + | HELLO + | HEARTBEAT_ACK + +exception Invalid_Opcode of int + +val to_int : t -> int +val from_int : int -> t +val to_string : t -> string
\ No newline at end of file diff --git a/lib/rl.mli b/lib/rl.mli new file mode 100644 index 0000000..f583653 --- /dev/null +++ b/lib/rl.mli @@ -0,0 +1,19 @@ +open Core +open Async + +module RouteMap : module type of Map.Make(String) + +type rl = { + limit: int; + remaining: int; + reset: int; +} + +type t = ((rl, read_write) Mvar.t) RouteMap.t + +val rl_of_header : Cohttp.Header.t -> rl option +val default : rl +val empty : t +val update : 'a RouteMap.t -> string -> f:('a option -> 'a) -> 'a RouteMap.t +val find : 'a RouteMap.t -> string -> 'a option +val find_exn : 'a RouteMap.t -> string -> 'a
\ No newline at end of file diff --git a/lib/s.ml b/lib/s.ml deleted file mode 100644 index c1c4583..0000000 --- a/lib/s.ml +++ /dev/null @@ -1,396 +0,0 @@ -open Async - -module type ClientOptions = sig - val token : string -end - -module type Message = sig - type t = Message_t.t - val add_reaction : t -> Emoji.t -> Yojson.Safe.json Deferred.Or_error.t - val remove_reaction : t -> Emoji.t -> User_t.t -> Yojson.Safe.json Deferred.Or_error.t - val clear_reactions : t -> Yojson.Safe.json Deferred.Or_error.t - val delete : t -> Yojson.Safe.json Deferred.Or_error.t - val pin : t -> Yojson.Safe.json Deferred.Or_error.t - val unpin : t -> Yojson.Safe.json Deferred.Or_error.t - val reply : t -> string -> Yojson.Safe.json Deferred.Or_error.t - val set_content : t -> string -> Yojson.Safe.json Deferred.Or_error.t - val set_embed : t -> Embed.t -> Yojson.Safe.json Deferred.Or_error.t -end - -module type Ban = sig - type t = Ban_t.t -end - -module type Channel = sig - type t = Channel_t.t - val say : content:string -> t -> Message_t.t Deferred.Or_error.t - val send_message : - ?embed:Yojson.Safe.json -> - ?content:string -> - ?file:string -> - ?tts:bool -> - t -> - Message_t.t Deferred.Or_error.t - val delete : t -> unit Deferred.Or_error.t - val get_message : id:Snowflake.t -> t -> Message_t.t Deferred.Or_error.t - val get_messages : - ?mode:[ `Before | `After | `Around ] -> - ?id:Snowflake.t -> - ?limit:int -> - t -> - Message_t.t list Deferred.Or_error.t - val broadcast_typing : t -> unit Deferred.Or_error.t - val get_pins : t -> Message_t.t list Deferred.Or_error.t - (* TODO more things related to guild channels *) -end - -module type Member = sig - type t = Member_t.t - val add_role : role:Role_t.t -> Member_t.t -> unit Deferred.Or_error.t - val remove_role : role:Role_t.t -> Member_t.t -> unit Deferred.Or_error.t - val ban : ?reason:string -> ?days:int -> Member_t.t -> unit Deferred.Or_error.t - val kick : ?reason:string -> Member_t.t -> unit Deferred.Or_error.t - val deafen : Member_t.t -> unit Deferred.Or_error.t - val unmute : Member_t.t -> unit Deferred.Or_error.t - val undeafen : Member_t.t -> unit Deferred.Or_error.t -end - -module type Reaction = sig - type t = Reaction_t.t - (* val delete : Reaction_t.t -> Yojson.Safe.json Deferred.Or_error.t - val get_users : Reaction_t.t -> int -> User_t.t list Deferred.Or_error.t - val get_users_after : Reaction_t.t -> Snowflake.t -> int -> User_t.t list Deferred.Or_error.t - val get_users_before : Reaction_t.t -> Snowflake.t -> int -> User_t.t list Deferred.Or_error.t *) -end - -module type Role = sig - type t = Role_t.t - val allow_mention : t -> Yojson.Safe.json Deferred.Or_error.t - val delete : t -> Yojson.Safe.json Deferred.Or_error.t - val disallow_mention : t -> Yojson.Safe.json Deferred.Or_error.t - val hoist : t -> Yojson.Safe.json Deferred.Or_error.t - val set_colour : colour:int -> t -> Yojson.Safe.json Deferred.Or_error.t - val set_name : name:string -> t -> Yojson.Safe.json Deferred.Or_error.t - val unhoist : t -> Yojson.Safe.json Deferred.Or_error.t -end - -module type User = sig - type t = User_t.t - val tag : t -> string - val mention : t -> string - val default_avatar : t -> string - val face : t -> string - (* val private_channel : t -> Channel_t.t *) - (* val send : t -> Yojson.Safe.json Deferred.Or_error.t *) -end - -module type Guild = sig - type t = Guild_t.t - val ban_user : id:Snowflake.t -> ?reason:string -> ?days:int -> t -> unit Deferred.Or_error.t - val create_emoji : name:string -> image:string -> t -> Emoji.t Deferred.Or_error.t - val create_role : - name:string -> - ?colour:int -> - ?permissions:int -> - ?hoist:bool -> - ?mentionable:bool -> - t -> - Role_t.t Deferred.Or_error.t - val create_channel : mode:[ `Text | `Voice | `Category ] -> name:string -> t -> Channel_t.t Deferred.Or_error.t - val delete : t -> unit Deferred.Or_error.t - val get_ban : id:Snowflake.t -> t -> Ban_t.t Deferred.Or_error.t - val get_bans : t -> Ban_t.t list Deferred.Or_error.t - val get_channel : id:Snowflake.t -> t -> Channel_t.t Deferred.Or_error.t - val get_emoji : id:Snowflake.t -> t -> Emoji.t Deferred.Or_error.t - val get_invites : t -> Yojson.Safe.json Deferred.Or_error.t - val get_member : id:Snowflake.t -> t -> Member_t.t Deferred.Or_error.t - val get_prune_count : days:int -> t -> int Deferred.Or_error.t - val get_role : id:Snowflake.t -> t -> Role_t.t option - val get_webhooks : t -> Yojson.Safe.json Deferred.Or_error.t - val kick_user : id:Snowflake.t -> ?reason:string -> t -> unit Deferred.Or_error.t - val leave : t -> Yojson.Safe.json Deferred.Or_error.t - val list_voice_regions : t -> Yojson.Safe.json Deferred.Or_error.t - val prune : days:int -> t -> int Deferred.Or_error.t - val request_members : t -> Member_t.t list Deferred.Or_error.t - val set_afk_channel : id:Snowflake.t -> t -> t Deferred.Or_error.t - val set_afk_timeout : timeout:int -> t -> t Deferred.Or_error.t - val set_name : name:string -> t -> t Deferred.Or_error.t - val set_icon : icon:string -> t -> t Deferred.Or_error.t - val unban_user : id:Snowflake.t -> ?reason:string -> t -> unit Deferred.Or_error.t -end - -module type Http = sig - val token : string - - module Base : sig - exception Invalid_Method - - val base_url : string - - val process_url : string -> Uri.t - val process_request_body : Yojson.Safe.json -> Cohttp_async.Body.t - val process_request_headers : unit -> Cohttp.Header.t - - val process_response : - string -> - Cohttp_async.Response.t * Cohttp_async.Body.t -> - Yojson.Safe.json Deferred.Or_error.t - - val request : - ?body:Yojson.Safe.json -> - [> `DELETE | `GET | `PATCH | `POST | `PUT ] -> - string -> - Yojson.Safe.json Deferred.Or_error.t - end - - (* Auto-generated signatures *) - val get_gateway : unit -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val get_gateway_bot : unit -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val get_channel : int -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val modify_channel : - int -> Yojson.Safe.json -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val delete_channel : int -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val get_messages : int -> int -> string * int -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val get_message : int -> int -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val create_message : - int -> Yojson.Safe.json -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val create_reaction : - int -> int -> string -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val delete_own_reaction : - int -> int -> string -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val delete_reaction : - int -> int -> string -> int -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val get_reactions : - int -> int -> string -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val delete_reactions : - int -> int -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val edit_message : - int -> - int -> Yojson.Safe.json -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val delete_message : - int -> int -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val bulk_delete : - int -> Yojson.Safe.json -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val edit_channel_permissions : - int -> - int -> Yojson.Safe.json -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val get_channel_invites : int -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val create_channel_invite : - int -> Yojson.Safe.json -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val delete_channel_permission : - int -> int -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val broadcast_typing : int -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val get_pinned_messages : int -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val pin_message : int -> int -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val unpin_message : int -> int -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val group_recipient_add : - int -> int -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val group_recipient_remove : - int -> int -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val get_emojis : int -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val get_emoji : int -> int -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val create_emoji : - int -> Yojson.Safe.json -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val edit_emoji : - int -> - int -> Yojson.Safe.json -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val delete_emoji : int -> int -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val create_guild : - Yojson.Safe.json -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val get_guild : int -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val edit_guild : - int -> Yojson.Safe.json -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val delete_guild : int -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val get_guild_channels : int -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val create_guild_channel : - int -> Yojson.Safe.json -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val modify_guild_channel_positions : - int -> Yojson.Safe.json -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val get_member : int -> int -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val get_members : int -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val add_member : - int -> - int -> Yojson.Safe.json -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val edit_member : - int -> - int -> Yojson.Safe.json -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val remove_member : - int -> - int -> Yojson.Safe.json -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val change_nickname : - int -> Yojson.Safe.json -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val add_member_role : - int -> int -> int -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val remove_member_role : - int -> int -> int -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val get_bans : int -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val get_ban : int -> int -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val guild_ban_add : - int -> - int -> Yojson.Safe.json -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val guild_ban_remove : - int -> - int -> Yojson.Safe.json -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val get_roles : int -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val guild_role_add : - int -> Yojson.Safe.json -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val guild_roles_edit : - int -> Yojson.Safe.json -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val guild_role_edit : - int -> - int -> Yojson.Safe.json -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val guild_role_remove : - int -> int -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val guild_prune_count : - int -> int -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val guild_prune_start : - int -> int -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val get_guild_voice_regions : - int -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val get_guild_invites : int -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val get_integrations : int -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val add_integration : - int -> Yojson.Safe.json -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val edit_integration : - int -> - int -> Yojson.Safe.json -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val delete_integration : - int -> int -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val sync_integration : - int -> int -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val get_guild_embed : int -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val edit_guild_embed : - int -> Yojson.Safe.json -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val get_vanity_url : int -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val get_invite : string -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val delete_invite : string -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val get_current_user : unit -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val edit_current_user : - Yojson.Safe.json -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val get_guilds : unit -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val leave_guild : int -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val get_private_channels : - unit -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val create_dm : - Yojson.Safe.json -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val create_group_dm : - Yojson.Safe.json -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val get_connections : unit -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val get_user : int -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val get_voice_regions : unit -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val create_webhook : - int -> Yojson.Safe.json -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val get_channel_webhooks : int -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val get_guild_webhooks : int -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val get_webhook : int -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val get_webhook_with_token : - int -> string -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val edit_webhook : - int -> Yojson.Safe.json -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val edit_webhook_with_token : - int -> - string -> Yojson.Safe.json -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val delete_webhook : int -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val delete_webhook_with_token : - int -> string -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val execute_webhook : - int -> - string -> Yojson.Safe.json -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val execute_slack_webhook : - int -> - string -> Yojson.Safe.json -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val execute_git_webhook : - int -> - string -> Yojson.Safe.json -> Yojson.Safe.json Core.Or_error.t Conduit_async.io - val get_audit_logs : - int -> Yojson.Safe.json -> Yojson.Safe.json Core.Or_error.t Conduit_async.io -end - -module type Models = sig - module Ban : Ban - module Channel : Channel - module Guild : Guild - module Member : Member - module Message : Message - module Reaction : Reaction - module Role : Role - module User : User -end - -module type Handler = sig - val handle_event : - Event.t -> - unit -end - -module type Handler_f = sig - module Make(Models : Models) : Handler -end - -module type Dispatch = sig - val dispatch : ev:string -> Yojson.Safe.json -> unit -end - -module type Sharder = sig - exception Invalid_Payload - exception Failureo_Establish_Heartbeat - - type t - - val start : - ?count:int -> - unit -> - t Deferred.t - - module Shard : sig - type shard - type 'a t = { - mutable state: 'a; - mutable binds: ('a -> unit) list; - } - - val bind : - f:('a -> unit) -> - 'a t -> - unit - - val heartbeat : - shard -> - shard Deferred.t - - val set_status : - status:Yojson.Safe.json -> - shard -> - shard Deferred.t - - val request_guild_members : - ?query:string -> - ?limit:int -> - guild:Snowflake.t -> - shard -> - shard Deferred.t - - val create : - url:string -> - shards:int * int -> - unit -> - shard Deferred.t - end - - val set_status : - status:Yojson.Safe.json -> - t -> - Shard.shard list Deferred.t - - val set_status_with : - f:(Shard.shard -> Yojson.Safe.json) -> - t -> - Shard.shard list Deferred.t - - val request_guild_members : - ?query:string -> - ?limit:int -> - guild:Snowflake.t -> - t -> - Shard.shard list Deferred.t -end diff --git a/lib/sharder.ml b/lib/sharder.ml index f417f92..823fe28 100644 --- a/lib/sharder.ml +++ b/lib/sharder.ml @@ -1,341 +1,337 @@ -module Make(H : S.Http)(D : S.Dispatch) = struct - open Async - open Core - open Websocket_async +open Async +open Core +open Websocket_async - exception Invalid_Payload - exception Failure_to_Establish_Heartbeat +exception Invalid_Payload +exception Failure_to_Establish_Heartbeat - let token = H.token +module Shard = struct + type shard = { + hb: unit Ivar.t option; + seq: int; + session: string option; + pipe: Frame.t Pipe.Reader.t * Frame.t Pipe.Writer.t; + ready: unit Ivar.t; + url: string; + id: int * int; + } - module Shard = struct - type shard = { - hb: unit Ivar.t option; - seq: int; - session: string option; - pipe: Frame.t Pipe.Reader.t * Frame.t Pipe.Writer.t; - ready: unit Ivar.t; - url: string; - id: int * int; - } + type 'a t = { + mutable state: 'a; + } - type 'a t = { - mutable state: 'a; - } + let identify_lock = Mutex.create () - let identify_lock = Mutex.create () + let parse (frame:[`Ok of Frame.t | `Eof]) = + match frame with + | `Ok s -> begin + let open Frame.Opcode in + match s.opcode with + | Text -> Some (Yojson.Safe.from_string s.content) + | _ -> None + end + | `Eof -> None - let parse (frame:[`Ok of Frame.t | `Eof]) = - match frame with - | `Ok s -> begin - let open Frame.Opcode in - match s.opcode with - | Text -> Some (Yojson.Safe.from_string s.content) - | _ -> None - end - | `Eof -> None + let push_frame ?payload ~ev shard = + print_endline @@ "Pushing frame. OP: " ^ Opcode.to_string @@ ev; + let content = match payload with + | None -> "" + | Some p -> + Yojson.Safe.to_string @@ `Assoc [ + ("op", `Int (Opcode.to_int ev)); + ("d", p); + ] + in + let (_, write) = shard.pipe in + Pipe.write write @@ Frame.create ~content () + >>| fun () -> + shard - let push_frame ?payload ~ev shard = - print_endline @@ "Pushing frame. OP: " ^ Opcode.to_string @@ ev; - let content = match payload with - | None -> "" - | Some p -> - Yojson.Safe.to_string @@ `Assoc [ - ("op", `Int (Opcode.to_int ev)); - ("d", p); - ] - in - let (_, write) = shard.pipe in - Pipe.write write @@ Frame.create ~content () - >>| fun () -> - shard + let heartbeat shard = + let payload = match shard.seq with + | 0 -> `Null + | i -> `Int i + in + push_frame ~payload ~ev:HEARTBEAT shard - let heartbeat shard = - let payload = match shard.seq with - | 0 -> `Null - | i -> `Int i - in - push_frame ~payload ~ev:HEARTBEAT shard + let dispatch ~payload shard = + let module J = Yojson.Safe.Util in + let seq = J.(member "s" payload |> to_int) in + let t = J.(member "t" payload |> to_string) in + let data = J.member "d" payload in + let session = if t = "READY" then begin + Ivar.fill_if_empty shard.ready (); + J.(member "session_id" data |> to_string_option) + end else None in + Event.handle_event ~ev:t data; + return { shard with + seq = seq; + session = session; + } - let dispatch ~payload shard = - let module J = Yojson.Safe.Util in - let seq = J.(member "s" payload |> to_int) in - let t = J.(member "t" payload |> to_string) in - let data = J.member "d" payload in - let session = if t = "READY" then begin - Ivar.fill_if_empty shard.ready (); - J.(member "session_id" data |> to_string_option) - end else None in - D.dispatch ~ev:t data; - return { shard with - seq = seq; - session = session; - } + let set_status ~(status:Yojson.Safe.json) shard = + let payload = match status with + | `Assoc [("name", `String name); ("type", `Int t)] -> + `Assoc [ + ("status", `String "online"); + ("afk", `Bool false); + ("since", `Null); + ("game", `Assoc [ + ("name", `String name); + ("type", `Int t) + ]) + ] + | `String name -> + `Assoc [ + ("status", `String "online"); + ("afk", `Bool false); + ("since", `Null); + ("game", `Assoc [ + ("name", `String name); + ("type", `Int 0) + ]) + ] + | _ -> raise Invalid_Payload + in + Ivar.read shard.ready >>= fun _ -> + push_frame ~payload ~ev:STATUS_UPDATE shard - let set_status ~(status:Yojson.Safe.json) shard = - let payload = match status with - | `Assoc [("name", `String name); ("type", `Int t)] -> - `Assoc [ - ("status", `String "online"); - ("afk", `Bool false); - ("since", `Null); - ("game", `Assoc [ - ("name", `String name); - ("type", `Int t) - ]) - ] - | `String name -> - `Assoc [ - ("status", `String "online"); - ("afk", `Bool false); - ("since", `Null); - ("game", `Assoc [ - ("name", `String name); - ("type", `Int 0) - ]) - ] - | _ -> raise Invalid_Payload - in - Ivar.read shard.ready >>= fun _ -> - push_frame ~payload ~ev:STATUS_UPDATE shard + let request_guild_members ?(query="") ?(limit=0) ~guild shard = + let payload = `Assoc [ + ("guild_id", `String (Int.to_string guild)); + ("query", `String query); + ("limit", `Int limit); + ] in + Ivar.read shard.ready >>= fun _ -> + push_frame ~payload ~ev:REQUEST_GUILD_MEMBERS shard - let request_guild_members ?(query="") ?(limit=0) ~guild shard = + let initialize ?data shard = + let module J = Yojson.Safe.Util in + let hb = match shard.hb with + | None -> begin + match data with + | Some data -> + let hb_interval = J.(member "heartbeat_interval" data |> to_int) in + let stop_hb = Ivar.create () in + let stopper i = + Ivar.read stop_hb + >>> fun () -> + Ivar.fill_if_empty i () + in + let stop = Deferred.create stopper in + Clock.every' + ~continue_on_error:true + ~stop + (Core.Time.Span.create ~ms:hb_interval ()) + (fun () -> heartbeat shard >>= fun _ -> return ()); + stop_hb + | None -> raise Failure_to_Establish_Heartbeat + end + | Some s -> s + in + let shard = { shard with hb = Some hb; } in + let (cur, max) = shard.id in + let shards = [`Int cur; `Int max] in + match shard.session with + | None -> begin + Mutex.lock identify_lock; let payload = `Assoc [ - ("guild_id", `String (Int.to_string guild)); - ("query", `String query); - ("limit", `Int limit); + ("token", `String !Config.token); + ("properties", `Assoc [ + ("$os", `String Sys.os_type); + ("$device", `String "dis.ml"); + ("$browser", `String "dis.ml") + ]); + ("compress", `Bool false); (* TODO add compression handling*) + ("large_threshold", `Int 250); + ("shard", `List shards); ] in - Ivar.read shard.ready >>= fun _ -> - push_frame ~payload ~ev:REQUEST_GUILD_MEMBERS shard - - let initialize ?data shard = - let module J = Yojson.Safe.Util in - let hb = match shard.hb with - | None -> begin - match data with - | Some data -> - let hb_interval = J.(member "heartbeat_interval" data |> to_int) in - let stop_hb = Ivar.create () in - let stopper i = - Ivar.read stop_hb - >>> fun () -> - Ivar.fill_if_empty i () - in - let stop = Deferred.create stopper in - Clock.every' - ~continue_on_error:true - ~stop - (Core.Time.Span.create ~ms:hb_interval ()) - (fun () -> heartbeat shard >>= fun _ -> return ()); - stop_hb - | None -> raise Failure_to_Establish_Heartbeat - end - | Some s -> s - in - let shard = { shard with hb = Some hb; } in - let (cur, max) = shard.id in - let shards = [`Int cur; `Int max] in - match shard.session with - | None -> begin - Mutex.lock identify_lock; - let payload = `Assoc [ - ("token", `String token); - ("properties", `Assoc [ - ("$os", `String Sys.os_type); - ("$device", `String "dis.ml"); - ("$browser", `String "dis.ml") - ]); - ("compress", `Bool false); (* TODO add compression handling*) - ("large_threshold", `Int 250); - ("shard", `List shards); - ] in - push_frame ~payload ~ev:IDENTIFY shard - >>| fun s -> begin - Clock.after (Core.Time.Span.create ~sec:5 ()) - >>> (fun _ -> Mutex.unlock identify_lock); - s - end + push_frame ~payload ~ev:IDENTIFY shard + >>| fun s -> begin + Clock.after (Core.Time.Span.create ~sec:5 ()) + >>> (fun _ -> Mutex.unlock identify_lock); + s end - | Some s -> - let payload = `Assoc [ - ("token", `String token); - ("session_id", `String s); - ("seq", `Int shard.seq) - ] in - push_frame ~payload ~ev:RESUME shard + end + | Some s -> + let payload = `Assoc [ + ("token", `String !Config.token); + ("session_id", `String s); + ("seq", `Int shard.seq) + ] in + push_frame ~payload ~ev:RESUME shard - let handle_frame ~f shard = - let module J = Yojson.Safe.Util in - let op = J.(member "op" f |> to_int) - |> Opcode.from_int - in - match op with - | DISPATCH -> dispatch ~payload:f shard - | HEARTBEAT -> heartbeat shard - | INVALID_SESSION -> begin - if J.(member "d" f |> to_bool) then - initialize shard - else begin - initialize { shard with session = None; } - end + let handle_frame ~f shard = + let module J = Yojson.Safe.Util in + let op = J.(member "op" f |> to_int) + |> Opcode.from_int + in + match op with + | DISPATCH -> dispatch ~payload:f shard + | HEARTBEAT -> heartbeat shard + | INVALID_SESSION -> begin + if J.(member "d" f |> to_bool) then + initialize shard + else begin + initialize { shard with session = None; } end - | RECONNECT -> initialize shard - | HELLO -> initialize ~data:(J.member "d" f) shard - | HEARTBEAT_ACK -> return shard - | opcode -> - print_endline @@ "Invalid Opcode: " ^ Opcode.to_string opcode; - return shard + end + | RECONNECT -> initialize shard + | HELLO -> initialize ~data:(J.member "d" f) shard + | HEARTBEAT_ACK -> return shard + | opcode -> + print_endline @@ "Invalid Opcode: " ^ Opcode.to_string opcode; + return shard - let rec make_client + let rec make_client + ~initialized + ~extra_headers + ~app_to_ws + ~ws_to_app + ~net_to_ws + ~ws_to_net + uri = + client ~initialized ~extra_headers ~app_to_ws ~ws_to_app ~net_to_ws ~ws_to_net - uri = - client + uri + >>> fun res -> + match res with + | Ok () -> () + | Error _ -> + let backoff = Time.Span.create ~ms:500 () in + Clock.after backoff >>> (fun () -> + make_client + ~initialized + ~extra_headers + ~app_to_ws + ~ws_to_app + ~net_to_ws + ~ws_to_net + uri) + + + let create ~url ~shards () = + let open Core in + let uri = (url ^ "?v=6&encoding=json") |> Uri.of_string in + let extra_headers = Http.Base.process_request_headers () in + let host = Option.value_exn ~message:"no host in uri" Uri.(host uri) in + let port = + match Uri.port uri, Uri_services.tcp_port_of_uri uri with + | Some p, _ -> p + | None, Some p -> p + | _ -> 443 in + let scheme = Option.value_exn ~message:"no scheme in uri" Uri.(scheme uri) in + let tcp_fun (net_to_ws, ws_to_net) = + let (app_to_ws, write) = Pipe.create () in + let (read, ws_to_app) = Pipe.create () in + let initialized = Ivar.create () in + make_client ~initialized ~extra_headers ~app_to_ws ~ws_to_app ~net_to_ws ~ws_to_net - uri - >>> fun res -> - match res with - | Ok () -> () - | Error _ -> - let backoff = Time.Span.create ~ms:500 () in - Clock.after backoff >>> (fun () -> - make_client - ~initialized - ~extra_headers - ~app_to_ws - ~ws_to_app - ~net_to_ws - ~ws_to_net - uri) - - - let create ~url ~shards () = - let open Core in - let uri = (url ^ "?v=6&encoding=json") |> Uri.of_string in - let extra_headers = H.Base.process_request_headers () in - let host = Option.value_exn ~message:"no host in uri" Uri.(host uri) in - let port = - match Uri.port uri, Uri_services.tcp_port_of_uri uri with - | Some p, _ -> p - | None, Some p -> p - | _ -> 443 in - let scheme = Option.value_exn ~message:"no scheme in uri" Uri.(scheme uri) in - let tcp_fun (net_to_ws, ws_to_net) = - let (app_to_ws, write) = Pipe.create () in - let (read, ws_to_app) = Pipe.create () in - let initialized = Ivar.create () in - make_client - ~initialized - ~extra_headers - ~app_to_ws - ~ws_to_app - ~net_to_ws - ~ws_to_net - uri; - Ivar.read initialized >>| fun () -> - { - pipe = (read, write); - ready = Ivar.create (); - hb = None; - seq = 0; - id = shards; - session = None; - url; - } + uri; + Ivar.read initialized >>| fun () -> + { + pipe = (read, write); + ready = Ivar.create (); + hb = None; + seq = 0; + id = shards; + session = None; + url; + } + in + match Unix.getaddrinfo host (string_of_int port) [] with + | [] -> failwithf "DNS resolution failed for %s" host () + | { ai_addr; _ } :: _ -> + let addr = + match scheme, ai_addr with + | _, ADDR_UNIX path -> `Unix_domain_socket path + | "https", ADDR_INET (h, p) + | "wss", ADDR_INET (h, p) -> + let h = Ipaddr_unix.of_inet_addr h in + `OpenSSL (h, p, Conduit_async.V2.Ssl.Config.create ()) + | _, ADDR_INET (h, p) -> + let h = Ipaddr_unix.of_inet_addr h in + `TCP (h, p) in - match Unix.getaddrinfo host (string_of_int port) [] with - | [] -> failwithf "DNS resolution failed for %s" host () - | { ai_addr; _ } :: _ -> - let addr = - match scheme, ai_addr with - | _, ADDR_UNIX path -> `Unix_domain_socket path - | "https", ADDR_INET (h, p) - | "wss", ADDR_INET (h, p) -> - let h = Ipaddr_unix.of_inet_addr h in - `OpenSSL (h, p, Conduit_async.V2.Ssl.Config.create ()) - | _, ADDR_INET (h, p) -> - let h = Ipaddr_unix.of_inet_addr h in - `TCP (h, p) - in - Conduit_async.V2.connect addr >>= tcp_fun + Conduit_async.V2.connect addr >>= tcp_fun - let recreate shard = - print_endline "Reconnecting..."; - (match shard.hb with - | Some hb -> Ivar.fill_if_empty hb () - | None -> () - ); - create ~url:(shard.url) ~shards:(shard.id) () - end + let recreate shard = + print_endline "Reconnecting..."; + (match shard.hb with + | Some hb -> Ivar.fill_if_empty hb () + | None -> () + ); + create ~url:(shard.url) ~shards:(shard.id) () +end - type t = { - shards: (Shard.shard Shard.t) list; - } +type t = { + shards: (Shard.shard Shard.t) list; +} - let start ?count () = - let module J = Yojson.Safe.Util in - H.get_gateway_bot () >>= fun data -> - let data = match data with - | Ok d -> d - | Error e -> Error.raise e - in - let url = J.(member "url" data |> to_string) in - let count = match count with - | Some c -> c - | None -> J.(member "shards" data |> to_int) - in - let shard_list = (0, count) in - let rec ev_loop (t:Shard.shard Shard.t) = - let (read, _) = t.state.pipe in - Pipe.read read - >>= fun frame -> - (match Shard.parse frame with - | Some f -> begin - Shard.handle_frame ~f t.state - >>| fun s -> (t.state <- s; t) - end - | None -> begin - Shard.recreate t.state - >>| fun s -> (t.state <- s; t) - end) - >>= fun t -> - ev_loop t - in - let rec gen_shards l a = - match l with - | (id, total) when id >= total -> return a - | (id, total) -> - Shard.create ~url ~shards:(id, total) () - >>= fun shard -> - let t = Shard.{ state = shard; } in - ev_loop t >>> ignore; - gen_shards (id+1, total) (t :: a) - in - gen_shards shard_list [] - >>| fun shards -> - { shards; } +let start ?count () = + let module J = Yojson.Safe.Util in + Http.get_gateway_bot () >>= fun data -> + let data = match data with + | Ok d -> d + | Error e -> Error.raise e + in + let url = J.(member "url" data |> to_string) in + let count = match count with + | Some c -> c + | None -> J.(member "shards" data |> to_int) + in + let shard_list = (0, count) in + let rec ev_loop (t:Shard.shard Shard.t) = + let (read, _) = t.state.pipe in + Pipe.read read + >>= fun frame -> + (match Shard.parse frame with + | Some f -> begin + Shard.handle_frame ~f t.state + >>| fun s -> (t.state <- s; t) + end + | None -> begin + Shard.recreate t.state + >>| fun s -> (t.state <- s; t) + end) + >>= fun t -> + ev_loop t + in + let rec gen_shards l a = + match l with + | (id, total) when id >= total -> return a + | (id, total) -> + Shard.create ~url ~shards:(id, total) () + >>= fun shard -> + let t = Shard.{ state = shard; } in + ev_loop t >>> ignore; + gen_shards (id+1, total) (t :: a) + in + gen_shards shard_list [] + >>| fun shards -> + { shards; } - let set_status ~status sharder = - Deferred.all @@ List.map ~f:(fun t -> - Shard.set_status ~status t.state - ) sharder.shards +let set_status ~status sharder = + Deferred.all @@ List.map ~f:(fun t -> + Shard.set_status ~status t.state + ) sharder.shards - let set_status_with ~f sharder = - Deferred.all @@ List.map ~f:(fun t -> - Shard.set_status ~status:(f t.state) t.state - ) sharder.shards +let set_status_with ~f sharder = + Deferred.all @@ List.map ~f:(fun t -> + Shard.set_status ~status:(f t.state) t.state + ) sharder.shards - let request_guild_members ?query ?limit ~guild sharder = - Deferred.all @@ List.map ~f:(fun t -> - Shard.request_guild_members ~guild ?query ?limit t.state - ) sharder.shards -end
\ No newline at end of file +let request_guild_members ?query ?limit ~guild sharder = + Deferred.all @@ List.map ~f:(fun t -> + Shard.request_guild_members ~guild ?query ?limit t.state + ) sharder.shards
\ No newline at end of file diff --git a/lib/sharder.mli b/lib/sharder.mli new file mode 100644 index 0000000..554ed73 --- /dev/null +++ b/lib/sharder.mli @@ -0,0 +1,57 @@ +open Async + +exception Invalid_Payload +exception Failure_to_Establish_Heartbeat + +type t + +val start : + ?count:int -> + unit -> + t Deferred.t + +module Shard : sig + type shard + type 'a t = { + mutable state: 'a; + } + + val heartbeat : + shard -> + shard Deferred.t + + val set_status : + status:Yojson.Safe.json -> + shard -> + shard Deferred.t + + val request_guild_members : + ?query:string -> + ?limit:int -> + guild:Snowflake.t -> + shard -> + shard Deferred.t + + val create : + url:string -> + shards:int * int -> + unit -> + shard Deferred.t +end + +val set_status : + status:Yojson.Safe.json -> + t -> + Shard.shard list Deferred.t + +val set_status_with : + f:(Shard.shard -> Yojson.Safe.json) -> + t -> + Shard.shard list Deferred.t + +val request_guild_members : + ?query:string -> + ?limit:int -> + guild:Snowflake.t -> + t -> + Shard.shard list Deferred.t
\ No newline at end of file |