B22T6OTOYMTCUQJGC4DVNB2FNKIYQHLU3I7H2OBWTNLX5WT2Y5RQC
let _FRAME_SIZE = _SAMPLE_RATE / 1000 * _FRAME_LEN
(** Maximum packet size for a voice packet.
Set a safe amount below the Ethernet MTU to avoid fragmentation/rejection. *)
let _VOICE_PACKET_MAX = 1460
(* https://tools.ietf.org/html/rfc7587#section-4.2 *)
let ts_incr = Uint32.of_int @@ (48000 / 1000 * _FRAME_LEN)
[@@deriving yojson] [@@yojson.allow_extra_fields]
[@@deriving of_yojson, show] [@@yojson.allow_extra_fields]
end
module Channel_pins_update = struct
type t = {
guild_id : Models.Snowflake.t option; [@yojson.option]
channel_id : Models.Snowflake.t;
last_pin_timestamp : int option option; [@yojson.option]
}
[@@deriving of_yojson, show] [@@yojson.allow_extra_fields]
end
module Guild_user = struct
type t = { guild_id : Models.Snowflake.t; user : Models.User.t }
[@@deriving of_yojson, show] [@@yojson.allow_extra_fields]
end
module Guild_emojis = struct
type t = { guild_id : Models.Snowflake.t; emojis : Models.Emoji.t list }
[@@deriving of_yojson, show] [@@yojson.allow_extra_fields]
end
module Guild_member_update = struct
type t = {
guild_id : Models.Snowflake.t;
roles : Models.Snowflake.t list;
user : Models.User.t;
nick : string option option; [@yojson.option]
joined_at : string;
premium_since : string option option; [@yojson.option]
pending : bool option; [@yojson.option]
}
[@@deriving of_yojson, show] [@@yojson.allow_extra_fields]
end
module Presence = struct
type t = {
user : Models.User.partial;
guild_id : Models.Snowflake.t;
status : Models.Presence_status.unsupported;
activities : Models.Activity.t list;
client_status : client_status;
}
and client_status = {
desktop : Models.Presence_status.unsupported option; [@yojson]
mobile : Models.Presence_status.unsupported option; [@yojson]
web : Models.Presence_status.unsupported option; [@yojson]
}
[@@deriving of_yojson, show] [@@yojson.allow_extra_fields]
end
module Guild_members_chunk = struct
type t = {
guild_id : Models.Snowflake.t;
members : Models.Guild_member.t list;
chunk_index : int;
chunk_count : int;
not_found : Models.Snowflake.t list option; [@yojson.option]
presences : Presence.t list option; [@yojson.option]
nonce : string option; [@yojson.option]
}
[@@deriving of_yojson, show] [@@yojson.allow_extra_fields]
end
module Guild_role = struct
type t = { guild_id : Models.Snowflake.t; role : Models.Role.t }
[@@deriving of_yojson, show] [@@yojson.allow_extra_fields]
end
module Guild_role_id = struct
type t = { guild_id : Models.Snowflake.t; role_id : Models.Snowflake.t }
[@@deriving of_yojson, show] [@@yojson.allow_extra_fields]
end
type guild_obj = { guild_id : Models.Snowflake.t }
[@@deriving yojson, show] [@@yojson.allow_extra]
module Message_delete = struct
type t = {
id : Models.Snowflake.t;
channel_id : Models.Snowflake.t;
guild_id : Models.Snowflake.t option; [@yojson.option]
}
[@@deriving of_yojson, show] [@@yojson.allow_extra_fields]
end
module Message_delete_bulk = struct
type t = {
ids : Models.Snowflake.t list;
channel_id : Models.Snowflake.t;
guild_id : Models.Snowflake.t option; [@yojson.option]
}
[@@deriving of_yojson, show] [@@yojson.allow_extra_fields]
end
module Message_reaction_add = struct
type t = {
user_id : Models.Snowflake.t;
channel_id : Models.Snowflake.t;
message_id : Models.Snowflake.t;
guild_id : Models.Snowflake.t option; [@yojson.option]
member : Models.Guild_member.t option; [@yojson.option]
emoji : Models.Emoji.reaction;
}
[@@deriving of_yojson, show] [@@yojson.allow_extra_fields]
end
module Message_reaction_remove = struct
type t = {
user_id : Models.Snowflake.t;
channel_id : Models.Snowflake.t;
message_id : Models.Snowflake.t;
guild_id : Models.Snowflake.t option; [@yojson.option]
emoji : Models.Emoji.reaction;
}
[@@deriving of_yojson, show] [@@yojson.allow_extra_fields]
end
module Message_reaction_remove_all = struct
type t = {
channel_id : Models.Snowflake.t;
message_id : Models.Snowflake.t;
guild_id : Models.Snowflake.t option; [@yojson.option]
}
[@@deriving of_yojson, show] [@@yojson.allow_extra_fields]
end
module Message_reaction_remove_emoji = struct
type t = {
channel_id : Models.Snowflake.t;
message_id : Models.Snowflake.t;
guild_id : Models.Snowflake.t option; [@yojson.option]
emoji : Models.Emoji.reaction;
}
[@@deriving of_yojson, show] [@@yojson.allow_extra_fields]
end
module Typing_start = struct
type t = {
channel_id : Models.Snowflake.t;
guild_id : Models.Snowflake.t option; [@yojson.option]
user_id : Models.Snowflake.t;
timestamp : int;
member : Models.Guild_member.t option; [@yojson.option]
}
[@@deriving of_yojson, show] [@@yojson.allow_extra_fields]
| VoiceStateUpdate of VoiceState.t
| VoiceServerUpdate of VoiceServerUpdate.t
(* channels *)
| Channel_create of Models.Channel.t
| Channel_update of Models.Channel.t
| Channel_delete of Models.Channel.t
| Channel_pins_update of Channel_pins_update.t
(* guilds *)
| Guild_create of Models.Guild.t
| Guild_update of Models.Guild.t
| Guild_delete of Models.Guild.unavailable
| Guild_ban_add of Guild_user.t
| Guild_ban_remove of Guild_user.t
| Guild_emojis_update of Guild_emojis.t
| Guild_integrations_update of Models.Snowflake.t
| Guild_member_add of {
guild_id : Models.Snowflake.t;
member : Models.Guild_member.t;
}
| Guild_member_remove of Guild_user.t
| Guild_member_update of Guild_member_update.t
| Guild_members_chunk of Guild_members_chunk.t
| Guild_role_create of Guild_role.t
| Guild_role_update of Guild_role.t
| Guild_role_delete of Guild_role_id.t
(* TODO invites *)
| Invite_create
| Invite_delete
(* messages *)
| Message_create of Models.Message.t
| Message_update of Models.Message.partial
| Message_delete of Message_delete.t
| Message_delete_bulk of Message_delete_bulk.t
| Message_reaction_add of Message_reaction_add.t
| Message_reaction_remove of Message_reaction_remove.t
| Message_reaction_remove_all of Message_reaction_remove_all.t
| Message_reaction_remove_emoji of Message_reaction_remove_emoji.t
(* users *)
| Presence_update of Presence.t
| Typing_start of Typing_start.t
| User_update of Models.User.t
(* voice *)
| Voice_state_update of Voice_state.t
| Voice_server_update of Voice_server_update.t
(* TODO webhooks *)
| Webhooks_update
(* TODO commands *)
| Application_command_create
| Application_command_update
| Application_command_delete
(* TODO interactions *)
| Interaction_create
| "VOICE_STATE_UPDATE", Some d -> VoiceStateUpdate (VoiceState.t_of_yojson d)
(* channels *)
| "CHANNEL_CREATE", Some d -> Channel_create (Models.Channel.t_of_yojson d)
| "CHANNEL_UPDATE", Some d -> Channel_update (Models.Channel.t_of_yojson d)
| "CHANNEL_DELETE", Some d -> Channel_delete (Models.Channel.t_of_yojson d)
| "CHANNEL_PINS_UPDATE", Some d ->
Channel_pins_update (Channel_pins_update.t_of_yojson d)
(* guilds *)
| "GUILD_CREATE", Some d -> Guild_create (Models.Guild.t_of_yojson d)
| "GUILD_UPDATE", Some d -> Guild_update (Models.Guild.t_of_yojson d)
| "GUILD_DELETE", Some d ->
Guild_delete (Models.Guild.unavailable_of_yojson d)
| "GUILD_BAN_ADD", Some d -> Guild_ban_add (Guild_user.t_of_yojson d)
| "GUILD_BAN_REMOVE", Some d -> Guild_ban_remove (Guild_user.t_of_yojson d)
| "GUILD_EMOJIS_UPDATE", Some d ->
Guild_emojis_update (Guild_emojis.t_of_yojson d)
| "GUILD_INTEGRATIONS_UPDATE", Some d ->
let { guild_id } = guild_obj_of_yojson d in
Guild_integrations_update guild_id
| "GUILD_MEMBER_ADD", Some d ->
let { guild_id } = guild_obj_of_yojson d in
Guild_member_add { guild_id; member = Models.Guild_member.t_of_yojson d }
| "GUILD_MEMBER_REMOVE", Some d ->
Guild_member_remove (Guild_user.t_of_yojson d)
| "GUILD_MEMBER_UPDATE", Some d ->
Guild_member_update (Guild_member_update.t_of_yojson d)
| "GUILD_MEMBERS_CHUNK", Some d ->
Guild_members_chunk (Guild_members_chunk.t_of_yojson d)
| "GUILD_ROLE_CREATE", Some d -> Guild_role_create (Guild_role.t_of_yojson d)
| "GUILD_ROLE_UPDATE", Some d -> Guild_role_update (Guild_role.t_of_yojson d)
| "GUILD_ROLE_DELETE", Some d ->
Guild_role_delete (Guild_role_id.t_of_yojson d)
(* TODO invites *)
| "INVITE_CREATE", _ -> Invite_create
| "INVITE_DELETE", _ -> Invite_delete
(* messages *)
| "MESSAGE_CREATE", Some d -> Message_create (Models.Message.t_of_yojson d)
| "MESSAGE_UPDATE", Some d ->
Message_update (Models.Message.partial_of_yojson d)
| "MESSAGE_DELETE", Some d -> Message_delete (Message_delete.t_of_yojson d)
| "MESSAGE_DELETE_BULK", Some d ->
Message_delete_bulk (Message_delete_bulk.t_of_yojson d)
| "MESSAGE_CREATION_ADD", Some d ->
Message_reaction_add (Message_reaction_add.t_of_yojson d)
| "MESSAGE_CREATION_REMOVE", Some d ->
Message_reaction_remove (Message_reaction_remove.t_of_yojson d)
| "MESSAGE_CREATION_REMOVE_ALL", Some d ->
Message_reaction_remove_all (Message_reaction_remove_all.t_of_yojson d)
| "MESSAGE_CREATION_REMOVE_EMOJI", Some d ->
Message_reaction_remove_emoji
(Message_reaction_remove_emoji.t_of_yojson d)
(* users *)
| "PRESENCE_UPDATE", Some d -> Presence_update (Presence.t_of_yojson d)
| "TYPING_START", Some d -> Typing_start (Typing_start.t_of_yojson d)
| "USER_UPDATE", Some d -> User_update (Models.User.t_of_yojson d)
(* voice *)
| "VOICE_STATE_UPDATE", Some d ->
Voice_state_update (Voice_state.t_of_yojson d)
VoiceServerUpdate (VoiceServerUpdate.t_of_yojson d)
Voice_server_update (Voice_server_update.t_of_yojson d)
(* TODO webhooks *)
| "WEBHOOKS_UPDATE", _ -> Webhooks_update
(* TODO commands *)
| "APPLICATION_COMMAND_CREATE", _ -> Application_command_create
| "APPLICATION_COMMAND_UPDATE", _ -> Application_command_update
| "APPLICATION_COMMAND_DELETE", _ -> Application_command_delete
(* TODO interactions *)
| "INTERACTION_CREATE", _ -> Interaction_create
| RequestGuildMembers : GuildRequestMembers.t -> Dir.send t
| InvalidSession : bool -> Dir.recv t
| Request_guild_members : Guild_request_members.t -> Dir.send t
| Invalid_session : bool -> Dir.recv t
| PresenceUpdate d -> Raw.make ~d:(Presence.yojson_of_t d) ()
| VoiceStateUpdate d -> Raw.make ~d:(VoiceState.yojson_of_t d) ()
| Presence_update d -> Raw.make ~d:(Presence.yojson_of_t d) ()
| Voice_state_update d -> Raw.make ~d:(Voice_state.yojson_of_t d) ()
type t = {
name : string;
typ : int; [@key "type"]
url : string option option; [@yojson.option]
created_at : int;
timestamps : timestamps option; [@yojson.option]
application_id : Snowflake.t option; [@yojson.option]
details : string option option; [@yojson.option]
state : string option option; [@yojson.option]
emoji : Emoji.t option option; [@yojson.option]
(* party : Party.t option; [@yojson.option] *)
(* assets : Assets.t option; [@yojson.option] *)
(* secrets : Secrets.t option; [@yojson.option] *)
instance : bool option; [@yojson.option]
flags : int option; [@yojson.option]
}
[@@yojson.allow_extra_fields]
and timestamps = { start : int; end_ : int [@key "end"] }
[@@deriving yojson, show] [@@yojson.allow_extra_fields]
type partial = { id : Snowflake.t; flags : int }
[@@deriving yojson, show] [@@yojson.allow_extra_fields]
module Overwrite = struct
type t = {
id : Snowflake.t;
typ : int; [@key "type"]
allow : string;
deny : string;
}
[@@deriving yojson, show] [@@yojson.allow_extra_fields]
end
type t = {
id : Snowflake.t;
typ : int; [@key "type"]
guild_id : Snowflake.t option; [@yojson.option]
position : int option; [@yojson.option]
permission_overwrites : overwrite list option; [@yojson.option]
name : string option; [@yojson.option]
topic : string option option; [@yojson.option]
nsfw : bool option; [@yojson.option]
last_message_id : Snowflake.t option option; [@yojson.option]
bitrate : int option; [@yojson.option]
user_limit : int option; [@yojson.option]
rate_limit_per_user : int option; [@yojson.option]
recipients : User.t option; [@yojson.option]
icon : string option option; [@yojson.option]
owner_id : Snowflake.t option; [@yojson.option]
application_id : Snowflake.t option; [@yojson.option]
parent_id : Snowflake.t option; [@yojson.option]
last_pin_timestamp : string option option; [@yojson.option]
}
[@@yojson.allow_extra_fields]
and overwrite = Overwrite.t [@@deriving yojson, show]
type t = {
id : Snowflake.t option;
name : string;
roles : Snowflake.t list option; [@yojson.option]
user : User.t option; [@yojson.option]
require_colons : bool option; [@yojson.option]
managed : bool option; [@yojson.option]
animated : bool option; [@yojson.option]
available : bool option; [@yojson.option]
}
[@@deriving yojson, show] [@@yojson.allow_extra_fields]
type reaction = {
id : Snowflake.t option;
name : string option;
animated : bool option; [@yojson.option]
}
[@@deriving yojson, show] [@@yojson.allow_extra_fields]
type t
module Feature = struct
type t =
[ `Invite_splash
| `Vip_regions
| `Vanity_url
| `Verified
| `Partnered
| `Community
| `Commerce
| `News
| `Discoverable
| `Featurable
| `Animated_icon
| `Banner
| `Welcome_screen_enabled
| `Member_verification_gate_enabled
| `Preview_enabled
| `Unknown of string ]
[@@deriving show]
let t_of_yojson : Yojson.Safe.t -> t = function
| `String "INVITE_SPLASH" -> `Invite_splash
| `String "VIP_REGIONS" -> `Vip_regions
| `String "VANITY_URL" -> `Vanity_url
| `String "VERIFIED" -> `Verified
| `String "PARTNERED" -> `Partnered
| `String "COMMUNITY" -> `Community
| `String "COMMERCE" -> `Commerce
| `String "NEWS" -> `News
| `String "DISCOVERABLE" -> `Discoverable
| `String "FEATURABLE" -> `Featurable
| `String "ANIMATED_ICON" -> `Animated_icon
| `String "BANNER" -> `Banner
| `String "WELCOME_SCREEN_ENABLED" -> `Welcome_screen_enabled
| `String "MEMBER_VERIFICATION_GATE_ENABLED" ->
`Member_verification_gate_enabled
| `String "PREVIEW_ENABLED" -> `Preview_enabled
| `String other -> `Unknown other
| _ -> invalid_arg "expected string"
end
module Welcome_screen = struct
module Channel = struct
type t = {
channel_id : Snowflake.t;
description : string;
emoji_id : Snowflake.t option;
emoji_name : string option;
}
[@@deriving yojson, show] [@@yojson.allow_extra_fields]
end
type t = { description : string option; welcome_channels : channel list }
[@@deriving yojson, show] [@@yojson.allow_extra_fields]
and channel = Channel.t
end
type t = {
id : Snowflake.t;
name : string;
icon : string option;
icon_hash : string option option; [@yojson.option]
splash : string option;
discovery_splash : string option;
owner_id : Snowflake.t;
region : string;
afk_channel_id : Snowflake.t option;
afk_timeout : int;
widget_enabled : bool option; [@yojson.option]
widget_channel_id : Snowflake.t option option; [@yojson.option]
verification_level : int;
default_message_notifications : int;
explicit_content_filter : int;
roles : Role.t list;
emojis : Emoji.t list;
features : Feature.t list;
mfa_level : int;
application_id : Snowflake.t option;
system_channel_id : Snowflake.t option;
system_channel_flags : int;
rules_channel_id : Snowflake.t option;
max_presences : int option option; [@yojson.option]
max_members : int option; [@yojson.option]
vanity_url_code : string option;
description : string option;
banner : string option;
premium_tier : int;
premium_subscription_count : int option; [@yojson.option]
preferred_locale : string;
public_updates_channel_id : Snowflake.t option;
max_video_channel_users : int option; [@yojson.option]
approximate_member_count : int option; [@yojson.option]
approximate_presence_count : int option; [@yojson.option]
welcome_screen : Welcome_screen.t option; [@yojson.option]
}
[@@deriving of_yojson, show] [@@yojson.allow_extra_fields]
type unavailable = { id : Snowflake.t; unavailable : bool }
[@@deriving yojson, show] [@@yojson.allow_extra_fields]
type t = {
user : User.t option; [@yojson.option]
nick : string option option; [@yojson.option]
roles : Snowflake.t list;
joined_at : string;
premium_since : string option option; [@yojson.option]
deaf : bool;
mute : bool;
pending : bool option; [@yojson.option]
permissions : string option; [@yojson.option]
}
[@@deriving yojson, show] [@@yojson.allow_extra_fields]
type_ : int; [@key "type"]
timestamp : string;
edited_timestamp : string option;
tts : bool;
mention_everyone : bool;
mentions : User.t list;
mention_roles : Snowflake.t list;
mention_channels : Channel_mention.t list option; [@yojson.option]
(* attachments: Attachment.t list; *)
(* embeds: Embed.t list; *)
(* reactions: Reaction.t list option; [@yojson.option] *)
nonce : string option; [@yojson.option]
pinned : bool;
webhook_id : Snowflake.t option; [@yojson.option]
typ : int; [@key "type"]
(* activity : Activity.t option; [@yojson.option] *)
(* application : Application.t option; [@yojson.option] *)
(* message_reference : Reference.t option; [@yojson.option] *)
flags : int option; [@yojson.option]
(* stickers : Sticker.t list option; [@yojson.option] *)
referenced_message : t option option; [@yojson.option]
(* interaction : Interaction.t option; [@yojson.option] *)
}
[@@deriving yojson, show] [@@yojson.allow_extra_fields]
type partial = {
id : Snowflake.t;
channel_id : Snowflake.t;
content : string option; [@yojson.option]
timestamp : string option; [@yojson.option]
edited_timestamp : string;
type t = [ `online | `dnd | `idle | `invisible | `offline ] [@@deriving show]
type unsupported = [ t | `unsupported of string ] [@@deriving show]
let yojson_of_t = function
| `online -> `String "online"
| `dnd -> `String "dnd"
| `idle -> `String "idle"
| `invisible -> `String "invisible"
| `offline -> `String "offline"
let unsupported_of_yojson : Yojson.Safe.t -> unsupported = function
| `String "online" -> `online
| `String "dnd" -> `dnd
| `String "idle" -> `idle
| `String "invisible" -> `invisible
| `String "offline" -> `offline
| `String other -> `unsupported other
| _ -> invalid_arg "presence status not a string"
type t = {
id : Snowflake.t;
name : string;
color : int;
hoist : bool;
position : int;
permissions : string;
managed : bool;
mentionable : bool;
tags : tags option; [@yojson.option]
}
and tags = {
bot_id : Snowflake.t option; [@yojson.option]
interation_id : Snowflake.t option; [@yojson.option]
premium_subscriber : unit option; [@yojson.option]
}
[@@deriving yojson, show] [@@yojson.allow_extra_fields]
[@@deriving yojson] [@@yojson.allow_extra_fields]
[@@deriving yojson, show] [@@yojson.allow_extra_fields]
type partial = {
id : Snowflake.t;
username : string option; [@yojson.option]
discriminator : string option; [@yojson.option]
avatar : string option; [@yojson.option]
bot : bool option; [@yojson.option]
system : bool option; [@yojson.option]
mfa_enabled : bool option; [@yojson.option]
locale : string option; [@yojson.option]
verified : bool option; [@yojson.option]
email : string option option; [@yojson.option]
flags : int option; [@yojson.option]
premium_type : int option; [@yojson.option]
public_flags : int option; [@yojson.option]
}
[@@deriving yojson, show] [@@yojson.allow_extra_fields]
module WS_Client = Websocketaf_lwt.Client (Gluten_lwt_unix.Client)
module WSS_Client = Websocketaf_lwt.Client (Gluten_lwt_unix.Client.SSL)
module Ws_client = Websocketaf_lwt.Client (Gluten_lwt_unix.Client)
module Wss_client = Websocketaf_lwt.Client (Gluten_lwt_unix.Client.SSL)