@lagent_titi/kick.js-ts 1.0.1

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/README.md ADDED
@@ -0,0 +1,501 @@
1
+ # Kick.com API Client
2
+
3
+ [![NPM Version](https://img.shields.io/npm/v/@botk4cp3r/kick.js)](https://www.npmjs.com/package/@botk4cp3r/kick.js)
4
+ [![License](https://img.shields.io/npm/l/@botk4cp3r/kick.js)](https://github.com/BOT-K4CP3R/kick.api/blob/main/LICENSE)
5
+
6
+ ## 📋 Table of Contents
7
+ - [Installation](#-installation)
8
+ - [Quick Start](#-quick-start)
9
+ - [Chat System](#-chat-system)
10
+ - [Webhook Events](#-webhook-events)
11
+ - [Channel Management](#-channel-management)
12
+ - [Category System](#-category-system)
13
+ - [User Management](#-user-management)
14
+ - [Error Handling](#-error-handling)
15
+ - [TypeScript Support](#-typescript-support)
16
+ - [Examples](#-examples)
17
+
18
+ ## 📥 Installation
19
+
20
+ ```bash
21
+ npm install @lagent_titi/kick.api-ts
22
+ ```
23
+
24
+ ## 🚀 Quick Start
25
+
26
+ ```javascript
27
+ const { KickClient } = require('@botk4cp3r/kick.js');
28
+
29
+ // Create client instance
30
+ const client = new KickClient({
31
+ token: 'your-api-token',
32
+ webhookPort: 3000,
33
+ webhookPath: '/webhook',
34
+ webhookBaseUrl: 'http://your-domain.com'
35
+ });
36
+
37
+ // Start webhook server and subscribe to events
38
+ async function init() {
39
+ await client.startWebhookServer();
40
+
41
+ // Subscribe to all available events
42
+ await client.subscribeToEvents([
43
+ 'chat.message.sent',
44
+ 'channel.followed',
45
+ 'channel.subscription.new',
46
+ 'channel.subscription.renewal',
47
+ 'channel.subscription.gifts'
48
+ ]);
49
+
50
+ console.log('Bot is ready!');
51
+ }
52
+
53
+ // Listen for events
54
+ client.on('chatMessage', message => {
55
+ console.log(`${message.sender.username}: ${message.content}`);
56
+ });
57
+
58
+ client.on('channelFollowed', data => {
59
+ console.log(`New follower: ${data.follower.username}!`);
60
+ });
61
+
62
+ client.on('subscriptionNew', data => {
63
+ console.log(`New sub: ${data.subscriber.username}!`);
64
+ });
65
+
66
+ // Send a chat message
67
+ await client.sendChatMessage({
68
+ content: 'Hello World!',
69
+ type: 'bot'
70
+ });
71
+
72
+ init().catch(console.error);
73
+ ```
74
+
75
+ ## 💬 Chat System
76
+
77
+ ### Send Bot Messages
78
+ ```javascript
79
+ // Simple bot message
80
+ await client.sendChatMessage({
81
+ content: 'Hello from bot!',
82
+ type: 'bot'
83
+ });
84
+
85
+ // Simple user message
86
+ await client.sendChatMessage({
87
+ content: 'Hello! Kappa',
88
+ type: 'user',
89
+ broadcasterUserId: '123456'
90
+ });
91
+ ```
92
+
93
+ ### Listen for Chat Events
94
+ ```javascript
95
+ // New messages
96
+ client.on('chatMessage', msg => {
97
+ console.log(`${msg.sender.username}: ${msg.content}`);
98
+
99
+ // Auto-respond to commands
100
+ if (msg.content === '!ping') {
101
+ client.sendChatMessage({
102
+ content: 'Pong! 🏓',
103
+ type: 'bot'
104
+ });
105
+ }
106
+ });
107
+ ```
108
+
109
+ ## 📡 Webhook Events
110
+
111
+ ### Start Webhook Server
112
+ ```javascript
113
+ const client = new KickClient({
114
+ token: 'your-api-token',
115
+ webhookPort: 3000,
116
+ webhookPath: '/webhook',
117
+ webhookBaseUrl: 'http://your-domain.com'
118
+ });
119
+
120
+ await client.startWebhookServer();
121
+ ```
122
+
123
+ ### Subscribe to Events
124
+ ```javascript
125
+ // Subscribe to specific events
126
+ await client.subscribeToEvents([
127
+ 'chat.message.sent',
128
+ 'channel.followed',
129
+ 'subscription.new',
130
+ 'channel.subscription.renewal',
131
+ 'channel.subscription.gifts'
132
+ ]);
133
+
134
+ // Listen for events
135
+ client.on('channelFollowed', data => {
136
+ console.log(`New follower: ${data.follower.username}`);
137
+ });
138
+
139
+ client.on('subscriptionNew', data => {
140
+ console.log(`New sub: ${data.subscriber.username}`);
141
+ });
142
+ ```
143
+
144
+ ### Custom Event Handlers
145
+ ```javascript
146
+ client.on('chatMessage', async (message) => {
147
+ // Command system example
148
+ const commands = {
149
+ '!ping': () => 'Pong! 🏓',
150
+ '!discord': () => 'Join our Discord: discord.gg/example'
151
+ };
152
+
153
+ const command = message.content.toLowerCase();
154
+ if (commands[command]) {
155
+ await client.sendChatMessage({
156
+ content: commands[command](),
157
+ type: 'bot'
158
+ });
159
+ }
160
+ });
161
+ ```
162
+
163
+ ## 🎯 Event Subscriptions
164
+
165
+ ### Available Events
166
+ ```javascript
167
+ const AVAILABLE_EVENTS = {
168
+ 'chat.message.sent', // New chat messages
169
+ 'channel.followed', // When someone follows the channel
170
+ 'channel.subscription.renewal', // Subscription renewals
171
+ 'channel.subscription.gifts', // Gifted subscriptions
172
+ 'channel.subscription.new' // New subscriptions
173
+ };
174
+ ```
175
+
176
+ ### Managing Subscriptions
177
+
178
+ ```javascript
179
+ // Get current subscriptions
180
+ const currentSubs = await client.getEventSubscriptions();
181
+ console.log('Current subscriptions:', currentSubs);
182
+
183
+ // Subscribe to specific events
184
+ const subscription = await client.subscribeToEvents([
185
+ 'chat.message.sent',
186
+ 'channel.followed'
187
+ ]);
188
+
189
+ // Subscribe with custom webhook method
190
+ const webhookSub = await client.subscribeToEvents([
191
+ 'channel.subscription.new',
192
+ 'channel.subscription.gifts'
193
+ ]);
194
+
195
+ // Unsubscribe from events
196
+ await client.unsubscribeFromEvents(['subscription-id-1', 'subscription-id-2']);
197
+ ```
198
+
199
+ ### Event Validation
200
+
201
+ ```javascript
202
+ // Validate incoming webhook
203
+ const isValid = await client.validateWebhook(headers, rawBody);
204
+ if (isValid) {
205
+ console.log('Valid webhook event!');
206
+ }
207
+ ```
208
+
209
+ ### Full Subscription Example
210
+
211
+ ```javascript
212
+ const client = new KickClient({
213
+ token: 'your-api-token',
214
+ webhookPort: 3000,
215
+ webhookPath: '/webhook',
216
+ webhookBaseUrl: 'https://your-domain.com'
217
+ });
218
+
219
+ // Start webhook server
220
+ await client.startWebhookServer();
221
+
222
+ // Subscribe to multiple events
223
+ await client.subscribeToEvents([
224
+ 'chat.message.sent',
225
+ 'channel.followed',
226
+ 'subscription.new',
227
+ 'subscription.renewal',
228
+ 'subscription.gifts'
229
+ ]);
230
+
231
+ // Handle different events
232
+ client.on('chatMessage', msg => {
233
+ console.log(`Chat: ${msg.sender.username}: ${msg.content}`);
234
+ });
235
+
236
+ client.on('channelFollowed', data => {
237
+ console.log(`New follower: ${data.follower.username}`);
238
+ });
239
+
240
+ client.on('subscriptionNew', sub => {
241
+ console.log(`New sub: ${sub.subscriber.username}`);
242
+ });
243
+
244
+ client.on('subscriptionRenewal', renewal => {
245
+ console.log(`Renewal: ${renewal.subscriber.username}`);
246
+ });
247
+
248
+ client.on('subscriptionGifts', gifts => {
249
+ console.log(`${gifts.gifter.username} gifted ${gifts.giftees.length} subs!`);
250
+ });
251
+
252
+ // Error handling
253
+ client.on('error', error => {
254
+ console.error('Subscription error:', error);
255
+ });
256
+ ```
257
+
258
+ ### Webhook Payload Examples
259
+
260
+ #### Chat Message Event
261
+ ```javascript
262
+ {
263
+ eventType: 'chat.message.sent',
264
+ payload: {
265
+ messageId: '123456',
266
+ content: 'Hello world!',
267
+ sender: {
268
+ id: '789',
269
+ username: 'username',
270
+ displayName: 'Display Name'
271
+ },
272
+ emotes: [
273
+ {
274
+ id: '123',
275
+ name: 'Kappa',
276
+ position: { start: 6, end: 11 }
277
+ }
278
+ ]
279
+ }
280
+ }
281
+ ```
282
+
283
+ #### Follow Event
284
+ ```javascript
285
+ {
286
+ eventType: 'channel.followed',
287
+ payload: {
288
+ broadcaster: {
289
+ id: '123',
290
+ username: 'broadcaster'
291
+ },
292
+ follower: {
293
+ id: '456',
294
+ username: 'follower'
295
+ }
296
+ }
297
+ }
298
+ ```
299
+
300
+ #### Subscription Event
301
+ ```javascript
302
+ {
303
+ eventType: 'subscription.new',
304
+ payload: {
305
+ broadcaster: {
306
+ id: '123',
307
+ username: 'broadcaster'
308
+ },
309
+ subscriber: {
310
+ id: '456',
311
+ username: 'subscriber'
312
+ },
313
+ tier: 1,
314
+ months: 1
315
+ }
316
+ }
317
+ ```
318
+
319
+ ## 📺 Channel Management
320
+
321
+ ### Get Channel Info
322
+ ```javascript
323
+ // Get single channel
324
+ const channel = await client.getChannels(['123456']);
325
+
326
+ // Get multiple channels
327
+ const channels = await client.getChannels(['123', '456', '789']);
328
+ ```
329
+
330
+ ### Update Channel
331
+ ```javascript
332
+ // Update stream title and category
333
+ await client.updateChannel({
334
+ categoryId: '123',
335
+ streamTitle: '🔴 New Stream Title!'
336
+ });
337
+
338
+ // Update just title
339
+ await client.updateChannel({
340
+ streamTitle: '🔴 Playing Games!'
341
+ });
342
+ ```
343
+
344
+ ## 🎮 Category System
345
+
346
+ ### Search Categories
347
+ ```javascript
348
+ // Search all categories
349
+ const allCategories = await client.searchCategories();
350
+
351
+ // Search specific game
352
+ const gaming = await client.searchCategories('Minecraft');
353
+
354
+ // Get category by ID
355
+ const category = await client.getCategory('123');
356
+ ```
357
+
358
+ ## 👥 User Management
359
+
360
+ ### Get User Information
361
+ ```javascript
362
+ // Get single user
363
+ const user = await client.getUsers(['123456']);
364
+
365
+ // Get multiple users
366
+ const users = await client.getUsers(['123', '456', '789']);
367
+ ```
368
+
369
+ ## 🚨 Error Handling
370
+
371
+ ```javascript
372
+ try {
373
+ await client.sendChatMessage({
374
+ content: 'Test message'
375
+ });
376
+ } catch (error) {
377
+ if (error instanceof UnauthorizedError) {
378
+ console.error('Token is invalid or expired');
379
+ } else if (error instanceof ForbiddenError) {
380
+ console.error('Insufficient permissions');
381
+ } else if (error instanceof RateLimitError) {
382
+ console.error(`Rate limited. Try again in ${error.retryAfter} seconds`);
383
+ } else {
384
+ console.error('Unknown error:', error.message);
385
+ }
386
+ }
387
+ ```
388
+
389
+ ## 📝 TypeScript Support
390
+
391
+ ```typescript
392
+ import {
393
+ KickClient,
394
+ ChatMessageOptions,
395
+ ChannelUpdateOptions,
396
+ WebhookEventType
397
+ } from '@botk4cp3r/kick.js';
398
+
399
+ // Client with typed options
400
+ const client = new KickClient({
401
+ token: string,
402
+ webhookPort: number,
403
+ webhookPath: string,
404
+ webhookBaseUrl: string
405
+ });
406
+
407
+ // Typed message options
408
+ const messageOptions: ChatMessageOptions = {
409
+ content: string,
410
+ type: 'bot' | 'user',
411
+ broadcasterUserId?: string
412
+ };
413
+
414
+ // Typed event handlers
415
+ client.on('chatMessage', (message: ChatMessage) => {
416
+ console.log(message.content);
417
+ });
418
+ ```
419
+
420
+ ## 📚 Examples
421
+
422
+ ### Chat Bot Example
423
+ ```javascript
424
+ const { KickClient } = require('@botk4cp3r/kick.js');
425
+
426
+ const client = new KickClient({
427
+ token: 'your-api-token',
428
+ webhookPort: 3000,
429
+ webhookPath: '/webhook',
430
+ webhookBaseUrl: 'http://your-domain.com'
431
+ });
432
+
433
+ const commands = {
434
+ '!help': 'Available commands: !help, !ping',
435
+ '!ping': 'Pong! 🏓'
436
+ };
437
+
438
+ async function startBot() {
439
+ try {
440
+ // Start webhook server
441
+ await client.startWebhookServer();
442
+
443
+ // Subscribe to events
444
+ await client.subscribeToEvents([
445
+ 'chat.message.sent',
446
+ 'channel.followed',
447
+ 'channel.subscription.new',
448
+ 'channel.subscription.renewal',
449
+ 'channel.subscription.gifts'
450
+ ]);
451
+
452
+ console.log('Bot started and subscribed to events!');
453
+ } catch (error) {
454
+ console.error('Failed to start bot:', error);
455
+ process.exit(1);
456
+ }
457
+ }
458
+
459
+ // Chat command handler
460
+ client.on('chatMessage', async (message) => {
461
+ const command = message.content.toLowerCase();
462
+
463
+ if (commands[command]) {
464
+ await client.sendChatMessage({
465
+ content: commands[command],
466
+ type: 'bot'
467
+ });
468
+ }
469
+ });
470
+
471
+ // Event handlers
472
+ client.on('channelFollowed', async (data) => {
473
+ await client.sendChatMessage({
474
+ content: `Thanks for following, ${data.follower.username}! 🎉`,
475
+ type: 'bot'
476
+ });
477
+ });
478
+
479
+ client.on('subscriptionNew', async (data) => {
480
+ await client.sendChatMessage({
481
+ content: `Welcome to the team, ${data.subscriber.username}! 🎈`,
482
+ type: 'bot'
483
+ });
484
+ });
485
+
486
+ client.on('subscriptionRenewal', async (data) => {
487
+ await client.sendChatMessage({
488
+ content: `Thanks for resubbing, ${data.subscriber.username}! 💜`,
489
+ type: 'bot'
490
+ });
491
+ });
492
+
493
+ client.on('subscriptionGifts', async (data) => {
494
+ await client.sendChatMessage({
495
+ content: `Thanks ${data.gifter.username} for gifting ${data.giftees.length} subs! 🎁`,
496
+ type: 'bot'
497
+ });
498
+ });
499
+
500
+ startBot().catch(console.error);
501
+ ```
@@ -0,0 +1,56 @@
1
+ import { EventEmitter } from 'events';
2
+ import { CategoriesService } from './services/categories';
3
+ import { UsersService } from './services/users';
4
+ import { ChannelsService } from './services/channels';
5
+ import { ChatService } from './services/chat';
6
+ import { PublicKeyService } from './services/publicKey';
7
+ import { EventsService, WebhookType, WebhookHeaders } from './services/events';
8
+ import { WebhookHandler } from './webhooks/handler';
9
+ import { WebhookServer } from './webhooks/server';
10
+ interface KickClientOptions {
11
+ webhookPort?: number;
12
+ webhookPath?: string;
13
+ webhookBaseUrl?: string;
14
+ token?: string;
15
+ [key: string]: any;
16
+ }
17
+ export declare class KickClient extends EventEmitter {
18
+ options: Required<KickClientOptions>;
19
+ categories: CategoriesService;
20
+ users: UsersService;
21
+ channels: ChannelsService;
22
+ chat: ChatService;
23
+ publicKey: PublicKeyService;
24
+ events: EventsService;
25
+ webhookHandler: WebhookHandler;
26
+ webhookServer: WebhookServer;
27
+ token: string;
28
+ constructor(options?: KickClientOptions);
29
+ searchCategories(query?: string): Promise<any>;
30
+ getCategory(categoryId: string | number): Promise<any>;
31
+ introspectToken(): Promise<any>;
32
+ getUsers(userIds?: Array<string | number>): Promise<any>;
33
+ getChannels(broadcasterIds?: Array<string | number>): Promise<any>;
34
+ updateChannel(options: Record<string, any>): Promise<boolean>;
35
+ sendChatMessage(options: Record<string, any>): Promise<any>;
36
+ getPublicKey(): Promise<any>;
37
+ validateWebhook(headers: WebhookHeaders, body: any): Promise<{
38
+ isValid: boolean;
39
+ eventType: WebhookType;
40
+ version: string;
41
+ messageId: string;
42
+ timestamp: string;
43
+ payload: unknown;
44
+ }>;
45
+ getEventSubscriptions(): Promise<unknown>;
46
+ subscribeToEvents(events: WebhookType[], method?: string): Promise<unknown>;
47
+ unsubscribeFromEvents(subscriptionIds: string[]): Promise<boolean>;
48
+ startWebhookServer(): Promise<void>;
49
+ stopWebhookServer(): Promise<void>;
50
+ handleWebhookRequest(headers: WebhookHeaders, rawBody: any): Promise<{
51
+ eventType: string;
52
+ eventVersion: string;
53
+ payload: any;
54
+ }>;
55
+ }
56
+ export {};
package/dist/client.js ADDED
@@ -0,0 +1,86 @@
1
+ import { EventEmitter } from 'events';
2
+ import { CategoriesService } from './services/categories';
3
+ import { UsersService } from './services/users';
4
+ import { ChannelsService } from './services/channels';
5
+ import { ChatService } from './services/chat';
6
+ import { PublicKeyService } from './services/publicKey';
7
+ import { EventsService } from './services/events'; // ✅ Ajout
8
+ import { WebhookHandler } from './webhooks/handler';
9
+ import { WebhookServer } from './webhooks/server';
10
+ export class KickClient extends EventEmitter {
11
+ constructor(options = {}) {
12
+ var _a;
13
+ super();
14
+ this.options = Object.assign({ webhookPort: options.webhookPort || 3000, webhookPath: options.webhookPath || '/webhook', webhookBaseUrl: options.webhookBaseUrl || 'http://localhost', token: (_a = options.token) !== null && _a !== void 0 ? _a : '' }, options);
15
+ this.categories = new CategoriesService(this);
16
+ this.users = new UsersService(this);
17
+ this.channels = new ChannelsService(this);
18
+ this.chat = new ChatService(this);
19
+ this.publicKey = new PublicKeyService(this);
20
+ this.events = new EventsService(this);
21
+ this.webhookHandler = new WebhookHandler(this);
22
+ this.webhookServer = new WebhookServer(this, {
23
+ port: this.options.webhookPort,
24
+ path: this.options.webhookPath
25
+ });
26
+ this.token = options.token || '';
27
+ }
28
+ async searchCategories(query = '') {
29
+ return await this.categories.getCategories(query, this.token);
30
+ }
31
+ async getCategory(categoryId) {
32
+ return await this.categories.getCategory(categoryId, this.token);
33
+ }
34
+ async introspectToken() {
35
+ if (!this.token)
36
+ throw new Error('No token provided');
37
+ return await this.users.introspectToken(this.token);
38
+ }
39
+ async getUsers(userIds = []) {
40
+ return await this.users.getUsers(userIds.map(String), this.token);
41
+ }
42
+ async getChannels(broadcasterIds = []) {
43
+ return await this.channels.getChannels(broadcasterIds.map(String), this.token);
44
+ }
45
+ async updateChannel(options) {
46
+ if (!this.token)
47
+ throw new Error('No token provided');
48
+ const typedOptions = options;
49
+ return await this.channels.updateChannel(typedOptions, this.token);
50
+ }
51
+ async sendChatMessage(options) {
52
+ return await this.chat.sendMessage(Object.assign(Object.assign({}, options), { token: this.token, content: options.content // Assure-toi que content existe
53
+ }));
54
+ }
55
+ async getPublicKey() {
56
+ return await this.publicKey.getPublicKey();
57
+ }
58
+ async validateWebhook(headers, body) {
59
+ await this.events.initializeVerifier();
60
+ return this.events.validateWebhook(headers, body);
61
+ }
62
+ async getEventSubscriptions() {
63
+ if (!this.token)
64
+ throw new Error('No token provided');
65
+ return await this.events.getSubscriptions(this.token);
66
+ }
67
+ async subscribeToEvents(events, method = 'webhook') {
68
+ if (!this.token)
69
+ throw new Error('No token provided');
70
+ return await this.events.subscribe(events, method, this.token);
71
+ }
72
+ async unsubscribeFromEvents(subscriptionIds) {
73
+ if (!this.token)
74
+ throw new Error('No token provided');
75
+ return await this.events.unsubscribe(subscriptionIds, this.token);
76
+ }
77
+ async startWebhookServer() {
78
+ return await this.webhookServer.start();
79
+ }
80
+ async stopWebhookServer() {
81
+ return await this.webhookServer.stop();
82
+ }
83
+ async handleWebhookRequest(headers, rawBody) {
84
+ return await this.webhookHandler.handleWebhook(headers, rawBody);
85
+ }
86
+ }
@@ -0,0 +1,10 @@
1
+ export declare class KickApiError extends Error {
2
+ status: number;
3
+ constructor(message: string, status: number);
4
+ }
5
+ export declare class UnauthorizedError extends KickApiError {
6
+ constructor(message?: string);
7
+ }
8
+ export declare class ForbiddenError extends KickApiError {
9
+ constructor(message?: string);
10
+ }
package/dist/errors.js ADDED
@@ -0,0 +1,19 @@
1
+ export class KickApiError extends Error {
2
+ constructor(message, status) {
3
+ super(message);
4
+ this.name = 'KickApiError';
5
+ this.status = status;
6
+ }
7
+ }
8
+ export class UnauthorizedError extends KickApiError {
9
+ constructor(message = 'Unauthorized') {
10
+ super(message, 401);
11
+ this.name = 'UnauthorizedError';
12
+ }
13
+ }
14
+ export class ForbiddenError extends KickApiError {
15
+ constructor(message = 'Forbidden') {
16
+ super(message, 403);
17
+ this.name = 'ForbiddenError';
18
+ }
19
+ }
@@ -0,0 +1 @@
1
+ export * from './client';
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ export * from './client';