@manaobot/kick 1.0.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 +163 -0
- package/biome.json +44 -0
- package/bun.lock +78 -0
- package/example/01-authorize-bot/.env.example +7 -0
- package/example/01-authorize-bot/index.ts +60 -0
- package/example/02-webhook/.env.example +7 -0
- package/example/02-webhook/index.ts +80 -0
- package/example/03-ngrok/.env.example +7 -0
- package/example/03-ngrok/index.ts +92 -0
- package/example/04-categories-api/.env.example +7 -0
- package/example/04-categories-api/index.ts +77 -0
- package/example/05-users-api/.env.example +7 -0
- package/example/05-users-api/index.ts +60 -0
- package/example/06-channels-api/.env.example +7 -0
- package/example/06-channels-api/index.ts +60 -0
- package/example/07-channel-rewards-api/.env.example +7 -0
- package/example/07-channel-rewards-api/index.ts +60 -0
- package/example/08-basic-chat-bot/.env.example +7 -0
- package/example/08-basic-chat-bot/index.ts +102 -0
- package/package.json +23 -0
- package/qodana.yaml +31 -0
- package/src/KickClient.ts +172 -0
- package/src/Logger.ts +25 -0
- package/src/api/CategoriesAPI.ts +45 -0
- package/src/api/ChannelRewardsAPI.ts +121 -0
- package/src/api/ChannelsAPI.ts +63 -0
- package/src/api/KicksAPI.ts +37 -0
- package/src/api/LivestreamsAPI.ts +65 -0
- package/src/api/ModerationAPI.ts +60 -0
- package/src/api/UsersAPI.ts +72 -0
- package/src/auth/AuthManager.ts +64 -0
- package/src/auth/CallbackServer.ts +57 -0
- package/src/auth/OAuth.ts +55 -0
- package/src/auth/PKCE.ts +13 -0
- package/src/auth/TokenManager.ts +53 -0
- package/src/chat/ChatClient.ts +48 -0
- package/src/rest/RestClient.ts +39 -0
- package/src/webhooks/NgrokAdapter.ts +46 -0
- package/src/webhooks/WebhookRouter.ts +135 -0
- package/src/webhooks/WebhookServer.ts +41 -0
- package/tsconfig.json +29 -0
- package/types/api.d.ts +158 -0
- package/types/auth.d.ts +38 -0
- package/types/chat.d.ts +14 -0
- package/types/client.d.ts +67 -0
- package/types/index.d.ts +4 -0
- package/types/webhooks.d.ts +35 -0
package/README.md
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<a href="https://github.com/tinarskii/manao">
|
|
3
|
+
<img src="https://raw.githubusercontent.com/tinarskii/manao/main/docs/manao.svg" height="64px" width="auto" />
|
|
4
|
+
<h2 align="center">@manaobot/kick</h2>
|
|
5
|
+
</a>
|
|
6
|
+
<p align="center">
|
|
7
|
+
Minimal, type-safe JavaScript SDK for building Kick.com bots.
|
|
8
|
+
Designed for Bun. Works anywhere.
|
|
9
|
+
</p>
|
|
10
|
+
<div style="display: flex; flex-wrap: wrap; justify-content: center; gap: 8px;">
|
|
11
|
+
<img src="https://img.shields.io/npm/v/@manaobot/kick?color=00e701" alt="npm version">
|
|
12
|
+
<img src="https://img.shields.io/github/license/tinarskii/manao" />
|
|
13
|
+
<img src="https://img.shields.io/badge/Bun-%E2%9C%93-black?logo=bun" alt="Bun Compatible">
|
|
14
|
+
<a href="https://discord.gg/vkW7YMyYaf"><img src="https://img.shields.io/discord/964718161624715304" /></a>
|
|
15
|
+
</div>
|
|
16
|
+
</p>
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## ⚡ About
|
|
21
|
+
|
|
22
|
+
`@manaobot/kick` is a lightweight TypeScript SDK for building Kick.com bots, tools, and automation.
|
|
23
|
+
This library focuses on **OAuth**, **Webhooks**, and **REST APIs**, everything required to build production-grade Kick bots.
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## 📦 Installation
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
bun add @manaobot/kick
|
|
31
|
+
````
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## 🚀 Quick Start
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
import { KickClient } from "@manaobot/kick";
|
|
39
|
+
|
|
40
|
+
const kick = new KickClient({
|
|
41
|
+
clientId: process.env.KICK_CLIENT_ID!,
|
|
42
|
+
clientSecret: process.env.KICK_CLIENT_SECRET!,
|
|
43
|
+
redirectUri: "http://localhost:3000/callback",
|
|
44
|
+
scopes: ["chat:write"],
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
if (!process.env.KICK_REFRESH_TOKEN) {
|
|
48
|
+
console.log(kick.getAuthURL());
|
|
49
|
+
kick.auth.createCallbackServer({ port: 3000 });
|
|
50
|
+
await kick.auth.waitForAuthorization();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
await kick.chat.send({
|
|
54
|
+
content: "Hello from Kick SDK!"
|
|
55
|
+
});
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## ✨ Features
|
|
61
|
+
|
|
62
|
+
### 🔐 Authentication
|
|
63
|
+
|
|
64
|
+
* OAuth2 Authorization Code Flow
|
|
65
|
+
* Automatic token refresh
|
|
66
|
+
* PKCE support
|
|
67
|
+
* Built-in callback server
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
### 🧩 Webhooks
|
|
72
|
+
|
|
73
|
+
```ts
|
|
74
|
+
kick.webhooks.on("chat.message.sent", (event) => {
|
|
75
|
+
console.log(event.content);
|
|
76
|
+
});
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
* Signature verification
|
|
80
|
+
* ngrok integration
|
|
81
|
+
* Event subscription helpers
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
### 💬 Chat
|
|
86
|
+
|
|
87
|
+
```ts
|
|
88
|
+
await kick.chat.send({ content: "Hello chat!" });
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
### 🌐 REST APIs
|
|
94
|
+
|
|
95
|
+
Available via:
|
|
96
|
+
|
|
97
|
+
```ts
|
|
98
|
+
kick.api.*
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Currently supported:
|
|
102
|
+
|
|
103
|
+
* Categories API
|
|
104
|
+
* Users API
|
|
105
|
+
* Channels API
|
|
106
|
+
* Channel Rewards API
|
|
107
|
+
* Moderation API
|
|
108
|
+
* Livestreams API
|
|
109
|
+
* KICKs Leaderboard API
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## 📚 Examples
|
|
114
|
+
|
|
115
|
+
The repository includes numbered examples:
|
|
116
|
+
|
|
117
|
+
| Example | Description |
|
|
118
|
+
| ------------------------ | ------------------------ |
|
|
119
|
+
| `01-authorize-bot` | OAuth authorization |
|
|
120
|
+
| `02-webhook` | Webhook handling |
|
|
121
|
+
| `03-ngrok` | Public webhook tunneling |
|
|
122
|
+
| `04-categories-api` | Categories API |
|
|
123
|
+
| `05-users-api` | Users API |
|
|
124
|
+
| `06-channels-api` | Channels API |
|
|
125
|
+
| `07-channel-rewards-api` | Channel rewards |
|
|
126
|
+
| `08-basic-chat-bot` | Full bot template |
|
|
127
|
+
|
|
128
|
+
Run examples with:
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
bun example/08-basic-chat-bot
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## 🤝 Contributing
|
|
137
|
+
|
|
138
|
+
Pull requests are welcome.
|
|
139
|
+
|
|
140
|
+
If you want to help:
|
|
141
|
+
|
|
142
|
+
* improve typings
|
|
143
|
+
* add new API modules
|
|
144
|
+
* write examples
|
|
145
|
+
|
|
146
|
+
Join the Discord server:
|
|
147
|
+
|
|
148
|
+
[https://discord.gg/vkW7YMyYaf](https://discord.gg/vkW7YMyYaf)
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## 📜 License
|
|
153
|
+
|
|
154
|
+
GPL-3.0 License
|
|
155
|
+
See LICENSE file for details.
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
## ❤️ Part of the Manao Ecosystem
|
|
160
|
+
|
|
161
|
+
This SDK powers the **ManaoBot** project:
|
|
162
|
+
|
|
163
|
+
[https://github.com/tinarskii/manao](https://github.com/tinarskii/manao)
|
package/biome.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://biomejs.dev/schemas/2.2.4/schema.json",
|
|
3
|
+
"vcs": {
|
|
4
|
+
"enabled": false,
|
|
5
|
+
"clientKind": "git",
|
|
6
|
+
"useIgnoreFile": false
|
|
7
|
+
},
|
|
8
|
+
"files": {
|
|
9
|
+
"ignoreUnknown": false,
|
|
10
|
+
"experimentalScannerIgnores": ["dist", "node_modules", "tsconfig.json"]
|
|
11
|
+
},
|
|
12
|
+
"formatter": {
|
|
13
|
+
"enabled": true,
|
|
14
|
+
"indentStyle": "space",
|
|
15
|
+
"indentWidth": 2
|
|
16
|
+
},
|
|
17
|
+
"linter": {
|
|
18
|
+
"enabled": true,
|
|
19
|
+
"rules": {
|
|
20
|
+
"recommended": true
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"javascript": {
|
|
24
|
+
"formatter": {
|
|
25
|
+
"quoteStyle": "double",
|
|
26
|
+
"semicolons": "always",
|
|
27
|
+
"lineEnding": "crlf",
|
|
28
|
+
"arrowParentheses": "always",
|
|
29
|
+
"bracketSpacing": true,
|
|
30
|
+
"bracketSameLine": false
|
|
31
|
+
},
|
|
32
|
+
"parser": {
|
|
33
|
+
"unsafeParameterDecoratorsEnabled": true
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
"assist": {
|
|
37
|
+
"enabled": true,
|
|
38
|
+
"actions": {
|
|
39
|
+
"source": {
|
|
40
|
+
"organizeImports": "on"
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
package/bun.lock
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
{
|
|
2
|
+
"lockfileVersion": 1,
|
|
3
|
+
"workspaces": {
|
|
4
|
+
"": {
|
|
5
|
+
"name": "kick.js",
|
|
6
|
+
"dependencies": {
|
|
7
|
+
"consola": "^3.4.2",
|
|
8
|
+
},
|
|
9
|
+
"devDependencies": {
|
|
10
|
+
"@biomejs/biome": "2.3.14",
|
|
11
|
+
"@ngrok/ngrok": "^1.7.0",
|
|
12
|
+
"@types/bun": "^1.3.8",
|
|
13
|
+
},
|
|
14
|
+
"peerDependencies": {
|
|
15
|
+
"typescript": "^5",
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
"packages": {
|
|
20
|
+
"@biomejs/biome": ["@biomejs/biome@2.3.14", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "2.3.14", "@biomejs/cli-darwin-x64": "2.3.14", "@biomejs/cli-linux-arm64": "2.3.14", "@biomejs/cli-linux-arm64-musl": "2.3.14", "@biomejs/cli-linux-x64": "2.3.14", "@biomejs/cli-linux-x64-musl": "2.3.14", "@biomejs/cli-win32-arm64": "2.3.14", "@biomejs/cli-win32-x64": "2.3.14" }, "bin": { "biome": "bin/biome" } }, "sha512-QMT6QviX0WqXJCaiqVMiBUCr5WRQ1iFSjvOLoTk6auKukJMvnMzWucXpwZB0e8F00/1/BsS9DzcKgWH+CLqVuA=="],
|
|
21
|
+
|
|
22
|
+
"@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@2.3.14", "", { "os": "darwin", "cpu": "arm64" }, "sha512-UJGPpvWJMkLxSRtpCAKfKh41Q4JJXisvxZL8ChN1eNW3m/WlPFJ6EFDCE7YfUb4XS8ZFi3C1dFpxUJ0Ety5n+A=="],
|
|
23
|
+
|
|
24
|
+
"@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@2.3.14", "", { "os": "darwin", "cpu": "x64" }, "sha512-PNkLNQG6RLo8lG7QoWe/hhnMxJIt1tEimoXpGQjwS/dkdNiKBLPv4RpeQl8o3s1OKI3ZOR5XPiYtmbGGHAOnLA=="],
|
|
25
|
+
|
|
26
|
+
"@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@2.3.14", "", { "os": "linux", "cpu": "arm64" }, "sha512-KT67FKfzIw6DNnUNdYlBg+eU24Go3n75GWK6NwU4+yJmDYFe9i/MjiI+U/iEzKvo0g7G7MZqoyrhIYuND2w8QQ=="],
|
|
27
|
+
|
|
28
|
+
"@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@2.3.14", "", { "os": "linux", "cpu": "arm64" }, "sha512-LInRbXhYujtL3sH2TMCH/UBwJZsoGwfQjBrMfl84CD4hL/41C/EU5mldqf1yoFpsI0iPWuU83U+nB2TUUypWeg=="],
|
|
29
|
+
|
|
30
|
+
"@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@2.3.14", "", { "os": "linux", "cpu": "x64" }, "sha512-ZsZzQsl9U+wxFrGGS4f6UxREUlgHwmEfu1IrXlgNFrNnd5Th6lIJr8KmSzu/+meSa9f4rzFrbEW9LBBA6ScoMA=="],
|
|
31
|
+
|
|
32
|
+
"@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@2.3.14", "", { "os": "linux", "cpu": "x64" }, "sha512-KQU7EkbBBuHPW3/rAcoiVmhlPtDSGOGRPv9js7qJVpYTzjQmVR+C9Rfcz+ti8YCH+zT1J52tuBybtP4IodjxZQ=="],
|
|
33
|
+
|
|
34
|
+
"@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@2.3.14", "", { "os": "win32", "cpu": "arm64" }, "sha512-+IKYkj/pUBbnRf1G1+RlyA3LWiDgra1xpS7H2g4BuOzzRbRB+hmlw0yFsLprHhbbt7jUzbzAbAjK/Pn0FDnh1A=="],
|
|
35
|
+
|
|
36
|
+
"@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.3.14", "", { "os": "win32", "cpu": "x64" }, "sha512-oizCjdyQ3WJEswpb3Chdngeat56rIdSYK12JI3iI11Mt5T5EXcZ7WLuowzEaFPNJ3zmOQFliMN8QY1Pi+qsfdQ=="],
|
|
37
|
+
|
|
38
|
+
"@ngrok/ngrok": ["@ngrok/ngrok@1.7.0", "", { "optionalDependencies": { "@ngrok/ngrok-android-arm64": "1.7.0", "@ngrok/ngrok-darwin-arm64": "1.7.0", "@ngrok/ngrok-darwin-universal": "1.7.0", "@ngrok/ngrok-darwin-x64": "1.7.0", "@ngrok/ngrok-freebsd-x64": "1.7.0", "@ngrok/ngrok-linux-arm-gnueabihf": "1.7.0", "@ngrok/ngrok-linux-arm64-gnu": "1.7.0", "@ngrok/ngrok-linux-arm64-musl": "1.7.0", "@ngrok/ngrok-linux-x64-gnu": "1.7.0", "@ngrok/ngrok-linux-x64-musl": "1.7.0", "@ngrok/ngrok-win32-arm64-msvc": "1.7.0", "@ngrok/ngrok-win32-ia32-msvc": "1.7.0", "@ngrok/ngrok-win32-x64-msvc": "1.7.0" } }, "sha512-P06o9TpxrJbiRbHQkiwy/rUrlXRupc+Z8KT4MiJfmcdWxvIdzjCaJOdnNkcOTs6DMyzIOefG5tvk/HLdtjqr0g=="],
|
|
39
|
+
|
|
40
|
+
"@ngrok/ngrok-android-arm64": ["@ngrok/ngrok-android-arm64@1.7.0", "", { "os": "android", "cpu": "arm64" }, "sha512-8tco3ID6noSaNy+CMS7ewqPoIkIM6XO5COCzsUp3Wv3XEbMSyn65RN6cflX2JdqLfUCHcMyD0ahr9IEiHwqmbQ=="],
|
|
41
|
+
|
|
42
|
+
"@ngrok/ngrok-darwin-arm64": ["@ngrok/ngrok-darwin-arm64@1.7.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-+dmJSOzSO+MNDVrPOca2yYDP1W3KfP4qOlAkarIeFRIfqonQwq3QCBmcR7HAlZocLsSqEwyG6KP4RRvAuT0WGQ=="],
|
|
43
|
+
|
|
44
|
+
"@ngrok/ngrok-darwin-universal": ["@ngrok/ngrok-darwin-universal@1.7.0", "", { "os": "darwin" }, "sha512-fDEfewyE2pWGFBhOSwQZObeHUkc65U1l+3HIgSOe094TMHsqmyJD0KTCgW9KSn0VP4OvDZbAISi1T3nvqgZYhQ=="],
|
|
45
|
+
|
|
46
|
+
"@ngrok/ngrok-darwin-x64": ["@ngrok/ngrok-darwin-x64@1.7.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-+fwMi5uHd9G8BS42MMa9ye6exI5lwTcjUO6Ut497Vu0qgLONdVRenRqnEePV+Q3KtQR7NjqkMnomVfkr9MBjtw=="],
|
|
47
|
+
|
|
48
|
+
"@ngrok/ngrok-freebsd-x64": ["@ngrok/ngrok-freebsd-x64@1.7.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-2OGgbrjy3yLRrqAz5N6hlUKIWIXSpR5RjQa2chtZMsSbszQ6c9dI+uVQfOKAeo05tHMUgrYAZ7FocC+ig0dzdQ=="],
|
|
49
|
+
|
|
50
|
+
"@ngrok/ngrok-linux-arm-gnueabihf": ["@ngrok/ngrok-linux-arm-gnueabihf@1.7.0", "", { "os": "linux", "cpu": "arm" }, "sha512-SN9YIfEQiR9xN90QVNvdgvAemqMLoFVSeTWZs779145hQMhvF9Qd9rnWi6J+2uNNK10OczdV1oc/nq1es7u/3g=="],
|
|
51
|
+
|
|
52
|
+
"@ngrok/ngrok-linux-arm64-gnu": ["@ngrok/ngrok-linux-arm64-gnu@1.7.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-KDMgzPKFU2kbpVSaA2RZBBia5IPdJEe063YlyVFnSMJmPYWCUnMwdybBsucXfV9u1Lw/ZjKTKotIlbTWGn3HGw=="],
|
|
53
|
+
|
|
54
|
+
"@ngrok/ngrok-linux-arm64-musl": ["@ngrok/ngrok-linux-arm64-musl@1.7.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-e66vUdVrBlQ0lT9ZdamB4U604zt5Gualt8/WVcUGzbu8s5LajWd6g/mzZCUjK4UepjvMpfgmCp1/+rX7Rk8d5A=="],
|
|
55
|
+
|
|
56
|
+
"@ngrok/ngrok-linux-x64-gnu": ["@ngrok/ngrok-linux-x64-gnu@1.7.0", "", { "os": "linux", "cpu": "x64" }, "sha512-M6gF0DyOEFqXLfWxObfL3bxYZ4+PnKBHuyLVaqNfFN9Y5utY2mdPOn5422Ppbk4XoIK5/YkuhRqPJl/9FivKEw=="],
|
|
57
|
+
|
|
58
|
+
"@ngrok/ngrok-linux-x64-musl": ["@ngrok/ngrok-linux-x64-musl@1.7.0", "", { "os": "linux", "cpu": "x64" }, "sha512-4Ijm0dKeoyzZTMaYxR2EiNjtlK81ebflg/WYIO1XtleFrVy4UJEGnxtxEidYoT4BfCqi4uvXiK2Mx216xXKvog=="],
|
|
59
|
+
|
|
60
|
+
"@ngrok/ngrok-win32-arm64-msvc": ["@ngrok/ngrok-win32-arm64-msvc@1.7.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-u7qyWIJI2/YG1HTBnHwUR1+Z2tyGfAsUAItJK/+N1G0FeWJhIWQvSIFJHlaPy4oW1Dc8mSDBX9qvVsiQgLaRFg=="],
|
|
61
|
+
|
|
62
|
+
"@ngrok/ngrok-win32-ia32-msvc": ["@ngrok/ngrok-win32-ia32-msvc@1.7.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-/UdYUsLNv/Q8j9YJsyIfq/jLCoD8WP+NidouucTUzSoDtmOsXBBT3itLrmPiZTEdEgKiFYLuC1Zon8XQQvbVLA=="],
|
|
63
|
+
|
|
64
|
+
"@ngrok/ngrok-win32-x64-msvc": ["@ngrok/ngrok-win32-x64-msvc@1.7.0", "", { "os": "win32", "cpu": "x64" }, "sha512-UFJg/duEWzZlLkEs61Gz6/5nYhGaKI62I8dvUGdBR3NCtIMagehnFaFxmnXZldyHmCM8U0aCIFNpWRaKcrQkoA=="],
|
|
65
|
+
|
|
66
|
+
"@types/bun": ["@types/bun@1.3.8", "", { "dependencies": { "bun-types": "1.3.8" } }, "sha512-3LvWJ2q5GerAXYxO2mffLTqOzEu5qnhEAlh48Vnu8WQfnmSwbgagjGZV6BoHKJztENYEDn6QmVd949W4uESRJA=="],
|
|
67
|
+
|
|
68
|
+
"@types/node": ["@types/node@25.2.0", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-DZ8VwRFUNzuqJ5khrvwMXHmvPe+zGayJhr2CDNiKB1WBE1ST8Djl00D0IC4vvNmHMdj6DlbYRIaFE7WHjlDl5w=="],
|
|
69
|
+
|
|
70
|
+
"bun-types": ["bun-types@1.3.8", "", { "dependencies": { "@types/node": "*" } }, "sha512-fL99nxdOWvV4LqjmC+8Q9kW3M4QTtTR1eePs94v5ctGqU8OeceWrSUaRw3JYb7tU3FkMIAjkueehrHPPPGKi5Q=="],
|
|
71
|
+
|
|
72
|
+
"consola": ["consola@3.4.2", "", {}, "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA=="],
|
|
73
|
+
|
|
74
|
+
"typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
|
|
75
|
+
|
|
76
|
+
"undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="],
|
|
77
|
+
}
|
|
78
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Example 01: Authorizing a bot application
|
|
3
|
+
*
|
|
4
|
+
* This template demonstrates how to authorize a bot application using the ManaoKick library.
|
|
5
|
+
* The bot will send a message to the chat once authorized.
|
|
6
|
+
* In the first run, it will print the access and refresh tokens to the console for
|
|
7
|
+
* you to save in your environment variables file (.env).
|
|
8
|
+
*
|
|
9
|
+
* Before running this code, ensure you have the following environment variables set:
|
|
10
|
+
* - KICK_CLIENT_ID
|
|
11
|
+
* - KICK_CLIENT_SECRET
|
|
12
|
+
*
|
|
13
|
+
* Currently, the bot cannot receive messages from the chat.
|
|
14
|
+
*
|
|
15
|
+
* SCOPES: ["chat:write"]
|
|
16
|
+
* Make sure to refresh the tokens and update your environment variables when scopes change.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import { KickClient } from "../../src/KickClient.ts";
|
|
20
|
+
import type { KickTokenResponse } from "../../types";
|
|
21
|
+
|
|
22
|
+
// Initialize the KickClient with necessary credentials and scopes
|
|
23
|
+
const kick = new KickClient({
|
|
24
|
+
clientId: Bun.env.KICK_CLIENT_ID!,
|
|
25
|
+
clientSecret: Bun.env.KICK_CLIENT_SECRET!,
|
|
26
|
+
redirectUri: "http://localhost:3000/callback",
|
|
27
|
+
scopes: ["chat:write", "events:subscribe"],
|
|
28
|
+
showLog: false,
|
|
29
|
+
auth: {
|
|
30
|
+
initialTokens: Bun.env.KICK_REFRESH_TOKEN
|
|
31
|
+
? {
|
|
32
|
+
access_token: Bun.env.KICK_ACCESS_TOKEN!,
|
|
33
|
+
refresh_token: Bun.env.KICK_REFRESH_TOKEN!,
|
|
34
|
+
}
|
|
35
|
+
: undefined,
|
|
36
|
+
onTokenUpdate: (tokens: KickTokenResponse) => {
|
|
37
|
+
if (!Bun.env.KICK_REFRESH_TOKEN) {
|
|
38
|
+
console.log("\n[!] Copy these into your .env file:\n");
|
|
39
|
+
console.log(`KICK_ACCESS_TOKEN=${tokens.access_token}`);
|
|
40
|
+
console.log(`KICK_REFRESH_TOKEN=${tokens.refresh_token}`);
|
|
41
|
+
console.log(`\n====> Scopes granted: ${tokens.scope}`);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
Bun.env.KICK_ACCESS_TOKEN = tokens.access_token;
|
|
45
|
+
Bun.env.KICK_REFRESH_TOKEN = tokens.refresh_token;
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
// If no refresh token is found, initiate the authorization flow
|
|
50
|
+
if (!Bun.env.KICK_REFRESH_TOKEN) {
|
|
51
|
+
console.log(`Authorize the application by visiting:\n${kick.getAuthURL()}`);
|
|
52
|
+
kick.auth.createCallbackServer({ port: 3000 });
|
|
53
|
+
await kick.auth.waitForAuthorization();
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Confirm successful authorization
|
|
57
|
+
console.log("\n[✔] Application authorized successfully!");
|
|
58
|
+
await kick.chat.send({
|
|
59
|
+
content: "Hello from ManaoKick library!",
|
|
60
|
+
});
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Example 02: Subscribing to webhooks
|
|
3
|
+
*
|
|
4
|
+
* This template demonstrates how to subscribe to webhooks using the ManaoKick library.
|
|
5
|
+
* The bot will respond to a specific chat message event once authorized. (!ping -> pong 🏓)
|
|
6
|
+
* In the first run, it will print the access and refresh tokens to the console for
|
|
7
|
+
* you to save in your environment variables file (.env).
|
|
8
|
+
*
|
|
9
|
+
* Before running this code, ensure you have the following environment variables set:
|
|
10
|
+
* - KICK_CLIENT_ID
|
|
11
|
+
* - KICK_CLIENT_SECRET
|
|
12
|
+
*
|
|
13
|
+
* Please note that Kick server cannot access localhost webhooks. To test webhooks,
|
|
14
|
+
* consider using a tunneling service like ngrok to expose your local server to the internet.
|
|
15
|
+
*
|
|
16
|
+
* Simple bot template with ngrok adapter can be found in the next example: example/03-ngrok
|
|
17
|
+
*
|
|
18
|
+
* SCOPES: ["chat:write", "events:subscribe"]
|
|
19
|
+
* Make sure to refresh the tokens and update your environment variables when scopes change.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import { KickClient } from "../../src/KickClient.ts";
|
|
23
|
+
import type { ChatMessageEvent, KickTokenResponse } from "../../types";
|
|
24
|
+
|
|
25
|
+
// Initialize the KickClient with necessary credentials and scopes
|
|
26
|
+
const kick = new KickClient({
|
|
27
|
+
clientId: Bun.env.KICK_CLIENT_ID!,
|
|
28
|
+
clientSecret: Bun.env.KICK_CLIENT_SECRET!,
|
|
29
|
+
redirectUri: "http://localhost:3000/callback",
|
|
30
|
+
scopes: ["chat:write", "events:subscribe"],
|
|
31
|
+
showLog: false,
|
|
32
|
+
auth: {
|
|
33
|
+
initialTokens: Bun.env.KICK_REFRESH_TOKEN
|
|
34
|
+
? {
|
|
35
|
+
access_token: Bun.env.KICK_ACCESS_TOKEN!,
|
|
36
|
+
refresh_token: Bun.env.KICK_REFRESH_TOKEN!,
|
|
37
|
+
}
|
|
38
|
+
: undefined,
|
|
39
|
+
onTokenUpdate: (tokens: KickTokenResponse) => {
|
|
40
|
+
if (!Bun.env.KICK_REFRESH_TOKEN) {
|
|
41
|
+
console.log("\n[!] Copy these into your .env file:\n");
|
|
42
|
+
console.log(`KICK_ACCESS_TOKEN=${tokens.access_token}`);
|
|
43
|
+
console.log(`KICK_REFRESH_TOKEN=${tokens.refresh_token}`);
|
|
44
|
+
console.log(`\n====> Scopes granted: ${tokens.scope}`);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
Bun.env.KICK_ACCESS_TOKEN = tokens.access_token;
|
|
48
|
+
Bun.env.KICK_REFRESH_TOKEN = tokens.refresh_token;
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
// If no refresh token is found, initiate the authorization flow
|
|
53
|
+
if (!Bun.env.KICK_REFRESH_TOKEN) {
|
|
54
|
+
console.log(`Authorize the application by visiting:\n${kick.getAuthURL()}`);
|
|
55
|
+
kick.auth.createCallbackServer({ port: 3000 });
|
|
56
|
+
await kick.auth.waitForAuthorization();
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Confirm successful authorization
|
|
60
|
+
console.log("\n[✔] Application authorized successfully!");
|
|
61
|
+
await kick.chat.send({
|
|
62
|
+
content: "Hello from ManaoKick library!",
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
// Create a webhook server to listen for incoming events
|
|
66
|
+
kick.webhooks.createServer({ port: 5000, path: "/kick/webhook" });
|
|
67
|
+
|
|
68
|
+
// Subscribe to webhooks once authorized
|
|
69
|
+
kick.auth.onAuthorized(async () => {
|
|
70
|
+
await kick.webhooks.subscribe({
|
|
71
|
+
events: [{ name: "chat.message.sent" }],
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
// Handle incoming chat message events
|
|
76
|
+
kick.webhooks.on("chat.message.sent", async (event: ChatMessageEvent) => {
|
|
77
|
+
if (event.content === "!ping") {
|
|
78
|
+
await kick.chat.send({ content: "pong 🏓" });
|
|
79
|
+
}
|
|
80
|
+
});
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Example 03: Using ngrok adapter to expose local webhooks
|
|
3
|
+
*
|
|
4
|
+
* This template demonstrates how to use the ngrok adapter to expose local webhooks using the ManaoKick library.
|
|
5
|
+
* The bot will respond to a specific chat message event once authorized. (!ping -> pong 🏓)
|
|
6
|
+
* In the first run, it will print the access and refresh tokens to the console for
|
|
7
|
+
* you to save in your environment variables file (.env).
|
|
8
|
+
*
|
|
9
|
+
* Before running this code, ensure you have the following environment variables set:
|
|
10
|
+
* - KICK_CLIENT_ID
|
|
11
|
+
* - KICK_CLIENT_SECRET
|
|
12
|
+
*
|
|
13
|
+
* Additionally, set the NGROK_AUTHTOKEN environment variable with your ngrok authtoken.
|
|
14
|
+
* You can get an authtoken by signing up at https://ngrok.com/.
|
|
15
|
+
*
|
|
16
|
+
* Make sure to enable webhooks in Kick Developer Portal for your application, and ensure
|
|
17
|
+
* the webhook URL matches the one provided by ngrok.
|
|
18
|
+
*
|
|
19
|
+
* SCOPES: ["chat:write", "events:subscribe"]
|
|
20
|
+
* Make sure to refresh the tokens and update your environment variables when scopes change.
|
|
21
|
+
*
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
import { KickClient } from "../../src/KickClient.ts";
|
|
25
|
+
import type { ChatMessageEvent, KickTokenResponse } from "../../types";
|
|
26
|
+
|
|
27
|
+
// Initialize the KickClient with necessary credentials and scopes
|
|
28
|
+
const kick = new KickClient({
|
|
29
|
+
clientId: Bun.env.KICK_CLIENT_ID!,
|
|
30
|
+
clientSecret: Bun.env.KICK_CLIENT_SECRET!,
|
|
31
|
+
redirectUri: "http://localhost:3000/callback",
|
|
32
|
+
scopes: ["chat:write", "events:subscribe"],
|
|
33
|
+
showLog: false,
|
|
34
|
+
auth: {
|
|
35
|
+
initialTokens: Bun.env.KICK_REFRESH_TOKEN
|
|
36
|
+
? {
|
|
37
|
+
access_token: Bun.env.KICK_ACCESS_TOKEN!,
|
|
38
|
+
refresh_token: Bun.env.KICK_REFRESH_TOKEN!,
|
|
39
|
+
}
|
|
40
|
+
: undefined,
|
|
41
|
+
onTokenUpdate: (tokens: KickTokenResponse) => {
|
|
42
|
+
if (!Bun.env.KICK_REFRESH_TOKEN) {
|
|
43
|
+
console.log("\n[!] Copy these into your .env file:\n");
|
|
44
|
+
console.log(`KICK_ACCESS_TOKEN=${tokens.access_token}`);
|
|
45
|
+
console.log(`KICK_REFRESH_TOKEN=${tokens.refresh_token}`);
|
|
46
|
+
console.log(`\n====> Scopes granted: ${tokens.scope}`);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
Bun.env.KICK_ACCESS_TOKEN = tokens.access_token;
|
|
50
|
+
Bun.env.KICK_REFRESH_TOKEN = tokens.refresh_token;
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
// If no refresh token is found, initiate the authorization flow
|
|
55
|
+
if (!Bun.env.KICK_REFRESH_TOKEN) {
|
|
56
|
+
console.log(`Authorize the application by visiting:\n${kick.getAuthURL()}`);
|
|
57
|
+
kick.auth.createCallbackServer({ port: 3000 });
|
|
58
|
+
await kick.auth.waitForAuthorization();
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Confirm successful authorization
|
|
62
|
+
console.log("\n[✔] Application authorized successfully!");
|
|
63
|
+
await kick.chat.send({
|
|
64
|
+
content: "Hello from ManaoKick library!",
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// Handle incoming chat message events
|
|
68
|
+
kick.webhooks.on("chat.message.sent", async (event: ChatMessageEvent) => {
|
|
69
|
+
if (event.content === "!ping") {
|
|
70
|
+
await kick.chat.send({ content: "pong 🏓" });
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
// Set up ngrok to expose the webhook endpoint
|
|
75
|
+
const { url, close } = await kick.webhooks.ngrok({
|
|
76
|
+
port: 5000, // Use the same port as the webhook server
|
|
77
|
+
path: "/kick/webhook",
|
|
78
|
+
domain: "topical-goshawk-leading.ngrok-free.app", // <==== Replace with YOUR OWN ngrok domain!
|
|
79
|
+
authtoken: Bun.env.NGROK_AUTHTOKEN,
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
console.log(`[✔] ngrok tunnel established at: ${url}`);
|
|
83
|
+
|
|
84
|
+
// Create a webhook server to listen for incoming events
|
|
85
|
+
kick.webhooks.createServer({ port: 5000, path: "/kick/webhook" }); // Use port that ngrok will forward to
|
|
86
|
+
|
|
87
|
+
// Subscribe to webhooks once authorized
|
|
88
|
+
kick.auth.onAuthorized(async () => {
|
|
89
|
+
await kick.webhooks.subscribe({
|
|
90
|
+
events: [{ name: "chat.message.sent" }],
|
|
91
|
+
});
|
|
92
|
+
});
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Example 04: Using Categories API
|
|
3
|
+
*
|
|
4
|
+
* This template demonstrates how to use the Categories API with the ManaoKick library.
|
|
5
|
+
* The bot will send a message to the chat once authorized.
|
|
6
|
+
* In the first run, it will print the access and refresh tokens to the console for
|
|
7
|
+
* you to save in your environment variables file (.env).
|
|
8
|
+
*
|
|
9
|
+
* Before running this code, ensure you have the following environment variables set:
|
|
10
|
+
* - KICK_CLIENT_ID
|
|
11
|
+
* - KICK_CLIENT_SECRET
|
|
12
|
+
*
|
|
13
|
+
* SCOPES: []
|
|
14
|
+
* Make sure to refresh the tokens and update your environment variables when scopes change.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { KickClient } from "../../src/KickClient.ts";
|
|
18
|
+
import type { KickTokenResponse } from "../../types";
|
|
19
|
+
import { logger } from "../../src/Logger.ts";
|
|
20
|
+
|
|
21
|
+
// Initialize the KickClient with necessary credentials and scopes
|
|
22
|
+
const kick = new KickClient({
|
|
23
|
+
clientId: Bun.env.KICK_CLIENT_ID!,
|
|
24
|
+
clientSecret: Bun.env.KICK_CLIENT_SECRET!,
|
|
25
|
+
redirectUri: "http://localhost:3000/callback",
|
|
26
|
+
scopes: ["kicks:read"],
|
|
27
|
+
showLog: false,
|
|
28
|
+
auth: {
|
|
29
|
+
initialTokens: Bun.env.KICK_REFRESH_TOKEN
|
|
30
|
+
? {
|
|
31
|
+
access_token: Bun.env.KICK_ACCESS_TOKEN!,
|
|
32
|
+
refresh_token: Bun.env.KICK_REFRESH_TOKEN!,
|
|
33
|
+
}
|
|
34
|
+
: undefined,
|
|
35
|
+
onTokenUpdate: (tokens: KickTokenResponse) => {
|
|
36
|
+
if (!Bun.env.KICK_REFRESH_TOKEN) {
|
|
37
|
+
console.log("\n[!] Copy these into your .env file:\n");
|
|
38
|
+
console.log(`KICK_ACCESS_TOKEN=${tokens.access_token}`);
|
|
39
|
+
console.log(`KICK_REFRESH_TOKEN=${tokens.refresh_token}`);
|
|
40
|
+
console.log(`\n====> Scopes granted: ${tokens.scope}`);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
Bun.env.KICK_ACCESS_TOKEN = tokens.access_token;
|
|
44
|
+
Bun.env.KICK_REFRESH_TOKEN = tokens.refresh_token;
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
// If no refresh token is found, initiate the authorization flow
|
|
50
|
+
if (!Bun.env.KICK_REFRESH_TOKEN) {
|
|
51
|
+
console.log(`Authorize the application by visiting:\n${kick.getAuthURL()}`);
|
|
52
|
+
kick.auth.createCallbackServer({ port: 3000 });
|
|
53
|
+
await kick.auth.waitForAuthorization();
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Confirm successful authorization
|
|
57
|
+
console.log("\n[✔] Application authorized successfully!");
|
|
58
|
+
|
|
59
|
+
const name = (
|
|
60
|
+
await logger.prompt("Search categories by name (seperated with commas): ", {
|
|
61
|
+
type: "text",
|
|
62
|
+
})
|
|
63
|
+
).split(",");
|
|
64
|
+
|
|
65
|
+
let limit = Number(
|
|
66
|
+
await logger.prompt("Limit (default 10): ", {
|
|
67
|
+
type: "text",
|
|
68
|
+
}),
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
if (isNaN(limit) || limit <= 0) {
|
|
72
|
+
limit = 10;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const categories = await kick.api.categories.get({ name, limit });
|
|
76
|
+
console.log("\n[✔] Categories fetched successfully!");
|
|
77
|
+
console.log(categories);
|