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.
@@ -0,0 +1,306 @@
1
+ /**
2
+ * The Zynko API's objects, as the server sends them (docs.zynko.org/api/objetos). Ids are
3
+ * strings; times are milliseconds since 1970.
4
+ */
5
+ export type Id = string;
6
+ export interface User {
7
+ id: Id;
8
+ username: string;
9
+ display_name: string;
10
+ avatar: string | null;
11
+ bot: boolean;
12
+ }
13
+ export interface Profile {
14
+ user: User;
15
+ bio: string | null;
16
+ banner: string | null;
17
+ accent: string | null;
18
+ }
19
+ export interface Guild {
20
+ id: Id;
21
+ name: string;
22
+ icon: string | null;
23
+ owner_id: Id;
24
+ }
25
+ /** A house as READY and GUILD_CREATE bring it. */
26
+ export interface GuildFull extends Guild {
27
+ channels: Channel[];
28
+ members: Member[];
29
+ /** Ids of the members online now. */
30
+ presences: Id[];
31
+ roles: Role[];
32
+ emojis: Emoji[];
33
+ }
34
+ export declare const ChannelType: {
35
+ readonly TEXT: 0;
36
+ readonly DM: 1;
37
+ readonly VOICE: 2;
38
+ readonly CATEGORY: 4;
39
+ readonly POST: 11;
40
+ readonly FORUM: 15;
41
+ };
42
+ export interface Overwrite {
43
+ id: Id;
44
+ /** 0 = role, 1 = member. */
45
+ type: number;
46
+ allow: number;
47
+ deny: number;
48
+ }
49
+ export interface ForumTag {
50
+ id: Id;
51
+ name: string;
52
+ emoji: string | null;
53
+ moderated?: boolean;
54
+ }
55
+ export interface Channel {
56
+ id: Id;
57
+ guild_id: Id | null;
58
+ type: number;
59
+ name: string;
60
+ topic: string | null;
61
+ position: number;
62
+ parent_id: Id | null;
63
+ last_message_id: Id | null;
64
+ rate_limit_per_user?: number;
65
+ owner_id?: Id;
66
+ pinned?: boolean;
67
+ locked?: boolean;
68
+ message_count?: number;
69
+ applied_tags?: Id[];
70
+ /** The voice server a room runs on, when someone picked one. */
71
+ voice_server?: string;
72
+ available_tags?: ForumTag[];
73
+ /** In a DM: the other person. */
74
+ recipients?: User[];
75
+ permission_overwrites?: Overwrite[];
76
+ }
77
+ export interface Member {
78
+ guild_id: Id;
79
+ user: User;
80
+ nick: string | null;
81
+ is_admin: boolean;
82
+ joined_at: number;
83
+ /** Not including @everyone, which everybody has. */
84
+ roles: Id[];
85
+ }
86
+ export interface Role {
87
+ id: Id;
88
+ guild_id: Id;
89
+ name: string;
90
+ color: number | null;
91
+ position: number;
92
+ permissions: number;
93
+ hoist: boolean;
94
+ }
95
+ export interface Emoji {
96
+ id: Id;
97
+ guild_id: Id;
98
+ name: string;
99
+ url: string;
100
+ animated: boolean;
101
+ }
102
+ export interface Attachment {
103
+ id: Id;
104
+ filename: string;
105
+ content_type: string;
106
+ size: number;
107
+ /** `/api/attachments/{id}`: needs the token to download. */
108
+ url: string;
109
+ thumbnail?: string | null;
110
+ width?: number | null;
111
+ height?: number | null;
112
+ }
113
+ export interface ReactionCount {
114
+ /** A Unicode emoji, or `name:id` for a house emoji. */
115
+ emoji: string;
116
+ count: number;
117
+ me: boolean;
118
+ }
119
+ export interface MessageRef {
120
+ id: Id;
121
+ author: User | null;
122
+ content: string | null;
123
+ }
124
+ export interface Embed {
125
+ url: string;
126
+ site_name?: string;
127
+ title?: string;
128
+ description?: string;
129
+ author?: string;
130
+ color?: string;
131
+ image?: {
132
+ url: string;
133
+ width?: number;
134
+ height?: number;
135
+ large: boolean;
136
+ };
137
+ video?: {
138
+ provider: string;
139
+ id: string;
140
+ };
141
+ }
142
+ /** A bot's card: a title, text, fields and pictures with a colored edge. */
143
+ export interface Card {
144
+ title?: string;
145
+ /** Markdown, like a message. */
146
+ description?: string;
147
+ /** Where the title points. */
148
+ url?: string;
149
+ /** The edge's color, 0xRRGGBB. */
150
+ color?: number;
151
+ author?: {
152
+ name: string;
153
+ url?: string;
154
+ icon_url?: string;
155
+ };
156
+ fields?: {
157
+ name: string;
158
+ value: string;
159
+ inline?: boolean;
160
+ }[];
161
+ /** Wide, under the text. */
162
+ image?: {
163
+ url: string;
164
+ };
165
+ /** Small, beside the text. */
166
+ thumbnail?: {
167
+ url: string;
168
+ };
169
+ footer?: {
170
+ text: string;
171
+ icon_url?: string;
172
+ };
173
+ /** Shown in the footer, in ms. */
174
+ timestamp?: number;
175
+ }
176
+ export type ButtonStyle = 'primary' | 'secondary' | 'success' | 'danger' | 'link';
177
+ export interface Button {
178
+ style: ButtonStyle;
179
+ label?: string;
180
+ emoji?: string;
181
+ /** What the bot gets back when it is clicked (all but links). */
182
+ custom_id?: string;
183
+ /** Link buttons only. */
184
+ url?: string;
185
+ disabled?: boolean;
186
+ }
187
+ /** Rows of buttons, top to bottom: up to 5 rows of 5. */
188
+ export type Components = Button[][];
189
+ /** The command or click a bot's message answers. */
190
+ export interface InteractionRef {
191
+ id: Id;
192
+ /** The command; absent for a button. */
193
+ name?: string;
194
+ user: User;
195
+ }
196
+ export type OptionType = 'string' | 'integer' | 'number' | 'boolean' | 'user' | 'channel' | 'role';
197
+ export interface CommandOption {
198
+ name: string;
199
+ description: string;
200
+ type: OptionType;
201
+ required?: boolean;
202
+ /** The only values allowed. */
203
+ choices?: {
204
+ name: string;
205
+ value: string | number;
206
+ }[];
207
+ min_value?: number;
208
+ max_value?: number;
209
+ }
210
+ /** A "/" command (docs.zynko.org/bots/comandos). */
211
+ export interface Command {
212
+ /** 1 to 32 lowercase letters, digits, _ or -. */
213
+ name: string;
214
+ description: string;
215
+ options?: CommandOption[];
216
+ }
217
+ export interface InteractionData {
218
+ id: Id;
219
+ token: string;
220
+ type: 'command' | 'button';
221
+ channel_id: Id;
222
+ guild_id: Id | null;
223
+ user: User;
224
+ member: Member | null;
225
+ command?: {
226
+ name: string;
227
+ options: {
228
+ name: string;
229
+ type: OptionType;
230
+ value: string | number | boolean;
231
+ }[];
232
+ };
233
+ custom_id?: string;
234
+ message?: MessageData;
235
+ }
236
+ /**
237
+ * MESSAGE_UPDATE is always partial: an edit brings the text (and cards or buttons, when they
238
+ * changed); link previews come in one of their own. No author.
239
+ */
240
+ export type MessageUpdate = Pick<MessageData, 'id' | 'channel_id'> & Partial<Pick<MessageData, 'content' | 'edited_timestamp' | 'embeds' | 'cards' | 'components'>>;
241
+ export interface MessageData {
242
+ id: Id;
243
+ channel_id: Id;
244
+ author: User;
245
+ content: string;
246
+ timestamp: number;
247
+ edited_timestamp: number | null;
248
+ reply_to: MessageRef | null;
249
+ attachments: Attachment[];
250
+ reactions: ReactionCount[];
251
+ nonce: string | null;
252
+ embeds: Embed[];
253
+ cards?: Card[];
254
+ components?: Components;
255
+ interaction?: InteractionRef;
256
+ /** Only the person who used the command sees it. */
257
+ ephemeral?: boolean;
258
+ }
259
+ export interface Invite {
260
+ code: string;
261
+ guild_id: Id;
262
+ creator_id: Id;
263
+ uses: number;
264
+ max_uses: number | null;
265
+ expires_at: number | null;
266
+ }
267
+ export interface VoiceState {
268
+ user_id: Id;
269
+ guild_id: Id | null;
270
+ /** null when the account left voice. */
271
+ channel_id: Id | null;
272
+ self_mute: boolean;
273
+ self_deaf: boolean;
274
+ self_stream: boolean;
275
+ self_video: boolean;
276
+ session_id: string;
277
+ }
278
+ export interface Ready {
279
+ user: User;
280
+ guilds: GuildFull[];
281
+ dm_channels: Channel[];
282
+ presences: Id[];
283
+ voice_states: VoiceState[];
284
+ session_id: string;
285
+ }
286
+ export interface ReactionEvent {
287
+ message_id: Id;
288
+ channel_id: Id;
289
+ user_id: Id;
290
+ emoji: string;
291
+ }
292
+ export interface TypingEvent {
293
+ channel_id: Id;
294
+ user_id: Id;
295
+ timestamp: number;
296
+ }
297
+ /** The answer to joining a voice room (POST /channels/{id}/voice). */
298
+ export interface VoiceJoin {
299
+ url: string;
300
+ /** The voice server's id (Brasil 1, Brasil 2...). */
301
+ server?: string;
302
+ token: string;
303
+ room: string;
304
+ can_speak: boolean;
305
+ can_stream: boolean;
306
+ }
package/dist/types.js ADDED
@@ -0,0 +1,13 @@
1
+ /**
2
+ * The Zynko API's objects, as the server sends them (docs.zynko.org/api/objetos). Ids are
3
+ * strings; times are milliseconds since 1970.
4
+ */
5
+ export const ChannelType = {
6
+ TEXT: 0,
7
+ DM: 1,
8
+ VOICE: 2,
9
+ CATEGORY: 4,
10
+ POST: 11,
11
+ FORUM: 15,
12
+ };
13
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAoCH,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,IAAI,EAAE,CAAC;IACP,EAAE,EAAE,CAAC;IACL,KAAK,EAAE,CAAC;IACR,QAAQ,EAAE,CAAC;IACX,IAAI,EAAE,EAAE;IACR,KAAK,EAAE,EAAE;CACD,CAAC"}
@@ -0,0 +1,63 @@
1
+ import type { Client } from './client.js';
2
+ import { AudioPlayer, type FrameSink, type PlayerOptions } from './player.js';
3
+ import type { Channel, Id, VoiceState } from './types.js';
4
+ export interface JoinVoiceOptions extends PlayerOptions {
5
+ /**
6
+ * Hear the room: `audio` events with each person's sound (48 kHz). Off by default, so a
7
+ * bot that only plays does not download everyone's audio.
8
+ */
9
+ receive?: boolean;
10
+ /** "Conexão alternativa": media only through the voice server's relay. */
11
+ relay?: boolean;
12
+ /** Show the bot as deafened in the room (it still plays). */
13
+ deaf?: boolean;
14
+ }
15
+ export interface VoiceEvents {
16
+ /** Connected to the room's media (again, after a server move). */
17
+ ready: [];
18
+ /** One person's audio: interleaved 16-bit samples at 48 kHz, `channels` channels. */
19
+ audio: [userId: Id, samples: Int16Array, channels: number];
20
+ /** Who is speaking now, by user id. */
21
+ speaking: [userIds: Id[]];
22
+ /** Out of the room for good: left, removed, or the room went away. */
23
+ disconnect: [reason: string];
24
+ error: [error: Error];
25
+ }
26
+ export declare class VoiceConnection implements FrameSink {
27
+ readonly client: Client;
28
+ readonly channelId: Id;
29
+ private readonly opts;
30
+ status: 'connecting' | 'connected' | 'reconnecting' | 'closed';
31
+ /** The voice server the room is on (Brasil 1, Brasil 2...). */
32
+ server: string | null;
33
+ /** Can speak here: a room's roles may let the bot only listen. */
34
+ canSpeak: boolean;
35
+ readonly player: AudioPlayer;
36
+ private room;
37
+ private source;
38
+ private readonly emitter;
39
+ private leaving;
40
+ /** The server has confirmed the bot is in this room. */
41
+ private inRoom;
42
+ private moving;
43
+ constructor(client: Client, channelId: Id, opts?: JoinVoiceOptions);
44
+ on<K extends keyof VoiceEvents>(event: K, listener: (...args: VoiceEvents[K]) => void): this;
45
+ off<K extends keyof VoiceEvents>(event: K, listener: (...args: VoiceEvents[K]) => void): this;
46
+ /** The room's channel. */
47
+ get channel(): Channel | undefined;
48
+ /** Connects to the room's media and tells the house the bot is there. */
49
+ connect(): Promise<void>;
50
+ /** Leaves the room. */
51
+ leave(): Promise<void>;
52
+ capture(frame: Int16Array): Promise<void>;
53
+ flush(): void;
54
+ /** The room moved to another voice server (someone picked Brasil 1 or 2): follow it. */
55
+ onChannelUpdate(c: Channel): void;
56
+ /** The server says where the bot is in voice: elsewhere, or nowhere, ends this connection. */
57
+ onOwnState(v: VoiceState): void;
58
+ /** After the gateway reconnects: say again where the bot is. */
59
+ resync(): void;
60
+ private announce;
61
+ private hear;
62
+ private end;
63
+ }
package/dist/voice.js ADDED
@@ -0,0 +1,203 @@
1
+ /**
2
+ * A bot in a voice room. The Zynko server hands out a media token (POST /channels/{id}/voice)
3
+ * and the house learns where the bot is from gateway op 4; the audio itself travels through
4
+ * LiveKit, the same media server the apps use, through the `@livekit/rtc-node` package.
5
+ *
6
+ * ```ts
7
+ * const voice = await client.joinVoice(channelId);
8
+ * voice.player.enqueue('https://exemplo.com/musica.mp3');
9
+ * ```
10
+ */
11
+ import { EventEmitter } from 'node:events';
12
+ import { AudioPlayer, CHANNELS, FRAME_SAMPLES, SAMPLE_RATE } from './player.js';
13
+ let rtc = null;
14
+ async function loadRtc() {
15
+ if (rtc)
16
+ return rtc;
17
+ try {
18
+ rtc = (await import('@livekit/rtc-node'));
19
+ }
20
+ catch {
21
+ throw new Error('A voz precisa do pacote @livekit/rtc-node: npm install @livekit/rtc-node');
22
+ }
23
+ return rtc;
24
+ }
25
+ export class VoiceConnection {
26
+ client;
27
+ channelId;
28
+ opts;
29
+ status = 'connecting';
30
+ /** The voice server the room is on (Brasil 1, Brasil 2...). */
31
+ server = null;
32
+ /** Can speak here: a room's roles may let the bot only listen. */
33
+ canSpeak = true;
34
+ player;
35
+ room = null;
36
+ source = null;
37
+ emitter = new EventEmitter();
38
+ leaving = false;
39
+ /** The server has confirmed the bot is in this room. */
40
+ inRoom = false;
41
+ moving = null;
42
+ constructor(client, channelId, opts = {}) {
43
+ this.client = client;
44
+ this.channelId = channelId;
45
+ this.opts = opts;
46
+ this.player = new AudioPlayer(this, opts);
47
+ this.emitter.on('error', () => { });
48
+ }
49
+ on(event, listener) {
50
+ this.emitter.on(event, listener);
51
+ return this;
52
+ }
53
+ off(event, listener) {
54
+ this.emitter.off(event, listener);
55
+ return this;
56
+ }
57
+ /** The room's channel. */
58
+ get channel() {
59
+ return this.client.channels.get(this.channelId);
60
+ }
61
+ /** Connects to the room's media and tells the house the bot is there. */
62
+ async connect() {
63
+ const lk = await loadRtc();
64
+ const join = await this.client.rest.voiceToken(this.channelId);
65
+ this.server = join.server ?? null;
66
+ this.canSpeak = join.can_speak !== false;
67
+ const room = new lk.Room();
68
+ this.room = room;
69
+ room
70
+ .on(lk.RoomEvent.Disconnected, (reason) => {
71
+ if (this.room !== room || this.leaving)
72
+ return;
73
+ // The room closed under us: a server move is followed through CHANNEL_UPDATE; anything
74
+ // else (removed, room deleted) ends the connection.
75
+ if (this.moving)
76
+ return;
77
+ void this.end(`desconectado (${lk.DisconnectReason[reason] ?? reason})`);
78
+ })
79
+ .on(lk.RoomEvent.ActiveSpeakersChanged, (speakers) => this.emitter.emit('speaking', speakers.map((p) => p.identity)))
80
+ .on(lk.RoomEvent.TrackSubscribed, (track, _pub, participant) => {
81
+ if (track.kind !== lk.TrackKind.KIND_AUDIO || !this.opts.receive)
82
+ return;
83
+ void this.hear(lk, track, participant.identity);
84
+ });
85
+ const rtcConfig = this.opts.relay
86
+ ? { iceTransportType: lk.IceTransportType.TRANSPORT_RELAY, continualGatheringPolicy: lk.ContinualGatheringPolicy.GATHER_CONTINUALLY, iceServers: [] }
87
+ : undefined;
88
+ await room.connect(join.url, join.token, { autoSubscribe: !!this.opts.receive, dynacast: false, ...(rtcConfig ? { rtcConfig } : {}) });
89
+ if (this.room !== room)
90
+ return void room.disconnect();
91
+ if (this.canSpeak) {
92
+ const source = new lk.AudioSource(SAMPLE_RATE, CHANNELS, 200);
93
+ const track = lk.LocalAudioTrack.createAudioTrack('zynko', source);
94
+ await room.localParticipant.publishTrack(track, new lk.TrackPublishOptions({ source: lk.TrackSource.SOURCE_MICROPHONE, dtx: false, red: false, audioEncoding: { maxBitrate: 128000n } }));
95
+ this.source = source;
96
+ }
97
+ this.announce();
98
+ this.status = 'connected';
99
+ this.emitter.emit('ready');
100
+ }
101
+ /** Leaves the room. */
102
+ async leave() {
103
+ if (this.status === 'closed')
104
+ return;
105
+ this.leaving = true;
106
+ this.player.stop();
107
+ this.client.sendOp(4, { channel_id: null, self_mute: false, self_deaf: false });
108
+ await this.end('saiu');
109
+ }
110
+ // ---------- FrameSink, for the player ----------
111
+ async capture(frame) {
112
+ const lk = rtc;
113
+ if (!lk)
114
+ return;
115
+ // Moving to another server: wait for the new connection, then go on where it was.
116
+ if (this.moving)
117
+ await this.moving.catch(() => { });
118
+ const source = this.source;
119
+ if (!source || this.status === 'closed')
120
+ return;
121
+ await source.captureFrame(new lk.AudioFrame(frame, SAMPLE_RATE, CHANNELS, FRAME_SAMPLES));
122
+ }
123
+ flush() {
124
+ this.source?.clearQueue();
125
+ }
126
+ // ---------- from the client ----------
127
+ /** The room moved to another voice server (someone picked Brasil 1 or 2): follow it. */
128
+ onChannelUpdate(c) {
129
+ if (c.id !== this.channelId || this.status !== 'connected' || !c.voice_server || c.voice_server === this.server)
130
+ return;
131
+ this.moving = (async () => {
132
+ this.status = 'reconnecting';
133
+ const old = this.room;
134
+ const oldSource = this.source;
135
+ this.room = null;
136
+ this.source = null;
137
+ await old?.disconnect();
138
+ await oldSource?.close();
139
+ try {
140
+ await this.connect();
141
+ }
142
+ catch (e) {
143
+ await this.end('não conseguiu entrar no servidor novo');
144
+ this.emitter.emit('error', e instanceof Error ? e : new Error(String(e)));
145
+ }
146
+ })().finally(() => (this.moving = null));
147
+ }
148
+ /** The server says where the bot is in voice: elsewhere, or nowhere, ends this connection. */
149
+ onOwnState(v) {
150
+ if (this.status === 'closed' || this.leaving)
151
+ return;
152
+ if (v.channel_id === this.channelId) {
153
+ this.inRoom = true;
154
+ return;
155
+ }
156
+ // Moving from another room, its "left" state can arrive after this one began: only a state
157
+ // that comes once the server has the bot here means it was moved or removed.
158
+ if (!this.inRoom)
159
+ return;
160
+ void this.end(v.channel_id ? 'entrou em outra sala' : 'removido da sala');
161
+ }
162
+ /** After the gateway reconnects: say again where the bot is. */
163
+ resync() {
164
+ if (this.status === 'connected' || this.status === 'reconnecting')
165
+ this.announce();
166
+ }
167
+ announce() {
168
+ this.client.sendOp(4, { channel_id: this.channelId, self_mute: !this.canSpeak, self_deaf: !!this.opts.deaf });
169
+ }
170
+ async hear(lk, track, userId) {
171
+ const reader = new lk.AudioStream(track, SAMPLE_RATE, 1).getReader();
172
+ try {
173
+ for (;;) {
174
+ const { done, value } = await reader.read();
175
+ if (done || this.status === 'closed')
176
+ break;
177
+ this.emitter.emit('audio', userId, value.data, value.channels);
178
+ }
179
+ }
180
+ catch {
181
+ /* the track went away */
182
+ }
183
+ finally {
184
+ reader.releaseLock();
185
+ }
186
+ }
187
+ async end(reason) {
188
+ if (this.status === 'closed')
189
+ return;
190
+ this.status = 'closed';
191
+ this.player.stop();
192
+ const room = this.room;
193
+ const source = this.source;
194
+ this.room = null;
195
+ this.source = null;
196
+ await room?.disconnect().catch(() => { });
197
+ await source?.close().catch(() => { });
198
+ if (this.client.voice === this)
199
+ this.client.voice = null;
200
+ this.emitter.emit('disconnect', reason);
201
+ }
202
+ }
203
+ //# sourceMappingURL=voice.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"voice.js","sourceRoot":"","sources":["../src/voice.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,45 @@
1
1
  {
2
2
  "name": "zynko",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.1.0",
4
+ "description": "Biblioteca oficial para bots do Zynko: API, gateway e voz.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "main": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist",
17
+ "README.md"
18
+ ],
19
+ "engines": {
20
+ "node": ">=22"
21
+ },
22
+ "scripts": {
23
+ "build": "tsc -p tsconfig.json",
24
+ "check": "tsc -p tsconfig.json --noEmit"
25
+ },
26
+ "peerDependencies": {
27
+ "@livekit/rtc-node": "1.2.1"
28
+ },
29
+ "peerDependenciesMeta": {
30
+ "@livekit/rtc-node": {
31
+ "optional": true
32
+ }
33
+ },
34
+ "keywords": [
35
+ "zynko",
36
+ "bot",
37
+ "chat",
38
+ "voice"
39
+ ],
40
+ "devDependencies": {
41
+ "@livekit/rtc-node": "^1.2.1",
42
+ "@types/node": "^22.20.5",
43
+ "typescript": "^5.9.3"
44
+ }
45
+ }