|
1 | 1 | import { Events } from 'discord.js'; |
2 | | -import { |
3 | | - getGuildInfo, |
4 | | - addEmojiRecords, |
5 | | - deleteEmojiRecords, |
6 | | - insertGuild, |
7 | | -} from '../helpers/mongodbModel.js'; |
8 | | -import { |
9 | | - createEmojiRecord, |
10 | | - extractEmojis, |
11 | | - getUserOpt, |
12 | | - shouldProcessMessage, |
13 | | -} from '../helpers/utilities.js'; |
| 2 | +import { getGuildInfo, addEmojiRecords, deleteEmojiRecords, insertGuild } from '../helpers/mongodbModel.js'; |
| 3 | +import { createEmojiRecord, extractEmojis, getUserOpt, shouldProcessMessage } from '../helpers/utilities.js'; |
14 | 4 |
|
15 | | -async function processEmojis(message, action) { |
16 | | - const guildId = message.guildId; |
17 | | - const messageAuthorId = message.author.id; |
18 | | - const emojis = extractEmojis(message); |
19 | | - const emojiRecords = []; |
| 5 | +const tally = ids => |
| 6 | + ids.reduce((acc, id) => { acc[id] = (acc[id] || 0) + 1; return acc; }, {}); |
20 | 7 |
|
21 | | - for (const emoji of emojis) { |
22 | | - const guildEmoji = await message.guild.emojis.fetch(emoji[3]).catch(() => null); |
23 | | - if (!guildEmoji) continue; |
24 | | - const emojiRecord = createEmojiRecord( |
25 | | - guildId, |
26 | | - message.id, |
27 | | - guildEmoji.id, |
28 | | - messageAuthorId, |
29 | | - message.createdAt, |
30 | | - 'message' |
| 8 | +const diffList = (fromCount, toCount) => |
| 9 | + Object.entries(fromCount) |
| 10 | + .flatMap(([id, cnt]) => |
| 11 | + Array(Math.max(cnt - (toCount[id] || 0), 0)).fill(id) |
31 | 12 | ); |
32 | | - emojiRecords.push(emojiRecord); |
33 | | - } |
34 | 13 |
|
35 | | - if (emojiRecords.length === 0) return false; |
| 14 | +const fetchEmoji = (guild, id) => |
| 15 | + guild.emojis.cache.get(id) || guild.emojis.fetch(id).catch(() => null); |
36 | 16 |
|
37 | | - if (action === 'add') { |
38 | | - await addEmojiRecords(message.client.db, emojiRecords); |
39 | | - } else if (action === 'delete') { |
40 | | - const deleteFilter = { $or: emojiRecords }; |
41 | | - await deleteEmojiRecords(message.client.db, deleteFilter); |
42 | | - } |
| 17 | +async function addEmojis(db, guild, message, ids) { |
| 18 | + if (!ids.length) return; |
| 19 | + const records = ( |
| 20 | + await Promise.all( |
| 21 | + ids.map(async id => { |
| 22 | + const emoji = await fetchEmoji(guild, id); |
| 23 | + return emoji && createEmojiRecord( |
| 24 | + message.guildId, |
| 25 | + message.id, |
| 26 | + emoji.id, |
| 27 | + message.author.id, |
| 28 | + message.createdAt, |
| 29 | + 'message' |
| 30 | + ); |
| 31 | + }) |
| 32 | + ) |
| 33 | + ).filter(Boolean); |
| 34 | + if (records.length) await addEmojiRecords(db, records); |
43 | 35 | } |
44 | 36 |
|
45 | | -async function processMessageUpdate(oldMessage, newMessage) { |
46 | | - if(newMessage.partial) await newMessage.fetch(); |
47 | | - |
48 | | - const guildInfo = await getGuildInfo(newMessage.client.db, newMessage.guild); |
49 | | - const userOpt = await getUserOpt(guildInfo, newMessage.author.id); |
50 | | - |
51 | | - if (shouldProcessMessage(oldMessage, guildInfo, userOpt)) { |
52 | | - await processEmojis(oldMessage, 'delete'); |
53 | | - } |
54 | | - |
55 | | - if (shouldProcessMessage(newMessage, guildInfo, userOpt)) { |
56 | | - await processEmojis(newMessage, 'add'); |
57 | | - } |
| 37 | +async function removeEmojis(db, guild, message, ids) { |
| 38 | + if (!ids.length) return; |
| 39 | + const records = ( |
| 40 | + await Promise.all( |
| 41 | + ids.map(async id => { |
| 42 | + const emoji = await fetchEmoji(guild, id); |
| 43 | + return emoji && createEmojiRecord( |
| 44 | + message.guildId, |
| 45 | + message.id, |
| 46 | + emoji.id, |
| 47 | + message.author.id, |
| 48 | + message.createdAt, |
| 49 | + 'message' |
| 50 | + ); |
| 51 | + }) |
| 52 | + ) |
| 53 | + ).filter(Boolean); |
| 54 | + if (records.length) await deleteEmojiRecords(db, { $or: records }); |
58 | 55 | } |
59 | 56 |
|
60 | 57 | export default { |
61 | 58 | name: Events.MessageUpdate, |
62 | 59 | async execute(oldMessage, newMessage) { |
63 | 60 | try { |
64 | | - await processMessageUpdate(oldMessage, newMessage); |
| 61 | + if (newMessage.partial) await newMessage.fetch(); |
| 62 | + const { client, guild, author } = newMessage; |
| 63 | + const guildInfo = await getGuildInfo(client.db, guild); |
| 64 | + const userOpt = await getUserOpt(guildInfo, author.id); |
| 65 | + |
| 66 | + const oldIds = |
| 67 | + shouldProcessMessage(oldMessage, guildInfo, userOpt) |
| 68 | + ? extractEmojis(oldMessage).map(e => e[3]) |
| 69 | + : []; |
| 70 | + const newIds = |
| 71 | + shouldProcessMessage(newMessage, guildInfo, userOpt) |
| 72 | + ? extractEmojis(newMessage).map(e => e[3]) |
| 73 | + : []; |
| 74 | + |
| 75 | + const toAdd = diffList(tally(newIds), tally(oldIds)); |
| 76 | + const toRemove = diffList(tally(oldIds), tally(newIds)); |
| 77 | + |
| 78 | + await Promise.all([ |
| 79 | + addEmojis(client.db, guild, newMessage, toAdd), |
| 80 | + removeEmojis(client.db, guild, newMessage, toRemove) |
| 81 | + ]); |
65 | 82 | } catch (error) { |
66 | | - if (error.message == `Cannot read properties of null (reading 'usersOpt')`) { |
| 83 | + if (error.message.includes('usersOpt')) { |
67 | 84 | await insertGuild(newMessage.client.db, newMessage.guild); |
68 | 85 | } else { |
69 | 86 | console.error(Events.MessageUpdate, error); |
70 | 87 | } |
71 | 88 | } |
72 | | - }, |
| 89 | + } |
73 | 90 | }; |
0 commit comments