Channel.messages.fetch(id) giving mixed results
My bot uses the embed fields to match an Array from the embed to their character stats. On Desktop this issue doesn't seem to happen. When testing the submit command from mobile the statRoll message is giving me 2 different values. Sometimes the embeds are there and sometimes they are gone. Everything else looks to be the same.
Correct response (no errors):
Embeds missing:
{
channelId: "984143582027972681",
guildId: "984143580241211412",
id: "1152294200927334420",
createdTimestamp: 1694798746092,
type: 0,
system: false,
content: "<@1080207865861644328> rolled stats...",
author: {
id: "261302296103747584",
bot: true,
system: false,
flags: {
bitfield: 65536,
},
username: "Avrae",
globalName: null,
discriminator: "6944",
avatar: "b4926b52f7f1c966e01e25f0b33253f1",
banner: null,
accentColor: null,
avatarDecoration: null,
},
pinned: false,
tts: false,
nonce: null,
embeds: [
{
data: {
type: "rich",
title: "Generating Random Stats",
description: "**Server Settings:**\n● Minimum of 72\n● Maximum of 86\n● At least 2 over 14\n● At least 1 under 12",
color: 15036310,
fields: [
{
name: "Stats",
value: "**Stat 1:** 4d6kh3 (~~**1**~~, **6**, 3, **6**) = `15`\n**Stat 2:** 4d6kh3 (~~2~~, **6**, 4, **6**) = `16`\n**Stat 3:** 4d6kh3 (2, 5, ~~2~~, 3) = `10`\n**Stat 4:** 4d6kh3 (**6**, ~~3~~, 4, 5) = `15`\n**Stat 5:** 4d6kh3 (3, **6**, **6**, ~~2~~) = `15`\n**Stat 6:** 4d6kh3 (2, **6**, 3, ~~2~~) = `11`\n-----\nTotal = `82`",
inline: true,
},
],
},
},
],
components: [
],
attachments: {
},
stickers: {
},
position: null,
roleSubscriptionData: null,
editedTimestamp: null,
reactions: {
message: [Circular],
},
mentions: {
everyone: false,
users: {
},
roles: {
},
_members: null,
_channels: null,
_parsedUsers: null,
crosspostedChannels: {
},
repliedUser: null,
},
webhookId: null,
groupActivityApplication: null,
applicationId: null,
activity: null,
flags: {
bitfield: 0,
},
reference: null,
interaction: null,
}
{
channelId: "984143582027972681",
guildId: "984143580241211412",
id: "1152294200927334420",
createdTimestamp: 1694798746092,
type: 0,
system: false,
content: "<@1080207865861644328> rolled stats...",
author: {
id: "261302296103747584",
bot: true,
system: false,
flags: {
bitfield: 65536,
},
username: "Avrae",
globalName: null,
discriminator: "6944",
avatar: "b4926b52f7f1c966e01e25f0b33253f1",
banner: null,
accentColor: null,
avatarDecoration: null,
},
pinned: false,
tts: false,
nonce: null,
embeds: [
{
data: {
type: "rich",
title: "Generating Random Stats",
description: "**Server Settings:**\n● Minimum of 72\n● Maximum of 86\n● At least 2 over 14\n● At least 1 under 12",
color: 15036310,
fields: [
{
name: "Stats",
value: "**Stat 1:** 4d6kh3 (~~**1**~~, **6**, 3, **6**) = `15`\n**Stat 2:** 4d6kh3 (~~2~~, **6**, 4, **6**) = `16`\n**Stat 3:** 4d6kh3 (2, 5, ~~2~~, 3) = `10`\n**Stat 4:** 4d6kh3 (**6**, ~~3~~, 4, 5) = `15`\n**Stat 5:** 4d6kh3 (3, **6**, **6**, ~~2~~) = `15`\n**Stat 6:** 4d6kh3 (2, **6**, 3, ~~2~~) = `11`\n-----\nTotal = `82`",
inline: true,
},
],
},
},
],
components: [
],
attachments: {
},
stickers: {
},
position: null,
roleSubscriptionData: null,
editedTimestamp: null,
reactions: {
message: [Circular],
},
mentions: {
everyone: false,
users: {
},
roles: {
},
_members: null,
_channels: null,
_parsedUsers: null,
crosspostedChannels: {
},
repliedUser: null,
},
webhookId: null,
groupActivityApplication: null,
applicationId: null,
activity: null,
flags: {
bitfield: 0,
},
reference: null,
interaction: null,
}
{
channelId: "984143582027972681",
guildId: "984143580241211412",
id: "1152294200927334420",
createdTimestamp: 1694798746092,
type: 0,
system: false,
content: "<@1080207865861644328> rolled stats...",
author: {
id: "261302296103747584",
bot: true,
system: false,
flags: {
bitfield: 65536,
},
username: "Avrae",
globalName: null,
discriminator: "6944",
avatar: "b4926b52f7f1c966e01e25f0b33253f1",
banner: null,
accentColor: null,
avatarDecoration: null,
},
pinned: false,
tts: false,
nonce: null,
embeds: [
],
components: [
],
attachments: {
},
stickers: {
},
position: null,
roleSubscriptionData: null,
editedTimestamp: null,
reactions: {
message: [Circular],
},
mentions: {
everyone: false,
users: {
},
roles: {
},
_members: null,
_channels: null,
_parsedUsers: null,
crosspostedChannels: {
},
repliedUser: null,
},
webhookId: null,
groupActivityApplication: null,
applicationId: null,
activity: null,
flags: {
bitfield: 0,
},
reference: null,
interaction: null,
}
{
channelId: "984143582027972681",
guildId: "984143580241211412",
id: "1152294200927334420",
createdTimestamp: 1694798746092,
type: 0,
system: false,
content: "<@1080207865861644328> rolled stats...",
author: {
id: "261302296103747584",
bot: true,
system: false,
flags: {
bitfield: 65536,
},
username: "Avrae",
globalName: null,
discriminator: "6944",
avatar: "b4926b52f7f1c966e01e25f0b33253f1",
banner: null,
accentColor: null,
avatarDecoration: null,
},
pinned: false,
tts: false,
nonce: null,
embeds: [
],
components: [
],
attachments: {
},
stickers: {
},
position: null,
roleSubscriptionData: null,
editedTimestamp: null,
reactions: {
message: [Circular],
},
mentions: {
everyone: false,
users: {
},
roles: {
},
_members: null,
_channels: null,
_parsedUsers: null,
crosspostedChannels: {
},
repliedUser: null,
},
webhookId: null,
groupActivityApplication: null,
applicationId: null,
activity: null,
flags: {
bitfield: 0,
},
reference: null,
interaction: null,
}
6 Replies
- What's your exact discord.js
npm list discord.js
and node node -v
version?
- Not a discord.js issue? Check out #other-js-ts.
- Consider reading #how-to-get-help to improve your question!
- Explain what exactly your issue is.
- Post the full error stack trace, not just the top part!
- Show your code!
- Issue solved? Press the button!
- ✅
Marked as resolved by staffDo you have
MessageContent
intent enabled?Yes. The message always comes through on the desktop client but when testing on mobile sometimes Message.embeds is empty when there’s definitely an embed
I am unsure what's happening here, will just leave it for someone proficient to assist you.
const message = await channel.messages.fetch(msgId).catch((e) => null)
const message = await channel.messages.fetch(msgId).catch((e) => null)
public async chatInputSubmitCharacter(interaction: Command.ChatInputCommandInteraction) {
if (interaction.user.bot) return;
await interaction.deferReply({ ephemeral: true });
try {
const { options: args, channel: intChannel, user, guild } = interaction;
const channel = <TextChannel>guild.channels.cache.get(this.characterApprovalChannelId);
const statChannel = <TextChannel>guild.channels.cache.get(this.statRollChannelId);
const sheetUrl = args.getString('sheeturl');
if (isNullish(sheetUrl)) {
throw new Error('Please enter an sheet url to import');
}
//attempt to get ddb data from provided url
const urlSections = sheetUrl.split('/').reverse();
let raw: IBeyondData;
for (let section of urlSections) {
if (section && isNumber(section)) {
try {
raw = (await getBeyondData(section)).data;
} catch (error) {
throw new Error('Error trying to get DDB sheet:' + error.message);
}
}
}
if (raw === null) {
throw new Error('Unable to extract sheet information, please provide a public link.');
}
if (isNullishOrEmpty(raw.inventory)) {
throw new Error('Please complete your character inventory.');
}
let statRollMsg: Message<boolean>;
if (raw.configuration.abilityScoreType === StatGenerationMethodEnum.RolledStats) {
statRollMsg = await fetchMessageByLink(args.getString('staturl')).catch((e) =>
Promise.reject(`Please enter the link to the correct message in <#${this.statRollChannelId}>`)
);
}
const charData = await container.character.parseCharacterData(raw);
const reviewedData = container.character.reviewStatConformity(
raw.configuration.abilityScoreType,
charData,
isNullishOrEmpty(statRollMsg) ? null : statRollMsg.embeds.pop().fields
);
const submissionEmbed = await container.character.createApprovalEmbed(interaction, reviewedData, raw);
const approvalRow = new ActionRowBuilder<ButtonBuilder>().addComponents(
new ButtonBuilder()
.setCustomId(`${CharaterCustomIds.Approve}_${interaction.user.id}_${charData.id}`)
.setStyle(ButtonStyle.Success)
.setLabel('Approve'),
new ButtonBuilder()
.setCustomId(`${CharaterCustomIds.Reject}_${interaction.user.id}_${charData.id}`)
.setStyle(ButtonStyle.Danger)
.setLabel('Reject')
);
await channel.send({
content: `Hey ${guild.roles.cache.get(AdminRoles.VANGUARD_ROLE)} and ${guild.roles.cache.get(AdminRoles.WARDEN_ROLE)}`,
embeds: [submissionEmbed],
components: [approvalRow]
});
const cached = await container.redis.insert(RedisKeys.Submission, `${interaction.user.id}:${charData.id}`, raw);
if (!cached) {
throw new Error('Unable to save submission.');
}
return interaction.editReply("Thanks! You're submission has been submitted. You will be notified upon review.");
} catch (error: any) {
console.error(error);
return interaction.reply({
content: error.message || 'An unexpected error occurred. If the problem persists, please contact a Code Weaver.',
ephemeral: true
});
}
}
public async chatInputSubmitCharacter(interaction: Command.ChatInputCommandInteraction) {
if (interaction.user.bot) return;
await interaction.deferReply({ ephemeral: true });
try {
const { options: args, channel: intChannel, user, guild } = interaction;
const channel = <TextChannel>guild.channels.cache.get(this.characterApprovalChannelId);
const statChannel = <TextChannel>guild.channels.cache.get(this.statRollChannelId);
const sheetUrl = args.getString('sheeturl');
if (isNullish(sheetUrl)) {
throw new Error('Please enter an sheet url to import');
}
//attempt to get ddb data from provided url
const urlSections = sheetUrl.split('/').reverse();
let raw: IBeyondData;
for (let section of urlSections) {
if (section && isNumber(section)) {
try {
raw = (await getBeyondData(section)).data;
} catch (error) {
throw new Error('Error trying to get DDB sheet:' + error.message);
}
}
}
if (raw === null) {
throw new Error('Unable to extract sheet information, please provide a public link.');
}
if (isNullishOrEmpty(raw.inventory)) {
throw new Error('Please complete your character inventory.');
}
let statRollMsg: Message<boolean>;
if (raw.configuration.abilityScoreType === StatGenerationMethodEnum.RolledStats) {
statRollMsg = await fetchMessageByLink(args.getString('staturl')).catch((e) =>
Promise.reject(`Please enter the link to the correct message in <#${this.statRollChannelId}>`)
);
}
const charData = await container.character.parseCharacterData(raw);
const reviewedData = container.character.reviewStatConformity(
raw.configuration.abilityScoreType,
charData,
isNullishOrEmpty(statRollMsg) ? null : statRollMsg.embeds.pop().fields
);
const submissionEmbed = await container.character.createApprovalEmbed(interaction, reviewedData, raw);
const approvalRow = new ActionRowBuilder<ButtonBuilder>().addComponents(
new ButtonBuilder()
.setCustomId(`${CharaterCustomIds.Approve}_${interaction.user.id}_${charData.id}`)
.setStyle(ButtonStyle.Success)
.setLabel('Approve'),
new ButtonBuilder()
.setCustomId(`${CharaterCustomIds.Reject}_${interaction.user.id}_${charData.id}`)
.setStyle(ButtonStyle.Danger)
.setLabel('Reject')
);
await channel.send({
content: `Hey ${guild.roles.cache.get(AdminRoles.VANGUARD_ROLE)} and ${guild.roles.cache.get(AdminRoles.WARDEN_ROLE)}`,
embeds: [submissionEmbed],
components: [approvalRow]
});
const cached = await container.redis.insert(RedisKeys.Submission, `${interaction.user.id}:${charData.id}`, raw);
if (!cached) {
throw new Error('Unable to save submission.');
}
return interaction.editReply("Thanks! You're submission has been submitted. You will be notified upon review.");
} catch (error: any) {
console.error(error);
return interaction.reply({
content: error.message || 'An unexpected error occurred. If the problem persists, please contact a Code Weaver.',
ephemeral: true
});
}
}
export async function fetchMessageByLink(messageLink: string) {
const [guildId, channelId, messageId] = messageLink.split('/');
const { client, _config } = container;
if (guildId !== _config.guildId) {
return Promise.reject('This can only be used in Engrimoore');
}
const channel = await client.guilds.cache
.get(guildId)
.channels.fetch(channelId)
.catch((e) => Promise.reject(e));
if (channel.isTextBased()) {
const message = await channel.messages.fetch(messageId).catch((e) => Promise.reject(e));
if (isNullish(message)) {
return Promise.reject('Unable to fetch message by url');
}
return message;
}
return Promise.reject('Must be run in an Engrimoore Text Channel.');
}
export async function fetchMessageByLink(messageLink: string) {
const [guildId, channelId, messageId] = messageLink.split('/');
const { client, _config } = container;
if (guildId !== _config.guildId) {
return Promise.reject('This can only be used in Engrimoore');
}
const channel = await client.guilds.cache
.get(guildId)
.channels.fetch(channelId)
.catch((e) => Promise.reject(e));
if (channel.isTextBased()) {
const message = await channel.messages.fetch(messageId).catch((e) => Promise.reject(e));
if (isNullish(message)) {
return Promise.reject('Unable to fetch message by url');
}
return message;
}
return Promise.reject('Must be run in an Engrimoore Text Channel.');
}
!rollstats
and generates an embed with the array of stats
my bot is only for running my d&d westmarch not made for all servers
I'm thinking it may edit it because that might be why sometimes they are there and sometimes not
ok let me double check rn
not edited
Yes
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMembers,
GatewayIntentBits.MessageContent,
GatewayIntentBits.GuildEmojisAndStickers,
GatewayIntentBits.GuildVoiceStates,
GatewayIntentBits.GuildWebhooks,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.GuildMessageReactions,
GatewayIntentBits.DirectMessages,
GatewayIntentBits.DirectMessageReactions
],
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMembers,
GatewayIntentBits.MessageContent,
GatewayIntentBits.GuildEmojisAndStickers,
GatewayIntentBits.GuildVoiceStates,
GatewayIntentBits.GuildWebhooks,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.GuildMessageReactions,
GatewayIntentBits.DirectMessages,
GatewayIntentBits.DirectMessageReactions
],
export const CLIENT_OPTIONS: ClientOptions = {
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMembers,
GatewayIntentBits.MessageContent,
GatewayIntentBits.GuildEmojisAndStickers,
GatewayIntentBits.GuildVoiceStates,
GatewayIntentBits.GuildWebhooks,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.GuildMessageReactions,
GatewayIntentBits.DirectMessages,
GatewayIntentBits.DirectMessageReactions
],
allowedMentions: { users: [], roles: [] },
presence: {
activities: [{ name: 'over Engrimoore!', type: ActivityType.Watching }]
},
defaultPrefix: PREFIX,
disableMentionPrefix: true,
caseInsensitiveCommands: true,
logger: { level: PROD ? LogLevel.Info : LogLevel.Debug },
partials: [Partials.Channel],
loadMessageCommandListeners: true,
tasks: {
bull: {
connection: { ...parseRedisOptions() , db: envParseInteger('REDIS_DB')},
}
}
// sweepers: {
// ...Options.defaultSweeperSettings,
// messages: {
// interval: minutes.toSeconds(3),
// lifetime: minutes.toSeconds(15)
// }
// }
};
export const CLIENT_OPTIONS: ClientOptions = {
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMembers,
GatewayIntentBits.MessageContent,
GatewayIntentBits.GuildEmojisAndStickers,
GatewayIntentBits.GuildVoiceStates,
GatewayIntentBits.GuildWebhooks,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.GuildMessageReactions,
GatewayIntentBits.DirectMessages,
GatewayIntentBits.DirectMessageReactions
],
allowedMentions: { users: [], roles: [] },
presence: {
activities: [{ name: 'over Engrimoore!', type: ActivityType.Watching }]
},
defaultPrefix: PREFIX,
disableMentionPrefix: true,
caseInsensitiveCommands: true,
logger: { level: PROD ? LogLevel.Info : LogLevel.Debug },
partials: [Partials.Channel],
loadMessageCommandListeners: true,
tasks: {
bull: {
connection: { ...parseRedisOptions() , db: envParseInteger('REDIS_DB')},
}
}
// sweepers: {
// ...Options.defaultSweeperSettings,
// messages: {
// interval: minutes.toSeconds(3),
// lifetime: minutes.toSeconds(15)
// }
// }
};