zynko 0.0.0-stage → 0.1.0
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 +33 -2
- package/dist/bits.d.ts +42 -0
- package/dist/bits.js +46 -0
- package/dist/bits.js.map +1 -0
- package/dist/client.d.ts +132 -0
- package/dist/client.js +369 -0
- package/dist/client.js.map +1 -0
- package/dist/gateway.d.ts +28 -0
- package/dist/gateway.js +102 -0
- package/dist/gateway.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/interaction.d.ts +45 -0
- package/dist/interaction.js +73 -0
- package/dist/interaction.js.map +1 -0
- package/dist/message.d.ts +40 -0
- package/dist/message.js +67 -0
- package/dist/message.js.map +1 -0
- package/dist/player.d.ts +78 -0
- package/dist/player.js +230 -0
- package/dist/player.js.map +1 -0
- package/dist/rest.d.ts +122 -0
- package/dist/rest.js +129 -0
- package/dist/rest.js.map +1 -0
- package/dist/types.d.ts +306 -0
- package/dist/types.js +13 -0
- package/dist/types.js.map +1 -0
- package/dist/voice.d.ts +63 -0
- package/dist/voice.js +203 -0
- package/dist/voice.js.map +1 -0
- package/package.json +43 -4
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The realtime link (docs.zynko.org/api/gateway): HELLO, IDENTIFY with the token and the
|
|
3
|
+
* intents, heartbeats, and a fresh IDENTIFY after any drop (there is no RESUME: READY always
|
|
4
|
+
* brings the whole state again).
|
|
5
|
+
*/
|
|
6
|
+
export interface GatewayOptions {
|
|
7
|
+
url: string;
|
|
8
|
+
token: string;
|
|
9
|
+
intents: number;
|
|
10
|
+
onDispatch: (t: string, d: any) => void;
|
|
11
|
+
onState: (state: 'connecting' | 'ready' | 'reconnecting' | 'closed', detail?: unknown) => void;
|
|
12
|
+
}
|
|
13
|
+
export declare class Gateway {
|
|
14
|
+
private readonly opts;
|
|
15
|
+
private ws;
|
|
16
|
+
private beat;
|
|
17
|
+
private retry;
|
|
18
|
+
private stopped;
|
|
19
|
+
private lastAck;
|
|
20
|
+
constructor(opts: GatewayOptions);
|
|
21
|
+
connect(): void;
|
|
22
|
+
/** Sends an op (4: voice state). Returns whether the link was open. */
|
|
23
|
+
send(op: number, d: unknown): boolean;
|
|
24
|
+
close(): void;
|
|
25
|
+
private onMessage;
|
|
26
|
+
private onClose;
|
|
27
|
+
private clearBeat;
|
|
28
|
+
}
|
package/dist/gateway.js
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The realtime link (docs.zynko.org/api/gateway): HELLO, IDENTIFY with the token and the
|
|
3
|
+
* intents, heartbeats, and a fresh IDENTIFY after any drop (there is no RESUME: READY always
|
|
4
|
+
* brings the whole state again).
|
|
5
|
+
*/
|
|
6
|
+
/** Close codes after which trying again cannot help. */
|
|
7
|
+
const FATAL = new Set([4004]);
|
|
8
|
+
export class Gateway {
|
|
9
|
+
opts;
|
|
10
|
+
ws = null;
|
|
11
|
+
beat = null;
|
|
12
|
+
retry = 0;
|
|
13
|
+
stopped = false;
|
|
14
|
+
lastAck = 0;
|
|
15
|
+
constructor(opts) {
|
|
16
|
+
this.opts = opts;
|
|
17
|
+
}
|
|
18
|
+
connect() {
|
|
19
|
+
this.stopped = false;
|
|
20
|
+
this.opts.onState(this.retry ? 'reconnecting' : 'connecting');
|
|
21
|
+
const ws = new WebSocket(this.opts.url);
|
|
22
|
+
this.ws = ws;
|
|
23
|
+
ws.onmessage = (e) => this.onMessage(typeof e.data === 'string' ? e.data : String(e.data));
|
|
24
|
+
ws.onclose = (e) => this.onClose(ws, e.code, e.reason);
|
|
25
|
+
ws.onerror = () => {
|
|
26
|
+
/* onclose follows */
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
/** Sends an op (4: voice state). Returns whether the link was open. */
|
|
30
|
+
send(op, d) {
|
|
31
|
+
if (this.ws?.readyState !== WebSocket.OPEN)
|
|
32
|
+
return false;
|
|
33
|
+
this.ws.send(JSON.stringify({ op, d }));
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
close() {
|
|
37
|
+
this.stopped = true;
|
|
38
|
+
this.clearBeat();
|
|
39
|
+
this.ws?.close(1000);
|
|
40
|
+
this.ws = null;
|
|
41
|
+
}
|
|
42
|
+
onMessage(raw) {
|
|
43
|
+
let msg;
|
|
44
|
+
try {
|
|
45
|
+
msg = JSON.parse(raw);
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
switch (msg.op) {
|
|
51
|
+
case 10: {
|
|
52
|
+
this.send(2, { token: this.opts.token, intents: this.opts.intents });
|
|
53
|
+
this.clearBeat();
|
|
54
|
+
this.lastAck = Date.now();
|
|
55
|
+
const every = msg.d?.heartbeat_interval ?? 30_000;
|
|
56
|
+
this.beat = setInterval(() => {
|
|
57
|
+
// No answer to two beats in a row: the link is dead even if the socket says otherwise.
|
|
58
|
+
if (Date.now() - this.lastAck > every * 2 + 5_000)
|
|
59
|
+
return this.ws?.close(4900, 'heartbeat timeout');
|
|
60
|
+
this.send(1, null);
|
|
61
|
+
}, every);
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
case 11:
|
|
65
|
+
this.lastAck = Date.now();
|
|
66
|
+
return;
|
|
67
|
+
case 0:
|
|
68
|
+
this.lastAck = Date.now();
|
|
69
|
+
if (msg.t === 'READY') {
|
|
70
|
+
this.retry = 0;
|
|
71
|
+
this.opts.onState('ready');
|
|
72
|
+
}
|
|
73
|
+
if (msg.t)
|
|
74
|
+
this.opts.onDispatch(msg.t, msg.d);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
onClose(ws, code, reason) {
|
|
79
|
+
if (ws !== this.ws)
|
|
80
|
+
return;
|
|
81
|
+
this.clearBeat();
|
|
82
|
+
this.ws = null;
|
|
83
|
+
if (this.stopped)
|
|
84
|
+
return;
|
|
85
|
+
if (FATAL.has(code)) {
|
|
86
|
+
this.stopped = true;
|
|
87
|
+
this.opts.onState('closed', new Error(`Token recusado pelo gateway (${code} ${reason})`));
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
// 1s, 2s, 4s... up to 30s, with some jitter so a server restart is not hit all at once.
|
|
91
|
+
const wait = Math.min(30_000, 1000 * 2 ** this.retry) * (0.75 + Math.random() / 2);
|
|
92
|
+
this.retry++;
|
|
93
|
+
this.opts.onState('reconnecting', { code, reason, wait });
|
|
94
|
+
setTimeout(() => !this.stopped && this.connect(), wait);
|
|
95
|
+
}
|
|
96
|
+
clearBeat() {
|
|
97
|
+
if (this.beat)
|
|
98
|
+
clearInterval(this.beat);
|
|
99
|
+
this.beat = null;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=gateway.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gateway.js","sourceRoot":"","sources":["../src/gateway.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* zynko: the official library for Zynko bots (docs.zynko.org/bots).
|
|
3
|
+
* API and gateway with no dependencies; voice through `@livekit/rtc-node`, loaded only when
|
|
4
|
+
* a bot joins a voice room.
|
|
5
|
+
*/
|
|
6
|
+
export { Client, type CachedGuild, type ClientEvents, type ClientOptions } from './client.js';
|
|
7
|
+
export { Intents, Permissions, idTime } from './bits.js';
|
|
8
|
+
export { Interaction } from './interaction.js';
|
|
9
|
+
export { Message } from './message.js';
|
|
10
|
+
export { Rest, ZynkoError, type EditOptions, type FileInput, type ReplyOptions, type RestOptions, type SendOptions } from './rest.js';
|
|
11
|
+
export { AudioPlayer, tone, type AudioInput, type PlayerEvents, type PlayerOptions, type Track } from './player.js';
|
|
12
|
+
export type { JoinVoiceOptions, VoiceConnection, VoiceEvents } from './voice.js';
|
|
13
|
+
export * from './types.js';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* zynko: the official library for Zynko bots (docs.zynko.org/bots).
|
|
3
|
+
* API and gateway with no dependencies; voice through `@livekit/rtc-node`, loaded only when
|
|
4
|
+
* a bot joins a voice room.
|
|
5
|
+
*/
|
|
6
|
+
export { Client } from './client.js';
|
|
7
|
+
export { Intents, Permissions, idTime } from './bits.js';
|
|
8
|
+
export { Interaction } from './interaction.js';
|
|
9
|
+
export { Message } from './message.js';
|
|
10
|
+
export { Rest, ZynkoError } from './rest.js';
|
|
11
|
+
export { AudioPlayer, tone } from './player.js';
|
|
12
|
+
export * from './types.js';
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,MAAM,EAA2D,MAAM,aAAa,CAAC;AAC9F,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,UAAU,EAA2F,MAAM,WAAW,CAAC;AACtI,OAAO,EAAE,WAAW,EAAE,IAAI,EAAsE,MAAM,aAAa,CAAC;AAEpH,cAAc,YAAY,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { Client } from './client.js';
|
|
2
|
+
import { Message } from './message.js';
|
|
3
|
+
import type { EditOptions, ReplyOptions } from './rest.js';
|
|
4
|
+
import type { Channel, Id, InteractionData, Member, User } from './types.js';
|
|
5
|
+
/**
|
|
6
|
+
* Someone used one of the bot's "/" commands, or clicked a button on one of its messages.
|
|
7
|
+
* Answer within 15 minutes: `reply` posts a message (or one only they see), `update` changes
|
|
8
|
+
* the message whose button was clicked.
|
|
9
|
+
*
|
|
10
|
+
* ```ts
|
|
11
|
+
* client.on('interaction', async (i) => {
|
|
12
|
+
* if (i.command === 'dado') await i.reply(`🎲 ${1 + Math.floor(Math.random() * (i.option<number>('lados') ?? 6))}`);
|
|
13
|
+
* });
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
export declare class Interaction {
|
|
17
|
+
readonly client: Client;
|
|
18
|
+
readonly data: InteractionData;
|
|
19
|
+
readonly id: Id;
|
|
20
|
+
readonly token: string;
|
|
21
|
+
readonly type: 'command' | 'button';
|
|
22
|
+
readonly channelId: Id;
|
|
23
|
+
readonly guildId: Id | null;
|
|
24
|
+
/** Who used it. */
|
|
25
|
+
readonly user: User;
|
|
26
|
+
readonly member: Member | null;
|
|
27
|
+
/** The command's name, for commands. */
|
|
28
|
+
readonly command: string | null;
|
|
29
|
+
/** What was typed for each option, by name. */
|
|
30
|
+
readonly options: Record<string, string | number | boolean>;
|
|
31
|
+
/** The clicked button's `custom_id`, for buttons. */
|
|
32
|
+
readonly customId: string | null;
|
|
33
|
+
/** The message whose button was clicked. */
|
|
34
|
+
readonly message: Message | null;
|
|
35
|
+
/** Whether it was answered already. */
|
|
36
|
+
replied: boolean;
|
|
37
|
+
constructor(client: Client, data: InteractionData);
|
|
38
|
+
/** One option's value; `undefined` when it was left out. User, channel and role options are ids. */
|
|
39
|
+
option<T extends string | number | boolean = string>(name: string): T | undefined;
|
|
40
|
+
get channel(): Channel | undefined;
|
|
41
|
+
/** Answers with a message in the channel, or only for that person with `ephemeral: true`. May be called again for follow-ups. */
|
|
42
|
+
reply(answer: string | ReplyOptions): Promise<Message>;
|
|
43
|
+
/** Changes the message whose button was clicked: whatever is given (text, cards, buttons). */
|
|
44
|
+
update(edit: string | EditOptions): Promise<Message>;
|
|
45
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { Message } from './message.js';
|
|
2
|
+
/**
|
|
3
|
+
* Someone used one of the bot's "/" commands, or clicked a button on one of its messages.
|
|
4
|
+
* Answer within 15 minutes: `reply` posts a message (or one only they see), `update` changes
|
|
5
|
+
* the message whose button was clicked.
|
|
6
|
+
*
|
|
7
|
+
* ```ts
|
|
8
|
+
* client.on('interaction', async (i) => {
|
|
9
|
+
* if (i.command === 'dado') await i.reply(`🎲 ${1 + Math.floor(Math.random() * (i.option<number>('lados') ?? 6))}`);
|
|
10
|
+
* });
|
|
11
|
+
* ```
|
|
12
|
+
*/
|
|
13
|
+
export class Interaction {
|
|
14
|
+
client;
|
|
15
|
+
data;
|
|
16
|
+
id;
|
|
17
|
+
token;
|
|
18
|
+
type;
|
|
19
|
+
channelId;
|
|
20
|
+
guildId;
|
|
21
|
+
/** Who used it. */
|
|
22
|
+
user;
|
|
23
|
+
member;
|
|
24
|
+
/** The command's name, for commands. */
|
|
25
|
+
command;
|
|
26
|
+
/** What was typed for each option, by name. */
|
|
27
|
+
options;
|
|
28
|
+
/** The clicked button's `custom_id`, for buttons. */
|
|
29
|
+
customId;
|
|
30
|
+
/** The message whose button was clicked. */
|
|
31
|
+
message;
|
|
32
|
+
/** Whether it was answered already. */
|
|
33
|
+
replied = false;
|
|
34
|
+
constructor(client, data) {
|
|
35
|
+
this.client = client;
|
|
36
|
+
this.data = data;
|
|
37
|
+
this.id = data.id;
|
|
38
|
+
this.token = data.token;
|
|
39
|
+
this.type = data.type;
|
|
40
|
+
this.channelId = data.channel_id;
|
|
41
|
+
this.guildId = data.guild_id;
|
|
42
|
+
this.user = data.user;
|
|
43
|
+
this.member = data.member;
|
|
44
|
+
this.command = data.command?.name ?? null;
|
|
45
|
+
this.options = Object.fromEntries((data.command?.options ?? []).map((o) => [o.name, o.value]));
|
|
46
|
+
this.customId = data.custom_id ?? null;
|
|
47
|
+
this.message = data.message ? new Message(client, data.message) : null;
|
|
48
|
+
}
|
|
49
|
+
/** One option's value; `undefined` when it was left out. User, channel and role options are ids. */
|
|
50
|
+
option(name) {
|
|
51
|
+
return this.options[name];
|
|
52
|
+
}
|
|
53
|
+
get channel() {
|
|
54
|
+
return this.client.channels.get(this.channelId);
|
|
55
|
+
}
|
|
56
|
+
/** Answers with a message in the channel, or only for that person with `ephemeral: true`. May be called again for follow-ups. */
|
|
57
|
+
async reply(answer) {
|
|
58
|
+
const body = typeof answer === 'string' ? { content: answer } : answer;
|
|
59
|
+
const msg = await this.client.rest.interactionCallback(this.id, this.token, { ...body, type: 'message' });
|
|
60
|
+
this.replied = true;
|
|
61
|
+
return new Message(this.client, msg);
|
|
62
|
+
}
|
|
63
|
+
/** Changes the message whose button was clicked: whatever is given (text, cards, buttons). */
|
|
64
|
+
async update(edit) {
|
|
65
|
+
if (this.type !== 'button')
|
|
66
|
+
throw new Error('update() é só para cliques em botões');
|
|
67
|
+
const body = typeof edit === 'string' ? { content: edit } : edit;
|
|
68
|
+
const msg = await this.client.rest.interactionCallback(this.id, this.token, { ...body, type: 'update' });
|
|
69
|
+
this.replied = true;
|
|
70
|
+
return new Message(this.client, msg);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=interaction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interaction.js","sourceRoot":"","sources":["../src/interaction.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAIvC;;;;;;;;;;GAUG;AACH,MAAM,OAAO,WAAW;IAqBX;IACA;IArBF,EAAE,CAAK;IACP,KAAK,CAAS;IACd,IAAI,CAAuB;IAC3B,SAAS,CAAK;IACd,OAAO,CAAY;IAC5B,mBAAmB;IACV,IAAI,CAAO;IACX,MAAM,CAAgB;IAC/B,wCAAwC;IAC/B,OAAO,CAAgB;IAChC,+CAA+C;IACtC,OAAO,CAA4C;IAC5D,qDAAqD;IAC5C,QAAQ,CAAgB;IACjC,4CAA4C;IACnC,OAAO,CAAiB;IACjC,uCAAuC;IACvC,OAAO,GAAG,KAAK,CAAC;IAEhB,YACW,MAAc,EACd,IAAqB;QADrB,WAAM,GAAN,MAAM,CAAQ;QACd,SAAI,GAAJ,IAAI,CAAiB;QAE9B,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC;QAClB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QACxB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACtB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC;QACjC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC7B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACtB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAC1B,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,IAAI,IAAI,IAAI,CAAC;QAC1C,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC/F,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC;QACvC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACzE,CAAC;IAED,oGAAoG;IACpG,MAAM,CAA+C,IAAY;QAC/D,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAkB,CAAC;IAC7C,CAAC;IAED,IAAI,OAAO;QACT,OAAO,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAClD,CAAC;IAED,iIAAiI;IACjI,KAAK,CAAC,KAAK,CAAC,MAA6B;QACvC,MAAM,IAAI,GAAG,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;QACvE,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,EAAE,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;QAC1G,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACpB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACvC,CAAC;IAED,8FAA8F;IAC9F,KAAK,CAAC,MAAM,CAAC,IAA0B;QACrC,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ;YAAE,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;QACpF,MAAM,IAAI,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QACjE,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,EAAE,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;QACzG,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACpB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACvC,CAAC;CACF"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { Client } from './client.js';
|
|
2
|
+
import type { EditOptions, SendOptions } from './rest.js';
|
|
3
|
+
import type { Attachment, Card, Channel, Components, Embed, Id, InteractionRef, Member, MessageData, MessageRef, ReactionCount, User } from './types.js';
|
|
4
|
+
/** A message, with shortcuts to answer it, react, edit and delete. */
|
|
5
|
+
export declare class Message {
|
|
6
|
+
readonly client: Client;
|
|
7
|
+
readonly id: Id;
|
|
8
|
+
readonly channelId: Id;
|
|
9
|
+
readonly author: User;
|
|
10
|
+
content: string;
|
|
11
|
+
readonly timestamp: number;
|
|
12
|
+
editedTimestamp: number | null;
|
|
13
|
+
readonly replyTo: MessageRef | null;
|
|
14
|
+
attachments: Attachment[];
|
|
15
|
+
reactions: ReactionCount[];
|
|
16
|
+
embeds: Embed[];
|
|
17
|
+
cards: Card[];
|
|
18
|
+
components: Components;
|
|
19
|
+
/** The command or click this (bot) message answers. */
|
|
20
|
+
readonly interaction: InteractionRef | null;
|
|
21
|
+
/** Only its reader sees it, and it is not kept. */
|
|
22
|
+
readonly ephemeral: boolean;
|
|
23
|
+
readonly nonce: string | null;
|
|
24
|
+
constructor(client: Client, data: MessageData);
|
|
25
|
+
/** The channel, when the client has seen it. */
|
|
26
|
+
get channel(): Channel | undefined;
|
|
27
|
+
/** The house the message is in; null in a DM. */
|
|
28
|
+
get guildId(): Id | null;
|
|
29
|
+
/** The author as a member of the house (nickname, roles); undefined in DMs. */
|
|
30
|
+
get member(): Member | undefined;
|
|
31
|
+
/** Whether the author is the bot itself. */
|
|
32
|
+
get mine(): boolean;
|
|
33
|
+
/** Answers in the same channel, as a reply to this message. */
|
|
34
|
+
reply(message: string | Omit<SendOptions, 'replyTo'>): Promise<Message>;
|
|
35
|
+
react: (emoji: string) => Promise<unknown>;
|
|
36
|
+
unreact: (emoji: string) => Promise<unknown>;
|
|
37
|
+
/** Only the author edits: a bot edits its own messages (text, cards, buttons). */
|
|
38
|
+
edit: (edit: string | EditOptions) => Promise<Message>;
|
|
39
|
+
delete: () => Promise<unknown>;
|
|
40
|
+
}
|
package/dist/message.js
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/** A message, with shortcuts to answer it, react, edit and delete. */
|
|
2
|
+
export class Message {
|
|
3
|
+
client;
|
|
4
|
+
id;
|
|
5
|
+
channelId;
|
|
6
|
+
author;
|
|
7
|
+
content;
|
|
8
|
+
timestamp;
|
|
9
|
+
editedTimestamp;
|
|
10
|
+
replyTo;
|
|
11
|
+
attachments;
|
|
12
|
+
reactions;
|
|
13
|
+
embeds;
|
|
14
|
+
cards;
|
|
15
|
+
components;
|
|
16
|
+
/** The command or click this (bot) message answers. */
|
|
17
|
+
interaction;
|
|
18
|
+
/** Only its reader sees it, and it is not kept. */
|
|
19
|
+
ephemeral;
|
|
20
|
+
nonce;
|
|
21
|
+
constructor(client, data) {
|
|
22
|
+
this.client = client;
|
|
23
|
+
this.id = data.id;
|
|
24
|
+
this.channelId = data.channel_id;
|
|
25
|
+
this.author = data.author;
|
|
26
|
+
this.content = data.content;
|
|
27
|
+
this.timestamp = data.timestamp;
|
|
28
|
+
this.editedTimestamp = data.edited_timestamp;
|
|
29
|
+
this.replyTo = data.reply_to;
|
|
30
|
+
this.attachments = data.attachments ?? [];
|
|
31
|
+
this.reactions = data.reactions ?? [];
|
|
32
|
+
this.embeds = data.embeds ?? [];
|
|
33
|
+
this.cards = data.cards ?? [];
|
|
34
|
+
this.components = data.components ?? [];
|
|
35
|
+
this.interaction = data.interaction ?? null;
|
|
36
|
+
this.ephemeral = !!data.ephemeral;
|
|
37
|
+
this.nonce = data.nonce;
|
|
38
|
+
}
|
|
39
|
+
/** The channel, when the client has seen it. */
|
|
40
|
+
get channel() {
|
|
41
|
+
return this.client.channels.get(this.channelId);
|
|
42
|
+
}
|
|
43
|
+
/** The house the message is in; null in a DM. */
|
|
44
|
+
get guildId() {
|
|
45
|
+
return this.channel?.guild_id ?? null;
|
|
46
|
+
}
|
|
47
|
+
/** The author as a member of the house (nickname, roles); undefined in DMs. */
|
|
48
|
+
get member() {
|
|
49
|
+
const g = this.guildId;
|
|
50
|
+
return g ? this.client.guilds.get(g)?.members.get(this.author.id) : undefined;
|
|
51
|
+
}
|
|
52
|
+
/** Whether the author is the bot itself. */
|
|
53
|
+
get mine() {
|
|
54
|
+
return this.author.id === this.client.user?.id;
|
|
55
|
+
}
|
|
56
|
+
/** Answers in the same channel, as a reply to this message. */
|
|
57
|
+
async reply(message) {
|
|
58
|
+
const opts = typeof message === 'string' ? { content: message } : message;
|
|
59
|
+
return this.client.send(this.channelId, { ...opts, replyTo: this.id });
|
|
60
|
+
}
|
|
61
|
+
react = (emoji) => this.client.rest.react(this.channelId, this.id, emoji);
|
|
62
|
+
unreact = (emoji) => this.client.rest.unreact(this.channelId, this.id, emoji);
|
|
63
|
+
/** Only the author edits: a bot edits its own messages (text, cards, buttons). */
|
|
64
|
+
edit = async (edit) => new Message(this.client, await this.client.rest.editMessage(this.channelId, this.id, edit));
|
|
65
|
+
delete = () => this.client.rest.deleteMessage(this.channelId, this.id);
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=message.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message.js","sourceRoot":"","sources":["../src/message.ts"],"names":[],"mappings":"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"}
|
package/dist/player.d.ts
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import type { Readable } from 'node:stream';
|
|
2
|
+
export declare const SAMPLE_RATE = 48000;
|
|
3
|
+
export declare const CHANNELS = 2;
|
|
4
|
+
export declare const FRAME_SAMPLES = 960;
|
|
5
|
+
/**
|
|
6
|
+
* What to play:
|
|
7
|
+
* - a path or an http(s) link, opened by ffmpeg;
|
|
8
|
+
* - `{ stream }`: encoded audio (an mp3 download, a pipe), decoded by ffmpeg;
|
|
9
|
+
* - `{ pcm }`: raw PCM already at 48 kHz, stereo, 16-bit little-endian.
|
|
10
|
+
*/
|
|
11
|
+
export type AudioInput = string | {
|
|
12
|
+
stream: Readable | AsyncIterable<Uint8Array>;
|
|
13
|
+
} | {
|
|
14
|
+
pcm: Readable | AsyncIterable<Uint8Array>;
|
|
15
|
+
};
|
|
16
|
+
export interface Track<M = unknown> {
|
|
17
|
+
input: AudioInput;
|
|
18
|
+
/** Whatever you want back in events: a title, who asked for it... */
|
|
19
|
+
meta?: M;
|
|
20
|
+
}
|
|
21
|
+
export interface PlayerOptions {
|
|
22
|
+
/** ffmpeg's path. Default: FFMPEG_PATH, or `ffmpeg` on the PATH. */
|
|
23
|
+
ffmpeg?: string;
|
|
24
|
+
/**
|
|
25
|
+
* Hand http(s) links to yt-dlp first (its path, or true for `yt-dlp` on the PATH), for
|
|
26
|
+
* pages of sites it supports instead of direct audio links.
|
|
27
|
+
*/
|
|
28
|
+
ytdlp?: boolean | string;
|
|
29
|
+
}
|
|
30
|
+
/** Where the player writes frames: the voice connection. */
|
|
31
|
+
export interface FrameSink {
|
|
32
|
+
capture(frame: Int16Array): Promise<void>;
|
|
33
|
+
/** Drops what is buffered, so a skip or pause is heard at once. */
|
|
34
|
+
flush(): void;
|
|
35
|
+
}
|
|
36
|
+
export interface PlayerEvents<M> {
|
|
37
|
+
start: [track: Track<M>];
|
|
38
|
+
finish: [track: Track<M>];
|
|
39
|
+
error: [error: Error, track: Track<M>];
|
|
40
|
+
/** Nothing left in the queue. */
|
|
41
|
+
idle: [];
|
|
42
|
+
}
|
|
43
|
+
/** A sine wave, for testing: `{ pcm: tone(440, 2) }`. */
|
|
44
|
+
export declare function tone(hz?: number, seconds?: number, volume?: number): AsyncGenerator<Uint8Array>;
|
|
45
|
+
export declare class AudioPlayer<M = unknown> {
|
|
46
|
+
private readonly sink;
|
|
47
|
+
private readonly opts;
|
|
48
|
+
/** Played after the current one, in order. */
|
|
49
|
+
readonly queue: Track<M>[];
|
|
50
|
+
/** What is playing now. */
|
|
51
|
+
current: Track<M> | null;
|
|
52
|
+
paused: boolean;
|
|
53
|
+
private _volume;
|
|
54
|
+
private readonly emitter;
|
|
55
|
+
private abort;
|
|
56
|
+
private resumeWaiters;
|
|
57
|
+
private running;
|
|
58
|
+
constructor(sink: FrameSink, opts?: PlayerOptions);
|
|
59
|
+
on<K extends keyof PlayerEvents<M>>(event: K, listener: (...args: PlayerEvents<M>[K]) => void): this;
|
|
60
|
+
off<K extends keyof PlayerEvents<M>>(event: K, listener: (...args: PlayerEvents<M>[K]) => void): this;
|
|
61
|
+
/** 0 (silent) to 2 (twice as loud); 1 is as it came. */
|
|
62
|
+
get volume(): number;
|
|
63
|
+
set volume(v: number);
|
|
64
|
+
/** Plays now, in place of what was playing (the queue stays). */
|
|
65
|
+
play(input: AudioInput, meta?: M): Track<M>;
|
|
66
|
+
/** Adds to the end of the queue; starts if nothing is playing. */
|
|
67
|
+
enqueue(input: AudioInput, meta?: M): Track<M>;
|
|
68
|
+
/** Goes to the next in the queue. */
|
|
69
|
+
skip(): void;
|
|
70
|
+
/** Stops and empties the queue. */
|
|
71
|
+
stop(): void;
|
|
72
|
+
pause(): void;
|
|
73
|
+
resume(): void;
|
|
74
|
+
private loop;
|
|
75
|
+
private playOne;
|
|
76
|
+
/** The input as raw PCM. */
|
|
77
|
+
private open;
|
|
78
|
+
}
|