mirror of
https://github.com/qwerinope/qweribot.git
synced 2025-12-19 00:51:37 +01:00
add sound alerts, add more point redeem functions
This commit is contained in:
19
src/commands/disableredeem.ts
Normal file
19
src/commands/disableredeem.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { Command, sendMessage } from "commands";
|
||||
import parseCommandArgs from "lib/parseCommandArgs";
|
||||
import { disableRedeem, idMap, namedRedeems } from "pointRedeems";
|
||||
|
||||
export default new Command({
|
||||
name: 'disableRedeem',
|
||||
aliases: ['disableredeem'],
|
||||
usertype: 'moderator',
|
||||
disableable: false,
|
||||
execution: async msg => {
|
||||
const args = parseCommandArgs(msg.messageText);
|
||||
if (!args[0]) { await sendMessage("Please specify a point redemption to disable"); return; };
|
||||
const selection = namedRedeems.get(args[0]);
|
||||
if (!selection) { await sendMessage(`Redeem ${args[0]} doesn't exist. The internal names for redeems are here: https://github.com/qwerinope/qweribot#point-redeems`); return; };
|
||||
const id = idMap.get(selection.name);
|
||||
await disableRedeem(selection, id!);
|
||||
await sendMessage(`The ${selection.name} point redeem is now disabled`);
|
||||
}
|
||||
});
|
||||
19
src/commands/enableredeem.ts
Normal file
19
src/commands/enableredeem.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { Command, sendMessage } from "commands";
|
||||
import parseCommandArgs from "lib/parseCommandArgs";
|
||||
import { enableRedeem, idMap, namedRedeems } from "pointRedeems";
|
||||
|
||||
export default new Command({
|
||||
name: 'enableRedeem',
|
||||
aliases: ['enableredeem'],
|
||||
usertype: 'moderator',
|
||||
disableable: false,
|
||||
execution: async msg => {
|
||||
const args = parseCommandArgs(msg.messageText);
|
||||
if (!args[0]) { await sendMessage("Please specify a point redemption to enable"); return; };
|
||||
const selection = namedRedeems.get(args[0]);
|
||||
if (!selection) { await sendMessage(`Redeem ${args[0]} doesn't exist. The internal names for redeems are here: https://github.com/qwerinope/qweribot#point-redeems`); return; };
|
||||
const id = idMap.get(selection.name);
|
||||
await enableRedeem(selection, id!);
|
||||
await sendMessage(`The ${selection.name} point redeem is now enabled`);
|
||||
}
|
||||
});
|
||||
@@ -10,6 +10,7 @@ eventSub.onChannelRedemptionAdd(streamerId, async msg => {
|
||||
const user = await User.initUsername(msg.userName);
|
||||
try {
|
||||
await selection.execute(msg, user!);
|
||||
if (process.env.NODE_ENV === 'production') await msg.updateStatus('FULFILLED'); // only on prod
|
||||
} catch (err) {
|
||||
await sendMessage(`[ERROR]: Something went wrong with ${user?.displayName}'s redeem!`);
|
||||
logger.err(err as string);
|
||||
|
||||
@@ -19,7 +19,7 @@ export default class PointRedeem {
|
||||
public readonly color?: string;
|
||||
public readonly execute: (message: EventSubChannelRedemptionAddEvent, sender: User) => Promise<void>;
|
||||
constructor(options: pointRedeemOptions) {
|
||||
this.name = options.name
|
||||
this.name = options.name.toLowerCase();
|
||||
this.title = options.title;
|
||||
this.prompt = options.prompt;
|
||||
this.cost = options.cost;
|
||||
@@ -30,8 +30,6 @@ export default class PointRedeem {
|
||||
|
||||
import { readdir } from 'node:fs/promises';
|
||||
|
||||
const pointRedeems = new Map<number, PointRedeem>;
|
||||
|
||||
/** A map of all (including inactive) redeems mapped to names */
|
||||
const namedRedeems = new Map<string, PointRedeem>;
|
||||
|
||||
@@ -40,7 +38,6 @@ for (const file of files) {
|
||||
if (!file.endsWith('.ts')) continue;
|
||||
if (file === import.meta.file) continue;
|
||||
const redeem: PointRedeem = await import(import.meta.dir + '/' + file.slice(0, -3)).then(a => a.default);
|
||||
pointRedeems.set(redeem.cost, redeem);
|
||||
namedRedeems.set(redeem.name, redeem);
|
||||
};
|
||||
|
||||
@@ -48,15 +45,20 @@ export { namedRedeems };
|
||||
|
||||
const activeRedeems = new Map<string, PointRedeem>;
|
||||
|
||||
/** Map of redeemname to twitch redeem ID */
|
||||
const idMap = new Map<string, string>;
|
||||
|
||||
import { streamerApi, streamerId } from "main";
|
||||
import logger from "lib/logger";
|
||||
|
||||
const currentRedeems = new Map<string, string>;
|
||||
await streamerApi.channelPoints.getCustomRewards(streamerId).then(a => a.map(b => currentRedeems.set(b.title, b.id)));
|
||||
for (const [_, redeem] of Array.from(pointRedeems)) {
|
||||
for (const [_, redeem] of Array.from(namedRedeems)) {
|
||||
if (process.env.NODE_ENV !== 'production') continue; // If created with dev-app we won't be able to change it with prod app
|
||||
const selection = currentRedeems.get(redeem.title);
|
||||
if (selection) {
|
||||
currentRedeems.delete(redeem.title);
|
||||
idMap.set(redeem.name, selection);
|
||||
activeRedeems.set(selection, redeem);
|
||||
} else {
|
||||
const creation = await streamerApi.channelPoints.createCustomReward(streamerId, {
|
||||
@@ -66,12 +68,34 @@ for (const [_, redeem] of Array.from(pointRedeems)) {
|
||||
backgroundColor: redeem.color
|
||||
});
|
||||
logger.ok(`Created custom point redeem ${redeem.title}`);
|
||||
idMap.set(redeem.name, creation.id);
|
||||
activeRedeems.set(creation.id, redeem);
|
||||
};
|
||||
};
|
||||
|
||||
Array.from(currentRedeems).map(async ([title, redeem]) => { await streamerApi.channelPoints.deleteCustomReward(streamerId, redeem); logger.ok(`Deleted custom point redeem ${title}`); });
|
||||
Array.from(currentRedeems).map(async ([title, redeem]) => {
|
||||
if (process.env.NODE_ENV !== 'production') return;
|
||||
await streamerApi.channelPoints.deleteCustomReward(streamerId, redeem); logger.ok(`Deleted custom point redeem ${title}`);
|
||||
});
|
||||
|
||||
logger.ok("Successfully synced all custom point redeems");
|
||||
|
||||
export { activeRedeems };
|
||||
export async function enableRedeem(redeem: PointRedeem, id: string) {
|
||||
if (process.env.NODE_ENV !== 'production') return;
|
||||
await streamerApi.channelPoints.updateCustomReward(streamerId, id, {
|
||||
isEnabled: true
|
||||
});
|
||||
activeRedeems.set(id, redeem);
|
||||
logger.ok(`Enabled the ${redeem.name} point redeem`);
|
||||
};
|
||||
|
||||
export async function disableRedeem(redeem: PointRedeem, id: string) {
|
||||
if (process.env.NODE_ENV !== 'production') return;
|
||||
await streamerApi.channelPoints.updateCustomReward(streamerId, id, {
|
||||
isEnabled: false
|
||||
});
|
||||
activeRedeems.delete(id);
|
||||
logger.ok(`Disabled the ${redeem.name} point redeem`);
|
||||
};
|
||||
|
||||
export { activeRedeems, idMap };
|
||||
|
||||
15
src/pointRedeems/sfxEddieScream.ts
Normal file
15
src/pointRedeems/sfxEddieScream.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import PointRedeem from "pointRedeems";
|
||||
import { playAlert } from "web/alerts/serverFunctions";
|
||||
|
||||
export default new PointRedeem({
|
||||
name: "sfxEddieScream",
|
||||
title: "Eddie scream",
|
||||
cost: 100,
|
||||
color: "#A020F0",
|
||||
prompt: "Eddie screaming",
|
||||
execution: async msg => await playAlert({
|
||||
name: 'sound',
|
||||
user: msg.userDisplayName,
|
||||
sound: 'eddiescream'
|
||||
})
|
||||
});
|
||||
15
src/pointRedeems/sfxMrockMadhouse.ts
Normal file
15
src/pointRedeems/sfxMrockMadhouse.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import PointRedeem from "pointRedeems";
|
||||
import { playAlert } from "web/alerts/serverFunctions";
|
||||
|
||||
export default new PointRedeem({
|
||||
name: "sfxMrockMadhouse",
|
||||
title: "Welcome to the Madhouse",
|
||||
cost: 100,
|
||||
color: "#A020F0",
|
||||
prompt: "mrockstar20 saying 'Welcome to the Madhouse'",
|
||||
execution: async msg => await playAlert({
|
||||
name: 'sound',
|
||||
user: msg.userDisplayName,
|
||||
sound: 'mrockmadhouse'
|
||||
})
|
||||
});
|
||||
15
src/pointRedeems/sfxRipBozo.ts
Normal file
15
src/pointRedeems/sfxRipBozo.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import PointRedeem from "pointRedeems";
|
||||
import { playAlert } from "web/alerts/serverFunctions";
|
||||
|
||||
export default new PointRedeem({
|
||||
name: "sfxRipBozo",
|
||||
title: "RIP BOZO",
|
||||
cost: 500,
|
||||
color: "#A020F0",
|
||||
prompt: "Coffeezilla calls me a conman",
|
||||
execution: async msg => await playAlert({
|
||||
name: 'sound',
|
||||
user: msg.userDisplayName,
|
||||
sound: 'ripbozo'
|
||||
})
|
||||
});
|
||||
@@ -21,11 +21,18 @@ export type tntExplosionAlert = alertBase<'tntExplosion'> & {
|
||||
targets: string[];
|
||||
};
|
||||
|
||||
export type soundAlerts = 'mrockmadhouse' | 'eddiescream' | 'ripbozo';
|
||||
|
||||
export type soundAlert = alertBase<'sound'> & {
|
||||
sound: soundAlerts;
|
||||
};
|
||||
|
||||
export type alert =
|
||||
| userBlastAlert
|
||||
| userExecutionAlert
|
||||
| grenadeExplosionAlert
|
||||
| tntExplosionAlert;
|
||||
| tntExplosionAlert
|
||||
| soundAlert;
|
||||
|
||||
type playAlertEvent = {
|
||||
function: 'playAlert';
|
||||
|
||||
BIN
src/web/alerts/www/public/eddiescream.ogg
Normal file
BIN
src/web/alerts/www/public/eddiescream.ogg
Normal file
Binary file not shown.
BIN
src/web/alerts/www/public/mrockmadhouse.ogg
Normal file
BIN
src/web/alerts/www/public/mrockmadhouse.ogg
Normal file
Binary file not shown.
BIN
src/web/alerts/www/public/ripbozo.ogg
Normal file
BIN
src/web/alerts/www/public/ripbozo.ogg
Normal file
Binary file not shown.
@@ -3,6 +3,7 @@ import userBlast from "./userBlast";
|
||||
import userExecution from "./userExecution";
|
||||
import grenadeExplosion from "./grenadeExplosion";
|
||||
import tntExplosion from "./tntExplosion";
|
||||
import sound from "./sound";
|
||||
|
||||
export type AlertRunner = {
|
||||
duration: number;
|
||||
@@ -19,4 +20,5 @@ export default {
|
||||
'userExecution': userExecution,
|
||||
'grenadeExplosion': grenadeExplosion,
|
||||
'tntExplosion': tntExplosion,
|
||||
'sound': sound
|
||||
} as AlertMap;
|
||||
|
||||
8
src/web/alerts/www/src/alerts/sound.ts
Normal file
8
src/web/alerts/www/src/alerts/sound.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import { soundAlert } from "web/alerts/types";
|
||||
import { AlertRunner } from "./index";
|
||||
|
||||
export default async function execute(alert: soundAlert): Promise<AlertRunner> {
|
||||
const audio = new Audio(`/alerts/public/${alert.sound}.ogg`);
|
||||
audio.play();
|
||||
return { blocking: false, duration: 1, alertDiv: document.createElement('div') };
|
||||
};
|
||||
Reference in New Issue
Block a user