Sending Messages
Fetch a channel, then channel.send. Reply with message.reply. Forward with send({ forward }).
Fetch the channel, then send. Guild text, guild voice, and DMs are text-based. channel.send throws INVALID_CHANNEL_TYPE on category and link channels only. Voice chat uses the same send / reply path as a text channel.
const channel = await client.channels.fetch(channelId);
if (!channel.isTextBased()) return;
await channel.send('hi');From a message (full Message or PartialMessage):
const channel = await message.resolveChannel();
await channel.send('hi');channel.toString() is <#id>. client.channels.delete(id) only drops the cache; API delete is channel.delete().
Reply vs send
message.reply() is a threaded reply. Use channel.send() for a standalone post in that channel.
client.on(Events.MessageCreate, async (message) => {
if (message.content === '!ping') await message.reply('Pong!');
if (message.content === '!hello') {
const channel = message.channel ?? (await message.resolveChannel());
await channel.send('Hello. Not a reply.');
}
});Skip the reply ping:
await message.reply('Got it.', { ping: false });Forward
Post a copy of an existing message into this channel. Do not combine replyTo and forward on the same send.
const dest = await client.channels.fetch(logChannelId);
if (!dest.isTextBased()) return;
await dest.send({
content: 'Forwarded from another channel:',
forward: {
channelId: message.channelId,
messageId: message.id,
guildId: message.guildId,
},
});Received forwards expose snapshots on message.messageSnapshots.
Voice text
If channel.isVoice() (or channel.isTextBased()), send works. Playing audio is a different package: Voice.
if (channel.isVoice()) {
await channel.send('Talk in the VC chat.');
}Another channel
const log = await client.channels.fetch(logChannelId);
if (!log.isTextBased()) return;
await log.send({ embeds: [embed] });message.channel is the cached text, voice, or DM channel, or null. message.member is the author's cached member.
Fetch a message
const channel = await client.channels.fetch(channelId);
if (!channel.isTextBased()) return;
const msg = await channel.messages.fetch(messageId);
await msg.edit({ content: 'Updated!' });Typing
const channel = message.channel ?? (await message.resolveChannel());
await channel.sendTyping();
await slowOperation();
await message.reply('Done!');message.send / message.sendTo / client.channels.send still exist if you only have IDs and do not want the channel object. Prefer fetch then channel.send.
See also: Embeds, File Attachments, Allowed Mentions, Channels.