2020-06-18 03:18:54 +00:00
import json , discordobject , user , options , nimcordutils , message , httpcore , asyncdispatch , asyncfutures , strutils
type
ChannelType * = enum
2020-06-18 03:36:37 +00:00
## This enum shows the type of the channel.
2020-06-18 03:18:54 +00:00
chanTypeGuildText = 0 ,
chanTypeDM = 1 ,
chanTypeGuildVoice = 2 ,
chanTypeGroupDM = 3 ,
chanTypeGuildCategory = 4 ,
chanTypeGuildNews = 5 ,
chanTypeGuildStore = 6
Channel * = ref object of DiscordObject
2020-06-18 03:36:37 +00:00
## Discord channel object.
2020-06-18 03:18:54 +00:00
` type ` * : ChannelType ## The type of channel.
guildID * : snowflake ## The id of the guild.
position * : int ## Sorting position of the channel.
#permissionOverwrites*: seq[Permissions] ## Explicit permission overwrites for members and roles.
name * : string ## The name of the channel (2-100 characters).
topic * : string ## The channel topic (0-1024 characters).
nsfw * : bool ## Whether the channel is nsfw.
lastMessageID * : snowflake ## The id of the last message sent in this channel (may not point to an existing or valid message).
bitrate * : int ## The bitrate (in bits) of the voice channel.
userLimit * : int ## The user limit of the voice channel.
rateLimitPerUser * : int ## Amount of seconds a user has to wait before sending another message (0-21600); bots, as well as users with the permission manage_messages or manage_channel, are unaffected.
recipients * : seq [ User ] ## The recipients of the DM
icon * : string ## Icon hash
ownerID : snowflake ## ID of the DM creator
applicationID : snowflake ## Application id of the group DM creator if it is bot-created
parentID : snowflake ## ID of the parent category for a channel
lastPinTimestamp : string ## When the last pinned message was pinned
2020-06-18 04:51:20 +00:00
ChannelModify * = ref object
2020-06-18 03:18:54 +00:00
## Use this type to modify a channel by setting each fields.
name * : Option [ string ]
` type ` * : Option [ ChannelType ]
position * : Option [ int ]
topic * : Option [ string ]
nsfw * : Option [ bool ]
rateLimitPerUser * : Option [ int ]
bitrate * : Option [ int ]
userLimit * : Option [ int ]
#permissionOverwrites*: seq[Permissions] ## Explicit permission overwrites for members and roles.
parentID * : Option [ snowflake ]
proc newChannel * ( channel : JsonNode ) : Channel {. inline . } =
2020-06-18 03:36:37 +00:00
## Parses the channel from json.
2020-06-18 03:18:54 +00:00
var chan = Channel (
id : getIDFromJson ( channel [ " id " ] . getStr ( ) ) ,
` type ` : ChannelType ( channel [ " type " ] . getInt ( ) ) ,
)
if ( channel . contains ( " guild_id " ) ) :
chan . guildID = getIDFromJson ( channel [ " guild_id " ] . getStr ( ) )
if ( channel . contains ( " position " ) ) :
chan . position = channel [ " position " ] . getInt ( )
if ( channel . contains ( " permission_overwrites " ) ) :
echo " permission_overwrites "
if ( channel . contains ( " name " ) ) :
chan . name = channel [ " name " ] . getStr ( )
if ( channel . contains ( " topic " ) ) :
chan . topic = channel [ " topic " ] . getStr ( )
if ( channel . contains ( " nsfw " ) ) :
chan . nsfw = channel [ " nsfw " ] . getBool ( )
if ( channel . contains ( " last_message_id " ) ) :
chan . lastMessageID = getIDFromJson ( channel [ " last_message_id " ] . getStr ( ) )
if ( channel . contains ( " bitrate " ) ) :
chan . bitrate = channel [ " bitrate " ] . getInt ( )
if ( channel . contains ( " user_limit " ) ) :
chan . userLimit = channel [ " user_limit " ] . getInt ( )
if ( channel . contains ( " rate_limit_per_user " ) ) :
chan . rateLimitPerUser = channel [ " rate_limit_per_user " ] . getInt ( )
if ( channel . contains ( " recipients " ) ) :
for recipient in channel [ " recipients " ] :
chan . recipients . insert ( newUser ( recipient ) )
if ( channel . contains ( " icon " ) ) :
chan . icon = channel [ " icon " ] . getStr ( )
if ( channel . contains ( " owner_id " ) ) :
chan . ownerID = getIDFromJson ( channel [ " owner_id " ] . getStr ( ) )
if ( channel . contains ( " application_id " ) ) :
chan . applicationID = getIDFromJson ( channel [ " application_id " ] . getStr ( ) )
if ( channel . contains ( " parent_id " ) ) :
chan . parentID = getIDFromJson ( channel [ " parent_id " ] . getStr ( ) )
if ( channel . contains ( " last_pin_timestamp " ) ) :
chan . lastPinTimestamp = channel [ " last_pin_timestamp " ] . getStr ( )
return chan
proc sendMessage * ( channel : Channel , content : string , tts : bool = false ) : Message =
2020-06-18 03:36:37 +00:00
## Send a message through the channel.
2020-06-18 03:18:54 +00:00
let messagePayload = % * { " content " : content , " tts " : tts }
return newMessage ( sendRequest ( endpoint ( " /channels/ " & $ channel . id & " /messages " ) , HttpPost ,
defaultHeaders ( newHttpHeaders ( { " Content-Type " : " application/json " } ) ) , channel . id ,
RateLimitBucketType . channel , messagePayload ) )
proc modifyChannel * ( channel : Channel , modify : ChannelModify ) : Future [ Channel ] {. async . } =
2020-06-18 03:36:37 +00:00
## Modifies the channel.
##
## Examples:
2020-06-18 04:51:20 +00:00
## .. code-block:: nim
## var chan = getChannel(703084913510973472)
## chan = chan.modifyChannel(ChannelModify(topic: some("This is the channel topic")))
2020-06-18 03:36:37 +00:00
2020-06-18 03:18:54 +00:00
var modifyPayload = % * { }
if ( modify . name . isSome ) :
modifyPayload . add ( " name " , % modify . name . get ( ) )
if ( modify . ` type ` . isSome ) :
modifyPayload . add ( " type " , % modify . ` type ` . get ( ) )
if ( modify . position . isSome ) :
modifyPayload . add ( " position " , % modify . position . get ( ) )
if ( modify . topic . isSome ) :
modifyPayload . add ( " topic " , % modify . topic . get ( ) )
if ( modify . nsfw . isSome ) :
modifyPayload . add ( " nsfw " , % modify . nsfw . get ( ) )
if ( modify . rateLimitPerUser . isSome ) :
modifyPayload . add ( " rate_limit_per_user " , % modify . rateLimitPerUser . get ( ) )
if ( modify . bitrate . isSome ) :
modifyPayload . add ( " bitrate " , % modify . bitrate . get ( ) )
if ( modify . userLimit . isSome ) :
modifyPayload . add ( " user_limit " , % modify . userLimit . get ( ) )
#[ if (modify.name.isSome):
modifyPayload . add ( " permission_overwrites " , % modify . parentID . get ( ) 0 ] #
if ( modify . parentID . isSome ) :
modifyPayload . add ( " parent_id " , % modify . parentID . get ( ) )
return newChannel ( sendRequest ( endpoint ( " /channels/ " & $ channel . id ) , HttpPatch ,
defaultHeaders ( newHttpHeaders ( { " Content-Type " : " application/json " } ) ) ,
channel . id , RateLimitBucketType . channel , modifyPayload ) )
proc deleteChannel * ( channel : Channel ) {. async . } =
2020-06-18 03:36:37 +00:00
## Delete the channel.
2020-06-18 03:18:54 +00:00
discard sendRequest ( endpoint ( " /channels/ " & $ channel . id ) , HttpDelete ,
2020-06-18 04:51:38 +00:00
defaultHeaders ( ) , channel . id , RateLimitBucketType . channel )
type MessagesGetRequest * = object
## Use this type to get a channel's messages by setting some of the fields.
## You can only set one of `around`, `before`, or `after`.
around * : Option [ snowflake ]
before * : Option [ snowflake ]
after * : Option [ snowflake ]
limit * : Option [ int ]
proc getMessages * ( channel : Channel , request : MessagesGetRequest ) : seq [ Message ] =
## Gets messages in the channel.
##
## Examples:
## .. code-block:: nim
## var chan = getChannel(703084913510973472)
## channel.getMessages(MessagesGetRequest(limit: some(15), before: some(723030179760570428)))
var url : string = endpoint ( " /channels/ " & $ channel . id & " /messages? " )
if ( request . around . isSome ) :
url = url & " around= " & $ request . around . get ( )
# Raise some exceptions to make sure the user doesn't
# try to set more than one of these fields
if ( request . before . isSome ) :
if ( request . around . isSome ) :
raise newException ( Defect , " You cannot get around and before a message! Choose one... " )
url = url & " before= " & $ request . before . get ( )
if ( request . after . isSome ) :
if ( request . around . isSome or request . before . isSome ) :
raise newException ( Defect , " You cannot get around/before and after a message! Choose one... " )
url = url & " after= " & $ request . after . get ( )
if ( request . limit . isSome ) :
# Add the `&` for the url if something else is set.
if ( request . around . isSome or request . before . isSome or request . after . isSome ) :
url = url & " & "
url = url & " limit= " & $ request . limit . get ( )
let response = sendRequest ( url , HttpGet , defaultHeaders ( newHttpHeaders ( ) ) ,
channel . id , RateLimitBucketType . channel )
for message in response :
result . add ( newMessage ( message ) )