Skip to content

Commit 70921e8

Browse files
committed
fix: Update Twurple dependencies and enhance feature handling
- Downgraded @twurple/pubsub from version 8.0.0 to 7.4.0 in package.json. - Enhanced twurple.interfaces.ts to include partial types for api, chat, and pubsub features. - Implemented createFeatureDisabledError and createDisabledFeatureProxy functions in twurple.utils.ts to handle disabled features more gracefully.
1 parent 0ea218a commit 70921e8

File tree

11 files changed

+386
-7
lines changed

11 files changed

+386
-7
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@
6161
"typescript": "^5.0.0",
6262
"@twurple/api": "^8.0.0",
6363
"@twurple/chat": "^8.0.0",
64-
"@twurple/pubsub": "^8.0.0"
64+
"@twurple/pubsub": "^7.4.0"
6565
},
6666
"publishConfig": {
6767
"access": "public"

playground/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
tokens.*.json

playground/bun.lock

Lines changed: 124 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

playground/package.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"name": "playground",
3+
"version": "1.0.0",
4+
"private": true,
5+
"dependencies": {
6+
"@nestjs/config": "^4.0.3",
7+
"@tacxou/nestjs_module_twurple": "link:../",
8+
"@twurple/api": "^8.0.3",
9+
"@twurple/chat": "^8.0.3",
10+
"@twurple/pubsub": "^7.4.0",
11+
"@twurple/auth": "^8.0.3"
12+
},
13+
"devDependencies": {
14+
"@types/node": "latest",
15+
"@types/bun": "latest",
16+
"typescript": "latest"
17+
}
18+
}

playground/src/app.module.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { Module } from '@nestjs/common'
2+
import { TwurpleModule, TwurpleOptions } from '@tacxou/nestjs_module_twurple'
3+
import { ConfigModule, ConfigService } from '@nestjs/config'
4+
import cfgapp from './config'
5+
import { AppService } from './app.service'
6+
7+
@Module({
8+
imports: [
9+
ConfigModule.forRoot({
10+
isGlobal: true,
11+
load: [await cfgapp],
12+
}),
13+
TwurpleModule.forRootAsync({
14+
imports: [ConfigModule],
15+
inject: [ConfigService],
16+
useFactory: async (config: ConfigService) => {
17+
// const cfg = config.get<TwurpleOptions>('twurple.options')
18+
// console.log('cfg', cfg)
19+
// console.log('cfg', await cfgapp())
20+
return {
21+
config: (await cfgapp()).twurple.options,
22+
features: {
23+
chat: true,
24+
},
25+
}
26+
},
27+
}),
28+
],
29+
providers: [AppService],
30+
})
31+
export class AppModule {
32+
}

playground/src/app.service.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { Injectable, Logger, OnApplicationBootstrap } from '@nestjs/common'
2+
import { InjectTwurpleChat } from '@tacxou/nestjs_module_twurple'
3+
import { ChatClient, ChatMessage } from '@twurple/chat'
4+
import { readFileSync } from 'fs'
5+
6+
@Injectable()
7+
export class AppService implements OnApplicationBootstrap {
8+
private readonly package: Partial<any>
9+
protected readonly logger: Logger = new Logger(AppService.name)
10+
11+
public constructor(@InjectTwurpleChat() private readonly chat: ChatClient) {
12+
this.package = JSON.parse(readFileSync('package.json', 'utf-8'))
13+
}
14+
15+
public onApplicationBootstrap() {
16+
this.logger.log(`Now listening with version <${this.package.version}> 🕹️`)
17+
18+
this.chat.onMessage((channel, user, message) => {
19+
if (message === '!ping') {
20+
void this.chat.say(channel, `Pong @${user}`)
21+
}
22+
})
23+
24+
void this.chat.connect()
25+
26+
this.chat.onConnect(() => {
27+
this.logger.log('Chat connected')
28+
})
29+
30+
this.chat.onDisconnect(() => {
31+
this.logger.log('Chat disconnected')
32+
})
33+
34+
}
35+
}

playground/src/config.ts

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import { TwurpleOptions } from "@tacxou/nestjs_module_twurple"
2+
import { exchangeCode , RefreshingAuthProvider } from "@twurple/auth"
3+
import fs from 'fs/promises'
4+
5+
export interface ConfigInstance {
6+
twurple: {
7+
options: TwurpleOptions
8+
}
9+
}
10+
11+
// noinspection JSUnresolvedReference
12+
export default async (): Promise<ConfigInstance> => {
13+
// const tokenData = await getAppToken(
14+
// process.env['STREAMKITS_TWURPLE_CLIENTID'] ?? '',
15+
// process.env['STREAMKITS_TWURPLE_CLIENTSECRET'] ?? '',
16+
// )
17+
// console.log(tokenData)
18+
// const tokenData = {
19+
// accessToken: '[ACCESS_TOKEN]',
20+
// refreshToken: '[REFRESH_TOKEN]',
21+
// expiresIn: 1,
22+
// obtainmentTimestamp: 0,
23+
// }
24+
25+
const params = new URLSearchParams({
26+
client_id: process.env.STREAMKITS_TWURPLE_CLIENTID!,
27+
redirect_uri: 'https://a1b2c3d4.ngrok-free.app',
28+
response_type: 'code',
29+
scope: [
30+
'chat:read',
31+
'chat:edit',
32+
'channel:read:redemptions'
33+
].join(' ')
34+
});
35+
36+
const url = `https://id.twitch.tv/oauth2/authorize?${params}`;
37+
38+
console.log(url);
39+
40+
// const tokenData = await exchangeCode(
41+
// process.env['STREAMKITS_TWURPLE_CLIENTID'] ?? '',
42+
// process.env['STREAMKITS_TWURPLE_CLIENTSECRET'] ?? '',
43+
// '[CODE]',
44+
// 'https://a1b2c3d4.ngrok-free.app',
45+
// )
46+
// console.log(tokenData)
47+
48+
const tokenData = JSON.parse(await fs.readFile('./tokens.125328655.json', 'utf-8'))
49+
const authProvider = new RefreshingAuthProvider({
50+
clientId: process.env['STREAMKITS_TWURPLE_CLIENTID'] ?? '',
51+
clientSecret: process.env['STREAMKITS_TWURPLE_CLIENTSECRET'] ?? '',
52+
})
53+
authProvider.onRefresh(async (userId, newTokenData) => await fs.writeFile(`./tokens.${userId}.json`, JSON.stringify(newTokenData, null, 4), 'utf-8'))
54+
await authProvider.addUserForToken(tokenData, ['chat'])
55+
56+
return {
57+
twurple: {
58+
options: {
59+
authProvider,
60+
features: {
61+
api: {},
62+
chat: {
63+
channels: ['tacxtv'],
64+
logger: {
65+
minLevel: 'debug',
66+
}
67+
},
68+
pubsub: {},
69+
},
70+
},
71+
},
72+
}
73+
}

playground/src/main.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { NestFactory } from '@nestjs/core'
2+
import { AppModule } from './app.module'
3+
import cfgapp from './config'
4+
5+
;(async () => {
6+
await cfgapp()
7+
const app = await NestFactory.createApplicationContext(AppModule)
8+
app.enableShutdownHooks()
9+
})()

playground/tsconfig.json

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"compilerOptions": {
3+
"target": "ES2022",
4+
"module": "ESNext",
5+
"moduleResolution": "node",
6+
"strict": true,
7+
"esModuleInterop": true,
8+
"experimentalDecorators": true,
9+
"emitDecoratorMetadata": true,
10+
"skipLibCheck": true,
11+
"baseUrl": ".",
12+
"paths": {
13+
"@tacxou/nestjs_module_twurple": ["../src/index.ts"],
14+
"@nestjs/common": ["../node_modules/@nestjs/common"],
15+
"@nestjs/common/*": ["../node_modules/@nestjs/common/*"],
16+
"@nestjs/core": ["../node_modules/@nestjs/core"],
17+
"@nestjs/core/*": ["../node_modules/@nestjs/core/*"]
18+
}
19+
},
20+
"include": ["src/**/*.ts"]
21+
}

src/twurple.interfaces.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import { AuthProvider } from '@twurple/auth'
22
import { ModuleMetadata, Type } from '@nestjs/common'
3+
import { ChatClientOptions } from '@twurple/chat'
4+
import { ApiConfig } from '@twurple/api'
5+
import { PubSubClientConfig } from '@twurple/pubsub/lib/PubSubClient'
36

47
export interface TwurpleModuleOptions {
58
config: TwurpleOptions
@@ -17,9 +20,9 @@ export interface TwurpleModuleFeatureOptions {
1720
export interface TwurpleOptions {
1821
authProvider: AuthProvider
1922
features?: {
20-
api?: TwurpleModuleFeatureOptions
21-
chat?: TwurpleModuleFeatureOptions
22-
pubsub?: TwurpleModuleFeatureOptions
23+
api?: TwurpleModuleFeatureOptions & Partial<ApiConfig>
24+
chat?: TwurpleModuleFeatureOptions & Partial<ChatClientOptions>
25+
pubsub?: TwurpleModuleFeatureOptions & Partial<PubSubClientConfig>
2326
}
2427
}
2528

0 commit comments

Comments
 (0)