mirror of
https://github.com/arthur-pbty/xiao.git
synced 2026-06-03 23:36:43 +02:00
Redis Timer System
This commit is contained in:
@@ -13,6 +13,10 @@ POSTER_TIME=
|
|||||||
REPORT_CHANNEL_ID=
|
REPORT_CHANNEL_ID=
|
||||||
JOIN_LEAVE_CHANNEL_ID=
|
JOIN_LEAVE_CHANNEL_ID=
|
||||||
|
|
||||||
|
# Redis info
|
||||||
|
REDIS_HOST=
|
||||||
|
REDIS_PASS=
|
||||||
|
|
||||||
# Emoji IDs
|
# Emoji IDs
|
||||||
GOLD_FISH_EMOJI_ID=
|
GOLD_FISH_EMOJI_ID=
|
||||||
GOLD_FISH_EMOJI_NAME=
|
GOLD_FISH_EMOJI_NAME=
|
||||||
|
|||||||
@@ -161,6 +161,13 @@ The difficulty in getting all of these keys is why I recommend
|
|||||||
* `REPORT_CHANNEL_ID` is the ID of the Discord channel you want to send messages from `report` to. Not required, and if not provided the report command simply DMs the owner.
|
* `REPORT_CHANNEL_ID` is the ID of the Discord channel you want to send messages from `report` to. Not required, and if not provided the report command simply DMs the owner.
|
||||||
* `JOIN_LEAVE_CHANNEL_ID` is the ID of the Discord channel to send a message to whenever a new server adds or removes the bot. Not required.
|
* `JOIN_LEAVE_CHANNEL_ID` is the ID of the Discord channel to send a message to whenever a new server adds or removes the bot. Not required.
|
||||||
|
|
||||||
|
### Redis Info
|
||||||
|
|
||||||
|
This is information for connecting to Redis.
|
||||||
|
|
||||||
|
* `REDIS_HOST` is the host for your Redis connection. Probably `127.0.0.1`.
|
||||||
|
* `REDIS_PASS` is the password for your Redis connection.
|
||||||
|
|
||||||
### Emoji IDs
|
### Emoji IDs
|
||||||
|
|
||||||
All the emoji IDs are the IDs of Discord custom emoji. You need to
|
All the emoji IDs are the IDs of Discord custom emoji. You need to
|
||||||
|
|||||||
@@ -50,9 +50,12 @@ client.registry
|
|||||||
})
|
})
|
||||||
.registerCommandsIn(path.join(__dirname, 'commands'));
|
.registerCommandsIn(path.join(__dirname, 'commands'));
|
||||||
|
|
||||||
client.on('ready', () => {
|
client.on('ready', async () => {
|
||||||
client.logger.info(`[READY] Logged in as ${client.user.tag}! ID: ${client.user.id}`);
|
client.logger.info(`[READY] Logged in as ${client.user.tag}! ID: ${client.user.id}`);
|
||||||
|
|
||||||
|
// Set up existing timers
|
||||||
|
await client.timers.fetchAll();
|
||||||
|
|
||||||
// Push client-related activities
|
// Push client-related activities
|
||||||
client.activities.push(
|
client.activities.push(
|
||||||
{ text: () => `${formatNumber(client.guilds.cache.size)} servers`, type: 'WATCHING' },
|
{ text: () => `${formatNumber(client.guilds.cache.size)} servers`, type: 'WATCHING' },
|
||||||
|
|||||||
+4
-10
@@ -17,21 +17,15 @@ module.exports = class TimerCommand extends Command {
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
this.timers = new Map();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
run(msg, { time }) {
|
async run(msg, { time }) {
|
||||||
if (this.timers.has(msg.channel.id)) return msg.reply('Only one timer can be set per channel.');
|
const exists = await this.client.timers.exists(msg.channel.id, msg.author.id);
|
||||||
|
if (exists) return msg.reply('Only one timer can be set per channel per user.');
|
||||||
const timeMs = time.startDate.getTime() - Date.now();
|
const timeMs = time.startDate.getTime() - Date.now();
|
||||||
if (timeMs > 600000) return msg.reply('Times above 10 minutes are not currently supported. Sorry!');
|
|
||||||
const display = moment().add(timeMs, 'ms').fromNow();
|
const display = moment().add(timeMs, 'ms').fromNow();
|
||||||
const title = time.eventTitle || 'something';
|
const title = time.eventTitle || 'something';
|
||||||
const timeout = setTimeout(async () => {
|
await this.client.timers.setTimer(msg.channel.id, timeMs, msg.author.id, title);
|
||||||
await msg.channel.send(`🕰️ ${msg.author}, you wanted me to remind you of: **"${title}"**.`);
|
|
||||||
this.timers.delete(msg.channel.id);
|
|
||||||
}, timeMs);
|
|
||||||
this.timers.set(msg.channel.id, timeout);
|
|
||||||
return msg.say(`🕰️ Okay, I will remind you **"${title}"** ${display}.`);
|
return msg.say(`🕰️ Okay, I will remind you **"${title}"** ${display}.`);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
+2
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "xiao",
|
"name": "xiao",
|
||||||
"version": "119.43.2",
|
"version": "119.44.0",
|
||||||
"description": "Your personal server companion.",
|
"description": "Your personal server companion.",
|
||||||
"main": "Xiao.js",
|
"main": "Xiao.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@@ -48,6 +48,7 @@
|
|||||||
"gifencoder": "^2.0.1",
|
"gifencoder": "^2.0.1",
|
||||||
"gm": "^1.23.1",
|
"gm": "^1.23.1",
|
||||||
"html-entities": "^1.3.1",
|
"html-entities": "^1.3.1",
|
||||||
|
"ioredis": "^4.19.2",
|
||||||
"js-beautify": "^1.13.0",
|
"js-beautify": "^1.13.0",
|
||||||
"mathjs": "^8.0.1",
|
"mathjs": "^8.0.1",
|
||||||
"moment": "^2.29.1",
|
"moment": "^2.29.1",
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ const Collection = require('@discordjs/collection');
|
|||||||
const winston = require('winston');
|
const winston = require('winston');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
const Redis = require('./Redis');
|
||||||
|
const TimerManager = require('./timer/TimerManager');
|
||||||
const PokemonStore = require('./pokemon/PokemonStore');
|
const PokemonStore = require('./pokemon/PokemonStore');
|
||||||
const MemePosterClient = require('./MemePoster');
|
const MemePosterClient = require('./MemePoster');
|
||||||
const activities = require('../assets/json/activity');
|
const activities = require('../assets/json/activity');
|
||||||
@@ -30,7 +32,9 @@ module.exports = class XiaoClient extends CommandoClient {
|
|||||||
winston.format.printf(log => `[${log.timestamp}] [${log.level.toUpperCase()}]: ${log.message}`)
|
winston.format.printf(log => `[${log.timestamp}] [${log.level.toUpperCase()}]: ${log.message}`)
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
this.redis = Redis ? Redis.db : null;
|
||||||
this.webhook = new WebhookClient(XIAO_WEBHOOK_ID, XIAO_WEBHOOK_TOKEN, { disableMentions: 'everyone' });
|
this.webhook = new WebhookClient(XIAO_WEBHOOK_ID, XIAO_WEBHOOK_TOKEN, { disableMentions: 'everyone' });
|
||||||
|
this.timers = new TimerManager(this);
|
||||||
this.pokemon = new PokemonStore();
|
this.pokemon = new PokemonStore();
|
||||||
this.memePoster = POSTER_ID && POSTER_TOKEN ? new MemePosterClient(POSTER_ID, POSTER_TOKEN, {
|
this.memePoster = POSTER_ID && POSTER_TOKEN ? new MemePosterClient(POSTER_ID, POSTER_TOKEN, {
|
||||||
subreddits,
|
subreddits,
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
const Redis = require('ioredis');
|
||||||
|
const { REDIS_HOST, REDIS_PASS } = process.env;
|
||||||
|
const redis = new Redis({
|
||||||
|
port: 6379,
|
||||||
|
host: REDIS_HOST,
|
||||||
|
enableReadyCheck: true,
|
||||||
|
password: REDIS_PASS,
|
||||||
|
db: 0
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = class RedisClient {
|
||||||
|
static get db() {
|
||||||
|
return redis;
|
||||||
|
}
|
||||||
|
|
||||||
|
static start() {
|
||||||
|
redis.on('connect', () => console.info('[REDIS][CONNECT]: Connecting...'));
|
||||||
|
redis.on('ready', () => console.info('[REDIS][READY]: Ready!'));
|
||||||
|
redis.on('error', error => console.error(`[REDIS][ERROR]: Encountered error:\n${error}`));
|
||||||
|
redis.on('reconnecting', () => console.warn('[REDIS][RECONNECT]: Reconnecting...'));
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
const Redis = require('../Redis');
|
||||||
|
|
||||||
|
module.exports = class TimerManager {
|
||||||
|
constructor(client) {
|
||||||
|
Object.defineProperty(this, 'client', { value: client });
|
||||||
|
}
|
||||||
|
|
||||||
|
async fetchAll() {
|
||||||
|
const timers = await Redis.db.hgetall('timer');
|
||||||
|
for (const data of Object.keys(timers)) {
|
||||||
|
data = JSON.parse(data);
|
||||||
|
await this.setTimer(data.channelID, new Date(data.time) - new Date(), data.userID, data.title, false);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
async setTimer(channelID, time, userID, title, updateRedis = true) {
|
||||||
|
const data = { time: new Date(Date.now() + time).toISOString(), channelID, userID, title };
|
||||||
|
const timeout = setTimeout(async () => {
|
||||||
|
try {
|
||||||
|
const channel = await this.client.channels.fetch(channelID);
|
||||||
|
await channel.send(`🕰️ <@${userID}>, you wanted me to remind you of: **"${title}"**.`);
|
||||||
|
} finally {
|
||||||
|
await Redis.db.hdel('timer', `${channelID}-${userID}`);
|
||||||
|
}
|
||||||
|
}, time);
|
||||||
|
if (updateRedis) await Redis.db.hset('timer', { [`${channelID}-${userID}`]: JSON.stringify(data) });
|
||||||
|
return timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
exists(channelID, userID) {
|
||||||
|
return Redis.db.hexists('timer', `${channelID}-${userID}`);
|
||||||
|
}
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user