mirror of
https://github.com/qwerinope/qweribot.git
synced 2025-12-19 04:51:38 +01:00
change databases from surrealdb to pocketbase
This commit is contained in:
@@ -21,9 +21,5 @@ STREAMER_ID= # Twitch ID of the streaming user
|
||||
CHATTER_ID= # Twitch ID of the chatting user
|
||||
CHATTER_IS_STREAMER= # If the bot that activates on commands is on the same account as the streamer, set this to true. Make sure the STREAMER_ID and CHATTER_ID match in that case.
|
||||
|
||||
# SurrealDB config
|
||||
SURREAL_URL= # SurrealDB URL, can either be remotely hosted or selfhosted
|
||||
SURREAL_NAMESPACE= # SurrealDB Namespace. You need to create this manually
|
||||
SURREAL_DATABASE= # SurrealDB Database. You need to create this manually
|
||||
SURREAL_USERNAME= # SurrealDB username for authenticating
|
||||
SURREAL_PASSWORD= # SurrealDB password for authenticating. Remember to escape characters like $ with a backslash
|
||||
# Pocketbase config
|
||||
# POCKETBASE_URL= # Pocketbase URL. Defaults to localhost:8090
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -33,5 +33,6 @@ report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json
|
||||
# Finder (MacOS) folder config
|
||||
.DS_Store
|
||||
|
||||
# Redis/Valkey database
|
||||
# Redis/Valkey & Pocketbase databases
|
||||
db/redis/
|
||||
db/pocketbase/
|
||||
|
||||
@@ -66,7 +66,7 @@ export async function createAuthProvider(user: string, intents: string[], stream
|
||||
|
||||
authData.onRefresh(async (user, token) => {
|
||||
console.info(`Successfully refreshed auth for user ${user}`);
|
||||
await updateAuthRecord(user, token.scope, token);
|
||||
await updateAuthRecord(user, token);
|
||||
});
|
||||
|
||||
authData.onRefreshFailure((user, err) => {
|
||||
|
||||
@@ -1,31 +1,27 @@
|
||||
import Surreal from "surrealdb";
|
||||
import type { AccessToken } from "@twurple/auth";
|
||||
import PocketBase, { RecordService } from "pocketbase";
|
||||
|
||||
const surrealurl = process.env.SURREAL_URL ?? "";
|
||||
if (surrealurl === "") { console.error("Please provide a SURREAL_URL in .env."); process.exit(1); };
|
||||
const namespace = process.env.SURREAL_NAMESPACE ?? "";
|
||||
if (namespace === "") { console.error("Please provide a SURREAL_NAMESPACE in .env."); process.exit(1); };
|
||||
const database = process.env.SURREAL_DATABASE ?? "";
|
||||
if (database === "") { console.error("Please provide a SURREAL_DATABASE in .env."); process.exit(1); };
|
||||
const username = process.env.SURREAL_USERNAME ?? "";
|
||||
if (username === "") { console.error("Please provide a SURREAL_USERNAME in .env."); process.exit(1); };
|
||||
const password = process.env.SURREAL_PASSWORD ?? "";
|
||||
if (password === "") { console.error("Please provide a SURREAL_PASSWORD in .env."); process.exit(1); };
|
||||
const pocketbaseurl = process.env.POCKETBASE_URL ?? "localhost:8090";
|
||||
if (pocketbaseurl === "") { console.error("Please provide a POCKETBASE_URL in .env."); process.exit(1); };
|
||||
|
||||
export default async function DB(): Promise<Surreal> {
|
||||
const db = new Surreal();
|
||||
try {
|
||||
await db.connect(surrealurl, {
|
||||
auth: {
|
||||
username,
|
||||
password
|
||||
}
|
||||
});
|
||||
await db.use({ namespace, database });
|
||||
return db;
|
||||
}
|
||||
catch (err) {
|
||||
console.error("Failed to connect to SurrealDB:", err instanceof Error ? err.message : String(err));
|
||||
await db.close();
|
||||
throw err;
|
||||
};
|
||||
export type authRecord = {
|
||||
id: string;
|
||||
accesstoken: AccessToken;
|
||||
};
|
||||
|
||||
export type userRecord = {
|
||||
id: string;
|
||||
username: string;
|
||||
balance: number;
|
||||
inventory: object;
|
||||
lastlootbox: string;
|
||||
};
|
||||
|
||||
type TypedPocketBase = {
|
||||
collection(idOrName: 'auth'): RecordService<authRecord>;
|
||||
collection(idOrName: 'users'): RecordService<userRecord>;
|
||||
};
|
||||
|
||||
const pb = new PocketBase(pocketbaseurl) as TypedPocketBase;
|
||||
|
||||
export default pb;
|
||||
|
||||
@@ -1,77 +1,38 @@
|
||||
import type { AccessToken } from "@twurple/auth";
|
||||
import DB from "./connection";
|
||||
import type { RecordId } from "surrealdb";
|
||||
|
||||
type authRecord = {
|
||||
accesstoken: AccessToken,
|
||||
user: string,
|
||||
};
|
||||
|
||||
export async function createAuthRecord(token: AccessToken, userId: string): Promise<void> {
|
||||
const db = await DB();
|
||||
if (!db) return;
|
||||
|
||||
const data: authRecord = {
|
||||
accesstoken: token,
|
||||
user: userId
|
||||
};
|
||||
import pocketbase, { type authRecord } from "./connection";
|
||||
const pb = pocketbase.collection('auth');
|
||||
|
||||
export async function createAuthRecord(token: AccessToken, userId: string) {
|
||||
try {
|
||||
await db.create("auth", data);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
} finally {
|
||||
await db.close();
|
||||
};
|
||||
};
|
||||
|
||||
type getAuthRecordQuery = authRecord & { id: RecordId };
|
||||
type getAuthRecordResult = { accesstoken: AccessToken, id: RecordId };
|
||||
|
||||
export async function getAuthRecord(userId: string, requiredIntents: string[]): Promise<getAuthRecordResult | undefined> {
|
||||
const db = await DB();
|
||||
if (!db) return undefined;
|
||||
try {
|
||||
const data = await db.query<getAuthRecordQuery[][]>("SELECT * from auth WHERE user=$userId AND accesstoken.scope CONTAINSALL $intents;", { userId, intents: requiredIntents });
|
||||
if (!data[0] || !data[0][0]) return undefined;
|
||||
return { accesstoken: data[0][0].accesstoken, id: data[0][0].id };
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return undefined;
|
||||
} finally {
|
||||
await db.close();
|
||||
};
|
||||
};
|
||||
|
||||
export async function updateAuthRecord(userId: string, intents: string[], newtoken: AccessToken): Promise<boolean> {
|
||||
const db = await DB();
|
||||
if (!db) return false;
|
||||
try {
|
||||
const data = await getAuthRecord(userId, intents);
|
||||
const newrecord: authRecord = {
|
||||
accesstoken: newtoken,
|
||||
user: userId
|
||||
const data: authRecord = {
|
||||
accesstoken: token,
|
||||
id: userId
|
||||
};
|
||||
await db.update(data?.id!, newrecord);
|
||||
return true;
|
||||
await pb.create(data);
|
||||
} catch (err) { };
|
||||
};
|
||||
|
||||
export async function getAuthRecord(userId: string, requiredIntents: string[]) {
|
||||
try {
|
||||
const data = await pb.getOne(userId);
|
||||
if (!requiredIntents.every(intent => data.accesstoken.scope.includes(intent))) return undefined;
|
||||
return { accesstoken: data.accesstoken };
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return false;
|
||||
} finally {
|
||||
await db.close();
|
||||
return undefined;
|
||||
};
|
||||
};
|
||||
|
||||
export async function updateAuthRecord(userId: string, newtoken: AccessToken) {
|
||||
try {
|
||||
const newrecord = {
|
||||
accesstoken: newtoken,
|
||||
};
|
||||
await pb.update(userId, newrecord);
|
||||
} catch (err) { };
|
||||
};
|
||||
|
||||
export async function deleteAuthRecord(userId: string): Promise<void> {
|
||||
const db = await DB();
|
||||
if (!db) return;
|
||||
try {
|
||||
const data = await db.query<getAuthRecordQuery[][]>("SELECT * FROM auth WHERE user=$userId;", { userId });
|
||||
if (!data[0] || !data[0][0]) return undefined;
|
||||
for (const obj of data[0]) {
|
||||
db.delete(obj.id);
|
||||
};
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
};
|
||||
await pb.delete(userId);
|
||||
} catch (err) { };
|
||||
};
|
||||
|
||||
12
bun.lock
12
bun.lock
@@ -6,7 +6,7 @@
|
||||
"dependencies": {
|
||||
"@twurple/auth": "^7.3.0",
|
||||
"@twurple/eventsub-http": "^7.3.0",
|
||||
"surrealdb": "^1.3.2",
|
||||
"pocketbase": "^0.26.1",
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bun": "latest",
|
||||
@@ -75,12 +75,12 @@
|
||||
|
||||
"inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="],
|
||||
|
||||
"isows": ["isows@1.0.7", "", { "peerDependencies": { "ws": "*" } }, "sha512-I1fSfDCZL5P0v33sVqeTDSpcstAg/N+wF5HS033mogOVIp4B+oHC7oOCsA3axAbBSGTJ8QubbNmnIRN/h8U7hg=="],
|
||||
|
||||
"klona": ["klona@2.0.6", "", {}, "sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA=="],
|
||||
|
||||
"node-fetch": ["node-fetch@2.7.0", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A=="],
|
||||
|
||||
"pocketbase": ["pocketbase@0.26.1", "", {}, "sha512-fjcPDpxyqTZCwqGUTPUV7vssIsNMqHxk9GxbhxYHPEf18RqX2d9cpSqbbHk7aas30jqkgptuKfG7aY/Mytjj3g=="],
|
||||
|
||||
"retry": ["retry@0.13.1", "", {}, "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg=="],
|
||||
|
||||
"safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="],
|
||||
@@ -89,8 +89,6 @@
|
||||
|
||||
"statuses": ["statuses@1.5.0", "", {}, "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA=="],
|
||||
|
||||
"surrealdb": ["surrealdb@1.3.2", "", { "dependencies": { "isows": "^1.0.6", "uuidv7": "^1.0.1" }, "peerDependencies": { "tslib": "^2.6.3", "typescript": "^5.0.0" } }, "sha512-mL7nij33iuon3IQP72F46fgX3p2LAxFCWCBDbZB7IohZ13RTEwJVNq7nZeP1eMSceQUpKzS6OHIWOuF9LYAkNw=="],
|
||||
|
||||
"toidentifier": ["toidentifier@1.0.0", "", {}, "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw=="],
|
||||
|
||||
"tr46": ["tr46@0.0.3", "", {}, "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="],
|
||||
@@ -103,14 +101,10 @@
|
||||
|
||||
"unpipe": ["unpipe@1.0.0", "", {}, "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ=="],
|
||||
|
||||
"uuidv7": ["uuidv7@1.0.2", "", { "bin": { "uuidv7": "cli.js" } }, "sha512-8JQkH4ooXnm1JCIhqTMbtmdnYEn6oKukBxHn1Ic9878jMkL7daTI7anTExfY18VRCX7tcdn5quzvCb6EWrR8PA=="],
|
||||
|
||||
"webidl-conversions": ["webidl-conversions@3.0.1", "", {}, "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="],
|
||||
|
||||
"whatwg-url": ["whatwg-url@5.0.0", "", { "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" } }, "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw=="],
|
||||
|
||||
"ws": ["ws@8.18.2", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ=="],
|
||||
|
||||
"httpanda/@types/node": ["@types/node@14.18.63", "", {}, "sha512-fAtCfv4jJg+ExtXhvCkCqUKZ+4ok/JQk01qDKhL5BDDoS3AxKXhV5/MAVUZyQnSEd2GT92fkgZl0pz0Q0AzcIQ=="],
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,3 +9,12 @@ services:
|
||||
- ./db/redis:/data
|
||||
environment:
|
||||
- VALKEY_EXTRA_FLAGS=--save 60 1
|
||||
pocketbase:
|
||||
container_name: qweribot-pocketbase
|
||||
build:
|
||||
context: ./pocketbase
|
||||
ports:
|
||||
- 8090:8090
|
||||
restart: no
|
||||
volumes:
|
||||
- ./db/pocketbase:/pb/pb_data
|
||||
|
||||
@@ -12,6 +12,6 @@
|
||||
"dependencies": {
|
||||
"@twurple/auth": "^7.3.0",
|
||||
"@twurple/eventsub-http": "^7.3.0",
|
||||
"surrealdb": "^1.3.2"
|
||||
"pocketbase": "^0.26.1"
|
||||
}
|
||||
}
|
||||
|
||||
20
pocketbase/Dockerfile
Normal file
20
pocketbase/Dockerfile
Normal file
@@ -0,0 +1,20 @@
|
||||
FROM alpine:latest
|
||||
|
||||
ARG PB_VERSION=0.28.4
|
||||
ARG PB_ZIPNAME=pocketbase_${PB_VERSION}_linux_amd64.zip
|
||||
|
||||
RUN apk add --no-cache \
|
||||
unzip \
|
||||
ca-certificates
|
||||
|
||||
ADD https://github.com/pocketbase/pocketbase/releases/download/v${PB_VERSION}/${PB_ZIPNAME} /tmp/${PB_ZIPNAME}
|
||||
ADD https://github.com/pocketbase/pocketbase/releases/download/v${PB_VERSION}/checksums.txt /tmp/checksums.txt
|
||||
WORKDIR /tmp
|
||||
RUN grep ${PB_ZIPNAME} checksums.txt | sha256sum -c
|
||||
RUN unzip /tmp/${PB_ZIPNAME} -d /pb/
|
||||
|
||||
COPY ./pb_migrations /pb/pb_migrations
|
||||
COPY ./pb_hooks /pb/pb_hooks
|
||||
|
||||
EXPOSE 8090
|
||||
CMD ["/pb/pocketbase", "serve", "--http=0.0.0.0:8090"]
|
||||
Reference in New Issue
Block a user