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/dist/player.js ADDED
@@ -0,0 +1,230 @@
1
+ /**
2
+ * Plays audio into a voice connection: files and links through ffmpeg (any format and stream
3
+ * it opens: mp3, ogg, wav, radio streams...), raw PCM, or tones. A queue, pause, skip,
4
+ * volume. Audio goes out as 48 kHz stereo 16-bit, in 20 ms frames.
5
+ */
6
+ import { spawn } from 'node:child_process';
7
+ import { EventEmitter } from 'node:events';
8
+ export const SAMPLE_RATE = 48_000;
9
+ export const CHANNELS = 2;
10
+ export const FRAME_SAMPLES = 960; // 20 ms per channel
11
+ const FRAME_BYTES = FRAME_SAMPLES * CHANNELS * 2;
12
+ /** A sine wave, for testing: `{ pcm: tone(440, 2) }`. */
13
+ export async function* tone(hz = 440, seconds = 1, volume = 0.2) {
14
+ const total = Math.round(seconds * SAMPLE_RATE);
15
+ for (let start = 0; start < total; start += FRAME_SAMPLES) {
16
+ const n = Math.min(FRAME_SAMPLES, total - start);
17
+ const buf = new Int16Array(n * CHANNELS);
18
+ for (let i = 0; i < n; i++) {
19
+ const v = Math.round(Math.sin((2 * Math.PI * hz * (start + i)) / SAMPLE_RATE) * volume * 32767);
20
+ buf[i * 2] = v;
21
+ buf[i * 2 + 1] = v;
22
+ }
23
+ yield new Uint8Array(buf.buffer);
24
+ }
25
+ }
26
+ export class AudioPlayer {
27
+ sink;
28
+ opts;
29
+ /** Played after the current one, in order. */
30
+ queue = [];
31
+ /** What is playing now. */
32
+ current = null;
33
+ paused = false;
34
+ _volume = 1;
35
+ emitter = new EventEmitter();
36
+ abort = null;
37
+ resumeWaiters = [];
38
+ running = false;
39
+ constructor(sink, opts = {}) {
40
+ this.sink = sink;
41
+ this.opts = opts;
42
+ this.emitter.on('error', () => { });
43
+ }
44
+ on(event, listener) {
45
+ this.emitter.on(event, listener);
46
+ return this;
47
+ }
48
+ off(event, listener) {
49
+ this.emitter.off(event, listener);
50
+ return this;
51
+ }
52
+ /** 0 (silent) to 2 (twice as loud); 1 is as it came. */
53
+ get volume() {
54
+ return this._volume;
55
+ }
56
+ set volume(v) {
57
+ this._volume = Math.max(0, Math.min(2, v));
58
+ }
59
+ /** Plays now, in place of what was playing (the queue stays). */
60
+ play(input, meta) {
61
+ const track = { input, meta };
62
+ this.queue.unshift(track);
63
+ if (this.running)
64
+ this.skip();
65
+ else
66
+ void this.loop();
67
+ return track;
68
+ }
69
+ /** Adds to the end of the queue; starts if nothing is playing. */
70
+ enqueue(input, meta) {
71
+ const track = { input, meta };
72
+ this.queue.push(track);
73
+ if (!this.running)
74
+ void this.loop();
75
+ return track;
76
+ }
77
+ /** Goes to the next in the queue. */
78
+ skip() {
79
+ this.abort?.();
80
+ this.sink.flush();
81
+ this.resume();
82
+ }
83
+ /** Stops and empties the queue. */
84
+ stop() {
85
+ this.queue.length = 0;
86
+ this.skip();
87
+ }
88
+ pause() {
89
+ if (this.paused || !this.current)
90
+ return;
91
+ this.paused = true;
92
+ this.sink.flush();
93
+ }
94
+ resume() {
95
+ this.paused = false;
96
+ for (const w of this.resumeWaiters.splice(0))
97
+ w();
98
+ }
99
+ async loop() {
100
+ this.running = true;
101
+ try {
102
+ let track;
103
+ while ((track = this.queue.shift())) {
104
+ this.current = track;
105
+ this.emitter.emit('start', track);
106
+ try {
107
+ await this.playOne(track);
108
+ this.emitter.emit('finish', track);
109
+ }
110
+ catch (e) {
111
+ this.emitter.emit('error', e instanceof Error ? e : new Error(String(e)), track);
112
+ }
113
+ }
114
+ }
115
+ finally {
116
+ this.current = null;
117
+ this.running = false;
118
+ this.paused = false;
119
+ this.emitter.emit('idle');
120
+ }
121
+ }
122
+ async playOne(track) {
123
+ let stopped = false;
124
+ const procs = [];
125
+ this.abort = () => {
126
+ stopped = true;
127
+ for (const p of procs)
128
+ p.kill('SIGKILL');
129
+ };
130
+ const pcm = this.open(track.input, procs);
131
+ let carry = new Uint8Array(0);
132
+ try {
133
+ for await (const chunk of pcm) {
134
+ if (stopped)
135
+ break;
136
+ const bytes = chunk instanceof Uint8Array ? chunk : new Uint8Array(chunk);
137
+ let data = carry.length ? concat(carry, bytes) : bytes;
138
+ let at = 0;
139
+ for (; at + FRAME_BYTES <= data.length; at += FRAME_BYTES) {
140
+ while (this.paused && !stopped)
141
+ await new Promise((r) => this.resumeWaiters.push(r));
142
+ if (stopped)
143
+ break;
144
+ const frame = new Int16Array(data.slice(at, at + FRAME_BYTES).buffer);
145
+ if (this._volume !== 1)
146
+ scale(frame, this._volume);
147
+ await this.sink.capture(frame);
148
+ }
149
+ carry = data.slice(at);
150
+ if (stopped)
151
+ break;
152
+ }
153
+ // The last partial frame, padded with silence.
154
+ if (!stopped && carry.length) {
155
+ const frame = new Int16Array(FRAME_SAMPLES * CHANNELS);
156
+ frame.set(new Int16Array(carry.slice(0, carry.length - (carry.length % 2)).buffer));
157
+ await this.sink.capture(frame);
158
+ }
159
+ const failed = procs.find((p) => p.exitCode !== null && p.exitCode !== 0 && !stopped);
160
+ if (failed)
161
+ throw new Error(`${failed.spawnfile} terminou com código ${failed.exitCode}`);
162
+ }
163
+ finally {
164
+ this.abort = null;
165
+ for (const p of procs)
166
+ if (p.exitCode === null)
167
+ p.kill('SIGKILL');
168
+ }
169
+ }
170
+ /** The input as raw PCM. */
171
+ open(input, procs) {
172
+ if (typeof input === 'object' && 'pcm' in input)
173
+ return input.pcm;
174
+ const ffmpeg = this.opts.ffmpeg ?? process.env.FFMPEG_PATH ?? 'ffmpeg';
175
+ const out = ['-f', 's16le', '-ar', String(SAMPLE_RATE), '-ac', String(CHANNELS), '-loglevel', 'error', 'pipe:1'];
176
+ let source = null;
177
+ let args;
178
+ if (typeof input === 'string') {
179
+ const http = /^https?:\/\//i.test(input);
180
+ if (http && this.opts.ytdlp) {
181
+ const ytdlp = typeof this.opts.ytdlp === 'string' ? this.opts.ytdlp : 'yt-dlp';
182
+ const y = spawn(ytdlp, ['-f', 'bestaudio/best', '--no-playlist', '--quiet', '-o', '-', input], { stdio: ['ignore', 'pipe', 'inherit'] });
183
+ procs.push(y);
184
+ source = y.stdout;
185
+ args = ['-i', 'pipe:0', ...out];
186
+ }
187
+ else {
188
+ const reconnect = http ? ['-reconnect', '1', '-reconnect_streamed', '1', '-reconnect_delay_max', '5'] : [];
189
+ args = [...reconnect, '-i', input, ...out];
190
+ }
191
+ }
192
+ else {
193
+ source = input.stream;
194
+ args = ['-i', 'pipe:0', ...out];
195
+ }
196
+ const f = spawn(ffmpeg, ['-hide_banner', ...(source ? [] : ['-nostdin']), ...args], {
197
+ stdio: [source ? 'pipe' : 'ignore', 'pipe', 'inherit'],
198
+ });
199
+ f.on('error', () => { });
200
+ procs.push(f);
201
+ if (source)
202
+ void pipeInto(source, f);
203
+ return f.stdout;
204
+ }
205
+ }
206
+ async function pipeInto(source, f) {
207
+ try {
208
+ for await (const chunk of source) {
209
+ if (!f.stdin.write(chunk))
210
+ await new Promise((r) => f.stdin.once('drain', r));
211
+ }
212
+ }
213
+ catch {
214
+ /* ffmpeg went away (skip) */
215
+ }
216
+ finally {
217
+ f.stdin?.end();
218
+ }
219
+ }
220
+ function concat(a, b) {
221
+ const out = new Uint8Array(a.length + b.length);
222
+ out.set(a);
223
+ out.set(b, a.length);
224
+ return out;
225
+ }
226
+ function scale(frame, v) {
227
+ for (let i = 0; i < frame.length; i++)
228
+ frame[i] = Math.max(-32768, Math.min(32767, Math.round(frame[i] * v)));
229
+ }
230
+ //# sourceMappingURL=player.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"player.js","sourceRoot":"","sources":["../src/player.ts"],"names":[],"mappings":"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"}
package/dist/rest.d.ts ADDED
@@ -0,0 +1,122 @@
1
+ import type { Attachment, Card, Channel, Command, Components, Id, Invite, Member, MessageData, Profile, Role, User, VoiceJoin } from './types.js';
2
+ /** An answer the API refused (docs.zynko.org/api/#erros). */
3
+ export declare class ZynkoError extends Error {
4
+ /** HTTP status. */
5
+ readonly status: number;
6
+ /** `bad_request`, `forbidden`, `not_found`, `rate_limited`... */
7
+ readonly code: string;
8
+ constructor(
9
+ /** HTTP status. */
10
+ status: number,
11
+ /** `bad_request`, `forbidden`, `not_found`, `rate_limited`... */
12
+ code: string, message: string);
13
+ }
14
+ export interface RestOptions {
15
+ token: string;
16
+ /** Where the API is: https://zynko.org/api unless you run your own server. */
17
+ api?: string;
18
+ /** Waits out a 429 and tries again, up to this many times (0: never). */
19
+ retries?: number;
20
+ }
21
+ export interface SendOptions {
22
+ content?: string;
23
+ /** Answer this message (from the same channel). */
24
+ replyTo?: Id;
25
+ /** Files to send with it, uploaded first (up to 10). */
26
+ files?: FileInput[];
27
+ nonce?: string;
28
+ /** Cards (up to 5). */
29
+ cards?: Card[];
30
+ /** Rows of buttons. */
31
+ components?: Components;
32
+ }
33
+ /** What an interaction's answer carries. */
34
+ export interface ReplyOptions {
35
+ content?: string;
36
+ cards?: Card[];
37
+ components?: Components;
38
+ /** Only the person who used the command sees it (and it is not kept). No buttons. */
39
+ ephemeral?: boolean;
40
+ }
41
+ export interface EditOptions {
42
+ content?: string;
43
+ cards?: Card[];
44
+ components?: Components;
45
+ }
46
+ export interface FileInput {
47
+ name: string;
48
+ data: Blob | Uint8Array | ArrayBuffer;
49
+ contentType?: string;
50
+ }
51
+ /**
52
+ * The HTTP API with a bot's token. Every route is reachable through `request`; the common
53
+ * ones have their own method.
54
+ */
55
+ export declare class Rest {
56
+ readonly api: string;
57
+ private readonly token;
58
+ private readonly retries;
59
+ constructor(opts: RestOptions);
60
+ /** The server's address without /api, to turn `/api/media/...` paths into links. */
61
+ get base(): string;
62
+ request<T = unknown>(method: string, path: string, body?: unknown): Promise<T>;
63
+ get: <T>(path: string) => Promise<T>;
64
+ post: <T>(path: string, body?: unknown) => Promise<T>;
65
+ patch: <T>(path: string, body: unknown) => Promise<T>;
66
+ put: <T>(path: string, body?: unknown) => Promise<T>;
67
+ delete: <T>(path: string) => Promise<T>;
68
+ /** Sends a message; files are uploaded first. */
69
+ send(channelId: Id, message: string | SendOptions): Promise<MessageData>;
70
+ /** Uploads a file to a channel, to be sent in a message (see `send`). */
71
+ upload(channelId: Id, file: FileInput): Promise<Attachment>;
72
+ /** Changes the bot's own message: whatever is given (text, cards, buttons). */
73
+ editMessage: (channelId: Id, messageId: Id, edit: string | EditOptions) => Promise<MessageData>;
74
+ deleteMessage: (channelId: Id, messageId: Id) => Promise<unknown>;
75
+ /** Messages, newest first; `before`/`after` an id, up to `limit` (100). */
76
+ messages(channelId: Id, q?: {
77
+ before?: Id;
78
+ after?: Id;
79
+ limit?: number;
80
+ }): Promise<MessageData[]>;
81
+ react: (channelId: Id, messageId: Id, emoji: string) => Promise<unknown>;
82
+ unreact: (channelId: Id, messageId: Id, emoji: string) => Promise<unknown>;
83
+ /** "Digitando..." for a few seconds. */
84
+ typing: (channelId: Id) => Promise<unknown>;
85
+ me: () => Promise<User>;
86
+ profile: (userId: Id) => Promise<Profile>;
87
+ /** The DM with someone (opened if needed). */
88
+ dm: (userId: Id) => Promise<Channel>;
89
+ members: (guildId: Id) => Promise<Member[]>;
90
+ kick: (guildId: Id, userId: Id) => Promise<unknown>;
91
+ ban: (guildId: Id, userId: Id) => Promise<unknown>;
92
+ unban: (guildId: Id, userId: Id) => Promise<unknown>;
93
+ addRole: (guildId: Id, userId: Id, roleId: Id) => Promise<unknown>;
94
+ removeRole: (guildId: Id, userId: Id, roleId: Id) => Promise<unknown>;
95
+ createRole: (guildId: Id, role: {
96
+ name: string;
97
+ color?: number | null;
98
+ permissions?: number;
99
+ hoist?: boolean;
100
+ }) => Promise<Role>;
101
+ createChannel: (guildId: Id, channel: {
102
+ name: string;
103
+ type?: number;
104
+ parent_id?: Id | null;
105
+ topic?: string;
106
+ }) => Promise<Channel>;
107
+ editChannel: (channelId: Id, patch: Partial<Pick<Channel, "name" | "topic" | "position" | "parent_id" | "rate_limit_per_user">>) => Promise<Channel>;
108
+ deleteChannel: (channelId: Id) => Promise<unknown>;
109
+ createInvite: (guildId: Id, opts?: {
110
+ max_age_secs?: number;
111
+ max_uses?: number;
112
+ }) => Promise<Invite>;
113
+ /** Replaces all of the bot's "/" commands. */
114
+ setCommands: (commands: Command[]) => Promise<Command[]>;
115
+ commands: () => Promise<Command[]>;
116
+ /** Answers an interaction (see `Interaction`). */
117
+ interactionCallback: (id: Id, token: string, body: ReplyOptions & {
118
+ type?: "message" | "update";
119
+ }) => Promise<MessageData>;
120
+ /** A media token for a voice room (the voice connection uses it; see `Client.joinVoice`). */
121
+ voiceToken: (channelId: Id) => Promise<VoiceJoin>;
122
+ }
package/dist/rest.js ADDED
@@ -0,0 +1,129 @@
1
+ /** An answer the API refused (docs.zynko.org/api/#erros). */
2
+ export class ZynkoError extends Error {
3
+ status;
4
+ code;
5
+ constructor(
6
+ /** HTTP status. */
7
+ status,
8
+ /** `bad_request`, `forbidden`, `not_found`, `rate_limited`... */
9
+ code, message) {
10
+ super(message);
11
+ this.status = status;
12
+ this.code = code;
13
+ this.name = 'ZynkoError';
14
+ }
15
+ }
16
+ const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
17
+ /**
18
+ * The HTTP API with a bot's token. Every route is reachable through `request`; the common
19
+ * ones have their own method.
20
+ */
21
+ export class Rest {
22
+ api;
23
+ token;
24
+ retries;
25
+ constructor(opts) {
26
+ this.token = opts.token;
27
+ this.api = (opts.api ?? 'https://zynko.org/api').replace(/\/$/, '');
28
+ this.retries = opts.retries ?? 3;
29
+ }
30
+ /** The server's address without /api, to turn `/api/media/...` paths into links. */
31
+ get base() {
32
+ return this.api.replace(/\/api$/, '');
33
+ }
34
+ async request(method, path, body) {
35
+ for (let attempt = 0;; attempt++) {
36
+ const form = body instanceof FormData;
37
+ const res = await fetch(this.api + path, {
38
+ method,
39
+ headers: {
40
+ Authorization: `Bot ${this.token}`,
41
+ ...(body !== undefined && !form ? { 'Content-Type': 'application/json' } : {}),
42
+ },
43
+ body: body === undefined ? undefined : form ? body : JSON.stringify(body),
44
+ });
45
+ if (res.ok) {
46
+ const text = await res.text();
47
+ return (text ? JSON.parse(text) : undefined);
48
+ }
49
+ let err = {};
50
+ try {
51
+ err = await res.json();
52
+ }
53
+ catch {
54
+ /* not JSON */
55
+ }
56
+ if (res.status === 429 && attempt < this.retries && err.code === 'rate_limited') {
57
+ await sleep((err.retry_after_ms ?? Number(res.headers.get('retry-after') ?? 1) * 1000) + 50);
58
+ continue;
59
+ }
60
+ throw new ZynkoError(res.status, err.code ?? 'http_' + res.status, err.message ?? res.statusText);
61
+ }
62
+ }
63
+ get = (path) => this.request('GET', path);
64
+ post = (path, body) => this.request('POST', path, body ?? {});
65
+ patch = (path, body) => this.request('PATCH', path, body);
66
+ put = (path, body) => this.request('PUT', path, body);
67
+ delete = (path) => this.request('DELETE', path);
68
+ // ---------- messages ----------
69
+ /** Sends a message; files are uploaded first. */
70
+ async send(channelId, message) {
71
+ const opts = typeof message === 'string' ? { content: message } : message;
72
+ const attachment_ids = [];
73
+ for (const f of opts.files ?? [])
74
+ attachment_ids.push((await this.upload(channelId, f)).id);
75
+ return this.post(`/channels/${channelId}/messages`, {
76
+ content: opts.content ?? '',
77
+ ...(opts.replyTo ? { reply_to: opts.replyTo } : {}),
78
+ ...(opts.nonce ? { nonce: opts.nonce } : {}),
79
+ ...(attachment_ids.length ? { attachment_ids } : {}),
80
+ ...(opts.cards?.length ? { cards: opts.cards } : {}),
81
+ ...(opts.components?.length ? { components: opts.components } : {}),
82
+ });
83
+ }
84
+ /** Uploads a file to a channel, to be sent in a message (see `send`). */
85
+ upload(channelId, file) {
86
+ const form = new FormData();
87
+ const blob = file.data instanceof Blob ? file.data : new Blob([file.data], { type: file.contentType ?? 'application/octet-stream' });
88
+ form.append('file', blob, file.name);
89
+ return this.request('POST', `/channels/${channelId}/attachments`, form);
90
+ }
91
+ /** Changes the bot's own message: whatever is given (text, cards, buttons). */
92
+ editMessage = (channelId, messageId, edit) => this.patch(`/channels/${channelId}/messages/${messageId}`, typeof edit === 'string' ? { content: edit } : edit);
93
+ deleteMessage = (channelId, messageId) => this.delete(`/channels/${channelId}/messages/${messageId}`);
94
+ /** Messages, newest first; `before`/`after` an id, up to `limit` (100). */
95
+ messages(channelId, q = {}) {
96
+ const params = new URLSearchParams(Object.entries(q).filter(([, v]) => v !== undefined).map(([k, v]) => [k, String(v)]));
97
+ return this.get(`/channels/${channelId}/messages${params.size ? '?' + params : ''}`);
98
+ }
99
+ react = (channelId, messageId, emoji) => this.put(`/channels/${channelId}/messages/${messageId}/reactions/${encodeURIComponent(emoji)}`);
100
+ unreact = (channelId, messageId, emoji) => this.delete(`/channels/${channelId}/messages/${messageId}/reactions/${encodeURIComponent(emoji)}`);
101
+ /** "Digitando..." for a few seconds. */
102
+ typing = (channelId) => this.post(`/channels/${channelId}/typing`);
103
+ // ---------- people, houses, channels ----------
104
+ me = () => this.get('/users/@me');
105
+ profile = (userId) => this.get(`/users/${userId}/profile`);
106
+ /** The DM with someone (opened if needed). */
107
+ dm = (userId) => this.post('/users/@me/channels', { recipient_id: userId });
108
+ members = (guildId) => this.get(`/guilds/${guildId}/members`);
109
+ kick = (guildId, userId) => this.delete(`/guilds/${guildId}/members/${userId}`);
110
+ ban = (guildId, userId) => this.put(`/guilds/${guildId}/bans/${userId}`);
111
+ unban = (guildId, userId) => this.delete(`/guilds/${guildId}/bans/${userId}`);
112
+ addRole = (guildId, userId, roleId) => this.put(`/guilds/${guildId}/members/${userId}/roles/${roleId}`);
113
+ removeRole = (guildId, userId, roleId) => this.delete(`/guilds/${guildId}/members/${userId}/roles/${roleId}`);
114
+ createRole = (guildId, role) => this.post(`/guilds/${guildId}/roles`, role);
115
+ createChannel = (guildId, channel) => this.post(`/guilds/${guildId}/channels`, channel);
116
+ editChannel = (channelId, patch) => this.patch(`/channels/${channelId}`, patch);
117
+ deleteChannel = (channelId) => this.delete(`/channels/${channelId}`);
118
+ createInvite = (guildId, opts = {}) => this.post(`/guilds/${guildId}/invites`, opts);
119
+ // ---------- commands ----------
120
+ /** Replaces all of the bot's "/" commands. */
121
+ setCommands = (commands) => this.put('/users/@me/commands', commands);
122
+ commands = () => this.get('/users/@me/commands');
123
+ /** Answers an interaction (see `Interaction`). */
124
+ interactionCallback = (id, token, body) => this.post(`/interactions/${id}/${token}/callback`, body);
125
+ // ---------- voice ----------
126
+ /** A media token for a voice room (the voice connection uses it; see `Client.joinVoice`). */
127
+ voiceToken = (channelId) => this.post(`/channels/${channelId}/voice`);
128
+ }
129
+ //# sourceMappingURL=rest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rest.js","sourceRoot":"","sources":["../src/rest.ts"],"names":[],"mappings":"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"}