summaryrefslogtreecommitdiff
path: root/packages/gateway/src/commands/react.ts
blob: 08e5822e8e160d6ab7f6d5fc3920a84e098638ea (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
import { Message } from "discord.js";
import { replyWithCleanup } from "../utilities";

export const handleReactCommand = async (message: Message) => {
  if (message.author.bot) return;

  if (!message.content.startsWith("uma!react")) return;

  const application = await message.client.application?.fetch();
  const ownerId = application?.owner?.id;

  if (message.author.id !== ownerId) return;

  const parameters = message.content.split(" ");

  if (parameters.length < 3) {
    await replyWithCleanup(
      message,
      "❌ Usage: `uma!react <message_id> <emoji1> [emoji2] [emoji3] ...` or `uma!react <channel_id> <message_id> <emoji1> [emoji2] [emoji3] ...`\nExamples:\n- `uma!react 1234567890123456789 👍` (current channel)\n- `uma!react 1234567890123456789 👍 ❤️ 🎉` (multiple emojis)\n- `uma!react 1234567890123456789 🇭 🇪 🇱 🇵` (spell out word)\n- `uma!react #general 1234567890123456789 👍` (specific channel)\n- `uma!react 9876543210987654321 1234567890123456789 👍` (channel by ID)",
    );

    return;
  }

  let targetChannel: any;
  let messageId: string;
  let emojis: string[];
  const channelMatch = parameters[1].match(/<#(\d+)>/);
  const channelIdMatch = parameters[1].match(/^\d{17,19}$/);

  if (channelMatch || channelIdMatch) {
    if (parameters.length < 4) {
      await replyWithCleanup(
        message,
        "❌ Usage: `uma!react <channel_id> <message_id> <emoji1> [emoji2] [emoji3] ...`",
      );

      return;
    }

    const channelId = channelMatch ? channelMatch[1] : parameters[1];

    messageId = parameters[2];
    emojis = parameters.slice(3);

    try {
      targetChannel = await message.client.channels.fetch(channelId);
    } catch {
      await replyWithCleanup(
        message,
        "❌ Channel not found or not accessible.",
      );

      return;
    }
  } else {
    targetChannel = message.channel;
    messageId = parameters[1];
    emojis = parameters.slice(2);
  }

  if (!targetChannel || !targetChannel.isTextBased()) {
    await replyWithCleanup(message, "❌ Target channel is not a text channel.");

    return;
  }

  try {
    const targetMessage = await targetChannel.messages.fetch(messageId);

    if (!targetMessage) {
      await replyWithCleanup(message, "❌ Message not found.");

      return;
    }

    const results: string[] = [];
    const errors: string[] = [];

    for (const emoji of emojis) {
      try {
        const existingReaction = targetMessage.reactions.cache.get(emoji);
        const botReacted = existingReaction?.users.cache.has(
          message.client.user?.id || "",
        );

        if (botReacted) {
          await targetMessage.reactions.cache
            .get(emoji)
            ?.users.remove(message.client.user?.id);
          results.push(`Removed ${emoji}`);
        } else {
          await targetMessage.react(emoji);
          results.push(`Added ${emoji}`);
        }
      } catch (error) {
        console.error(`Error processing emoji ${emoji}:`, error);
        errors.push(emoji);
      }
    }

    let resultMessage = `✅ Processed ${emojis.length} emoji(s) in ${targetChannel}:\n`;

    if (results.length > 0) resultMessage += results.join(", ") + "\n";

    if (errors.length > 0)
      resultMessage += `❌ Failed to process: ${errors.join(", ")}`;

    await replyWithCleanup(message, resultMessage);
  } catch (error) {
    console.error("Error toggling reactions:", error);
    await replyWithCleanup(
      message,
      "❌ Failed to toggle reactions on the message.",
    );
  }
};