1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
|
'use strict';
const { GatewayOpcodes, ActivityType } = require('discord-api-types/v10');
const { Presence } = require('./Presence');
const { DiscordjsTypeError, ErrorCodes } = require('../errors');
/**
* Represents the client's presence.
* @extends {Presence}
*/
class ClientPresence extends Presence {
constructor(client, data = {}) {
super(client, Object.assign(data, { status: data.status ?? 'online', user: { id: null } }));
}
/**
* Sets the client's presence
* @param {PresenceData} presence The data to set the presence to
* @returns {ClientPresence}
*/
set(presence) {
const packet = this._parse(presence);
this._patch(packet);
if (presence.shardId === undefined) {
this.client.ws.broadcast({ op: GatewayOpcodes.PresenceUpdate, d: packet });
} else if (Array.isArray(presence.shardId)) {
for (const shardId of presence.shardId) {
this.client.ws.shards.get(shardId).send({ op: GatewayOpcodes.PresenceUpdate, d: packet });
}
} else {
this.client.ws.shards.get(presence.shardId).send({ op: GatewayOpcodes.PresenceUpdate, d: packet });
}
return this;
}
/**
* Parses presence data into a packet ready to be sent to Discord
* @param {PresenceData} presence The data to parse
* @returns {APIPresence}
* @private
*/
_parse({ status, since, afk, activities }) {
const data = {
activities: [],
afk: typeof afk === 'boolean' ? afk : false,
since: typeof since === 'number' && !Number.isNaN(since) ? since : null,
status: status ?? this.status,
};
if (activities?.length) {
for (const [i, activity] of activities.entries()) {
if (typeof activity.name !== 'string') {
throw new DiscordjsTypeError(ErrorCodes.InvalidType, `activities[${i}].name`, 'string');
}
activity.type ??= ActivityType.Playing;
if (activity.type === ActivityType.Custom && !activity.state) {
activity.state = activity.name;
activity.name = 'Custom Status';
}
data.activities.push({
type: activity.type,
name: activity.name,
state: activity.state,
url: activity.url,
});
}
} else if (!activities && (status || afk || since) && this.activities.length) {
data.activities.push(
...this.activities.map(a => ({
name: a.name,
state: a.state ?? undefined,
type: a.type,
url: a.url ?? undefined,
})),
);
}
return data;
}
}
module.exports = ClientPresence;
/* eslint-disable max-len */
/**
* @external APIPresence
* @see {@link https://discord.com/developers/docs/rich-presence/how-to#updating-presence-update-presence-payload-fields}
*/
|