How to (and is it possible to) make link markup work in a discord bot message? - discord

What I'm trying to achieve is simple:
send a message like links: [link1](https://example.com/1), [link1](https://example.com/2) via a bot
get it displayed as "links: link1, link1"
In a ephemeral follow up, it works as expected:
const content = "links: [link1](https://example.com/1), [link1](https://example.com/2)"
await interaction.followUp({
ephemeral: true,
content,
})
But when I send this to a public channel like this:
await channel.send(content)
I'm getting it as plain text (links: [link1](https://example.com/1), [link1](https://example.com/2)) except the links are clickable.
Is it possible to get the same result as in an ephemeral message?
I've checked the permissions, there's only "embed" links (which sounds like "allow links in embeds", and not "allow links in messages) and it is enabled anyway on server for everyone, for the bot and in the channel. So what am I missing here?
PS Here they say that "it's only possible if the message was sent with webhook though", but I'm not quite sure what does this mean (can this be different for a public and an ephemeral message?)

You cannot use hyper links in normal messages sent by a bot. You need to use a Webhook. Considering you're using discord.js, see this guide on their documentation. When using something like that it will work as expected
const { WebhookClient } = require('discord.js');
const webhookClient = new WebhookClient({ url: "WEBHOOK_URL" });
webhookClient.send({
content: "[Hello world](https://github.com)",
username: "Webhook Username",
});
Otherwise you may use embeds and send one of these with your bot and the content you wish to have.

Right, so I've found a solution based on suggestion by Krypton. As an embed doesn't look nice and manual creation of a webhook is not an option for me, I've found that I can create a webhook on the go and use it.
After some testing, I've figured that such webhooks are also permanent (although they can be found in another part of settings than the manually created ones); they should be deleted as there's a limit of 15 webhooks – an attempt to create more fails (with DiscordAPIError[30007]: Maximum number of webhooks reached (15)).
Instead of doing
await channel.send(content)
I've put
// a guard, TypeScript requires us to be sure
if(channel instanceof TextChannel) {
const webhook = await channel.createWebhook({
// a message from a webhook has a different sender, here we set its name,
// for instance the same as the name of our bot (likewise, we can set an avatar)
name: "MyBot",
})
await webhook.send(content)
await webhook.delete()
}
This seems to be a minimal code change to get the links working.

Related

Discordjs: Specifying channel for an interaction.reply

I am using Discordjs v13. I have created a slash command and I am able to "print" a message using
await interaction.reply(messageObj);
I need to send the reply to a different channel where the command was triggered, is this possible?
Something like:
interaction.setChannel(channelId).reply(...)
OR
interaction.reply({
channel: ....
....
})
What you want is not possible. The Discord API does not allow to specify the channel where the app interaction should be replied in: https://discord.com/developers/docs/interactions/receiving-and-responding#responding-to-an-interaction
However if you are concerned with the reply being shown to everyone, you can make the reply ephemeral. If you want to log interactions, you can reply to the interaction then send another message using the solution provided in the comments of your question.
this is actually possible in discordjs v14 and may be in v13 as well. Carl-bot does it with suggestions.but its not an actual reply
use
interaction.guild.channels.cache.get('channel-id').send('message')
this will send a message in a the select channel you may still want to
interaction.reply({Content:'replied in #channel' [embed], ephemeral: true })
so the user knows the reply was redirected . ephemeral: true makes the replay only visible to the user that evoked the interaction.
and if you need the message id for the new message use
const msg = await interaction.guild.channels.cache.get('channel-id').send('message');
to send the message and you can do something like const messageid = msg.id

Discord: Reading messages from one channel in a (non-admin perm) server, and posting it to another (with admin perms)

I am new to Discord API framework.
ServerFROM is a public server that I was invited to (non-admin perms). Hence I cannot add bots there. But I can view the content in ChannelFROM (a text channel in ServerFROM)
I have my own ServerTO (in which I have admin perms and so can do anything). Inside of which, I have the target ChannelTO
I want to deploy a listener on ChannelFROM, such when there is a new message (announcement) in ChannelFROM, I want it to be read and reposted in ChannelTO.
Something similar to what is done in this Stackoverflow issue, except that I cannot have some script run locally 24x7 on my machine. Maybe use Github Actions or something similar?
How can I go about doing it? Any ideas are appreciated. Maybe some form of a server, or just a custom Discord bot
And thanks in advance.
you can use Custom bot for that. I dont know other way
here's how i do it
1st : We Get the ID of the Channel that you wanted to listen
2nd : We make a Output or where the bot copy the message from and send it
3rd : Bot required a permission to view the channel and send message
or in the nutshell ( sorry if im bad at explaining )
client.on("messageCreate", message => {
if(message.author.bot) return;
if(message.channel.id === ID_HERE) // ChannelFROM in ID_HERE
{
let MSG = message.content
let Author = message.member.displayName
let Avatar = message.author.displayAvatarURL({dynamic: true})
const Embed = new MessageEmbed()
.setAuthor(Author , Avatar )
.setDescription(MSG)
.setColor("RANDOM")
client.channels.cache.get(ID_HERE).send({ embeds: [Embed] }) // SendTo in ID_HERE
}
})
you can remove if(message.author.bot) return; if you want it also read other bot message on that specific channel

Approval/Denial System using Discord.js

DISCORD.JS
Hey! So, recently, I was on a server that contained an amazing bot. That was an approval or denial system. So, what would happen for example, somebody would sign a google form and the google script will send the response via a webhook (I already know that code) in an embed to a private channel named "awaiting-result", now, the bot will automatically add reactions to the message, for example, ✅ and ❌. Then, a staff member will react with either one of those emojis and it will send to two different channels. If the reaction was a ✅, then the bot will remove all reactions from the original message, copy the exact embed from the google form response, and send it to a channel named "accepted-logs" with a message above it "Your log has been accepted by ${person}". If it was an ❌, it will do the exact same thing as the approved one. I have been trying hard, but cant find it. All I ready need is the bot code, not the form script. So basically, you react, copy the exact embed, send to another channel. Itll be very helpful, thanks!
List of useful links:
https://discordjs.guide/popular-topics/reactions.html#unicode-emojis
https://discordjs.guide/popular-topics/collectors.html#reaction-collectors
https://discordjs.guide/popular-topics/embeds.html#using-the-embed-constructor
I'm pretty sure you could just store the embed contents in an Object, then you can wait for the collector to collect a ✅ or ❌, check if the user has admin role (e.t.c), and then find the channel the embed needs to be sent too
let channel = client.channels.cache.find(channel => channel.name === "name");
and then you can send the embed to the channel via
channel.send(embed);
In order to make an embed, you just do:
let embed = new Discord.MessageEmbed();
And then you can add fields to it (see link #3). Then you can simply just do
let approvalChannel = client.channels.cache.find(channel => channel.name = "admin-approval");
approvalChannel.send(embed);
// Code for reaction collector

Is there anyway I can make a Discord js Bot that send an embed when a specific account in instagram posts

i just want it to send an embed or even just the link of the post when the account posts on Instagram. I tried the IFTTT website but they only let you do this for your own instagram account and i want it to do the above for another public account. Thenks.
I don't think that coding the entire project out for you would be useful, so I can give you some pointers:
For the Instagram scraping, I'd suggest using Nightmare, a high-level browser automation library. It's easy to use and quite powerful.
Here's what the start of your program should look like:
const Discord = require('discord.js');
const client = new Discord.Client();
const Nightmare = require('nightmare')
const nightmare = Nightmare({ show: true })
const accountName = 'insertaccountnamehere'
Nightmare({ show: false })
.goto(`https://www.instagram.com/${accountName}`)
// your turn
You would update some variable that keeps the newest post, check if it changed, and then send whatever you want: embed, link, so on.

How to get username from client id after the user has left the guild

I have statistics. I am downloading from the User Id database and I am replacing the ID with its name, but if the user has left the server, there is an error because there is no such user.
I have bot.users.get(id) but when a user leaves the server, an error pops up.
Can I get the username with the ID differently if the user is not on the server?
Sorry for being late, like literally. You can perform a request to get a user from Discord by a UserResolvable with Client#fetchUser(<UserResolvable>);.
In practice, the code should look like this;
const Discord = require("discord.js");
const Client = new Discord.Client();
Client.login("YoUr.nIcE.toKe.n");
Client.on("ready", function () { // Should do that when the client is ready.
const User = Client.fetchUser("123456789012345678");
console.log(User); // Some user object.
});
Hope I helped you nonetheless.
~Q
Since client.users stores only cached users, you won't be able to retrieve their username in a reliable way from there.
DISCLAIMER: This method is really inefficient, but discord.js hasn't been made for this kind of work. If you want to make it easier, just write Unknown user (client_id)
If you're not able to get the username from a user list you could try to use messages: use channel.fetchMessages() on every channel of your guild until you find a message in which message.author.id == your_id, when you find it you can get the username with message.author.username
There's also another solution: a self-bot. Keep in mind that this one is not supported by Discord itself, and could result in a permanent ban for the account you're using.
With that said, if you use a self-bot you can use the TextChannel.search() method to quickly find a message with your author id and then grab the username from the author.

Resources