summaryrefslogtreecommitdiff
path: root/packages/gateway/src/commands/characterClaimParser.ts
blob: 84fab04b92ecd5a4d1f17938f1963be9fb24f99d (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 { Client, Message } from "discord.js";
import {
  CHARACTER_LIST_MESSAGE_ID,
  CHARACTER_LIST_CHANNEL_ID,
} from "../../../shared";
import { log, LogLevel } from "../../../shared/log";

interface ClaimedCharacter {
  name: string;
  mention: string;
}

interface UnclaimedCharacter {
  name: string;
}

interface CharacterListData {
  claimed: ClaimedCharacter[];
  unclaimed: UnclaimedCharacter[];
  unregistered: string[];
}

export const fetchCharacterList = async (
  client: Client,
): Promise<CharacterListData | null> => {
  try {
    const channel = await client.channels.fetch(CHARACTER_LIST_CHANNEL_ID);

    if (!channel || !channel.isTextBased() || channel.isDMBased()) {
      log(
        `Failed to fetch character list channel: ${CHARACTER_LIST_CHANNEL_ID}`,
        LogLevel.Error,
      );

      return null;
    }

    const message = await channel.messages.fetch(CHARACTER_LIST_MESSAGE_ID);

    if (!message) {
      log(
        `Failed to fetch character list message: ${CHARACTER_LIST_MESSAGE_ID}`,
        LogLevel.Error,
      );

      return null;
    }

    const claimed: ClaimedCharacter[] = [];
    const unclaimed: UnclaimedCharacter[] = [];
    const unregistered: string[] = [];

    for (const embed of message.embeds) {
      const description =
        embed.description || embed.fields.map((f) => f.value).join("\n");

      if (!description) continue;

      const lines = description.split("\n");

      for (const line of lines) {
        const trimmed = line.trim();

        if (
          !trimmed ||
          trimmed.startsWith(".") ||
          trimmed.startsWith("☆") ||
          !trimmed.includes("►")
        )
          continue;

        const match = trimmed.match(/^(.+?)\s*[►➤]\s*(?:<@(\d+)>)?$/);

        if (match) {
          const [, characterName] = match;
          const mention = match[2];

          if (mention) {
            claimed.push({
              name: characterName.trim(),
              mention: mention.trim(),
            });
          } else {
            unclaimed.push({ name: characterName.trim() });
          }
        }
      }
    }

    return { claimed, unclaimed, unregistered };
  } catch (error) {
    log(`Failed to fetch character list: ${error}`, LogLevel.Error);

    return null;
  }
};

export const getCharacterNameFromMessage = async (
  message: Message,
): Promise<string | null> => {
  if (message.webhookId) return message.author.username;

  if (message.author.bot) return message.author.username;

  let member = message.member;

  if (!member && message.guild)
    try {
      member = await message.guild.members.fetch(message.author.id);
    } catch {
      return message.author.username;
    }

  if (member?.displayName) return member.displayName;

  return message.author.username;
};