LOADING JASON DISCORD HOST V1
LOADING JASON DISCORD HOST V1
Jason Discord Host V1
Welcome Bot listens for new members and posts a branded embed in the channel you choose. Message text supports {user}, {server}, and {count}. Moderators can preview the embed and change the destination channel without editing files mid-session.
Enable: Server Members Intent.
require("dotenv").config();
const {
Client,
GatewayIntentBits,
EmbedBuilder,
SlashCommandBuilder,
PermissionFlagsBits,
ChannelType,
Events,
MessageFlags,
} = require("discord.js");
const TOKEN = process.env.DISCORD_TOKEN;
const GUILD_ID = process.env.GUILD_ID?.trim();
if (!TOKEN) {
console.error("Missing DISCORD_TOKEN. Copy .env.example to .env and add your bot token.");
process.exit(1);
}
const runtime = {
welcomeChannelId: process.env.WELCOME_CHANNEL_ID?.trim() || "",
welcomeMessage:
process.env.WELCOME_MESSAGE ||
"Welcome to {server}, {user}! You are member #{count}.",
};
const client = new Client({
intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMembers],
});
const commands = [
new SlashCommandBuilder().setName("ping").setDescription("Check that Welcome Bot is online."),
new SlashCommandBuilder()
.setName("setwelcome")
.setDescription("Set the channel used for welcome messages.")
.addChannelOption((option) =>
option
.setName("channel")
.setDescription("Text channel for welcome embeds")
.addChannelTypes(ChannelType.GuildText, ChannelType.GuildAnnouncement)
.setRequired(true),
)
.setDefaultMemberPermissions(PermissionFlagsBits.ManageGuild),
new SlashCommandBuilder()
.setName("welcometest")
.setDescription("Send a preview welcome embed in this channel.")
.setDefaultMemberPermissions(PermissionFlagsBits.ManageGuild),
].map((command) => command.toJSON());
function formatWelcome(template, member) {
return template
.replaceAll("{user}", `${member}`)
.replaceAll("{server}", member.guild.name)
.replaceAll("{count}", String(member.guild.memberCount));
}
function buildWelcomeEmbed(member) {
return new EmbedBuilder()
.setColor(0x22f0ff)
.setTitle("New member arrived")
.setDescription(formatWelcome(runtime.welcomeMessage, member))
.setThumbnail(member.user.displayAvatarURL({ size: 256 }))
.addFields(
{ name: "User", value: `${member.user.tag}`, inline: true },
{ name: "Member count", value: `${member.guild.memberCount}`, inline: true },
)
.setFooter({ text: "Jason Discord Host V1 · Welcome Bot" })
.setTimestamp();
}
async function registerCommands() {
if (GUILD_ID) {
const guild = await client.guilds.fetch(GUILD_ID);
await guild.commands.set(commands);
console.log(`Registered guild commands in ${guild.name}`);
return;
}
await client.application.commands.set(commands);
console.log("Registered global slash commands (can take up to an hour to appear).");
}
client.once(Events.ClientReady, async () => {
console.log(`Welcome Bot online as ${client.user.tag}`);
try {
await registerCommands();
} catch (error) {
console.error("Failed to register commands:", error);
}
});
client.on(Events.GuildMemberAdd, async (member) => {
const channelId = runtime.welcomeChannelId;
if (!channelId) {
console.warn("No WELCOME_CHANNEL_ID set. Use /setwelcome or add it to .env.");
return;
}
const channel = await member.guild.channels.fetch(channelId).catch(() => null);
if (!channel || !channel.isTextBased()) {
console.warn(`Welcome channel ${channelId} is missing or not text-based.`);
return;
}
await channel.send({
content: `${member}`,
embeds: [buildWelcomeEmbed(member)],
});
});
client.on(Events.InteractionCreate, async (interaction) => {
if (!interaction.isChatInputCommand()) return;
if (interaction.commandName === "ping") {
await interaction.reply({
content: `Pong — ${client.ws.ping}ms. Welcome channel: ${
runtime.welcomeChannelId ? `<#${runtime.welcomeChannelId}>` : "not set"
}`,
flags: MessageFlags.Ephemeral,
});
return;
}
if (interaction.commandName === "setwelcome") {
const channel = interaction.options.getChannel("channel", true);
runtime.welcomeChannelId = channel.id;
await interaction.reply({
content: `Welcome messages will now post in ${channel}. Update WELCOME_CHANNEL_ID in .env to keep this after a restart.`,
flags: MessageFlags.Ephemeral,
});
return;
}
if (interaction.commandName === "welcometest") {
if (!interaction.inGuild() || !interaction.member) {
await interaction.reply({ content: "Run this command in a server.", flags: MessageFlags.Ephemeral });
return;
}
const member = await interaction.guild.members.fetch(interaction.user.id);
await interaction.reply({ embeds: [buildWelcomeEmbed(member)] });
}
});
client.login(TOKEN).catch((error) => {
console.error("Login failed. Check DISCORD_TOKEN and privileged intents.", error);
process.exit(1);
});