aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAdelyn Breelove <[email protected]>2019-01-17 09:47:39 -0700
committerAdelyn Breelove <[email protected]>2019-01-17 09:47:39 -0700
commit8760c74b63eb44acad13829ef41b2e705f031ecb (patch)
tree90240eaaafc8f033c707fa00fdb3837ba485c0b9 /lib
parentMember methods are here (diff)
parentnew event dispatching (diff)
downloaddisml-8760c74b63eb44acad13829ef41b2e705f031ecb.tar.xz
disml-8760c74b63eb44acad13829ef41b2e705f031ecb.zip
Resolve non-ff merge
Diffstat (limited to 'lib')
-rw-r--r--lib/client.ml42
-rw-r--r--lib/config.ml37
-rw-r--r--lib/config.mli37
-rw-r--r--lib/dispatch.ml9
-rw-r--r--lib/dune2
-rw-r--r--lib/endpoints.mli61
-rw-r--r--lib/event.ml53
-rw-r--r--lib/http.ml502
-rw-r--r--lib/http.mli185
-rw-r--r--lib/models.ml10
-rw-r--r--lib/models/ban.ml4
-rw-r--r--lib/models/ban.mli1
-rw-r--r--lib/models/channel.ml116
-rw-r--r--lib/models/channel.mli22
-rw-r--r--lib/models/guild.ml254
-rw-r--r--lib/models/guild.mli34
-rw-r--r--lib/models/member.ml55
-rw-r--r--lib/models/member.mli10
-rw-r--r--lib/models/message.ml82
-rw-r--r--lib/models/message.mli12
-rw-r--r--lib/models/reaction.ml7
-rw-r--r--lib/models/reaction.mli5
-rw-r--r--lib/models/role.ml34
-rw-r--r--lib/models/role.mli10
-rw-r--r--lib/models/user.ml34
-rw-r--r--lib/models/user.mli7
-rw-r--r--lib/opcode.mli18
-rw-r--r--lib/rl.mli19
-rw-r--r--lib/s.ml396
-rw-r--r--lib/sharder.ml606
-rw-r--r--lib/sharder.mli57
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
diff --git a/lib/dune b/lib/dune
index 0e28b0b..275cdae 100644
--- a/lib/dune
+++ b/lib/dune
@@ -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