From 60b93e259e9986db0671398912b74c027c53c0e5 Mon Sep 17 00:00:00 2001 From: Niklas Date: Wed, 16 Dec 2020 20:22:57 +0100 Subject: [PATCH 1/5] Added PubSub package and sample --- nodecg-io-pubsub/extension/index.ts | 31 ++++++++ nodecg-io-pubsub/extension/pubSubClient.ts | 82 ++++++++++++++++++++++ nodecg-io-pubsub/package.json | 43 ++++++++++++ nodecg-io-pubsub/pubsub-schema.json | 12 ++++ nodecg-io-pubsub/tsconfig.json | 3 + samples/pubsubsample/extension/index.ts | 32 +++++++++ samples/pubsubsample/package.json | 26 +++++++ samples/pubsubsample/tsconfig.json | 3 + 8 files changed, 232 insertions(+) create mode 100644 nodecg-io-pubsub/extension/index.ts create mode 100644 nodecg-io-pubsub/extension/pubSubClient.ts create mode 100644 nodecg-io-pubsub/package.json create mode 100644 nodecg-io-pubsub/pubsub-schema.json create mode 100644 nodecg-io-pubsub/tsconfig.json create mode 100644 samples/pubsubsample/extension/index.ts create mode 100644 samples/pubsubsample/package.json create mode 100644 samples/pubsubsample/tsconfig.json diff --git a/nodecg-io-pubsub/extension/index.ts b/nodecg-io-pubsub/extension/index.ts new file mode 100644 index 000000000..886dc5507 --- /dev/null +++ b/nodecg-io-pubsub/extension/index.ts @@ -0,0 +1,31 @@ +import { NodeCG } from "nodecg/types/server"; +import { emptySuccess, Result, success } from "nodecg-io-core/extension/utils/result"; +import { ServiceBundle } from "nodecg-io-core/extension/serviceBundle"; +import { PubSubServiceClient } from "./pubSubClient"; + +export { PubSubServiceClient } from "./pubSubClient"; + + +export interface PubSubServiceConfig { + oauthKey: string; +} + +module.exports = (nodecg: NodeCG) => { + new TwitchService(nodecg, "pubsub", __dirname, "../pubsub-schema.json").register(); +}; + +class TwitchService extends ServiceBundle { + async validateConfig(config: PubSubServiceConfig): Promise> { + await PubSubServiceClient.getTokenInfo(config); // This will throw a error if the token is invalid + return emptySuccess(); + } + + async createClient(config: PubSubServiceConfig): Promise> { + const client = await PubSubServiceClient.createClient(config); + + return success(client); + } + + stopClient(_: PubSubServiceClient): void { + } +} diff --git a/nodecg-io-pubsub/extension/pubSubClient.ts b/nodecg-io-pubsub/extension/pubSubClient.ts new file mode 100644 index 000000000..edc43996d --- /dev/null +++ b/nodecg-io-pubsub/extension/pubSubClient.ts @@ -0,0 +1,82 @@ +import { ServiceClient } from "nodecg-io-core/extension/types"; +import { getTokenInfo, StaticAuthProvider, TokenInfo } from "twitch-auth"; +import { PubSubServiceConfig } from "./index"; +import { + PubSubBitsBadgeUnlockMessage, + PubSubBitsMessage, + PubSubChatModActionMessage, + PubSubClient, + PubSubListener, + PubSubRedemptionMessage, + PubSubSubscriptionMessage, + PubSubWhisperMessage, +} from "twitch-pubsub-client"; +import { ApiClient } from "twitch"; + +export class PubSubServiceClient implements ServiceClient { + constructor(private client: PubSubClient, private userid: string) { + } + + /** + * Creates a instance of TwitchServiceClient using the credentials from the passed config. + */ + static async createClient(cfg: PubSubServiceConfig): Promise { + // Create a twitch authentication provider + const tokenInfo = await PubSubServiceClient.getTokenInfo(cfg); + const authProvider = new StaticAuthProvider(tokenInfo.clientId, this.normalizeToken(cfg), tokenInfo.scopes); + + // Create the actual chat client and connect + const apiClient = new ApiClient({ authProvider }); + const pubSubClient = new PubSubClient(); + const userID = await pubSubClient.registerUserListener(apiClient); + + return new PubSubServiceClient(pubSubClient, userID); + } + + /** + * Gets the token info for the passed config. + */ + static async getTokenInfo(cfg: PubSubServiceConfig): Promise { + return await getTokenInfo(this.normalizeToken(cfg)); + } + + /** + * Strips any "oauth:" before the token away, because the client needs the token without it. + */ + static normalizeToken(cfg: PubSubServiceConfig): string { + return cfg.oauthKey.replace("oauth:", ""); + } + + getNativeClient(): PubSubClient { + return this.client; + } + + getUserID(): string { + return this.userid; + } + + async onRedemption(callback: (message: PubSubRedemptionMessage) => void): Promise> { + return await this.client.onRedemption(this.userid, callback); + } + + async onSubscription(callback: (message: PubSubSubscriptionMessage) => void): Promise> { + return await this.client.onSubscription(this.userid, callback); + } + + async onBits(callback: (message: PubSubBitsMessage) => void): Promise> { + return await this.client.onBits(this.userid, callback); + } + + async onBitsBadgeUnlock(callback: (message: PubSubBitsBadgeUnlockMessage) => void): Promise> { + return await this.client.onBitsBadgeUnlock(this.userid, callback); + } + + async onModAction(channelID: string, callback: (message: PubSubChatModActionMessage) => void): Promise> { + return await this.client.onModAction(this.userid, channelID, callback); + } + + async onWhisper(callback: (message: PubSubWhisperMessage) => void): Promise> { + return await this.client.onWhisper(this.userid, callback); + } + +} diff --git a/nodecg-io-pubsub/package.json b/nodecg-io-pubsub/package.json new file mode 100644 index 000000000..70f096259 --- /dev/null +++ b/nodecg-io-pubsub/package.json @@ -0,0 +1,43 @@ +{ + "name": "nodecg-io-pubsub", + "version": "0.1.0", + "description": "Allows access to the Twitch PubSub API.", + "homepage": "https://nodecg.io/samples/pubsub", + "author": { + "name": "derNiklaas", + "url": "https://github.com/derNiklaas" + }, + "repository": { + "type": "git", + "url": "https://github.com/codeoverflow-org/nodecg-io.git", + "directory": "nodecg-io-pubsub" + }, + "main": "extension", + "scripts": { + "build": "tsc -b", + "watch": "tsc -b -w", + "clean": "tsc -b --clean" + }, + "keywords": [ + "nodecg-io", + "nodecg-bundle" + ], + "nodecg": { + "compatibleRange": "^1.1.1", + "bundleDependencies": { + "nodecg-io-core": "^0.1.0" + } + }, + "license": "MIT", + "devDependencies": { + "@types/node": "^14.6.4", + "nodecg": "^1.6.1", + "typescript": "^4.0.2" + }, + "dependencies": { + "nodecg-io-core": "^0.1.0", + "twitch": "^4.3.6", + "twitch-pubsub-client": "^4.3.6", + "ws": "^7.4.1" + } +} diff --git a/nodecg-io-pubsub/pubsub-schema.json b/nodecg-io-pubsub/pubsub-schema.json new file mode 100644 index 000000000..66d9d9c34 --- /dev/null +++ b/nodecg-io-pubsub/pubsub-schema.json @@ -0,0 +1,12 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "additionalProperties": false, + "properties": { + "oauthKey": { + "type": "string", + "description": "A OAuth2 key for the twitch api." + } + }, + "required": ["oauthKey"] +} diff --git a/nodecg-io-pubsub/tsconfig.json b/nodecg-io-pubsub/tsconfig.json new file mode 100644 index 000000000..1c8405620 --- /dev/null +++ b/nodecg-io-pubsub/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "../tsconfig.common.json" +} diff --git a/samples/pubsubsample/extension/index.ts b/samples/pubsubsample/extension/index.ts new file mode 100644 index 000000000..96e776c10 --- /dev/null +++ b/samples/pubsubsample/extension/index.ts @@ -0,0 +1,32 @@ +import { NodeCG } from "nodecg/types/server"; +import { PubSubServiceClient } from "nodecg-io-pubsub/extension"; +import { requireService } from "nodecg-io-core/extension/serviceClientWrapper"; + + +module.exports = function(nodecg: NodeCG) { + nodecg.log.info("Sample bundle for discord started"); + + const pubsub = requireService(nodecg, "pubsub"); + + pubsub?.onAvailable((client) => { + nodecg.log.info("PubSub client has been updated, adding handlers for messages."); + client.onSubscription(async (message) => { + const user = await message.getUser(); + if (user) console.log(`${user.displayName} just subscribed (${message.cumulativeMonths} months)`); + }); + client.onBits(async (message) => { + const user = await message.getUser(); + if (user) console.log(`${user.displayName} cheered ${message.bits} Bits`); + }); + client.onBitsBadgeUnlock(async (message) => { + const user = await message.getUser(); + if (user) console.log(`${user.displayName} just unlocked the ${message.badgeTier} Badge`); + }); + client.onRedemption(async (message) => { + const user = await message.getUser(); + if (user) console.log(`${user.displayName} redeemed ${message.rewardName} (${message.message})`); + }); + }); + + pubsub?.onUnavailable(() => nodecg.log.info("PubSub client has been unset.")); +}; \ No newline at end of file diff --git a/samples/pubsubsample/package.json b/samples/pubsubsample/package.json new file mode 100644 index 000000000..0827caaa2 --- /dev/null +++ b/samples/pubsubsample/package.json @@ -0,0 +1,26 @@ +{ + "name": "pubsubsample", + "version": "0.1.0", + "nodecg": { + "compatibleRange": "^1.1.1", + "bundleDependencies": { + "nodecg-io-pubsub": "0.1.0" + } + }, + "scripts": { + "build": "tsc", + "watch": "tsc -w" + }, + "license": "MIT", + "devDependencies": { + "@types/ws": "^7.2.6", + "@types/node": "^14.6.4" + }, + "dependencies": { + "nodecg-io-pubsub": "0.1.0", + "nodecg-io-core": "0.1.0", + "ws": "^7.4.1", + "nodecg": "^1.6.1", + "typescript": "^4.0.2" + } +} diff --git a/samples/pubsubsample/tsconfig.json b/samples/pubsubsample/tsconfig.json new file mode 100644 index 000000000..c8bb01bee --- /dev/null +++ b/samples/pubsubsample/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "../../tsconfig.common.json" +} From cd6054dc06feb56f10f136d299c28b0ece8c9679 Mon Sep 17 00:00:00 2001 From: Niklas Date: Wed, 16 Dec 2020 22:38:54 +0100 Subject: [PATCH 2/5] Renamed Twitch Pubsub Service --- nodecg-io-twitch-pubsub/extension/index.ts | 29 ++++++ .../extension/pubSubClient.ts | 89 +++++++++++++++++++ nodecg-io-twitch-pubsub/package.json | 43 +++++++++ nodecg-io-twitch-pubsub/pubsub-schema.json | 12 +++ nodecg-io-twitch-pubsub/tsconfig.json | 3 + samples/pubsubsample/extension/index.ts | 11 ++- samples/pubsubsample/package.json | 45 +++++----- 7 files changed, 203 insertions(+), 29 deletions(-) create mode 100644 nodecg-io-twitch-pubsub/extension/index.ts create mode 100644 nodecg-io-twitch-pubsub/extension/pubSubClient.ts create mode 100644 nodecg-io-twitch-pubsub/package.json create mode 100644 nodecg-io-twitch-pubsub/pubsub-schema.json create mode 100644 nodecg-io-twitch-pubsub/tsconfig.json diff --git a/nodecg-io-twitch-pubsub/extension/index.ts b/nodecg-io-twitch-pubsub/extension/index.ts new file mode 100644 index 000000000..3807c7be9 --- /dev/null +++ b/nodecg-io-twitch-pubsub/extension/index.ts @@ -0,0 +1,29 @@ +import { NodeCG } from "nodecg/types/server"; +import { emptySuccess, Result, success } from "nodecg-io-core/extension/utils/result"; +import { ServiceBundle } from "nodecg-io-core/extension/serviceBundle"; +import { PubSubServiceClient } from "./pubSubClient"; + +export { PubSubServiceClient } from "./pubSubClient"; + +export interface PubSubServiceConfig { + oauthKey: string; +} + +module.exports = (nodecg: NodeCG) => { + new TwitchService(nodecg, "twitch-pubsub", __dirname, "../pubsub-schema.json").register(); +}; + +class TwitchService extends ServiceBundle { + async validateConfig(config: PubSubServiceConfig): Promise> { + await PubSubServiceClient.getTokenInfo(config); // This will throw a error if the token is invalid + return emptySuccess(); + } + + async createClient(config: PubSubServiceConfig): Promise> { + const client = await PubSubServiceClient.createClient(config); + + return success(client); + } + + stopClient(_: PubSubServiceClient): void {} +} diff --git a/nodecg-io-twitch-pubsub/extension/pubSubClient.ts b/nodecg-io-twitch-pubsub/extension/pubSubClient.ts new file mode 100644 index 000000000..9446f5dc8 --- /dev/null +++ b/nodecg-io-twitch-pubsub/extension/pubSubClient.ts @@ -0,0 +1,89 @@ +import { ServiceClient } from "nodecg-io-core/extension/types"; +import { getTokenInfo, StaticAuthProvider, TokenInfo } from "twitch-auth"; +import { PubSubServiceConfig } from "./index"; +import { + PubSubBitsBadgeUnlockMessage, + PubSubBitsMessage, + PubSubChatModActionMessage, + PubSubClient, + PubSubListener, + PubSubRedemptionMessage, + PubSubSubscriptionMessage, + PubSubWhisperMessage, +} from "twitch-pubsub-client"; +import { ApiClient } from "twitch"; + +export class PubSubServiceClient implements ServiceClient { + constructor(private client: PubSubClient, private userid: string) {} + + /** + * Creates a instance of TwitchServiceClient using the credentials from the passed config. + */ + static async createClient(cfg: PubSubServiceConfig): Promise { + // Create a twitch authentication provider + const tokenInfo = await PubSubServiceClient.getTokenInfo(cfg); + const authProvider = new StaticAuthProvider(tokenInfo.clientId, this.normalizeToken(cfg), tokenInfo.scopes); + + // Create the actual chat client and connect + const apiClient = new ApiClient({ authProvider }); + const pubSubClient = new PubSubClient(); + const userID = await pubSubClient.registerUserListener(apiClient); + + return new PubSubServiceClient(pubSubClient, userID); + } + + /** + * Gets the token info for the passed config. + */ + static async getTokenInfo(cfg: PubSubServiceConfig): Promise { + return await getTokenInfo(this.normalizeToken(cfg)); + } + + /** + * Strips any "oauth:" before the token away, because the client needs the token without it. + */ + static normalizeToken(cfg: PubSubServiceConfig): string { + return cfg.oauthKey.replace("oauth:", ""); + } + + getNativeClient(): PubSubClient { + return this.client; + } + + getUserID(): string { + return this.userid; + } + + async onRedemption( + callback: (message: PubSubRedemptionMessage) => void, + ): Promise> { + return await this.client.onRedemption(this.userid, callback); + } + + async onSubscription( + callback: (message: PubSubSubscriptionMessage) => void, + ): Promise> { + return await this.client.onSubscription(this.userid, callback); + } + + async onBits(callback: (message: PubSubBitsMessage) => void): Promise> { + return await this.client.onBits(this.userid, callback); + } + + async onBitsBadgeUnlock( + callback: (message: PubSubBitsBadgeUnlockMessage) => void, + ): Promise> { + return await this.client.onBitsBadgeUnlock(this.userid, callback); + } + + async onModAction( + channelID: string, + callback: (message: PubSubChatModActionMessage) => void, + ): Promise> { + return await this.client.onModAction(this.userid, channelID, callback); + } + + async onWhisper(callback: (message: PubSubWhisperMessage) => void): Promise> { + return await this.client.onWhisper(this.userid, callback); + } +} diff --git a/nodecg-io-twitch-pubsub/package.json b/nodecg-io-twitch-pubsub/package.json new file mode 100644 index 000000000..28348c184 --- /dev/null +++ b/nodecg-io-twitch-pubsub/package.json @@ -0,0 +1,43 @@ +{ + "name": "nodecg-io-twitch-pubsub", + "version": "0.1.0", + "description": "Allows access to the Twitch PubSub API.", + "homepage": "https://nodecg.io/samples/twitch-pubsub", + "author": { + "name": "derNiklaas", + "url": "https://github.com/derNiklaas" + }, + "repository": { + "type": "git", + "url": "https://github.com/codeoverflow-org/nodecg-io.git", + "directory": "nodecg-io-twitch-pubsub" + }, + "main": "extension", + "scripts": { + "build": "tsc -b", + "watch": "tsc -b -w", + "clean": "tsc -b --clean" + }, + "keywords": [ + "nodecg-io", + "nodecg-bundle" + ], + "nodecg": { + "compatibleRange": "^1.1.1", + "bundleDependencies": { + "nodecg-io-core": "^0.1.0" + } + }, + "license": "MIT", + "devDependencies": { + "@types/node": "^14.6.4", + "nodecg": "^1.6.1", + "typescript": "^4.0.2" + }, + "dependencies": { + "nodecg-io-core": "^0.1.0", + "twitch": "^4.3.6", + "twitch-pubsub-client": "^4.3.6", + "ws": "^7.4.1" + } +} diff --git a/nodecg-io-twitch-pubsub/pubsub-schema.json b/nodecg-io-twitch-pubsub/pubsub-schema.json new file mode 100644 index 000000000..66d9d9c34 --- /dev/null +++ b/nodecg-io-twitch-pubsub/pubsub-schema.json @@ -0,0 +1,12 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "additionalProperties": false, + "properties": { + "oauthKey": { + "type": "string", + "description": "A OAuth2 key for the twitch api." + } + }, + "required": ["oauthKey"] +} diff --git a/nodecg-io-twitch-pubsub/tsconfig.json b/nodecg-io-twitch-pubsub/tsconfig.json new file mode 100644 index 000000000..1c8405620 --- /dev/null +++ b/nodecg-io-twitch-pubsub/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "../tsconfig.common.json" +} diff --git a/samples/pubsubsample/extension/index.ts b/samples/pubsubsample/extension/index.ts index 96e776c10..7fa607cb1 100644 --- a/samples/pubsubsample/extension/index.ts +++ b/samples/pubsubsample/extension/index.ts @@ -1,12 +1,11 @@ import { NodeCG } from "nodecg/types/server"; -import { PubSubServiceClient } from "nodecg-io-pubsub/extension"; +import { PubSubServiceClient } from "nodecg-io-twitch-pubsub/extension"; import { requireService } from "nodecg-io-core/extension/serviceClientWrapper"; +module.exports = function (nodecg: NodeCG) { + nodecg.log.info("Sample bundle for twitch-pubsub started"); -module.exports = function(nodecg: NodeCG) { - nodecg.log.info("Sample bundle for discord started"); - - const pubsub = requireService(nodecg, "pubsub"); + const pubsub = requireService(nodecg, "twitch-pubsub"); pubsub?.onAvailable((client) => { nodecg.log.info("PubSub client has been updated, adding handlers for messages."); @@ -29,4 +28,4 @@ module.exports = function(nodecg: NodeCG) { }); pubsub?.onUnavailable(() => nodecg.log.info("PubSub client has been unset.")); -}; \ No newline at end of file +}; diff --git a/samples/pubsubsample/package.json b/samples/pubsubsample/package.json index 0827caaa2..4b6f18b29 100644 --- a/samples/pubsubsample/package.json +++ b/samples/pubsubsample/package.json @@ -1,26 +1,25 @@ { - "name": "pubsubsample", - "version": "0.1.0", - "nodecg": { - "compatibleRange": "^1.1.1", - "bundleDependencies": { - "nodecg-io-pubsub": "0.1.0" + "name": "pubsubsample", + "version": "0.1.0", + "nodecg": { + "compatibleRange": "^1.1.1", + "bundleDependencies": { + "nodecg-io-twitch-pubsub": "0.1.0" + } + }, + "scripts": { + "build": "tsc", + "watch": "tsc -w" + }, + "license": "MIT", + "devDependencies": { + "@types/ws": "^7.2.6", + "@types/node": "^14.6.4" + }, + "dependencies": { + "nodecg-io-twitch-pubsub": "0.1.0", + "nodecg-io-core": "0.1.0", + "nodecg": "^1.6.1", + "typescript": "^4.0.2" } - }, - "scripts": { - "build": "tsc", - "watch": "tsc -w" - }, - "license": "MIT", - "devDependencies": { - "@types/ws": "^7.2.6", - "@types/node": "^14.6.4" - }, - "dependencies": { - "nodecg-io-pubsub": "0.1.0", - "nodecg-io-core": "0.1.0", - "ws": "^7.4.1", - "nodecg": "^1.6.1", - "typescript": "^4.0.2" - } } From c725721f0527fb0e39bfaa306c003ec9fc7d811a Mon Sep 17 00:00:00 2001 From: Niklas Date: Wed, 16 Dec 2020 22:44:42 +0100 Subject: [PATCH 3/5] Changed code in sample --- samples/pubsubsample/extension/index.ts | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/samples/pubsubsample/extension/index.ts b/samples/pubsubsample/extension/index.ts index 7fa607cb1..5ce1a72cb 100644 --- a/samples/pubsubsample/extension/index.ts +++ b/samples/pubsubsample/extension/index.ts @@ -9,21 +9,17 @@ module.exports = function (nodecg: NodeCG) { pubsub?.onAvailable((client) => { nodecg.log.info("PubSub client has been updated, adding handlers for messages."); - client.onSubscription(async (message) => { - const user = await message.getUser(); - if (user) console.log(`${user.displayName} just subscribed (${message.cumulativeMonths} months)`); + client.onSubscription((message) => { + console.log(`${message.userDisplayName} just subscribed (${message.cumulativeMonths} months)`); }); - client.onBits(async (message) => { - const user = await message.getUser(); - if (user) console.log(`${user.displayName} cheered ${message.bits} Bits`); + client.onBits((message) => { + console.log(`${message.userName} cheered ${message.bits} Bits`); }); - client.onBitsBadgeUnlock(async (message) => { - const user = await message.getUser(); - if (user) console.log(`${user.displayName} just unlocked the ${message.badgeTier} Badge`); + client.onBitsBadgeUnlock((message) => { + console.log(`${message.userName} just unlocked the ${message.badgeTier} Badge`); }); - client.onRedemption(async (message) => { - const user = await message.getUser(); - if (user) console.log(`${user.displayName} redeemed ${message.rewardName} (${message.message})`); + client.onRedemption((message) => { + console.log(`${message.userDisplayName} redeemed ${message.rewardName} (${message.message})`); }); }); From 7ad6855e499d1d2dc6eec64889467b1308db6cb8 Mon Sep 17 00:00:00 2001 From: Niklas Date: Thu, 17 Dec 2020 00:04:13 +0100 Subject: [PATCH 4/5] Removed old folder --- nodecg-io-pubsub/extension/index.ts | 31 -------- nodecg-io-pubsub/extension/pubSubClient.ts | 82 ---------------------- nodecg-io-pubsub/package.json | 43 ------------ nodecg-io-pubsub/pubsub-schema.json | 12 ---- nodecg-io-pubsub/tsconfig.json | 3 - 5 files changed, 171 deletions(-) delete mode 100644 nodecg-io-pubsub/extension/index.ts delete mode 100644 nodecg-io-pubsub/extension/pubSubClient.ts delete mode 100644 nodecg-io-pubsub/package.json delete mode 100644 nodecg-io-pubsub/pubsub-schema.json delete mode 100644 nodecg-io-pubsub/tsconfig.json diff --git a/nodecg-io-pubsub/extension/index.ts b/nodecg-io-pubsub/extension/index.ts deleted file mode 100644 index 886dc5507..000000000 --- a/nodecg-io-pubsub/extension/index.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { NodeCG } from "nodecg/types/server"; -import { emptySuccess, Result, success } from "nodecg-io-core/extension/utils/result"; -import { ServiceBundle } from "nodecg-io-core/extension/serviceBundle"; -import { PubSubServiceClient } from "./pubSubClient"; - -export { PubSubServiceClient } from "./pubSubClient"; - - -export interface PubSubServiceConfig { - oauthKey: string; -} - -module.exports = (nodecg: NodeCG) => { - new TwitchService(nodecg, "pubsub", __dirname, "../pubsub-schema.json").register(); -}; - -class TwitchService extends ServiceBundle { - async validateConfig(config: PubSubServiceConfig): Promise> { - await PubSubServiceClient.getTokenInfo(config); // This will throw a error if the token is invalid - return emptySuccess(); - } - - async createClient(config: PubSubServiceConfig): Promise> { - const client = await PubSubServiceClient.createClient(config); - - return success(client); - } - - stopClient(_: PubSubServiceClient): void { - } -} diff --git a/nodecg-io-pubsub/extension/pubSubClient.ts b/nodecg-io-pubsub/extension/pubSubClient.ts deleted file mode 100644 index edc43996d..000000000 --- a/nodecg-io-pubsub/extension/pubSubClient.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { ServiceClient } from "nodecg-io-core/extension/types"; -import { getTokenInfo, StaticAuthProvider, TokenInfo } from "twitch-auth"; -import { PubSubServiceConfig } from "./index"; -import { - PubSubBitsBadgeUnlockMessage, - PubSubBitsMessage, - PubSubChatModActionMessage, - PubSubClient, - PubSubListener, - PubSubRedemptionMessage, - PubSubSubscriptionMessage, - PubSubWhisperMessage, -} from "twitch-pubsub-client"; -import { ApiClient } from "twitch"; - -export class PubSubServiceClient implements ServiceClient { - constructor(private client: PubSubClient, private userid: string) { - } - - /** - * Creates a instance of TwitchServiceClient using the credentials from the passed config. - */ - static async createClient(cfg: PubSubServiceConfig): Promise { - // Create a twitch authentication provider - const tokenInfo = await PubSubServiceClient.getTokenInfo(cfg); - const authProvider = new StaticAuthProvider(tokenInfo.clientId, this.normalizeToken(cfg), tokenInfo.scopes); - - // Create the actual chat client and connect - const apiClient = new ApiClient({ authProvider }); - const pubSubClient = new PubSubClient(); - const userID = await pubSubClient.registerUserListener(apiClient); - - return new PubSubServiceClient(pubSubClient, userID); - } - - /** - * Gets the token info for the passed config. - */ - static async getTokenInfo(cfg: PubSubServiceConfig): Promise { - return await getTokenInfo(this.normalizeToken(cfg)); - } - - /** - * Strips any "oauth:" before the token away, because the client needs the token without it. - */ - static normalizeToken(cfg: PubSubServiceConfig): string { - return cfg.oauthKey.replace("oauth:", ""); - } - - getNativeClient(): PubSubClient { - return this.client; - } - - getUserID(): string { - return this.userid; - } - - async onRedemption(callback: (message: PubSubRedemptionMessage) => void): Promise> { - return await this.client.onRedemption(this.userid, callback); - } - - async onSubscription(callback: (message: PubSubSubscriptionMessage) => void): Promise> { - return await this.client.onSubscription(this.userid, callback); - } - - async onBits(callback: (message: PubSubBitsMessage) => void): Promise> { - return await this.client.onBits(this.userid, callback); - } - - async onBitsBadgeUnlock(callback: (message: PubSubBitsBadgeUnlockMessage) => void): Promise> { - return await this.client.onBitsBadgeUnlock(this.userid, callback); - } - - async onModAction(channelID: string, callback: (message: PubSubChatModActionMessage) => void): Promise> { - return await this.client.onModAction(this.userid, channelID, callback); - } - - async onWhisper(callback: (message: PubSubWhisperMessage) => void): Promise> { - return await this.client.onWhisper(this.userid, callback); - } - -} diff --git a/nodecg-io-pubsub/package.json b/nodecg-io-pubsub/package.json deleted file mode 100644 index 70f096259..000000000 --- a/nodecg-io-pubsub/package.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "name": "nodecg-io-pubsub", - "version": "0.1.0", - "description": "Allows access to the Twitch PubSub API.", - "homepage": "https://nodecg.io/samples/pubsub", - "author": { - "name": "derNiklaas", - "url": "https://github.com/derNiklaas" - }, - "repository": { - "type": "git", - "url": "https://github.com/codeoverflow-org/nodecg-io.git", - "directory": "nodecg-io-pubsub" - }, - "main": "extension", - "scripts": { - "build": "tsc -b", - "watch": "tsc -b -w", - "clean": "tsc -b --clean" - }, - "keywords": [ - "nodecg-io", - "nodecg-bundle" - ], - "nodecg": { - "compatibleRange": "^1.1.1", - "bundleDependencies": { - "nodecg-io-core": "^0.1.0" - } - }, - "license": "MIT", - "devDependencies": { - "@types/node": "^14.6.4", - "nodecg": "^1.6.1", - "typescript": "^4.0.2" - }, - "dependencies": { - "nodecg-io-core": "^0.1.0", - "twitch": "^4.3.6", - "twitch-pubsub-client": "^4.3.6", - "ws": "^7.4.1" - } -} diff --git a/nodecg-io-pubsub/pubsub-schema.json b/nodecg-io-pubsub/pubsub-schema.json deleted file mode 100644 index 66d9d9c34..000000000 --- a/nodecg-io-pubsub/pubsub-schema.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "additionalProperties": false, - "properties": { - "oauthKey": { - "type": "string", - "description": "A OAuth2 key for the twitch api." - } - }, - "required": ["oauthKey"] -} diff --git a/nodecg-io-pubsub/tsconfig.json b/nodecg-io-pubsub/tsconfig.json deleted file mode 100644 index 1c8405620..000000000 --- a/nodecg-io-pubsub/tsconfig.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "extends": "../tsconfig.common.json" -} From fa62cae58e5ee6abb8a19f9ef98a7ec1ec674827 Mon Sep 17 00:00:00 2001 From: Niklas Date: Thu, 17 Dec 2020 00:05:43 +0100 Subject: [PATCH 5/5] Renamed class --- nodecg-io-twitch-pubsub/extension/index.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/nodecg-io-twitch-pubsub/extension/index.ts b/nodecg-io-twitch-pubsub/extension/index.ts index 3807c7be9..91886cf49 100644 --- a/nodecg-io-twitch-pubsub/extension/index.ts +++ b/nodecg-io-twitch-pubsub/extension/index.ts @@ -10,10 +10,10 @@ export interface PubSubServiceConfig { } module.exports = (nodecg: NodeCG) => { - new TwitchService(nodecg, "twitch-pubsub", __dirname, "../pubsub-schema.json").register(); + new TwitchPubSubService(nodecg, "twitch-pubsub", __dirname, "../pubsub-schema.json").register(); }; -class TwitchService extends ServiceBundle { +class TwitchPubSubService extends ServiceBundle { async validateConfig(config: PubSubServiceConfig): Promise> { await PubSubServiceClient.getTokenInfo(config); // This will throw a error if the token is invalid return emptySuccess(); @@ -25,5 +25,7 @@ class TwitchService extends ServiceBundle