Search code examples
javascriptdiscorddiscord.js

How can I send an automatic embed to a channel with an interval?


const { Client, EmbedBuilder, SlashCommandBuilder } = require('discord.js');
const Birthday = require('../../Models/Birthday');

module.exports = {
  data: new SlashCommandBuilder()
    .setName('birthday')
    .setDescription('Saves a user\'s birthday.')
    .addUserOption(option =>
      option.setName('user')
        .setDescription('Select the user.')
        .setRequired(true))
    .addStringOption(option =>
      option.setName('date')
        .setDescription('Select the birthdate (DD.MM.YYYY).')
        .setRequired(true)),

  async execute(interaction) {

    const user = interaction.options.getUser('user');
    const date = interaction.options.getString('date');

    const birthday = new Birthday({
      userId: user.id,
      birthday: date,
    });
    await birthday.save();

    await interaction.reply(`${user.username}'s birthday has been saved as ${date}.`,);

    setInterval(async () => {
    
        const today = new Date();
        const month = today.getMonth() + 1;
        const day = today.getDate();
    
    
        const users = await Birthday.find({ birthday: `${day}.${month}.` });
        const client = Client;
        const channel = client.channels.cache.get('1034193578450231346');
    
        for (const user of users) {
          const embed = new EmbedBuilder()
            .setColor('#0099ff')
            .setTitle(`Happy Birthday ${(user.userId)}!`)
            .setDescription(`Today is your birthday, ${user.birthday}! Have a great day! 🎉`)
            .setTimestamp()
    
          if (channel) {
            channel.send({ content: `<@${user.userId}>`, embeds: [embed] });
          }
        }
      }, 1000 * 60 * 1); 
    }
    
  }
  

I am trying to:

Save birthdays in a mongoDB schema and want my bot to check in an intervall if one of the dates is today, if yes, I want it to send automatically an embed message to a channel with a happy birthday message.

It saves the birthdates, but it doesn't really send the embed.


Solution

  • I feel like cron would be easier than setInterval if you want this to run at the start of every day. Using setInterval in the command would only create the interval if the command were run and multiple intervals would be created if the command were run multiple times. I recommend setting it somewhere in your main file. You also can't just import Client from discord.js like that. You need to construct the client in your main file and use that.

    client.on('ready', () => {
        setInterval(async () => {
            const today = new Date();
            const month = today.getMonth() + 1;
            const day = today.getDate();
        
            const users = await Birthday.find({ birthday: `${day}.${month}.` });
            const channel = client.channels.cache.get('1034193578450231346');
        
            for (const user of users) {
                const embed = new EmbedBuilder()
                .setColor('#0099ff')
                .setTitle(`Happy Birthday ${(user.userId)}!`)
                .setDescription(`Today is your birthday, ${user.birthday}! Have a great day! 🎉`)
                .setTimestamp()
        
              if (channel) {
                channel.send({ content: `<@${user.userId}>`, embeds: [embed] });
              }
          }
        }, 1000 * 60 * 1); 
    });