Skip to content

Commit 2b122c3

Browse files
author
GGESrv
committed
chore: initial relase
0 parents  commit 2b122c3

33 files changed

Lines changed: 2424 additions & 0 deletions

.gitignore

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
node_modules/
2+
package-lock.json
3+
.env
4+
.npm-cache/
5+
kick-tokens.json
6+
multi-streamers.json
7+
rotation-tokens.json
8+
*.tgz
9+
*.log

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Changelog
2+
3+
## 0.1.0 - 2025-11-02
4+
5+
- Initial release rebranded as **kapi-kit**
6+
- Complete coverage of Kick Public API endpoints with `KickApiClient`
7+
- OAuth helpers for client credentials, authorization code with PKCE, refresh, and revoke flows
8+
- Extensive example suite including single-channel and multi-stream bots
9+
- Error wrapper (`KickApiError`) with request id, status, and parsed response payload
10+
- Shared webhook utilities with signature + shared-secret validation

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 Kick Public API SDK contributors
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
# kapi-kit · Kick Public API toolkit for Node.js 22 🚀
2+
3+
[![npm version](https://img.shields.io/npm/v/kapi-kit.svg?label=npm)](https://www.npmjs.com/package/kapi-kit)
4+
[![node](https://img.shields.io/badge/node-%E2%89%A5%2022.0-6cc24a)](#requirements)
5+
[![license](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
6+
[![coverage](https://img.shields.io/badge/endpoints-100%25-brightgreen.svg)](docs/coverage.md)
7+
8+
`kapi-kit` is a batteries-included SDK for the [Kick Public API](https://github.com/KickEngineering/KickDevDocs). It is designed for modern Node.js runtimes (22+) and ships with everything you need to build bots, dashboards, or broadcaster tooling:
9+
10+
- 🔐 **OAuth 2.1 helpers** with PKCE utilities, refresh rotation, and token revocation
11+
- 💬 **Chat client** ready for bot *and* broadcaster messages, including replies
12+
- 📺 **Livestream, channel, moderation, kicks, and users** endpoints behind a unified client
13+
- 🪝 **Webhook receivers** complete with signature verification and shared-secret support
14+
- 🧪 **Drop-in examples** for every endpoint, from quick scripts to production-ready bots
15+
- 🧰 **Multi-tenant bot framework** so multiple streamers can adopt your bot with a single deployment
16+
17+
> **Status** – The codebase mirrors Kick’s public documentation as of 2025-10-27. Keep an eye on the [Kick Engineering announcements](https://github.com/KickEngineering/KickDevDocs) for new endpoints; extending `kapi-kit` is intentionally straightforward.
18+
19+
---
20+
21+
## Table of contents
22+
23+
1. [Requirements](#requirements)
24+
2. [Installation](#installation)
25+
3. [Quick start](#quick-start)
26+
4. [Authentication flows](#authentication-flows)
27+
5. [API tour](#api-tour)
28+
6. [Example gallery](#example-gallery)
29+
7. [Multi-stream bot architecture](#multi-stream-bot-architecture)
30+
8. [Endpoint coverage](#endpoint-coverage)
31+
9. [Roadmap](#roadmap)
32+
10. [Contributing](#contributing)
33+
11. [License](#license)
34+
35+
---
36+
37+
## Requirements
38+
39+
- **Node.js 22.0.0 or newer** (built-in `fetch` is used throughout)
40+
- **npm** or any compatible package manager
41+
- A registered [Kick developer application](https://kick.com/apps) with the scopes you plan to use
42+
43+
Check your environment quickly:
44+
45+
```bash
46+
npm run lint
47+
```
48+
49+
The command verifies Node.js version and `fetch` availability.
50+
51+
---
52+
53+
## Installation
54+
55+
```bash
56+
npm install kapi-kit
57+
```
58+
59+
or with pnpm:
60+
61+
```bash
62+
pnpm add kapi-kit
63+
```
64+
65+
`kapi-kit` ships as native ESM – just use standard `import` syntax.
66+
67+
---
68+
69+
## Quick start
70+
71+
```js
72+
import { KickApiClient } from 'kapi-kit';
73+
74+
const client = new KickApiClient({
75+
accessToken: process.env.KICK_ACCESS_TOKEN, // must include chat:write to send messages
76+
});
77+
78+
await client.sendChatMessage({
79+
type: 'bot',
80+
content: 'Hello Kick! 👋',
81+
});
82+
```
83+
84+
> Need scopes? Head to **Kick Dev Portal → Your App → Scopes** and grant `chat:write`.
85+
86+
---
87+
88+
## Authentication flows
89+
90+
| Scenario | Helper | Notes |
91+
| --- | --- | --- |
92+
| App-to-app calls (Client Credentials) | `KickAuthClient#getAppAccessToken` | Use when no broadcaster auth is required. |
93+
| Interactive login (Authorization Code + PKCE) | `createPkcePair`, `createAuthorizationUrl`, `KickAuthClient#exchangeCodeForToken` | Guides end-users through the consent screen. |
94+
| Refreshing access tokens | `KickAuthClient#refreshAccessToken` | Returns a *new* access and refresh token. Persist it! |
95+
| Revoking tokens | `KickAuthClient#revokeToken` | Works with either access or refresh tokens. |
96+
| Token introspection | `KickApiClient#introspectToken` | Confirms validity, scope, and expiry. |
97+
98+
🚦 **First time implementing OAuth?** Run `node examples/token-rotation.js`. It walks through the PKCE flow, stores the refresh token, and keeps rotating it so it never expires.
99+
100+
---
101+
102+
## API tour
103+
104+
`kapi-kit` exposes a single high-level client plus targeted helpers:
105+
106+
```js
107+
import {
108+
KickApiClient,
109+
KickChatClient,
110+
KickAuthClient,
111+
createAuthorizationUrl,
112+
createPkcePair,
113+
KickApiError,
114+
} from 'kapi-kit';
115+
```
116+
117+
| Area | Methods | Example |
118+
| --- | --- | --- |
119+
| **Chat** | `client.sendChatMessage`, `chat.sendMessage` | `examples/chat-send.js` |
120+
| **Channels** | `client.getChannels`, `client.updateChannelMetadata` | `examples/channels-get.js`, `examples/channels-update.js` |
121+
| **Livestreams** | `client.getLivestreams`, `client.getLivestreamStats` | `examples/livestreams-list.js` |
122+
| **Events** | `client.list/create/deleteEventSubscriptions` | `examples/events.js` |
123+
| **Moderation** | `client.banUser`, `client.unbanUser` | `examples/moderation.js` |
124+
| **Kicks** | `client.getKicksLeaderboard` | `examples/kicks-leaderboard.js` |
125+
| **Users** | `client.getUsers` | `examples/users.js` |
126+
| **Public key** | `client.getPublicKey` | `examples/public-key.js` |
127+
128+
Every method accepts an optional `AbortSignal` and raises a `KickApiError` with `status`, `statusText`, `body`, and `requestId` fields on failure.
129+
130+
---
131+
132+
## Example gallery
133+
134+
| Script | What it teaches | Typical use case |
135+
| --- | --- | --- |
136+
| `chat-send.js` | Send bot/broadcaster messages, replies, emotes | Simple bot posting updates |
137+
| `token-rotation.js` | Persistent refresh rotation + sample call | Long-running services |
138+
| `full-bot.js` | Single-channel bot with webhooks, `!ping`, `!title`, keep-alives | Bots for a single broadcaster |
139+
| `multi-stream-bot.js` | Multi-tenant bot with onboarding endpoint & webhook verification | SaaS bot adopted by many streamers |
140+
| `events.js` | Subscribe/unsubscribe/list webhook events | Dashboards & analytics |
141+
| `oauth-*` scripts | Client credentials, PKCE, refresh, revoke | Bootstrapping authentication flows |
142+
143+
All scripts can be launched directly:
144+
145+
```bash
146+
node examples/full-bot.js
147+
```
148+
149+
Each script documents the environment variables it reads—search for `process.env` inside the file for a cheat-sheet.
150+
151+
---
152+
153+
## Multi-stream bot architecture
154+
155+
`examples/multi-stream-bot.js` contains everything you need to run a “click to add bot” experience:
156+
157+
1. **User clicks “Add Bot”** on your website → Kick redirects back with `code` + `code_verifier`.
158+
2. Your frontend POSTs `{ code, code_verifier }` (and the optional `redirect_uri`) to `POST /kick/streamers/add`, sending `Kick-App-Secret` in the header.
159+
3. The server exchanges the code for tokens, stores the refresh token in `multi-streamers.json`, subscribes to `chat.message.sent`, and schedules token refreshes + keep-alive messages for that broadcaster.
160+
4. Kick delivers chat events to `POST /kick/webhook`. The bot validates the signature *and* shared secret, then responds to commands:
161+
- `!ping``!pong`
162+
- `!title The New Title` updates the stream title
163+
- Keep-alive messages post every 5 minutes as both bot and broadcaster.
164+
165+
Token refreshes are automatically persisted. If a broadcaster revokes access, refresh attempts will start failing—handle that by removing them from the store or prompting them to re-authorize.
166+
167+
---
168+
169+
## Endpoint coverage
170+
171+
See [docs/coverage.md](docs/coverage.md) for the full matrix mapping each Kick endpoint to SDK methods and runnable examples. It mirrors the official [Kick Dev Docs](https://github.com/KickEngineering/KickDevDocs).
172+
173+
---
174+
175+
## Roadmap
176+
177+
- [ ] Streaming consumer for real-time chat without webhooks
178+
- [ ] Lightweight HTTP client plug-in (Axios/undici swap)
179+
- [ ] TypeScript type declarations (today we rely on JSDoc)
180+
- [ ] Optional Redis-backed token stores for multi-stream bots
181+
182+
Got ideas or find a gap in Kick’s evolving API? Open an issue or PR—feedback is welcome!
183+
184+
---
185+
186+
## Contributing
187+
188+
1. Fork the repository.
189+
2. Install dependencies and run the lint check:
190+
```bash
191+
npm install
192+
npm run lint
193+
```
194+
3. Add tests or examples if your change affects behaviour.
195+
4. Open a pull request against `main` describing the change and relevant Kick docs.
196+
197+
---
198+
199+
## License
200+
201+
MIT © [Wydoyolo](https://github.com/Wydoyolo)
202+
203+
Kick API documentation is owned by Kick. See the official docs for the latest platform terms.

docs/coverage.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Kick Public API Coverage
2+
3+
The SDK implements every endpoint listed in the [Kick Dev Docs](https://github.com/KickEngineering/KickDevDocs) public documentation. Use the table below to trace an endpoint in the official docs to the matching helper and runnable example in `kapi-kit`.
4+
5+
| Kick Endpoint | SDK Method | Notes | Example Script |
6+
| --- | --- | --- | --- |
7+
| `POST /oauth/token` | `KickAuthClient#getAppAccessToken`, `#exchangeCodeForToken`, `#refreshAccessToken` | Client credentials, authorization code, and refresh flows | `examples/oauth-client-credentials.js`, `examples/oauth-authorization-code.js`, `examples/oauth-refresh.js` |
8+
| `POST /oauth/revoke` | `KickAuthClient#revokeToken` | Uses query-string token hint as documented | `examples/oauth-revoke.js` |
9+
| `POST /oauth/authorize` | `createAuthorizationUrl`, `createPkcePair` | Helper utilities for initiating PKCE authorization flows | `examples/token-rotation.js`, `examples/full-bot.js`, `examples/multi-stream-bot.js` |
10+
| `POST /chat` | `KickApiClient#sendChatMessage`, `KickChatClient#sendMessage` | Supports bot & user message types, optional replies | `examples/chat-send.js`, `examples/chat-client.js`, `examples/full-bot.js`, `examples/multi-stream-bot.js` |
11+
| `GET /categories` | `KickApiClient#searchCategories` | Handles pagination (`page`) | `examples/categories.js` |
12+
| `GET /categories/:category_id` | `KickApiClient#getCategoryById` | Returns full category payload | `examples/categories.js` |
13+
| `GET /channels` | `KickApiClient#getChannels` | Supports filtering by broadcaster IDs or slugs (mutually exclusive) | `examples/channels-get.js` |
14+
| `PATCH /channels` | `KickApiClient#updateChannelMetadata` | Updates category, title, and custom tags | `examples/channels-update.js`, `examples/full-bot.js`, `examples/multi-stream-bot.js` |
15+
| `GET /events/subscriptions` | `KickApiClient#listEventSubscriptions` | Optional broadcaster filtering | `examples/events.js`, `examples/full-bot.js`, `examples/multi-stream-bot.js` |
16+
| `POST /events/subscriptions` | `KickApiClient#createEventSubscriptions` | Accepts webhook subscriptions with event list validation | `examples/events.js`, `examples/full-bot.js`, `examples/multi-stream-bot.js` |
17+
| `DELETE /events/subscriptions` | `KickApiClient#deleteEventSubscriptions` | Accepts multiple subscription IDs | `examples/events.js`, `examples/full-bot.js`, `examples/multi-stream-bot.js` |
18+
| `GET /livestreams` | `KickApiClient#getLivestreams` | Supports language, category, sort, limit, broadcaster filters | `examples/livestreams-list.js` |
19+
| `GET /livestreams/stats` | `KickApiClient#getLivestreamStats` | Returns livestream count | `examples/livestreams-stats.js` |
20+
| `GET /kicks/leaderboard` | `KickApiClient#getKicksLeaderboard` | Optional `top` parameter | `examples/kicks-leaderboard.js` |
21+
| `POST /moderation/bans` | `KickApiClient#banUser` | Supports optional timeout duration & reason | `examples/moderation.js` |
22+
| `DELETE /moderation/bans` | `KickApiClient#unbanUser` | Reverses bans/timeouts | `examples/moderation.js` |
23+
| `GET /public-key` | `KickApiClient#getPublicKey` | Exposes verification public key | `examples/public-key.js` |
24+
| `POST /token/introspect` | `KickApiClient#introspectToken` | Mirrors RFC 7662 output | `examples/token-introspect.js` |
25+
| `GET /users` | `KickApiClient#getUsers` | Fetches authorised user or list of IDs | `examples/users.js` |
26+
27+
Every example is self-contained and can be executed directly after replacing placeholder credentials.

examples/categories.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { KickApiClient } from 'kapi-kit';
2+
3+
const client = new KickApiClient({ accessToken: 'YOUR_ACCESS_TOKEN' });
4+
5+
const categories = await client.searchCategories({ query: 'music' });
6+
console.log('Search results:', categories);
7+
8+
if (Array.isArray(categories) && categories.length > 0) {
9+
const category = await client.getCategoryById(categories[0].id);
10+
console.log('Category details:', category);
11+
}

examples/channels-get.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { KickApiClient } from 'kapi-kit';
2+
3+
const client = new KickApiClient({ accessToken: 'YOUR_ACCESS_TOKEN' });
4+
5+
const byBroadcasterId = await client.getChannels({ broadcasterUserIds: [123456] });
6+
console.log('Channels by broadcaster id:', byBroadcasterId);
7+
8+
const bySlug = await client.getChannels({ slugs: ['example-channel'] });
9+
console.log('Channels by slug:', bySlug);

examples/channels-update.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { KickApiClient } from 'kapi-kit';
2+
3+
const client = new KickApiClient({ accessToken: 'YOUR_ACCESS_TOKEN' });
4+
5+
await client.updateChannelMetadata({
6+
streamTitle: 'A better title for my stream',
7+
categoryId: 123, // Replace with a category id from /categories.
8+
customTags: ['speedrun', 'giveaway'],
9+
});
10+
11+
console.log('Channel metadata update accepted.');

examples/chat-client.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { KickChatClient } from 'kapi-kit';
2+
3+
// Supply a chat:write token. Messages default to the authenticated channel when `type` is `bot`.
4+
const chat = new KickChatClient({ accessToken: 'YOUR_ACCESS_TOKEN' });
5+
6+
const message = await chat.sendMessage({
7+
content: 'Hello from KickChatClient!',
8+
type: 'bot',
9+
});
10+
11+
console.log(message);

examples/chat-send.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { KickApiClient } from 'kapi-kit';
2+
3+
// Replace with an access token that includes the `chat:write` scope.
4+
const client = new KickApiClient({
5+
accessToken: 'YOUR_ACCESS_TOKEN',
6+
});
7+
8+
// Send as the authenticated bot. Kick routes bot messages to the broadcaster
9+
// associated with the token.
10+
const botMessage = await client.sendChatMessage({
11+
type: 'bot',
12+
content: 'Message will be sent to the authenticated channel.',
13+
});
14+
15+
console.log('Bot message:', botMessage);
16+
17+
// Send as a broadcaster user by providing the broadcaster user id.
18+
const userMessage = await client.sendChatMessage({
19+
type: 'user',
20+
content: 'Message will be sent to the specified broadcaster channel.',
21+
broadcasterUserId: 123456, // Replace with a real broadcaster user id.
22+
});
23+
24+
console.log('User message:', userMessage);

0 commit comments

Comments
 (0)