fix some syntax and stuff

This commit is contained in:
Darius
2025-09-26 21:44:24 +02:00
parent a0a76a8b75
commit cc5ecaf8e0
10 changed files with 346 additions and 30 deletions

288
package-lock.json generated
View File

@@ -13,12 +13,12 @@
"@twurple/api": "^7.4.0", "@twurple/api": "^7.4.0",
"@twurple/auth": "^7.4.0", "@twurple/auth": "^7.4.0",
"@twurple/chat": "^7.4.0", "@twurple/chat": "^7.4.0",
"axios": "^1.12.2",
"chalk": "^5.6.2", "chalk": "^5.6.2",
"dotenv": "^17.2.2" "dotenv": "^17.2.2"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^24.5.2", "@types/node": "^24.5.2",
"@types/tmi.js": "^1.8.6",
"nodemon": "^3.1.10", "nodemon": "^3.1.10",
"rimraf": "^6.0.1", "rimraf": "^6.0.1",
"ts-node": "^10.9.2", "ts-node": "^10.9.2",
@@ -384,13 +384,6 @@
"undici-types": "~7.12.0" "undici-types": "~7.12.0"
} }
}, },
"node_modules/@types/tmi.js": {
"version": "1.8.6",
"resolved": "https://registry.npmjs.org/@types/tmi.js/-/tmi.js-1.8.6.tgz",
"integrity": "sha512-LVzNK7AxTMyh9qHLanAQR1o0I9XzfbIcXk85cx85igmCJHHO1Sm71sdhQ8Mj1WmRGzynPIoCXx6mVaFynWbsQw==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/ws": { "node_modules/@types/ws": {
"version": "8.18.1", "version": "8.18.1",
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz",
@@ -473,6 +466,23 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
"license": "MIT"
},
"node_modules/axios": {
"version": "1.12.2",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.12.2.tgz",
"integrity": "sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==",
"license": "MIT",
"dependencies": {
"follow-redirects": "^1.15.6",
"form-data": "^4.0.4",
"proxy-from-env": "^1.1.0"
}
},
"node_modules/balanced-match": { "node_modules/balanced-match": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
@@ -517,6 +527,19 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/call-bind-apply-helpers": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
"integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"function-bind": "^1.1.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/chalk": { "node_modules/chalk": {
"version": "5.6.2", "version": "5.6.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz",
@@ -574,6 +597,18 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"license": "MIT",
"dependencies": {
"delayed-stream": "~1.0.0"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/concat-map": { "node_modules/concat-map": {
"version": "0.0.1", "version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@@ -621,6 +656,15 @@
} }
} }
}, },
"node_modules/delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
"license": "MIT",
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/diff": { "node_modules/diff": {
"version": "4.0.2", "version": "4.0.2",
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
@@ -643,6 +687,20 @@
"url": "https://dotenvx.com" "url": "https://dotenvx.com"
} }
}, },
"node_modules/dunder-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.1",
"es-errors": "^1.3.0",
"gopd": "^1.2.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/eastasianwidth": { "node_modules/eastasianwidth": {
"version": "0.2.0", "version": "0.2.0",
"resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
@@ -657,6 +715,51 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/es-define-property": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-errors": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-object-atoms": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
"integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-set-tostringtag": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
"integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.6",
"has-tostringtag": "^1.0.2",
"hasown": "^2.0.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/fill-range": { "node_modules/fill-range": {
"version": "7.1.1", "version": "7.1.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
@@ -670,6 +773,26 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/follow-redirects": {
"version": "1.15.11",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz",
"integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==",
"funding": [
{
"type": "individual",
"url": "https://github.com/sponsors/RubenVerborgh"
}
],
"license": "MIT",
"engines": {
"node": ">=4.0"
},
"peerDependenciesMeta": {
"debug": {
"optional": true
}
}
},
"node_modules/foreground-child": { "node_modules/foreground-child": {
"version": "3.3.1", "version": "3.3.1",
"resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz",
@@ -687,6 +810,22 @@
"url": "https://github.com/sponsors/isaacs" "url": "https://github.com/sponsors/isaacs"
} }
}, },
"node_modules/form-data": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz",
"integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==",
"license": "MIT",
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"es-set-tostringtag": "^2.1.0",
"hasown": "^2.0.2",
"mime-types": "^2.1.12"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/fsevents": { "node_modules/fsevents": {
"version": "2.3.3", "version": "2.3.3",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
@@ -702,6 +841,52 @@
"node": "^8.16.0 || ^10.6.0 || >=11.0.0" "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
} }
}, },
"node_modules/function-bind": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/get-intrinsic": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
"integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.2",
"es-define-property": "^1.0.1",
"es-errors": "^1.3.0",
"es-object-atoms": "^1.1.1",
"function-bind": "^1.1.2",
"get-proto": "^1.0.1",
"gopd": "^1.2.0",
"has-symbols": "^1.1.0",
"hasown": "^2.0.2",
"math-intrinsics": "^1.1.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/get-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
"integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
"license": "MIT",
"dependencies": {
"dunder-proto": "^1.0.1",
"es-object-atoms": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/glob": { "node_modules/glob": {
"version": "11.0.3", "version": "11.0.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-11.0.3.tgz", "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.3.tgz",
@@ -739,6 +924,18 @@
"node": ">= 6" "node": ">= 6"
} }
}, },
"node_modules/gopd": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-flag": { "node_modules/has-flag": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
@@ -749,6 +946,45 @@
"node": ">=4" "node": ">=4"
} }
}, },
"node_modules/has-symbols": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-tostringtag": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
"integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
"license": "MIT",
"dependencies": {
"has-symbols": "^1.0.3"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/hasown": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
"license": "MIT",
"dependencies": {
"function-bind": "^1.1.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/ignore-by-default": { "node_modules/ignore-by-default": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz",
@@ -879,6 +1115,36 @@
"dev": true, "dev": true,
"license": "ISC" "license": "ISC"
}, },
"node_modules/math-intrinsics": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/mime-db": {
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/mime-types": {
"version": "2.1.35",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
"license": "MIT",
"dependencies": {
"mime-db": "1.52.0"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/minimatch": { "node_modules/minimatch": {
"version": "10.0.3", "version": "10.0.3",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.3.tgz", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.3.tgz",
@@ -1031,6 +1297,12 @@
"url": "https://github.com/sponsors/jonschlinkert" "url": "https://github.com/sponsors/jonschlinkert"
} }
}, },
"node_modules/proxy-from-env": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
"license": "MIT"
},
"node_modules/pstree.remy": { "node_modules/pstree.remy": {
"version": "1.1.8", "version": "1.1.8",
"resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz",

View File

@@ -7,7 +7,8 @@
"clean": "rimraf dist", "clean": "rimraf dist",
"build": "npm run clean && tsc -p .", "build": "npm run clean && tsc -p .",
"start": "node dist/bot.js", "start": "node dist/bot.js",
"dev": "nodemon src/bot.ts" "dev": "nodemon src/bot.ts",
"setup": "nodemon src/setup.ts"
}, },
"keywords": [], "keywords": [],
"author": "", "author": "",
@@ -15,7 +16,6 @@
"type": "module", "type": "module",
"devDependencies": { "devDependencies": {
"@types/node": "^24.5.2", "@types/node": "^24.5.2",
"@types/tmi.js": "^1.8.6",
"nodemon": "^3.1.10", "nodemon": "^3.1.10",
"rimraf": "^6.0.1", "rimraf": "^6.0.1",
"ts-node": "^10.9.2", "ts-node": "^10.9.2",
@@ -26,6 +26,7 @@
"@twurple/api": "^7.4.0", "@twurple/api": "^7.4.0",
"@twurple/auth": "^7.4.0", "@twurple/auth": "^7.4.0",
"@twurple/chat": "^7.4.0", "@twurple/chat": "^7.4.0",
"axios": "^1.12.2",
"chalk": "^5.6.2", "chalk": "^5.6.2",
"dotenv": "^17.2.2" "dotenv": "^17.2.2"
} }

View File

@@ -1,5 +1,5 @@
import { chatClient } from "../core/chat-client.ts"; import { chatClient } from "../core/chat-client.ts";
import type { ICommand, ICommandRequirements } from "./interface"; import type { ICommand, ICommandRequirements } from "./interface.ts";
export abstract class BaseCommand implements ICommand { export abstract class BaseCommand implements ICommand {
protected get chatClient() { protected get chatClient() {

View File

@@ -1,8 +1,20 @@
import type { ChatMessage } from "@twurple/chat"; import type { ChatMessage } from "@twurple/chat";
import { logSuccess } from "../util/logger.ts"; import axios from "axios";
import { logError, logSuccess } from "../util/logger.ts";
import { BaseCommand } from "./base-command.ts"; import { BaseCommand } from "./base-command.ts";
import type { ICommandRequirements } from "./interface.ts"; import type { ICommandRequirements } from "./interface.ts";
interface ISong {
title: string;
artists: string;
album: string;
playingFrom: string;
status: "playing" | "paused";
url: string;
current: string;
duration: string;
}
export class SongCommand extends BaseCommand { export class SongCommand extends BaseCommand {
name = "song"; name = "song";
cooldown = 0; cooldown = 0;
@@ -19,7 +31,24 @@ export class SongCommand extends BaseCommand {
_text: string, _text: string,
_msg: ChatMessage, _msg: ChatMessage,
) => { ) => {
logSuccess(`${channel} song command triggered`); logSuccess(`${channel} ${user} song command triggered`);
logSuccess(await getSongFromTidal());
// client.say(channel, "testing"); // client.say(channel, "testing");
}; };
} }
async function getSongFromTidal() {
axios.get<ISong>("http://localhost:47836/current").then(
(response) => {
const currentSong = response.data;
const status = currentSong.status === "playing" ? "▶️" : "⏸️";
return `listening to ${currentSong.title} by ${currentSong.artists}. ${status} ${currentSong.current}/${currentSong.duration}. link: ${currentSong.url}`;
},
() => {
logError("error getting song from tidal");
return "";
},
);
}

View File

@@ -9,4 +9,4 @@ export const Config = {
client_secret: process.env.CLIENT_SECRET || "", client_secret: process.env.CLIENT_SECRET || "",
channels: process.env.CHANNELS?.split(",") || [], channels: process.env.CHANNELS?.split(",") || [],
developers: process.env.DEVELOPERS?.split(",") || [], developers: process.env.DEVELOPERS?.split(",") || [],
}; } as const;

View File

@@ -1,6 +1,6 @@
import { ApiClient } from "@twurple/api"; import { ApiClient } from "@twurple/api";
import { AppTokenAuthProvider } from "@twurple/auth"; import { AppTokenAuthProvider } from "@twurple/auth";
import { Config } from "../config/config"; import { Config } from "../config/config.ts";
const authProvider = new AppTokenAuthProvider( const authProvider = new AppTokenAuthProvider(
Config.client_id, Config.client_id,

View File

@@ -1,12 +1,11 @@
import { promises as fs } from "node:fs"; import { promises as fs } from "node:fs";
import * as readline from "node:readline";
import type { AccessToken } from "@twurple/auth"; import type { AccessToken } from "@twurple/auth";
export class TokenManager { export class TokenManager {
private readonly tokenFilePath: string; private readonly tokenFilePath: string;
constructor(userId: string) { constructor(userId: string) {
this.tokenFilePath = `./tokens/${userId}.json`; this.tokenFilePath = `../db/token.${userId}.json`;
} }
async getToken(): Promise<AccessToken | null> { async getToken(): Promise<AccessToken | null> {

View File

@@ -1,12 +1,14 @@
import { exchangeCode } from "@twurple/auth"; import { exchangeCode } from "@twurple/auth";
import { Config } from "./config/config"; import { Config } from "./config/config.ts";
import { TokenManager } from "./core/token-manager"; import { TokenManager } from "./core/token-manager.ts";
import { TwitchAuth } from "./util/auth"; import { TwitchAuth } from "./util/auth.ts";
import { getUserId } from "./util/general"; import { getUserId, promptForInput } from "./util/general.ts";
import { logError, logInfo, logWarning } from "./util/logger"; import { logError, logInfo, logWarning } from "./util/logger.ts";
const botname = ""; const botname = await promptForInput("enter bot username: ");
const developers = [""]; const developers = (
await promptForInput("enter developer usernames (,separated): ")
).split(",");
const scopes = ["chat:read", "chat:edit", "channel:moderate"]; const scopes = ["chat:read", "chat:edit", "channel:moderate"];
const port = 3000; const port = 3000;
const redirectUri = `http://localhost:${port}`; const redirectUri = `http://localhost:${port}`;

View File

@@ -4,14 +4,12 @@ import {
type ServerResponse, type ServerResponse,
} from "node:http"; } from "node:http";
import { URL } from "node:url"; import { URL } from "node:url";
import { Config } from "../config/config.js"; import { Config } from "../config/config.ts";
export class TwitchAuth { export class TwitchAuth {
private readonly clientId: string;
private readonly redirectUri: string; private readonly redirectUri: string;
constructor(redirectUri: string = "http://localhost:3000") { constructor(redirectUri: string = "http://localhost:3000") {
this.clientId = Config.client_id;
this.redirectUri = redirectUri; this.redirectUri = redirectUri;
} }
@@ -19,7 +17,7 @@ export class TwitchAuth {
const baseUrl = "https://id.twitch.tv/oauth2/authorize"; const baseUrl = "https://id.twitch.tv/oauth2/authorize";
const params = new URLSearchParams({ const params = new URLSearchParams({
response_type: "code", response_type: "code",
client_id: this.clientId, client_id: Config.client_id,
redirect_uri: this.redirectUri, redirect_uri: this.redirectUri,
scope: scopes.join(" "), scope: scopes.join(" "),
}); });

View File

@@ -1,5 +1,6 @@
import { apiClient } from "../core/api-client"; import * as readline from "node:readline";
import { logError, logInfo } from "./logger"; import { apiClient } from "../core/api-client.ts";
import { logError, logInfo } from "./logger.ts";
export async function getUserId(username: string): Promise<string | null> { export async function getUserId(username: string): Promise<string | null> {
const user = await apiClient.users.getUserByName(username); const user = await apiClient.users.getUserByName(username);
@@ -10,3 +11,17 @@ export async function getUserId(username: string): Promise<string | null> {
logError(`no user with name ${username} found`); logError(`no user with name ${username} found`);
return null; return null;
} }
export async function promptForInput(prompt: string): Promise<string> {
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
return new Promise<string>((resolve) => {
rl.question(prompt, (answer) => {
rl.close();
resolve(answer.trim());
});
});
}