Skip to content

Commit f269a94

Browse files
Techbot121Meta Construct
authored and
Meta Construct
committed
add forward support for the chat relay
1 parent e34b28b commit f269a94

File tree

2 files changed

+99
-59
lines changed

2 files changed

+99
-59
lines changed

app/services/gamebridge/payloads/ChatPayload.ts

+98-58
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,87 @@ import * as requestSchema from "./structures/ChatRequest.json";
22
import * as responseSchema from "./structures/ChatResponse.json";
33
import { ChatRequest, ChatResponse } from "./structures";
44
import { GameServer } from "..";
5-
import Discord, { GuildMember, TextChannel } from "discord.js";
5+
import Discord from "discord.js";
66
import Payload from "./Payload";
77

8+
async function formatDiscordMessage(msg: Discord.Message | Discord.MessageSnapshot): Promise<{
9+
content: string;
10+
username?: string;
11+
nickname: string;
12+
avatar?: string;
13+
color: number;
14+
}> {
15+
let content = msg.content;
16+
content = content.replace(/<(a?):[^\s:<>]*:(\d+)>/g, (_, animated, id) => {
17+
const extension = !!animated ? "gif" : "png";
18+
return `https://media.discordapp.net/emojis/${id}.${extension}?v=1&size=64 `;
19+
});
20+
content = content.replace(
21+
/<#([\d]+)>/g,
22+
(_, id) =>
23+
`#${
24+
msg.guild?.channels.cache.has(id)
25+
? (msg.guild.channels.cache.get(id) as Discord.TextChannel).name
26+
: "(uncached channel)"
27+
}`
28+
);
29+
content = content.replace(
30+
/<@!?(\d+)>/g,
31+
(_, id) =>
32+
`@${
33+
msg.guild?.members.cache.has(id)
34+
? (msg.guild.members.cache.get(id) as Discord.GuildMember).displayName
35+
: "(uncached user)"
36+
}`
37+
);
38+
content = content.replace(/(https?:\/\/tenor.com\/view\/\S+)/g, (_, url) => url + ".gif");
39+
40+
for (const [, attachment] of msg.attachments) {
41+
content += (content.length > 0 ? "\n" : "") + attachment.url;
42+
}
43+
for (const [, sticker] of msg.stickers) {
44+
content += (content.length > 0 ? "\n" : "") + sticker.url;
45+
}
46+
47+
if (content.length === 0) {
48+
// no content, stickers or attachments, so it must be an embed or components
49+
// at this point it's better to just check on discord what the message was.
50+
if (msg.embeds.length > 0) {
51+
content += "[Embed]";
52+
} else {
53+
content += "[Something]";
54+
}
55+
}
56+
57+
const username = msg.author?.username;
58+
let nickname = "";
59+
let avatar: string | undefined = undefined;
60+
const color = msg.member?.displayColor ?? 0;
61+
62+
if (msg.author) {
63+
try {
64+
const author = await msg.guild?.members.fetch(msg.author.id);
65+
if (author && author.nickname && author.nickname.length > 0) {
66+
nickname = author.nickname;
67+
}
68+
} catch {}
69+
70+
const avatarhash = msg.author.avatar;
71+
avatar = avatarhash
72+
? `https://cdn.discordapp.com/avatars/${msg.author.id}/${avatarhash}${
73+
avatarhash.startsWith("a_") ? ".gif" : ".png"
74+
}`
75+
: msg.author.defaultAvatarURL;
76+
}
77+
78+
return {
79+
content,
80+
username,
81+
nickname,
82+
avatar,
83+
color,
84+
};
85+
}
886
export default class ChatPayload extends Payload {
987
protected static requestSchema = requestSchema;
1088
protected static responseSchema = responseSchema;
@@ -19,73 +97,35 @@ export default class ChatPayload extends Payload {
1997
msg = await msg.fetch();
2098
}
2199

22-
let content = msg.content;
23-
content = content.replace(/<(a?):[^\s:<>]*:(\d+)>/g, (_, animated, id) => {
24-
const extension = !!animated ? "gif" : "png";
25-
return `https://media.discordapp.net/emojis/${id}.${extension}?v=1&size=64 `;
26-
});
27-
content = content.replace(
28-
/<#([\d]+)>/g,
29-
(_, id) =>
30-
`#${
31-
msg.guild?.channels.cache.has(id)
32-
? (msg.guild.channels.cache.get(id) as TextChannel).name
33-
: "(uncached channel)"
34-
}`
35-
);
36-
content = content.replace(
37-
/<@!?(\d+)>/g,
38-
(_, id) =>
39-
`@${
40-
msg.guild?.members.cache.has(id)
41-
? (msg.guild.members.cache.get(id) as GuildMember).displayName
42-
: "(uncached user)"
43-
}`
44-
);
45-
content = content.replace(
46-
/(https?:\/\/tenor.com\/view\/\S+)/g,
47-
(_, url) => url + ".gif"
48-
);
49-
50-
for (const [, attachment] of msg.attachments) {
51-
content += (content.length > 0 ? "\n" : "") + attachment.url;
52-
}
53-
for (const [, sticker] of msg.stickers) {
54-
content += (content.length > 0 ? "\n" : "") + sticker.url;
55-
}
100+
const mainMsg = await formatDiscordMessage(msg);
56101
let reply: Discord.Message | undefined;
57102
if (msg.reference) {
58-
try {
59-
reply = await msg.fetchReference();
103+
try {
104+
if (msg.reference.type == 0) {
105+
reply = await msg.fetchReference();
106+
} else if (msg.reference.type == 1) {
107+
// who knows maybe discord will add more
108+
reply = undefined;
109+
const newContent = mainMsg.content;
110+
const snapshot = msg.messageSnapshots.first(); // discord currently only supports one snapshot
111+
if (!snapshot) return;
112+
const referenceMessage = await formatDiscordMessage(snapshot);
113+
114+
mainMsg.content = `-> Forwarded\n${referenceMessage.content}\n${newContent}`;
115+
}
60116
} catch {}
61117
}
62118

63-
const username = msg.author.username;
64-
let nickname = "";
65-
try {
66-
const author = await msg.guild?.members.fetch(msg.author.id);
67-
if (author && author.nickname && author.nickname.length > 0) {
68-
nickname = author.nickname;
69-
}
70-
} catch {} // dont care
71-
72-
const avatarhash = msg.author.avatar;
73-
const avatar = avatarhash
74-
? `https://cdn.discordapp.com/avatars/${msg.author.id}/${avatarhash}${
75-
avatarhash.startsWith("a_") ? ".gif" : ".png"
76-
}`
77-
: msg.author.defaultAvatarURL;
78-
79119
const payload: ChatResponse = {
80120
user: {
81121
id: msg.author.id,
82-
username: username,
83-
nick: nickname,
84-
color: msg.member?.displayColor ?? 0,
85-
avatar_url: avatar,
122+
username: mainMsg.username ?? "wtf", // I wish I knew how to typeguard this
123+
nick: mainMsg.nickname,
124+
color: mainMsg.color,
125+
avatar_url: mainMsg.avatar ?? "https://cdn.discordapp.com/embed/avatars/0.png",
86126
},
87127
msgID: msg.id,
88-
content: content,
128+
content: mainMsg.content,
89129
};
90130

91131
if (reply) {

app/services/gamebridge/payloads/structures/ChatResponse.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ export default interface ChatResponse {
33
avatar_url: string;
44
color: number;
55
id: string;
6-
nick: string;
6+
nick: string | "";
77
username: string;
88
};
99
replied_message?: {

0 commit comments

Comments
 (0)