This repository has been archived on 2023-04-26. You can view files and clone it, but cannot push or open issues or pull requests.
nimcord/src/message.nim

215 lines
9.1 KiB
Nim
Raw Normal View History

import json, discordobject, nimcordutils, user, member, httpcore, asyncdispatch, emoji, options
2020-05-31 05:08:44 +00:00
type
MessageType* = enum
default = 0,
recipientAdd = 1,
recipientRemove = 2,
call = 3,
channelNameChange = 4,
channelIconChange = 5,
channelPinnedMessage = 6,
guildMemberJoin = 7,
userPremiumGuildSubscription = 8,
userPremiumGuildSubscriptionTier1 = 9,
userPremiumGuildSubscriptionTier2 = 10,
userPremiumGuildSubscriptionTier3 = 11,
channelFollowAdd = 12,
guildDiscoveryDisqualified = 14,
guildDiscoveryRequalified = 15
MessageActivityType* = enum
join = 1,
spectate = 2,
listen = 3,
joinRequest = 5
MessageActivity* = object
`type`*: MessageActivityType
partyID*: string
MessageApplication* = object of DiscordObject
coverImage: string
description: string
icon: string
name: string
MessageReference* = object
messageID: snowflake
channelID: snowflake
guildID: snowflake
2020-06-18 20:31:51 +00:00
MessageFlags* = enum
msgFlagCrossposted = 0,
msgFlagIsCrossPost = 1,
msgFlagSuppressEmbeds = 2,
msgFlagSourceMsgDeleted = 3,
msgFlagUrgent = 4
Message* = ref object of DiscordObject
2020-05-31 05:08:44 +00:00
channelID*: snowflake
guildID*: snowflake
author*: User
member*: GuildMember
content*: string
timestamp*: string
editedTimestamp*: string
tts*: bool
mentionEveryone*: bool
mentions*: seq[User]
#mentionRoles*: seq[Role]
#mentionChannels*: seq[ChannelMention]
#attachments*: seq[Attachment]
#embeds*: seq[Embed]
#reactions*: seq[Reaction]
pinned*: bool
webhookID*: snowflake
`type`*: MessageType
activity*: MessageActivity
application*: MessageApplication
messageReference*: MessageReference
flags*: int
proc newMessage*(messageJson: JsonNode): Message =
2020-05-31 05:08:44 +00:00
var msg = Message(
id: getIDFromJson(messageJson["id"].getStr()),
2020-06-18 03:16:08 +00:00
channelID: getIDFromJson(messageJson["channel_id"].getStr()),
guildID: getIDFromJson(messageJson{"guild_id"}.getStr()),
content: messageJson["content"].getStr(),
timestamp: messageJson["timestamp"].getStr(),
editedTimestamp: messageJson{"edited_timestamp"}.getStr(),
tts: messageJson["tts"].getBool(),
mentionEveryone: messageJson["mention_everyone"].getBool(),
2020-05-31 05:08:44 +00:00
#mentionRoles
#mentionChannels?
2020-05-31 05:08:44 +00:00
#attachments
#embeds
#reactions?
pinned: messageJson["pinned"].getBool(),
2020-06-18 03:16:08 +00:00
webhookID: getIDFromJson(messageJson{"webhook_id"}.getStr()),
`type`: MessageType(messageJson["type"].getInt()),
flags: messageJson{"flags"}.getInt()
2020-05-31 05:08:44 +00:00
)
if (messageJson.contains("author")):
msg.author = newUser(messageJson["author"])
if (messageJson.contains("member")):
msg.member = newGuildMember(messageJson["member"])
2020-05-31 05:08:44 +00:00
if (messageJson.contains("mentions")):
let mentionsJson = messageJson["mentions"].getElems()
2020-05-31 05:08:44 +00:00
for userJson in mentionsJson.items:
2020-05-31 05:08:44 +00:00
msg.mentions.add(newUser(userJson))
if (messageJson.contains("activity")):
msg.activity = MessageActivity(`type`: MessageActivityType(messageJson["activity"]["type"].getInt()),
partyID: messageJson["activity"]["party_id"].getStr())
if (messageJson.contains("application")):
2020-05-31 05:08:44 +00:00
msg.application = MessageApplication(
id: getIDFromJson(messageJson["application"]["id"].getStr()),
coverImage: messageJson["application"]{"cover_image"}.getStr(),
description: messageJson["application"]["description"].getStr(),
icon: messageJson["application"]{"icon"}.getStr(),
name: messageJson["application"]["name"].getStr()
2020-05-31 05:08:44 +00:00
)
if (messageJson.contains("message_reference")):
2020-05-31 05:08:44 +00:00
msg.messageReference = MessageReference(
messageID: getIDFromJson(messageJson["message_reference"]{"message_id"}.getStr()),
channelID: getIDFromJson(messageJson["message_reference"]["channel_id"].getStr()),
guildID: getIDFromJson(messageJson["message_reference"]{"guild_id"}.getStr()),
2020-05-31 05:08:44 +00:00
)
2020-06-18 20:31:51 +00:00
return msg
proc addReaction*(message: Message, emoji: Emoji) {.async.} =
## Create a reaction for the message. This endpoint requires the
## `READ_MESSAGE_HISTORY` permission to be present on the current
## user. Additionally, if nobody else has reacted to the message
## using this emoji, this endpoint requires the 'ADD_REACTIONS'
## permission to be present on the current user.
##
## See also:
## * `removeReaction(message: Message, emoji: Emoji)`_
2020-06-18 20:31:51 +00:00
discard sendRequest(endpoint("/channels/" & $message.channelID & "/messages/" & $message.id &
"/reactions/" & emoji.toUrlEncoding() & "/@me"), HttpPut, defaultHeaders(),
message.channelID, RateLimitBucketType.channel)
proc removeReaction*(message: Message, emoji: Emoji) {.async.} =
## Delete a reaction the bot user has made for the message.
discard sendRequest(endpoint("/channels/" & $message.channelID & "/messages/" & $message.id &
"/reactions/" & emoji.toUrlEncoding() & "/@me"), HttpDelete, defaultHeaders(),
message.channelID, RateLimitBucketType.channel)
proc removeUserReaction*(message: Message, emoji: Emoji, user: User) {.async.} =
## Deletes another user's reaction. This endpoint requires the
## `MANAGE_MESSAGES` permission to be present on the current user
discard sendRequest(endpoint("/channels/" & $message.channelID & "/messages/" & $message.id &
"/reactions/" & emoji.toUrlEncoding() & "/" & $user.id), HttpDelete, defaultHeaders(),
message.channelID, RateLimitBucketType.channel)
type ReactantsGetRequest* = object
## Use this type to get a messages's reactants by setting
## some of the fields.
## You can only set one of `before` and `after`.
before*: Option[snowflake]
after*: Option[snowflake]
limit*: Option[int]
proc getReactants*(message: Message, emoji: Emoji, request: ReactantsGetRequest): seq[User] =
## Get a list of users that reacted with this emoji.
var url: string = endpoint("/channels/" & $message.channelID & "/messages/" & $message.id &
"/reactions/" & emoji.toUrlEncoding())
# Raise some exceptions to make sure the user doesn't
# try to set more than one of these fields
if (request.before.isSome):
url = url & "before=" & $request.before.get()
if (request.after.isSome):
if (request.before.isSome):
raise newException(Defect, "You cannot get 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.before.isSome or request.after.isSome):
url = url & "&"
url = url & "limit=" & $request.limit.get()
let json = sendRequest(url, HttpGet, defaultHeaders(), message.channelID,
RateLimitBucketType.channel)
for user in json:
result.add(newUser(user))
proc removeAllReactions*(message: Message) {.asnyc.} =
## Deletes all reactions on a message. This endpoint requires the
## `MANAGE_MESSAGES` permission to be present on the current user.
discard sendRequest(endpoint("/channels/" & $message.channelID & "/messages/" & $message.id &
"/reactions/"), HttpDelete, defaultHeaders(), message.channelID, RateLimitBucketType.channel)
proc removeAllReactions*(message: Message, emoji: Emoji) {.asnyc.} =
## Deletes all the reactions for a given emoji on a message. This
## endpoint requires the `MANAGE_MESSAGES` permission to be present
## on the current user.
discard sendRequest(endpoint("/channels/" & $message.channelID & "/messages/" & $message.id &
"/reactions/" & emoji.toUrlEncoding()), HttpDelete, defaultHeaders(), message.channelID,
RateLimitBucketType.channel)
2020-06-18 20:31:51 +00:00
#TODO: Embeds and maybe flags?
proc editMessage*(message: Message, content: string): Future[Message] {.async.} =
## Edit a previously sent message.
2020-06-18 20:31:51 +00:00
let jsonBody = %*{"content": content}
return newMessage(sendRequest(endpoint("/channels/" & $message.channelID & "/messages/" & $message.id),
HttpPatch, defaultHeaders(newHttpHeaders({"Content-Type": "application/json"})),
message.channelID, RateLimitBucketType.channel, jsonBody))
proc deleteMessage*(message: Message) {.async.} =
2020-06-18 20:31:51 +00:00
## Delete a message. If operating on a guild channel and trying to delete
## a message that was not sent by the current user, this endpoint requires
## the `MANAGE_MESSAGES` permission.
discard sendRequest(endpoint("/channels/" & $message.channelID & "/messages/" & $message.id),
HttpDelete, defaultHeaders(), message.channelID, RateLimitBucketType.channel)