Home > Software design >  issues with placeholders, with discord.js v14, mangodb
issues with placeholders, with discord.js v14, mangodb

Time:01-06

this is my ../Events/Guild/guildMemberAdd.js https://sourceb.in/iEEfLj7uM7

im trying to set placeholders that will in turn give out an output like

Welcome to OnlyScoped.gg @azz#5271! We're glad to have you as the 500th member.

but output is

Welcome to OnlyScoped.gg <@undefined>! We're glad to have you join us as the undefinedth member.`

../Commands/Moderation/setup-welcome.js

const {Message, Client, SlashCommandBuilder, PermissionFlagsBits} = require("discord.js");
const welcomeSchema = require("../../Models/Welcome");
const {model, Schema} = require("mongoose");

module.exports = {
    data: new SlashCommandBuilder()
    .setName("setup-welcome")
    .setDescription("Set up your welcome message for the discord bot.")
    .setDefaultMemberPermissions(PermissionFlagsBits.Administrator)
    .addChannelOption(option => 
        option.setName("channel")
        .setDescription("Channel for welcome messages.")
        .setRequired(true)
    )
    .addStringOption(option =>
        option.setName("welcome-message")
        .setDescription("Enter your welcome message.")
        .setRequired(true)
    )
    .addRoleOption(option =>
        option.setName("welcome-role")
        .setDescription("Enter your welcome role.")
        .setRequired(true)    
    ),

    async execute(interaction) {
        const {channel, options} = interaction;

        const welcomeChannel = options.getChannel("channel");
        const welcomeMessage = options.getString("welcome-message");
        const roleId = options.getRole("welcome-role");

        if(!interaction.guild.members.me.permissions.has(PermissionFlagsBits.SendMessages)) {
            interaction.reply({content: "I don't have permissions for this.", ephemeral: true});
        }

        welcomeSchema.findOne({Guild: interaction.guild.id}, async (err, data) => {
            if(!data) {
                const newWelcome = await welcomeSchema.create({
                    Guild: interaction.guild.id,
                    Channel: welcomeChannel.id,
                    Msg: welcomeMessage,
                    Role: roleId.id
                });
            }
            interaction.reply({content: 'Succesfully created a welcome message', ephemeral: true});
        })
    }
}

../Models/Welcome.js

const { model, Schema } = require("mongoose");

let welcomeSchema = new Schema({
  Guild: String,
  Channel: String,
  Msg: String,
  Role: String,
});

module.exports = model("Welcome", welcomeSchema);

im attempting to use string.replace()but its not working as expected

i decided to put it in guildMemberAdd.js since when a member joins this gets runs so it would be unwise to place it in setup-welcome.js or Welcome.js since those are not listening for anything.

for reference here's my package.json: https://sourceb.in/FMBgygjyoh

for the record i cant find any of the id's like member.id or member.count so those are wild guesses as to what they are. it could very well just be that as im still learning v14 this is my first project in it.

one other way i thought could work is if i just pass it off as an interpolated string in mongodb but it seems that the only string is with "" so i cant use default ones like ${member.count} so i decided to add placeholders

CodePudding user response:

The main issue I can see is incorrect property names as you mention in the question.

DiscordJS Docs: GuildMember
  • member.id => The Members ID
  • member.user.username => The Members username
  • member.guild.name => The Server's Name
  • member.guild.memberCount => Number of users within the Server

I'd advise the user to input data in a specific format like Hello {userName}!. Then you could run a program like

while (string.includes('{userName}')) {
    string.replace('{userName}', member.user.username);
}

CodePudding user response:

The basics of formatting a template are this:

const string = "Welcome to OnlyScoped.gg {tagUser}! We're glad to have you as the {memberCount} member.";
string = string.replace(/{tagUser}/g, member.toString());
string = string.replace(/{memberCount}/g, '500th');
return string; // "Welcome to OnlyScoped.gg <@123456789012345678>! We're glad to have you as the 500th member.";

To make something extensible, put template strings like this somewhere in your configuration:

{
    "welcome_message": "Welcome to OnlyScoped.gg {tagUser}! We're glad to have you as the {ordinal:memberCount} member."
}

and make a function

function formatMessage(template, lookup) {
  let output = template;
  output = output.replace(/{ordinal:([^}]*)}/g, (_, target) => withOrdinalSuffix(lookup(target)));
  output = output.replace(/{([^}]*)}/g, (_, target) => lookup(target));
  return output;
}

// https://stackoverflow.com/a/31615643/3310334
// turn 1 into '1st', 500 into '500th', 502 into '502nd'
function withOrdinalSuffix(n) {
  var s = ["th", "st", "nd", "rd"],
      v = n % 100;
  return n   (s[(v - 20) % 10] || s[v] || s[0]);
}

and then use the function with a template and the lookup function:

client.on('guildMemberAdd', member => {
  const welcomeMessageTemplate = config.welcome_message;
  const memberCount = member.guild.members.filter(member => !member.user.bot).size;
  const lookup = (item) => {
    const items = {
      memberCount,
      tagUser: member.toString()
    };
    return items[item];
  };
  const welcomeMessage = formatMessage(welcomeMessageTemplate, lookup);
  const welcomeChannel = member.guild.channels.cache.find(channel => channel.name === 'welcome');
  welcomeChannel.send(welcomeMessage);
});

CodePudding user response:

while (string.includes('{userName}')) {
    string.replace(/\{userName\}/g, member.user.username);
}
  • Related