Add ability to update bot's presence with Presence custom type

This commit is contained in:
SeanOMik 2020-06-20 23:38:23 -05:00
parent dc681a62e4
commit 4a1798c346
No known key found for this signature in database
GPG Key ID: FA4D55AC05268A88
2 changed files with 160 additions and 1 deletions

View File

@ -1,6 +1,6 @@
import websocket, asyncdispatch, json, httpClient, eventdispatcher, strformat
import eventhandler, streams, nimcordutils, discordobject, user, cache, clientobjects
import strutils, channel, options, message, emoji, guild, embed, os
import strutils, channel, options, message, emoji, guild, embed, os, presence
const
nimcordMajor = 0
@ -103,6 +103,15 @@ proc startConnection*(client: DiscordClient) {.async.} =
else:
raise newException(IOError, "Failed to get gateway url, token may of been incorrect!")
proc updateClientPresence*(client: DiscordClient, presence: Presence) {.async.} =
let jsonPayload = %* {
"op": ord(opPresenceUpdate),
"d": presence.presenceToJson()
}
echo "payload:", jsonPayload
await client.sendGatewayRequest(jsonPayload)
proc newDiscordClient(tkn: string): DiscordClient =
## Create a DiscordClient using a token.
##
@ -133,6 +142,9 @@ registerEventListener(EventType.evtReady, proc(bEvt: BaseEvent) =
echo "Logged in as: ", bot.clientUser.username, "#", bot.clientUser.discriminator
echo "ID: ", bot.clientUser.id
echo "--------------------"
let presence = newPresence("with Nimcord", activityTypeGame, clientStatusIdle, false)
asyncCheck event.client.updateClientPresence(presence)
)
registerEventListener(EventType.evtMessageCreate, proc(bEvt: BaseEvent) =

147
src/presence.nim Normal file
View File

@ -0,0 +1,147 @@
import json, discordobject, emoji, nimcordutils, times
type
ClientStatus* = enum
clientStatusOnline = "online",
clientStatusOffline = "offline",
clientStatusInvisible = "invisible",
clientStatusIdle = "idle",
clientStatusDnd = "dnd" ## Do not disturb.
ActivityType* = enum
activityTypeGame = 0,
activityTypeStreaming = 1,
activityTypeListening = 2,
activityTypeCustom = 3
ActivityFlag* = enum
activityFlagInstance = 0,
activityFlagJoin = 1,
activityFlagSpectate = 2,
activityFlagJoinRequest = 3,
activityFlagSync = 4,
activityFlagPlay = 5
ActivityTimestamp* = ref object
startTime*: uint
endTime*: uint
ActivityParty* = ref object
id*: string
currentSize*: uint
maxSize*: uint
ActivityAssets* = ref object
largeImg: string
largeText*: string
smallImg*: string
smallText*: string
ActivitySecrets* = ref object
join*: string
spectate*: string
match*: string
Activity* = ref object
name*: string
`type`*: ActivityType
url*: string
createdAt*: uint
timestamps*: seq[ActivityTimestamp]
applicationID*: snowflake
details*: string
state*: string
emoji*: Emoji
party*: ActivityParty
assets*: ActivityAssets
secrets*: ActivitySecrets
instance*: bool
flags*: uint
Presence* = ref object
status*: ClientStatus
game*: Activity
activities*: seq[Activity]
afk*: bool
proc newActivity*(json: JsonNode, guildID: snowflake): Activity =
## Parse a new activity from json.
var act = Activity(
name: json["name"].getStr(),
`type`: ActivityType(json["type"].getInt()),
url: json{"url"}.getStr(),
createdAt: uint(json{"created_at"}.getInt()),
applicationID: getIDFromJson(json{"application_id"}.getStr()),
details: json{"details"}.getStr(),
state: json{"state"}.getStr(),
#party?
#assets?
#secrets
instance: json{"instance"}.getBool(),
flags: uint(json{"flags"}.getInt()),
)
if (json.contains("timestamps")):
for timestamp in json["timestamps"]:
var time: ActivityTimestamp
if (timestamp.contains("start")):
time.startTime = uint(timestamp["start"].getInt())
if (timestamp.contains("end")):
time.endTime = uint(timestamp["end"].getInt())
act.timestamps.add(time)
if (json.contains("emoji")):
act.emoji = newEmoji(json["emoji"], guildID)
if (json.contains("party")):
var party: ActivityParty
if (json["party"].contains("id")):
party.id = json["party"]["id"].getStr()
if (json["party"].contains("size")):
party.currentSize = uint(json["party"]["size"].elems[0].getInt())
party.maxSize = uint(json["party"]["size"].elems[1].getInt())
if (json.contains("assets")):
var assets: ActivityAssets
if (json["assets"].contains("large_image")):
assets.largeImg = json["assets"]["large_image"].getStr()
if (json["assets"].contains("large_text")):
assets.largeText = json["assets"]["large_text"].getStr()
if (json["assets"].contains("small_image")):
assets.smallImg = json["assets"]["small_image"].getStr()
if (json["assets"].contains("small_text")):
assets.smallText = json["assets"]["small_text"].getStr()
if (json.contains("secrets")):
var secrets: ActivitySecrets
if (json["secrets"].contains("join")):
secrets.join = json["secrets"]["join"].getStr()
if (json["secrets"].contains("spectate")):
secrets.spectate = json["secrets"]["spectate"].getStr()
if (json["secrets"].contains("match")):
secrets.match = json["secrets"]["match"].getStr()
proc newPresence*(text: string, `type`: ActivityType, status: ClientStatus, afk: bool = false): Presence =
## Used to create a presence that you can use to update the presence of your bot's user.
return Presence(
status: status,
afk: afk,
game: Activity(
name: text,
`type`: `type`
)
)
proc presenceToJson*(presence: Presence): JsonNode =
## Convert a presence to json for sending via gateway.
## If your a user, no reason to use this!
result = %* {
"status": presence.status,
"afk": presence.afk,
"since": getTime().toUnix(),
"game": {
"name": presence.game.name,
"type": ord(presence.game.`type`)
}
}