@discordjs/rpc 0.2.0-dev.1786968995-99af6d8be → 0.2.0-dev.1788538586-ecea9ed57
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +70 -0
- package/dist/index.d.ts +465 -0
- package/dist/index.js +688 -0
- package/dist/index.js.map +1 -0
- package/package.json +18 -17
package/dist/index.js
ADDED
|
@@ -0,0 +1,688 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
|
+
|
|
4
|
+
// src/client.ts
|
|
5
|
+
import { randomUUID as randomUUID2 } from "crypto";
|
|
6
|
+
import { AsyncEventEmitter as AsyncEventEmitter2 } from "@vladfrangu/async_event_emitter";
|
|
7
|
+
import { RPCEvents, RPCCommands, Routes, RouteBases } from "discord-api-types/v10";
|
|
8
|
+
|
|
9
|
+
// src/RPCEventError.ts
|
|
10
|
+
var RPCEventError = class extends Error {
|
|
11
|
+
static {
|
|
12
|
+
__name(this, "RPCEventError");
|
|
13
|
+
}
|
|
14
|
+
code;
|
|
15
|
+
data;
|
|
16
|
+
constructor(data) {
|
|
17
|
+
if (typeof data === "string") {
|
|
18
|
+
super(data);
|
|
19
|
+
} else {
|
|
20
|
+
super(data.message);
|
|
21
|
+
this.code = data.code;
|
|
22
|
+
this.data = data;
|
|
23
|
+
}
|
|
24
|
+
this.name = "RPCEventError";
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
// src/constants.ts
|
|
29
|
+
var Events = /* @__PURE__ */ ((Events2) => {
|
|
30
|
+
Events2["ApplicationReady"] = "APPLICATION_READY";
|
|
31
|
+
Events2["Disconnected"] = "DISCONNECTED";
|
|
32
|
+
return Events2;
|
|
33
|
+
})(Events || {});
|
|
34
|
+
|
|
35
|
+
// src/ipc.ts
|
|
36
|
+
import { Buffer as Buffer2 } from "buffer";
|
|
37
|
+
import { randomUUID } from "crypto";
|
|
38
|
+
import fs from "fs/promises";
|
|
39
|
+
import { createConnection, Socket } from "net";
|
|
40
|
+
import path from "path";
|
|
41
|
+
import process2 from "process";
|
|
42
|
+
import { AsyncEventEmitter } from "@vladfrangu/async_event_emitter";
|
|
43
|
+
async function canOpenFile(path2) {
|
|
44
|
+
try {
|
|
45
|
+
await fs.access(path2);
|
|
46
|
+
return true;
|
|
47
|
+
} catch {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
__name(canOpenFile, "canOpenFile");
|
|
52
|
+
async function getIPCPath(id) {
|
|
53
|
+
if (process2.platform === "win32") {
|
|
54
|
+
return String.raw`\\?\pipe\discord-ipc-${id}`;
|
|
55
|
+
}
|
|
56
|
+
const prefix = process2.env.XDG_RUNTIME_DIR ?? process2.env.TMPDIR ?? "/tmp";
|
|
57
|
+
const bases = [prefix, path.join(prefix, "app", "com.discordapp.Discord"), path.join(prefix, "snap.discord")];
|
|
58
|
+
for (const base of bases) {
|
|
59
|
+
const candidate = path.join(base, `discord-ipc-${id}`);
|
|
60
|
+
if (await canOpenFile(candidate)) return candidate;
|
|
61
|
+
}
|
|
62
|
+
return path.join(prefix, `discord-ipc-${id}`);
|
|
63
|
+
}
|
|
64
|
+
__name(getIPCPath, "getIPCPath");
|
|
65
|
+
async function getIPC(id) {
|
|
66
|
+
const { promise, resolve, reject } = Promise.withResolvers();
|
|
67
|
+
const path2 = await getIPCPath(id);
|
|
68
|
+
const onError = /* @__PURE__ */ __name(async () => reject(new Error("Could not connect")), "onError");
|
|
69
|
+
const socket = createConnection(path2, () => {
|
|
70
|
+
socket.removeListener("error", onError);
|
|
71
|
+
resolve(socket);
|
|
72
|
+
});
|
|
73
|
+
socket.once("error", onError);
|
|
74
|
+
return promise;
|
|
75
|
+
}
|
|
76
|
+
__name(getIPC, "getIPC");
|
|
77
|
+
function encode(op, data) {
|
|
78
|
+
const stringifiedData = JSON.stringify(data);
|
|
79
|
+
const length = Buffer2.byteLength(stringifiedData);
|
|
80
|
+
const packet = Buffer2.allocUnsafe(8 + length);
|
|
81
|
+
packet.writeInt32LE(op, 0);
|
|
82
|
+
packet.writeInt32LE(length, 4);
|
|
83
|
+
packet.write(stringifiedData, 8, length);
|
|
84
|
+
return packet;
|
|
85
|
+
}
|
|
86
|
+
__name(encode, "encode");
|
|
87
|
+
var IPCTransport = class extends AsyncEventEmitter {
|
|
88
|
+
constructor(client) {
|
|
89
|
+
super();
|
|
90
|
+
this.client = client;
|
|
91
|
+
this.socket = new Socket();
|
|
92
|
+
this.working = {
|
|
93
|
+
op: 0,
|
|
94
|
+
len: 0,
|
|
95
|
+
buffer: Buffer2.from([])
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
client;
|
|
99
|
+
static {
|
|
100
|
+
__name(this, "IPCTransport");
|
|
101
|
+
}
|
|
102
|
+
socket;
|
|
103
|
+
working;
|
|
104
|
+
async connect() {
|
|
105
|
+
for (let id = 0; id < 10; id++) {
|
|
106
|
+
try {
|
|
107
|
+
this.socket = await getIPC(id);
|
|
108
|
+
break;
|
|
109
|
+
} catch (error) {
|
|
110
|
+
if (id === 9) throw error;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
this.socket.on("close", this.onClose.bind(this));
|
|
114
|
+
this.socket.on("error", this.onError.bind(this));
|
|
115
|
+
this.emit("open");
|
|
116
|
+
this.socket.write(
|
|
117
|
+
encode(0 /* Handshake */, {
|
|
118
|
+
v: 1,
|
|
119
|
+
client_id: this.client.clientId
|
|
120
|
+
})
|
|
121
|
+
);
|
|
122
|
+
this.socket.pause();
|
|
123
|
+
this.socket.on("readable", this.decode.bind(this));
|
|
124
|
+
}
|
|
125
|
+
async decode() {
|
|
126
|
+
let packet;
|
|
127
|
+
const chunks = [];
|
|
128
|
+
while ((packet = this.socket.read()) !== null) {
|
|
129
|
+
chunks.push(packet);
|
|
130
|
+
}
|
|
131
|
+
if (chunks.length === 0) return;
|
|
132
|
+
const packets = Buffer2.concat([this.working.buffer, ...chunks]);
|
|
133
|
+
if (this.working.buffer.byteLength === 0) {
|
|
134
|
+
this.working.op = packets.readInt32LE(0);
|
|
135
|
+
this.working.len = packets.readInt32LE(4);
|
|
136
|
+
}
|
|
137
|
+
this.working.buffer = packets;
|
|
138
|
+
const { op, len } = this.working;
|
|
139
|
+
let data;
|
|
140
|
+
try {
|
|
141
|
+
data = JSON.parse(packets.subarray(8, len + 8).toString());
|
|
142
|
+
} catch {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
this.working.buffer = Buffer2.from([]);
|
|
146
|
+
switch (op) {
|
|
147
|
+
case 3 /* Ping */:
|
|
148
|
+
this.send(data, 4 /* Pong */);
|
|
149
|
+
break;
|
|
150
|
+
case 1 /* Frame */:
|
|
151
|
+
if (!data) {
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
this.emit("message", data);
|
|
155
|
+
break;
|
|
156
|
+
case 2 /* Close */:
|
|
157
|
+
this.emit("close", data);
|
|
158
|
+
break;
|
|
159
|
+
default:
|
|
160
|
+
break;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
onClose(data) {
|
|
164
|
+
this.socket.removeAllListeners();
|
|
165
|
+
this.socket = new Socket();
|
|
166
|
+
this.working.buffer = Buffer2.from([]);
|
|
167
|
+
const error = typeof data === "boolean" ? new Error("socket closed") : data;
|
|
168
|
+
this.emit("close", error);
|
|
169
|
+
}
|
|
170
|
+
onError(error) {
|
|
171
|
+
this.emit("error", error);
|
|
172
|
+
}
|
|
173
|
+
send(data, op = 1 /* Frame */) {
|
|
174
|
+
this.socket.write(encode(op, data));
|
|
175
|
+
}
|
|
176
|
+
async close(options) {
|
|
177
|
+
const { promise, resolve, reject } = Promise.withResolvers();
|
|
178
|
+
const signal = options?.signal ?? AbortSignal.timeout(1e4);
|
|
179
|
+
const onAbort = /* @__PURE__ */ __name((_) => reject(signal.reason instanceof Error ? signal.reason : new Error(String(signal.reason))), "onAbort");
|
|
180
|
+
this.once("close", (error) => {
|
|
181
|
+
signal.removeEventListener("abort", onAbort);
|
|
182
|
+
resolve(error);
|
|
183
|
+
});
|
|
184
|
+
signal.addEventListener("abort", onAbort);
|
|
185
|
+
this.send({}, 2 /* Close */);
|
|
186
|
+
this.socket.end();
|
|
187
|
+
return promise;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Manual ping method
|
|
191
|
+
*/
|
|
192
|
+
ping() {
|
|
193
|
+
this.send(randomUUID(), 3 /* Ping */);
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
// src/util.ts
|
|
198
|
+
import { createRequire } from "module";
|
|
199
|
+
var register = /* @__PURE__ */ __name(async () => {
|
|
200
|
+
const require2 = createRequire(import.meta.url);
|
|
201
|
+
try {
|
|
202
|
+
const { app } = require2("electron");
|
|
203
|
+
return app.setAsDefaultProtocolClient.bind(app);
|
|
204
|
+
} catch {
|
|
205
|
+
try {
|
|
206
|
+
return require2("register-scheme");
|
|
207
|
+
} catch {
|
|
208
|
+
return false;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}, "register");
|
|
212
|
+
function getPid() {
|
|
213
|
+
if (typeof globalThis.process !== "undefined") {
|
|
214
|
+
return process.pid;
|
|
215
|
+
}
|
|
216
|
+
return null;
|
|
217
|
+
}
|
|
218
|
+
__name(getPid, "getPid");
|
|
219
|
+
function isValidTimestamp(timestamp) {
|
|
220
|
+
return Number.isInteger(timestamp) && timestamp >= 0 && timestamp <= 2147483647e3;
|
|
221
|
+
}
|
|
222
|
+
__name(isValidTimestamp, "isValidTimestamp");
|
|
223
|
+
|
|
224
|
+
// src/client.ts
|
|
225
|
+
var RPCClient = class extends AsyncEventEmitter2 {
|
|
226
|
+
static {
|
|
227
|
+
__name(this, "RPCClient");
|
|
228
|
+
}
|
|
229
|
+
options;
|
|
230
|
+
accessToken;
|
|
231
|
+
clientId;
|
|
232
|
+
clientSecret;
|
|
233
|
+
readyTimestamp;
|
|
234
|
+
application;
|
|
235
|
+
user;
|
|
236
|
+
/**
|
|
237
|
+
* The transport for the IPC
|
|
238
|
+
*/
|
|
239
|
+
transport;
|
|
240
|
+
/**
|
|
241
|
+
* Map of nonces being expected from the transport
|
|
242
|
+
*/
|
|
243
|
+
#expectedNonces;
|
|
244
|
+
constructor(options = {}) {
|
|
245
|
+
super();
|
|
246
|
+
this.options = options;
|
|
247
|
+
this.accessToken = "";
|
|
248
|
+
this.clientId = "";
|
|
249
|
+
this.clientSecret = "";
|
|
250
|
+
this.readyTimestamp = null;
|
|
251
|
+
this.application = null;
|
|
252
|
+
this.user = null;
|
|
253
|
+
this.transport = new IPCTransport(this);
|
|
254
|
+
this.transport.on("message", this.#onRpcMessage.bind(this));
|
|
255
|
+
this.#expectedNonces = /* @__PURE__ */ new Map();
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Returns the Date for when the client became ready
|
|
259
|
+
*/
|
|
260
|
+
get readyAt() {
|
|
261
|
+
if (this.readyTimestamp === null) return null;
|
|
262
|
+
return new Date(this.readyTimestamp);
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Returns true if the client is currently ready
|
|
266
|
+
*/
|
|
267
|
+
get ready() {
|
|
268
|
+
return this.readyTimestamp !== null;
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Search and connect to RPC
|
|
272
|
+
*/
|
|
273
|
+
async connect(options) {
|
|
274
|
+
const { promise, resolve, reject } = Promise.withResolvers();
|
|
275
|
+
if (this.ready) {
|
|
276
|
+
resolve(this);
|
|
277
|
+
return promise;
|
|
278
|
+
}
|
|
279
|
+
const signal = options?.signal ?? AbortSignal.timeout(1e4);
|
|
280
|
+
const onAbort = /* @__PURE__ */ __name((_) => {
|
|
281
|
+
this.removeListener(RPCEvents.Ready, onReady);
|
|
282
|
+
this.transport.removeListener("close", onClose);
|
|
283
|
+
const reason = signal.reason instanceof Error ? signal.reason : new Error(String(signal.reason));
|
|
284
|
+
reject(reason);
|
|
285
|
+
}, "onAbort");
|
|
286
|
+
const onReady = /* @__PURE__ */ __name(() => {
|
|
287
|
+
signal.removeEventListener("abort", onAbort);
|
|
288
|
+
this.readyTimestamp = Date.now();
|
|
289
|
+
resolve(this);
|
|
290
|
+
}, "onReady");
|
|
291
|
+
const onClose = /* @__PURE__ */ __name((data) => {
|
|
292
|
+
signal.removeEventListener("abort", onAbort);
|
|
293
|
+
this.removeListener(RPCEvents.Ready, onReady);
|
|
294
|
+
for (const expNonce of this.#expectedNonces.values()) {
|
|
295
|
+
expNonce.reject(new RPCEventError("connection closed"));
|
|
296
|
+
}
|
|
297
|
+
this.#expectedNonces.clear();
|
|
298
|
+
this.readyTimestamp = null;
|
|
299
|
+
this.emit("DISCONNECTED" /* Disconnected */);
|
|
300
|
+
reject(new RPCEventError(JSON.stringify(data)));
|
|
301
|
+
}, "onClose");
|
|
302
|
+
signal.addEventListener("abort", onAbort);
|
|
303
|
+
this.once(RPCEvents.Ready, onReady);
|
|
304
|
+
this.transport.once("close", onClose);
|
|
305
|
+
try {
|
|
306
|
+
await this.transport.connect();
|
|
307
|
+
} catch (error) {
|
|
308
|
+
this.readyTimestamp = null;
|
|
309
|
+
signal.removeEventListener("abort", onAbort);
|
|
310
|
+
this.removeListener(RPCEvents.Ready, onReady);
|
|
311
|
+
this.transport.removeListener("close", onClose);
|
|
312
|
+
reject(error);
|
|
313
|
+
}
|
|
314
|
+
return promise;
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Performs authentication flow. Automatically calls Client#connect if needed.
|
|
318
|
+
*
|
|
319
|
+
* @example
|
|
320
|
+
* logging in with a client id and secret
|
|
321
|
+
* ```ts
|
|
322
|
+
* client.login({ clientId: '1234567', clientSecret: 'abcdef123' });
|
|
323
|
+
* ```
|
|
324
|
+
*/
|
|
325
|
+
async login({ clientId, clientSecret, accessToken }, options) {
|
|
326
|
+
if (!clientId) {
|
|
327
|
+
throw new Error("A client id must be provided to login");
|
|
328
|
+
}
|
|
329
|
+
this.clientId = clientId;
|
|
330
|
+
await this.connect(options);
|
|
331
|
+
if (!this.options.scopes) {
|
|
332
|
+
this.emit("APPLICATION_READY" /* ApplicationReady */);
|
|
333
|
+
return this;
|
|
334
|
+
}
|
|
335
|
+
if (accessToken) {
|
|
336
|
+
return this.authenticate(accessToken, options);
|
|
337
|
+
}
|
|
338
|
+
if (!clientSecret) {
|
|
339
|
+
throw new Error("A client secret must be provided for authorization if scopes are included");
|
|
340
|
+
}
|
|
341
|
+
this.clientSecret = clientSecret;
|
|
342
|
+
const authorizeArgs = { client_id: this.clientId, scopes: this.options.scopes };
|
|
343
|
+
if (this.options.username) authorizeArgs.username = this.options.username;
|
|
344
|
+
return this.authenticate(await this.authorize(authorizeArgs, options), options);
|
|
345
|
+
}
|
|
346
|
+
async request(cmd, args = {}, options) {
|
|
347
|
+
const signal = options?.signal ?? AbortSignal.timeout(1e4);
|
|
348
|
+
signal.throwIfAborted();
|
|
349
|
+
const { promise, resolve, reject } = Promise.withResolvers();
|
|
350
|
+
const nonce = randomUUID2();
|
|
351
|
+
const payload = {
|
|
352
|
+
cmd,
|
|
353
|
+
args,
|
|
354
|
+
nonce
|
|
355
|
+
};
|
|
356
|
+
if (cmd === RPCCommands.Subscribe || cmd === RPCCommands.Unsubscribe) {
|
|
357
|
+
payload.evt = options?.evt;
|
|
358
|
+
}
|
|
359
|
+
this.transport.send(payload);
|
|
360
|
+
this.#expectedNonces.set(nonce, { resolve, reject });
|
|
361
|
+
const onAbort = /* @__PURE__ */ __name((_) => {
|
|
362
|
+
this.#expectedNonces.delete(nonce);
|
|
363
|
+
const reason = signal.reason instanceof Error ? signal.reason : new Error(String(signal.reason));
|
|
364
|
+
reject(reason);
|
|
365
|
+
}, "onAbort");
|
|
366
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
367
|
+
try {
|
|
368
|
+
return await promise;
|
|
369
|
+
} finally {
|
|
370
|
+
signal.removeEventListener("abort", onAbort);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* Message handler
|
|
375
|
+
*
|
|
376
|
+
* @param message - message
|
|
377
|
+
*/
|
|
378
|
+
#onRpcMessage(message) {
|
|
379
|
+
if (message.cmd === RPCCommands.Dispatch && message.evt === RPCEvents.Ready) {
|
|
380
|
+
if (message.data.user) {
|
|
381
|
+
this.user = message.data.user;
|
|
382
|
+
}
|
|
383
|
+
this.emit(RPCEvents.Ready, message.data);
|
|
384
|
+
} else if (message.cmd === RPCCommands.Dispatch) {
|
|
385
|
+
this.emit(message.evt, message.data);
|
|
386
|
+
} else {
|
|
387
|
+
if (!this.#expectedNonces.has(message.nonce)) {
|
|
388
|
+
return;
|
|
389
|
+
}
|
|
390
|
+
const { resolve, reject } = this.#expectedNonces.get(message.nonce);
|
|
391
|
+
if ("evt" in message && message.evt === RPCEvents.Error) {
|
|
392
|
+
reject(new RPCEventError(message.data));
|
|
393
|
+
} else {
|
|
394
|
+
resolve(message.data);
|
|
395
|
+
}
|
|
396
|
+
this.#expectedNonces.delete(message.nonce);
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* Authorize
|
|
401
|
+
*
|
|
402
|
+
* @param args - authorize args
|
|
403
|
+
*/
|
|
404
|
+
async authorize(args, options) {
|
|
405
|
+
const { code } = await this.request(RPCCommands.Authorize, args, options);
|
|
406
|
+
const jsonBody = {
|
|
407
|
+
client_id: this.clientId,
|
|
408
|
+
client_secret: this.clientSecret,
|
|
409
|
+
code,
|
|
410
|
+
grant_type: "authorization_code"
|
|
411
|
+
};
|
|
412
|
+
if (this.options.redirectUri) {
|
|
413
|
+
jsonBody.redirect_uri = this.options.redirectUri;
|
|
414
|
+
}
|
|
415
|
+
const response = await fetch(`${RouteBases.api}${Routes.oauth2TokenExchange()}`, {
|
|
416
|
+
method: "POST",
|
|
417
|
+
headers: {
|
|
418
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
|
419
|
+
},
|
|
420
|
+
body: new URLSearchParams(jsonBody),
|
|
421
|
+
...options
|
|
422
|
+
});
|
|
423
|
+
if (!response.ok) {
|
|
424
|
+
throw new Error(response.statusText);
|
|
425
|
+
}
|
|
426
|
+
const data = await response.json();
|
|
427
|
+
if (!("access_token" in data)) {
|
|
428
|
+
throw new Error(JSON.stringify(response));
|
|
429
|
+
}
|
|
430
|
+
return data.access_token;
|
|
431
|
+
}
|
|
432
|
+
/**
|
|
433
|
+
* Authenticate
|
|
434
|
+
*
|
|
435
|
+
* @param accessToken - access token
|
|
436
|
+
*/
|
|
437
|
+
async authenticate(accessToken, options) {
|
|
438
|
+
const { application, user } = await this.request(RPCCommands.Authenticate, { access_token: accessToken }, options);
|
|
439
|
+
this.accessToken = accessToken;
|
|
440
|
+
this.application = application;
|
|
441
|
+
this.user = user;
|
|
442
|
+
this.emit("APPLICATION_READY" /* ApplicationReady */);
|
|
443
|
+
return this;
|
|
444
|
+
}
|
|
445
|
+
/**
|
|
446
|
+
* Fetch a guild
|
|
447
|
+
*
|
|
448
|
+
* @param id - Guild id
|
|
449
|
+
* @param timeout - Timeout request
|
|
450
|
+
*/
|
|
451
|
+
async getGuild(id, timeout, options) {
|
|
452
|
+
return this.request(RPCCommands.GetGuild, { guild_id: id, timeout }, options);
|
|
453
|
+
}
|
|
454
|
+
/**
|
|
455
|
+
* Fetch all guilds
|
|
456
|
+
*
|
|
457
|
+
* @param timeout - Timeout request
|
|
458
|
+
*/
|
|
459
|
+
async getGuilds(timeout, options) {
|
|
460
|
+
return this.request(RPCCommands.GetGuilds, { timeout }, options);
|
|
461
|
+
}
|
|
462
|
+
/**
|
|
463
|
+
* Get a channel
|
|
464
|
+
*
|
|
465
|
+
* @param id - Channel id
|
|
466
|
+
*/
|
|
467
|
+
async getChannel(id, options) {
|
|
468
|
+
return this.request(RPCCommands.GetChannel, { channel_id: id }, options);
|
|
469
|
+
}
|
|
470
|
+
/**
|
|
471
|
+
* Get all channels
|
|
472
|
+
*
|
|
473
|
+
* @param id - Guild id
|
|
474
|
+
*/
|
|
475
|
+
async getChannels(id, options) {
|
|
476
|
+
const { channels } = await this.request(RPCCommands.GetChannels, { guild_id: id }, options);
|
|
477
|
+
return channels;
|
|
478
|
+
}
|
|
479
|
+
/**
|
|
480
|
+
* Create channel invite
|
|
481
|
+
*
|
|
482
|
+
* @param id - Channel id
|
|
483
|
+
*/
|
|
484
|
+
async createChannelInvite(id, options) {
|
|
485
|
+
return this.request(RPCCommands.CreateChannelInvite, { channel_id: id }, options);
|
|
486
|
+
}
|
|
487
|
+
/**
|
|
488
|
+
* Tell discord which devices are certified
|
|
489
|
+
*
|
|
490
|
+
* @param devices - Certified devices to send to discord
|
|
491
|
+
*/
|
|
492
|
+
async setCertifiedDevices(devices, options) {
|
|
493
|
+
return this.request(
|
|
494
|
+
RPCCommands.SetCertifiedDevices,
|
|
495
|
+
{
|
|
496
|
+
devices
|
|
497
|
+
},
|
|
498
|
+
options
|
|
499
|
+
);
|
|
500
|
+
}
|
|
501
|
+
/**
|
|
502
|
+
* Set the voice settings for a user, by id
|
|
503
|
+
*
|
|
504
|
+
* @param id - Id of the user to set
|
|
505
|
+
* @param settings - Settings to set
|
|
506
|
+
*/
|
|
507
|
+
async setUserVoiceSettings(id, settings, options) {
|
|
508
|
+
return this.request(
|
|
509
|
+
RPCCommands.SetUserVoiceSettings,
|
|
510
|
+
{
|
|
511
|
+
user_id: id,
|
|
512
|
+
...settings
|
|
513
|
+
},
|
|
514
|
+
options
|
|
515
|
+
);
|
|
516
|
+
}
|
|
517
|
+
/**
|
|
518
|
+
* Move the user to a voice channel
|
|
519
|
+
*
|
|
520
|
+
* @param id - Id of the voice channel
|
|
521
|
+
* @param args - select voice channel args
|
|
522
|
+
* @param options - request options
|
|
523
|
+
*/
|
|
524
|
+
async selectVoiceChannel(id, args = {}, options) {
|
|
525
|
+
const svcArgs = { ...args, channel_id: id };
|
|
526
|
+
return this.request(RPCCommands.SelectVoiceChannel, svcArgs, options);
|
|
527
|
+
}
|
|
528
|
+
/**
|
|
529
|
+
* Move the user to a text channel
|
|
530
|
+
*
|
|
531
|
+
* @param id - Id of the text channel
|
|
532
|
+
* @param args - select text channel args
|
|
533
|
+
* @param options - request options
|
|
534
|
+
*/
|
|
535
|
+
async selectTextChannel(id, args = {}, options) {
|
|
536
|
+
const stcArgs = { ...args, channel_id: id };
|
|
537
|
+
return this.request(RPCCommands.SelectTextChannel, stcArgs, options);
|
|
538
|
+
}
|
|
539
|
+
/**
|
|
540
|
+
* Get current voice settings
|
|
541
|
+
*
|
|
542
|
+
*/
|
|
543
|
+
async getVoiceSettings(options) {
|
|
544
|
+
return this.request(RPCCommands.GetVoiceSettings, {}, options);
|
|
545
|
+
}
|
|
546
|
+
/**
|
|
547
|
+
* Set current voice settings, overriding the current settings until this session disconnects.
|
|
548
|
+
* This also locks the settings for any other rpc sessions which may be connected.
|
|
549
|
+
*
|
|
550
|
+
* @param args - Settings
|
|
551
|
+
*/
|
|
552
|
+
async setVoiceSettings(args, options) {
|
|
553
|
+
return this.request(RPCCommands.SetVoiceSettings, args, options);
|
|
554
|
+
}
|
|
555
|
+
/**
|
|
556
|
+
* Sets the presence for the logged in user.
|
|
557
|
+
*
|
|
558
|
+
* @param activity - The rich presence to pass.
|
|
559
|
+
* @param pid - The application's process ID. Defaults to the executing process' PID.
|
|
560
|
+
* @remarks
|
|
561
|
+
* Clients may only update their activity 5 times per 20 seconds.
|
|
562
|
+
*/
|
|
563
|
+
async setActivity(activity = {}, pid = getPid(), options) {
|
|
564
|
+
activity.instance = Boolean(activity.instance);
|
|
565
|
+
if (activity.timestamps) {
|
|
566
|
+
if ("start" in activity.timestamps && !isValidTimestamp(activity.timestamps.start)) {
|
|
567
|
+
throw new RangeError("timestamps.start must fit into a unix timestamp");
|
|
568
|
+
}
|
|
569
|
+
if ("end" in activity.timestamps && !isValidTimestamp(activity.timestamps.end)) {
|
|
570
|
+
throw new RangeError("timestamps.end must fit into a unix timestamp");
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
return this.request(
|
|
574
|
+
RPCCommands.SetActivity,
|
|
575
|
+
{
|
|
576
|
+
pid: pid ?? 0,
|
|
577
|
+
activity
|
|
578
|
+
},
|
|
579
|
+
options
|
|
580
|
+
);
|
|
581
|
+
}
|
|
582
|
+
/**
|
|
583
|
+
* Clears the currently set presence, if any. This will hide the "Playing X" message
|
|
584
|
+
* displayed below the user's name.
|
|
585
|
+
*
|
|
586
|
+
* @param pid - The application's process ID. Defaults to the executing process' PID.
|
|
587
|
+
*/
|
|
588
|
+
async clearActivity(pid = getPid(), options) {
|
|
589
|
+
return this.request(
|
|
590
|
+
RPCCommands.SetActivity,
|
|
591
|
+
{
|
|
592
|
+
pid: pid ?? 0
|
|
593
|
+
},
|
|
594
|
+
options
|
|
595
|
+
);
|
|
596
|
+
}
|
|
597
|
+
/**
|
|
598
|
+
* Invite a user to join the game the RPC user is currently playing
|
|
599
|
+
*
|
|
600
|
+
* @param userId - The id of the user to invite
|
|
601
|
+
*/
|
|
602
|
+
async sendJoinInvite(userId, options) {
|
|
603
|
+
return this.request(
|
|
604
|
+
RPCCommands.SendActivityJoinInvite,
|
|
605
|
+
{
|
|
606
|
+
user_id: userId
|
|
607
|
+
},
|
|
608
|
+
options
|
|
609
|
+
);
|
|
610
|
+
}
|
|
611
|
+
/**
|
|
612
|
+
* Reject a join request from a user
|
|
613
|
+
*
|
|
614
|
+
* @param userId - The id of the user whose request you wish to reject
|
|
615
|
+
*/
|
|
616
|
+
async closeJoinRequest(userId, options) {
|
|
617
|
+
return this.request(
|
|
618
|
+
RPCCommands.CloseActivityJoinRequest,
|
|
619
|
+
{
|
|
620
|
+
user_id: userId
|
|
621
|
+
},
|
|
622
|
+
options
|
|
623
|
+
);
|
|
624
|
+
}
|
|
625
|
+
/**
|
|
626
|
+
* requires `relationships.read` scope
|
|
627
|
+
*/
|
|
628
|
+
async getRelationships(options) {
|
|
629
|
+
return this.request(RPCCommands.GetRelationships, {}, options);
|
|
630
|
+
}
|
|
631
|
+
/**
|
|
632
|
+
* Fetches a user
|
|
633
|
+
*/
|
|
634
|
+
async getUser(id, options) {
|
|
635
|
+
return this.request(RPCCommands.GetUser, { id }, options);
|
|
636
|
+
}
|
|
637
|
+
/**
|
|
638
|
+
* Fetches a user's profile picture
|
|
639
|
+
*/
|
|
640
|
+
async getImage({ id, format, size }, options) {
|
|
641
|
+
return (await this.request(RPCCommands.GetImage, { type: "user", id, format, size }, options)).data_url;
|
|
642
|
+
}
|
|
643
|
+
/**
|
|
644
|
+
* Subscribe to an event
|
|
645
|
+
*
|
|
646
|
+
* @param event - Name of event e.g. `MESSAGE_CREATE`
|
|
647
|
+
* @param args - Args for event e.g. `{ channel_id: '1234' }`
|
|
648
|
+
*/
|
|
649
|
+
async subscribe(...[event, args, options]) {
|
|
650
|
+
await this.request(RPCCommands.Subscribe, args, { evt: event, ...options });
|
|
651
|
+
return {
|
|
652
|
+
unsubscribe: /* @__PURE__ */ __name(async () => this.request(RPCCommands.Unsubscribe, args, { evt: event, ...options }), "unsubscribe")
|
|
653
|
+
};
|
|
654
|
+
}
|
|
655
|
+
/**
|
|
656
|
+
* Unsubscribe from an event
|
|
657
|
+
*
|
|
658
|
+
* @param event - Name of event e.g. `MESSAGE_CREATE`
|
|
659
|
+
* @param args - Args for event e.g. `{ channel_id: '1234' }`
|
|
660
|
+
*/
|
|
661
|
+
async unsubscribe(...[event, args, options]) {
|
|
662
|
+
await this.request(RPCCommands.Unsubscribe, args, { evt: event, ...options });
|
|
663
|
+
return {
|
|
664
|
+
subscribe: /* @__PURE__ */ __name(async () => this.request(RPCCommands.Subscribe, args, { evt: event, ...options }), "subscribe")
|
|
665
|
+
};
|
|
666
|
+
}
|
|
667
|
+
/**
|
|
668
|
+
* Destroy the client
|
|
669
|
+
*/
|
|
670
|
+
async destroy() {
|
|
671
|
+
await this.transport.close();
|
|
672
|
+
}
|
|
673
|
+
};
|
|
674
|
+
|
|
675
|
+
// src/index.ts
|
|
676
|
+
var version = "0.2.0-dev.1788538586-ecea9ed57";
|
|
677
|
+
export {
|
|
678
|
+
Events,
|
|
679
|
+
IPCTransport,
|
|
680
|
+
RPCClient,
|
|
681
|
+
RPCEventError,
|
|
682
|
+
encode,
|
|
683
|
+
getPid,
|
|
684
|
+
isValidTimestamp,
|
|
685
|
+
register,
|
|
686
|
+
version
|
|
687
|
+
};
|
|
688
|
+
//# sourceMappingURL=index.js.map
|