@openclaw/twitch 2026.2.21 → 2026.5.2-beta.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/README.md +2 -2
- package/api.ts +21 -0
- package/channel-plugin-api.ts +1 -0
- package/index.test.ts +13 -0
- package/index.ts +12 -16
- package/openclaw.plugin.json +224 -1
- package/package.json +36 -7
- package/runtime-api.ts +22 -0
- package/setup-entry.ts +9 -0
- package/setup-plugin-api.ts +3 -0
- package/src/access-control.test.ts +136 -239
- package/src/access-control.ts +11 -4
- package/src/actions.test.ts +74 -0
- package/src/actions.ts +7 -6
- package/src/client-manager-registry.ts +0 -28
- package/src/config-schema.test.ts +46 -0
- package/src/config-schema.ts +25 -21
- package/src/config.test.ts +147 -1
- package/src/config.ts +76 -15
- package/src/monitor.ts +126 -85
- package/src/outbound.test.ts +140 -75
- package/src/outbound.ts +4 -5
- package/src/plugin.test.ts +39 -1
- package/src/plugin.ts +176 -242
- package/src/probe.test.ts +1 -1
- package/src/probe.ts +16 -5
- package/src/resolver.ts +5 -3
- package/src/runtime.ts +8 -13
- package/src/send.test.ts +92 -59
- package/src/send.ts +18 -15
- package/src/setup-surface.test.ts +511 -0
- package/src/setup-surface.ts +520 -0
- package/src/status.test.ts +120 -153
- package/src/status.ts +1 -1
- package/src/test-fixtures.ts +1 -1
- package/src/token.test.ts +22 -1
- package/src/token.ts +8 -6
- package/src/twitch-client.test.ts +18 -25
- package/src/twitch-client.ts +5 -6
- package/src/types.ts +7 -46
- package/src/utils/twitch.ts +8 -2
- package/tsconfig.json +16 -0
- package/CHANGELOG.md +0 -21
- package/src/onboarding.test.ts +0 -316
- package/src/onboarding.ts +0 -417
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@ Twitch channel plugin for OpenClaw.
|
|
|
5
5
|
## Install (local checkout)
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
openclaw plugins install ./
|
|
8
|
+
openclaw plugins install ./path/to/local/twitch-plugin
|
|
9
9
|
```
|
|
10
10
|
|
|
11
11
|
## Install (npm)
|
|
@@ -31,7 +31,7 @@ Minimal config (simplified single-account):
|
|
|
31
31
|
accessToken: "oauth:abc123...", // OAuth Access Token (add oauth: prefix)
|
|
32
32
|
clientId: "xyz789...", // Client ID from Token Generator
|
|
33
33
|
channel: "vevisk", // Channel to join (required)
|
|
34
|
-
allowFrom: ["123456789"], // (recommended) Your Twitch user ID only (Convert your twitch username to ID at https://www.streamweasels.com/tools/convert-twitch-username
|
|
34
|
+
allowFrom: ["123456789"], // (recommended) Your Twitch user ID only (Convert your twitch username to ID at https://www.streamweasels.com/tools/convert-twitch-username-to-user-id/)
|
|
35
35
|
},
|
|
36
36
|
},
|
|
37
37
|
}
|
package/api.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export {
|
|
2
|
+
type ChannelAccountSnapshot,
|
|
3
|
+
type ChannelCapabilities,
|
|
4
|
+
type ChannelGatewayContext,
|
|
5
|
+
type ChannelLogSink,
|
|
6
|
+
type ChannelMessageActionAdapter,
|
|
7
|
+
type ChannelMessageActionContext,
|
|
8
|
+
type ChannelMeta,
|
|
9
|
+
type ChannelOutboundAdapter,
|
|
10
|
+
type ChannelOutboundContext,
|
|
11
|
+
type ChannelPlugin,
|
|
12
|
+
type ChannelResolveKind,
|
|
13
|
+
type ChannelResolveResult,
|
|
14
|
+
type ChannelStatusAdapter,
|
|
15
|
+
type OpenClawConfig,
|
|
16
|
+
type OutboundDeliveryResult,
|
|
17
|
+
type RuntimeEnv,
|
|
18
|
+
type WizardPrompter,
|
|
19
|
+
} from "./runtime-api.js";
|
|
20
|
+
export { twitchPlugin } from "./src/plugin.js";
|
|
21
|
+
export { setTwitchRuntime } from "./src/runtime.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { twitchPlugin } from "./src/plugin.js";
|
package/index.test.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { assertBundledChannelEntries } from "openclaw/plugin-sdk/channel-test-helpers";
|
|
2
|
+
import { describe } from "vitest";
|
|
3
|
+
import entry from "./index.js";
|
|
4
|
+
import setupEntry from "./setup-entry.js";
|
|
5
|
+
|
|
6
|
+
describe("twitch bundled entries", () => {
|
|
7
|
+
assertBundledChannelEntries({
|
|
8
|
+
entry,
|
|
9
|
+
expectedId: "twitch",
|
|
10
|
+
expectedName: "Twitch",
|
|
11
|
+
setupEntry,
|
|
12
|
+
});
|
|
13
|
+
});
|
package/index.ts
CHANGED
|
@@ -1,20 +1,16 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { emptyPluginConfigSchema } from "openclaw/plugin-sdk";
|
|
3
|
-
import { twitchPlugin } from "./src/plugin.js";
|
|
4
|
-
import { setTwitchRuntime } from "./src/runtime.js";
|
|
1
|
+
import { defineBundledChannelEntry } from "openclaw/plugin-sdk/channel-entry-contract";
|
|
5
2
|
|
|
6
|
-
export {
|
|
7
|
-
|
|
8
|
-
const plugin = {
|
|
3
|
+
export default defineBundledChannelEntry({
|
|
9
4
|
id: "twitch",
|
|
10
5
|
name: "Twitch",
|
|
11
|
-
description: "Twitch channel plugin",
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
api.registerChannel({ plugin: twitchPlugin as any });
|
|
6
|
+
description: "Twitch IRC chat channel plugin",
|
|
7
|
+
importMetaUrl: import.meta.url,
|
|
8
|
+
plugin: {
|
|
9
|
+
specifier: "./channel-plugin-api.js",
|
|
10
|
+
exportName: "twitchPlugin",
|
|
17
11
|
},
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
12
|
+
runtime: {
|
|
13
|
+
specifier: "./api.js",
|
|
14
|
+
exportName: "setTwitchRuntime",
|
|
15
|
+
},
|
|
16
|
+
});
|
package/openclaw.plugin.json
CHANGED
|
@@ -1,9 +1,232 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "twitch",
|
|
3
|
-
"
|
|
3
|
+
"activation": {
|
|
4
|
+
"onStartup": false
|
|
5
|
+
},
|
|
6
|
+
"channels": [
|
|
7
|
+
"twitch"
|
|
8
|
+
],
|
|
9
|
+
"channelEnvVars": {
|
|
10
|
+
"twitch": [
|
|
11
|
+
"OPENCLAW_TWITCH_ACCESS_TOKEN"
|
|
12
|
+
]
|
|
13
|
+
},
|
|
4
14
|
"configSchema": {
|
|
5
15
|
"type": "object",
|
|
6
16
|
"additionalProperties": false,
|
|
7
17
|
"properties": {}
|
|
18
|
+
},
|
|
19
|
+
"channelConfigs": {
|
|
20
|
+
"twitch": {
|
|
21
|
+
"schema": {
|
|
22
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
23
|
+
"anyOf": [
|
|
24
|
+
{
|
|
25
|
+
"type": "object",
|
|
26
|
+
"properties": {
|
|
27
|
+
"name": {
|
|
28
|
+
"type": "string"
|
|
29
|
+
},
|
|
30
|
+
"enabled": {
|
|
31
|
+
"type": "boolean"
|
|
32
|
+
},
|
|
33
|
+
"markdown": {
|
|
34
|
+
"type": "object",
|
|
35
|
+
"properties": {
|
|
36
|
+
"tables": {
|
|
37
|
+
"type": "string",
|
|
38
|
+
"enum": [
|
|
39
|
+
"off",
|
|
40
|
+
"bullets",
|
|
41
|
+
"code",
|
|
42
|
+
"block"
|
|
43
|
+
]
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
"additionalProperties": false
|
|
47
|
+
},
|
|
48
|
+
"defaultAccount": {
|
|
49
|
+
"type": "string"
|
|
50
|
+
},
|
|
51
|
+
"username": {
|
|
52
|
+
"type": "string"
|
|
53
|
+
},
|
|
54
|
+
"accessToken": {
|
|
55
|
+
"type": "string"
|
|
56
|
+
},
|
|
57
|
+
"clientId": {
|
|
58
|
+
"type": "string"
|
|
59
|
+
},
|
|
60
|
+
"channel": {
|
|
61
|
+
"type": "string",
|
|
62
|
+
"minLength": 1
|
|
63
|
+
},
|
|
64
|
+
"allowFrom": {
|
|
65
|
+
"type": "array",
|
|
66
|
+
"items": {
|
|
67
|
+
"type": "string"
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
"allowedRoles": {
|
|
71
|
+
"type": "array",
|
|
72
|
+
"items": {
|
|
73
|
+
"type": "string",
|
|
74
|
+
"enum": [
|
|
75
|
+
"moderator",
|
|
76
|
+
"owner",
|
|
77
|
+
"vip",
|
|
78
|
+
"subscriber",
|
|
79
|
+
"all"
|
|
80
|
+
]
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
"requireMention": {
|
|
84
|
+
"type": "boolean"
|
|
85
|
+
},
|
|
86
|
+
"responsePrefix": {
|
|
87
|
+
"type": "string"
|
|
88
|
+
},
|
|
89
|
+
"clientSecret": {
|
|
90
|
+
"type": "string"
|
|
91
|
+
},
|
|
92
|
+
"refreshToken": {
|
|
93
|
+
"type": "string"
|
|
94
|
+
},
|
|
95
|
+
"expiresIn": {
|
|
96
|
+
"anyOf": [
|
|
97
|
+
{
|
|
98
|
+
"type": "number"
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
"type": "null"
|
|
102
|
+
}
|
|
103
|
+
]
|
|
104
|
+
},
|
|
105
|
+
"obtainmentTimestamp": {
|
|
106
|
+
"type": "number"
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
"required": [
|
|
110
|
+
"username",
|
|
111
|
+
"accessToken",
|
|
112
|
+
"channel"
|
|
113
|
+
],
|
|
114
|
+
"additionalProperties": false
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"type": "object",
|
|
118
|
+
"properties": {
|
|
119
|
+
"name": {
|
|
120
|
+
"type": "string"
|
|
121
|
+
},
|
|
122
|
+
"enabled": {
|
|
123
|
+
"type": "boolean"
|
|
124
|
+
},
|
|
125
|
+
"markdown": {
|
|
126
|
+
"type": "object",
|
|
127
|
+
"properties": {
|
|
128
|
+
"tables": {
|
|
129
|
+
"type": "string",
|
|
130
|
+
"enum": [
|
|
131
|
+
"off",
|
|
132
|
+
"bullets",
|
|
133
|
+
"code",
|
|
134
|
+
"block"
|
|
135
|
+
]
|
|
136
|
+
}
|
|
137
|
+
},
|
|
138
|
+
"additionalProperties": false
|
|
139
|
+
},
|
|
140
|
+
"defaultAccount": {
|
|
141
|
+
"type": "string"
|
|
142
|
+
},
|
|
143
|
+
"accounts": {
|
|
144
|
+
"type": "object",
|
|
145
|
+
"propertyNames": {
|
|
146
|
+
"type": "string"
|
|
147
|
+
},
|
|
148
|
+
"additionalProperties": {
|
|
149
|
+
"type": "object",
|
|
150
|
+
"properties": {
|
|
151
|
+
"username": {
|
|
152
|
+
"type": "string"
|
|
153
|
+
},
|
|
154
|
+
"accessToken": {
|
|
155
|
+
"type": "string"
|
|
156
|
+
},
|
|
157
|
+
"clientId": {
|
|
158
|
+
"type": "string"
|
|
159
|
+
},
|
|
160
|
+
"channel": {
|
|
161
|
+
"type": "string",
|
|
162
|
+
"minLength": 1
|
|
163
|
+
},
|
|
164
|
+
"enabled": {
|
|
165
|
+
"type": "boolean"
|
|
166
|
+
},
|
|
167
|
+
"allowFrom": {
|
|
168
|
+
"type": "array",
|
|
169
|
+
"items": {
|
|
170
|
+
"type": "string"
|
|
171
|
+
}
|
|
172
|
+
},
|
|
173
|
+
"allowedRoles": {
|
|
174
|
+
"type": "array",
|
|
175
|
+
"items": {
|
|
176
|
+
"type": "string",
|
|
177
|
+
"enum": [
|
|
178
|
+
"moderator",
|
|
179
|
+
"owner",
|
|
180
|
+
"vip",
|
|
181
|
+
"subscriber",
|
|
182
|
+
"all"
|
|
183
|
+
]
|
|
184
|
+
}
|
|
185
|
+
},
|
|
186
|
+
"requireMention": {
|
|
187
|
+
"type": "boolean"
|
|
188
|
+
},
|
|
189
|
+
"responsePrefix": {
|
|
190
|
+
"type": "string"
|
|
191
|
+
},
|
|
192
|
+
"clientSecret": {
|
|
193
|
+
"type": "string"
|
|
194
|
+
},
|
|
195
|
+
"refreshToken": {
|
|
196
|
+
"type": "string"
|
|
197
|
+
},
|
|
198
|
+
"expiresIn": {
|
|
199
|
+
"anyOf": [
|
|
200
|
+
{
|
|
201
|
+
"type": "number"
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
"type": "null"
|
|
205
|
+
}
|
|
206
|
+
]
|
|
207
|
+
},
|
|
208
|
+
"obtainmentTimestamp": {
|
|
209
|
+
"type": "number"
|
|
210
|
+
}
|
|
211
|
+
},
|
|
212
|
+
"required": [
|
|
213
|
+
"username",
|
|
214
|
+
"accessToken",
|
|
215
|
+
"channel"
|
|
216
|
+
],
|
|
217
|
+
"additionalProperties": false
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
},
|
|
221
|
+
"required": [
|
|
222
|
+
"accounts"
|
|
223
|
+
],
|
|
224
|
+
"additionalProperties": false
|
|
225
|
+
}
|
|
226
|
+
]
|
|
227
|
+
},
|
|
228
|
+
"label": "Twitch",
|
|
229
|
+
"description": "Twitch chat integration"
|
|
230
|
+
}
|
|
8
231
|
}
|
|
9
232
|
}
|
package/package.json
CHANGED
|
@@ -1,20 +1,49 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/twitch",
|
|
3
|
-
"version": "2026.2.
|
|
3
|
+
"version": "2026.5.2-beta.1",
|
|
4
4
|
"description": "OpenClaw Twitch channel plugin",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/openclaw/openclaw"
|
|
8
|
+
},
|
|
5
9
|
"type": "module",
|
|
6
10
|
"dependencies": {
|
|
7
|
-
"@twurple/api": "^8.
|
|
8
|
-
"@twurple/auth": "^8.
|
|
9
|
-
"@twurple/chat": "^8.
|
|
10
|
-
"zod": "^4.3.6"
|
|
11
|
+
"@twurple/api": "^8.1.3",
|
|
12
|
+
"@twurple/auth": "^8.1.3",
|
|
13
|
+
"@twurple/chat": "^8.1.3"
|
|
11
14
|
},
|
|
12
15
|
"devDependencies": {
|
|
13
|
-
"openclaw": "workspace:*"
|
|
16
|
+
"@openclaw/plugin-sdk": "workspace:*"
|
|
14
17
|
},
|
|
15
18
|
"openclaw": {
|
|
16
19
|
"extensions": [
|
|
17
20
|
"./index.ts"
|
|
18
|
-
]
|
|
21
|
+
],
|
|
22
|
+
"setupEntry": "./setup-entry.ts",
|
|
23
|
+
"install": {
|
|
24
|
+
"npmSpec": "@openclaw/twitch",
|
|
25
|
+
"defaultChoice": "npm",
|
|
26
|
+
"minHostVersion": ">=2026.4.10"
|
|
27
|
+
},
|
|
28
|
+
"compat": {
|
|
29
|
+
"pluginApi": ">=2026.5.2-beta.1"
|
|
30
|
+
},
|
|
31
|
+
"build": {
|
|
32
|
+
"openclawVersion": "2026.5.2-beta.1"
|
|
33
|
+
},
|
|
34
|
+
"channel": {
|
|
35
|
+
"id": "twitch",
|
|
36
|
+
"label": "Twitch",
|
|
37
|
+
"selectionLabel": "Twitch (Chat)",
|
|
38
|
+
"docsPath": "/channels/twitch",
|
|
39
|
+
"blurb": "Twitch chat integration",
|
|
40
|
+
"aliases": [
|
|
41
|
+
"twitch-chat"
|
|
42
|
+
]
|
|
43
|
+
},
|
|
44
|
+
"release": {
|
|
45
|
+
"publishToClawHub": true,
|
|
46
|
+
"publishToNpm": true
|
|
47
|
+
}
|
|
19
48
|
}
|
|
20
49
|
}
|
package/runtime-api.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// Private runtime barrel for the bundled Twitch extension.
|
|
2
|
+
// Keep this barrel thin and aligned with the local extension surface.
|
|
3
|
+
|
|
4
|
+
export type {
|
|
5
|
+
ChannelAccountSnapshot,
|
|
6
|
+
ChannelCapabilities,
|
|
7
|
+
ChannelGatewayContext,
|
|
8
|
+
ChannelLogSink,
|
|
9
|
+
ChannelMessageActionAdapter,
|
|
10
|
+
ChannelMessageActionContext,
|
|
11
|
+
ChannelMeta,
|
|
12
|
+
ChannelOutboundAdapter,
|
|
13
|
+
ChannelOutboundContext,
|
|
14
|
+
ChannelResolveKind,
|
|
15
|
+
ChannelResolveResult,
|
|
16
|
+
ChannelStatusAdapter,
|
|
17
|
+
} from "openclaw/plugin-sdk/channel-contract";
|
|
18
|
+
export type { ChannelPlugin } from "openclaw/plugin-sdk/channel-core";
|
|
19
|
+
export type { OutboundDeliveryResult } from "openclaw/plugin-sdk/channel-send-result";
|
|
20
|
+
export type { OpenClawConfig } from "openclaw/plugin-sdk/config-types";
|
|
21
|
+
export type { RuntimeEnv } from "openclaw/plugin-sdk/runtime";
|
|
22
|
+
export type { WizardPrompter } from "openclaw/plugin-sdk/setup";
|
package/setup-entry.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { defineBundledChannelSetupEntry } from "openclaw/plugin-sdk/channel-entry-contract";
|
|
2
|
+
|
|
3
|
+
export default defineBundledChannelSetupEntry({
|
|
4
|
+
importMetaUrl: import.meta.url,
|
|
5
|
+
plugin: {
|
|
6
|
+
specifier: "./setup-plugin-api.js",
|
|
7
|
+
exportName: "twitchSetupPlugin",
|
|
8
|
+
},
|
|
9
|
+
});
|