How to fetch discord member list - javascript

I'm trying to fetch the member list of a discord server. The Discord bot is inside the server and has admin permission. I'm referring to this part of the documentation Discord Docs.
const response = await fetch(`https://discord.com/api/guilds/685509789178003502/members`, {
headers: {
Authorization: `Bot ${botToken}`
}
})
var currentUser = await response.json()
This is the response I'm getting
{"message":"Missing Access","code":50001}
I checked it like a million times and the bot has admin perms 100%.

Enable Members Intent
Further Reading: https://gist.github.com/advaith1/e69bcc1cdd6d0087322734451f15aa2f

Related

How to create a function to send messages

I have a node.js app that I have created a discord bot to interact with. I would like it so that if a particular event happens with my node.js app that it will send a message to a particular channel in my discord server.
This is my first time using discord.js. However, my thought was to create a function that I can call to send my messages. However, it would seem that I need to wait for my client to be ready first.
Alternatively, would I just have to instantiate a new client every time I want to send a message and wait for it to come available before I send the message I want?
I feel like there has to be a better way... Is there a clean way that I can set up this basic discord bot that I can just call a function to send a message from anywhere within my app?
Here is the code that I have now:
import { Client, Events, GatewayIntentBits } from "discord.js";
import { botToken, CHANNEL_ID } from "../../config.js";
const client = new Client({ intents: [GatewayIntentBits.Guilds] }); // Create a new client instance
// When the client is ready, run this code (only once)
// We use 'c' for the event parameter to keep it separate from the already defined 'client'
client.once(Events.ClientReady, c => {
console.log(`Ready! Logged in as ${c.user.tag}`);
client.channels.cache.get(CHANNEL_ID).send("Hello!");
});
// Log in to Discord with your client's token
client.login(botToken);
"I would like it so that if a particular event happens with my node.js app that it will send a message to a particular channel in my discord server."
It sounds like you're looking for webhooks. Webhooks are a way for an external source, such as your Node.js app, to send messages to a Discord channel without having to log in as a bot. Instead of using a Discord bot, you can use a webhook to send messages to a channel as if they were posted by a bot.
Using a webhook is simple; you just need to make an HTTP POST request to a URL provided by Discord, with the message you want to send in the body of the request. Discord will then post that message to the specified channel.
This is useful in cases where you want to receive notifications from your app in a Discord channel, or simply want to send messages to a channel without having to log in as a bot. It's a clean and efficient way to integrate your app with Discord.
Here is an example of a sendMessage function. It takes two arguments, payload and webhookUrl. If the payload is not a string, it is assumed to be an object that conforms to the Discord webhook format and will be used as is.
function sendMessage(payload, webhookUrl) {
const data = typeof payload === 'string' ? { content: payload } : payload;
return new Promise((resolve, reject) => {
fetch(webhookUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
})
.then((response) => {
if (!response.ok) {
reject(new Error(`Could not send message: ${response.status}`));
}
resolve();
})
.catch((error) => {
console.error(error);
reject(error);
});
});
}
If you're using node.js v18+, you can use the built-in fetch, if not, you'll need to install a library like node-fetch, axios, or something else.
Here is an example how you could use it:
// send a simple message
sendMessage('Hello from my app!', WEBHOOK_URL).catch((error) =>
console.error(error),
);
// send a message, but change the username and the avatar
sendMessage(
{
content: 'Hello from my app!',
avatar_url: 'https://i.imgur.com/KEungv8.png',
username: 'Test Hook',
},
WEBHOOK_URL,
).catch((error) => console.error(error));
// send an embed and change the user again
sendMessage(
{
avatar_url: 'https://i.imgur.com/ofPowdD.png',
username: 'Cattian Hook',
embeds: [
{
title: 'Cats, cats, cats',
color: 0xe7d747,
thumbnail: {
url: 'https://i.imgur.com/2bvab7y.jpeg',
},
},
],
},
WEBHOOK_URL,
).catch((error) => console.error(error));
And here is the result:
If you're already using discord.js, you can use the WebhookClient:
import { WebhookClient } from 'discord.js';
const webhookClient = new WebhookClient({
url: WEBHOOK_URL,
});
webhookClient.send({
content: 'Discord.js webhook test',
username: 'DJS Webhook',
avatarURL: 'https://i.imgur.com/KEungv8.png',
});
To create a webhook, you'll need to go to your discord server settings and click on APPS => Integrations. Then click on the Create Webhook button. There you can select the channel where you want the messages to be sent.
Once the webhook is created, you can click the Copy webhook URL button and use that URL.

How to fetch discord.js bot informations like bot username or bot id without login in it and using token

All i want is to get simple discord bot informations using token, but i dont want to make bot online.
I tried using discord API and it doesnt work for me but discord.js client it works but makes bot online and i dont want it.
This code will login to discord, get the bot's info, then logout.
const { Client } = require('discord.js'),
const client = new Client();
client.on('ready', async () => {
console.log(client) // or client.user if you just want client user info
client.destroy() // logs out of Discord
})
client.login('...')
You can set the status of the bot to invisible by using <client>.setStatus().
Full example:
const Discord = require('discord.js'); // Define Discord
const client = new client(); // Define client
client.login('your-token-here'); // Login your Discord bot
client.once('ready', function() { // When the client is ready
client.setStatus('invisible'); // Makes the bot look offline
});

How to send private messages in slack channel?

I am currently sending a message to the slack channel using below function. But I want to send a private message which should be visible to selected member of the slack channel.
How can I do that ?
async function sendSlackMessage() {
const url = 'https://slack.com/api/chat.postMessage';
const inputBody = {
channel: "Slack_Channel_ID",
text: `Hey Welcome to the slack`,
};
const slackHeaders = {
'Content-Type': 'application/json;charset=utf-8',
'Authorization': 'Slack_Token',
};
const slackRes = await axios.post(url, inputBody, { headers: slackHeaders });
console.log(slackRes)
}
sendSlackMessage()
Solution using Boltjs for Javascript:
To send a private message visible only to a specific user on a channel on Slack, we may use a different method chat.postEphemeral from Bolt for JavaScript. Using the above method you can send an ephemeral message to a users in a channel that is visible only to a specific user that you can choose to display.
Note: I have offered my solution as simple blocks, you need to encapsulate it within the function you need this feature to operate on.
Requirements:
For using the chat.postEphemeral you are required to send the following arguments to work.
token: Slack_Bot_Token {Authentication token bearing required scopes. Tokens should be passed as an HTTP Authorization header or alternatively, as a POST parameter.}
channel: {Channel, private group, or IM channel to send message to. Can be an encoded ID, or a name}
user: {id of the user who will receive the ephemeral message. The user should be in the channel specified by the channel argument.}
text: "Anything you need here"
blocks: "Pack and Send from Block Kit Message Builder, not necessary though"
Note:
extract the channel id from the function or pass it as args to the async function
extract the user id from the function or pass it as args to the async function
text field is not enforced when blocks are used.
Methods Access: app.client.
chat.postEphemeral
Required Scopes in Slack App:
Bot Tokens
User Tokens
Example Code:
// Building the args object from body (Can also use, action, context, and few other slack parameters from Bolt API for js)
const args = {
user: body.user.id,
channel: body.container.channel_id,
team: body.user.team_id,
token: body.user.id,
trigger: body.trigger_id,
url: body.response_url,
};
Slack App Code:
try {
// Call the chat.postEphemeral method using the WebClient
const result = await client.chat.postEphemeral({
channel: channelId,
user: userId,
token: userToken,
text: "Shhhh only you can see this :shushing_face:"
});
console.log(result);
}
catch (error) {
console.error(error);
}
Documentation:
View this documentation for more Information: Slack API for Methods
Check here to Create Message Block Kits for Slack: Slack Block Kit Builder

How to use node.js to create a new chat message in an existing channel in Teams with application permissions

I am trying to create a new chat message in an existing channel in Teams using node.js. My application needs to send messages to this channel to notify members of the channel that something has happened with my app and allow replies, etc.
It looks like Microsoft has limited this functionality to the migration permission, based on this document note.
Note: Application permissions are only supported for migration. In the future, Microsoft may require you or your customers to pay additional fees based on the amount of data imported.
Since I am not trying to migrate data from another service, and instead trying to create a new chat in the channel, am I out of luck?
Is there any way to create a new chat message in a channel using application permissions vs. signed in user permissions?
I am getting this error:
{
error: {
code: 'Unauthorized',
message: 'Unauthorized',
innerError: {
date: '2021-05-15T01:07:08',
'request-id': '<my request-id>',
'client-request-id': '<my client-request-id>'
}
}
}
This is my code:
let res = await fetch(`https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/token`, {
method: 'post',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body: `client_id=${clientId}&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default&client_secret=${clientSecret}&grant_type=client_credentials`
})
let token = await res.json()
let teamsId = '<teamsId>'
let teamsChannelId = '19%<teamsChannelId>#thread.tacv2'
const chatMessage = {
body: {
content: 'Hello World'
}
};
let sendChat = await fetch(`https://graph.microsoft.com/v1.0/teams/${teamsId}/channels/${teamsChannelId}/messages`, {
method: 'post',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + token.access_token
},
body: JSON.stringify(chatMessage)
})
let chatRes = await sendChat.json()
console.log(chatRes)
If you just create a new chat message in the channel, it's not supported to use application permissions. As the document says, "Application permissions are only supported for migration.". And you can see the supported permission is Teamwork.Migrate.All, which is used to manage migration to Microsoft Teams.
It's recommended for you to use authorization code flow with the delegated permission(ChannelMessage.Send). You could also get access token directly with username and password using ropc flow, but it carries risks, you could use it just for test.
// Request an authorization code
https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize?
client_id=<client_id>
&response_type=code
&redirect_uri=<redirect_uri>
&response_mode=query
&scope=https://graph.microsoft.com/ChannelMessage.Send
&state=12345
// Request an access token with a client_secret
POST https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token
Content-Type: application/x-www-form-urlencoded
client_id=<client_id>
&scope=https://graph.microsoft.com/ChannelMessage.Send
&code=<authorization code from previous step>
&redirect_uri=<redirect_uri>
&grant_type=authorization_code
&code_verifier=ThisIsntRandomButItNeedsToBe43CharactersLong
&client_secret=<client_secret>
Note: you need to add ChannelMessage.Send permission in API permissions first.
Sample of node js using the auth code flow: https://learn.microsoft.com/en-us/azure/active-directory/develop/quickstart-v2-nodejs-webapp-msal

Discord: Get User by Id

I'm trying to create a web application to manage the users of my Discord server. In my database, I have stored only the users' ids.
I tried to use the discord.js API, but from what I've understood it requires a discord bot to do that. That's not what I want. I would like to retrieve the user's information from my frontend, even by calling a backend function, but without having a discord bot which is always online. In other words, I need something simpler.
I would like to request users' information by using only the id. Which is the best way to do that in JavaScript?
You can use the Discord API.
First, create a Discord application here. Once you've done that, click 'Bot' on the sidebar and create a bot for that application. There, you'll see a section called 'Token' under the bot username. Copy this and store it somewhere secure. It is important to never share your token. If you do, you should regenerate it to prevent abuse.
You can then use the Get User endpoint (/users/{user.id}/) to retrieve the user for an ID. This should be done by the backend as it involves authenticating with the bot token.
Using the API directly
Here is a minimal example of how you would fetch a user by their ID using the Discord API using Node.js:
const fetch = require('node-fetch')
// You might want to store this in an environment variable or something
const token = 'YOUR_TOKEN'
const fetchUser = async id => {
const response = await fetch(`https://discord.com/api/v9/users/${id}`, {
headers: {
Authorization: `Bot ${token}`
}
})
if (!response.ok) throw new Error(`Error status code: ${response.status}`)
return JSON.parse(await response.json())
}
The response would be something like this:
{
"id": "123456789012345678",
"username": "some username",
"avatar": null,
"discriminator": "1234",
"public_flags": 0,
"banner": null,
"banner_color": null,
"accent_color": null
}
Using a library
Alternatively, you may be able to use a Discord library to do this instead. The following examples also handle rate limits.
#discordjs/rest + discord-api-types
const {REST} = require('#discordjs/rest')
const {Routes} = require('discord-api-types/v9')
const token = 'YOUR_TOKEN'
const rest = new REST().setToken(token)
const fetchUser = async id => rest.get(Routes.user(id))
The result would be the same JSON as described above.
For TypeScript users:
import type {RESTGetAPIUserResult, Snowflake} from 'discord-api-types/v9'
const fetchUser = async (id: Snowflake): Promise<RESTGetAPIUserResult> =>
rest.get(Routes.user(id)) as Promise<RESTGetAPIUserResult>
discord.js
When I first posted this answer, #discordjs/rest didn't exist yet.
const {Client} = require('discord.js')
const token = 'YOUR_TOKEN'
const client = new Client({intents: []})
client.token = token
const fetchUser = async id => client.users.fetch(id)
The result of fetchUser would be a discord.js User object.
Something you can do is
let user = message.guild.cache.get('id');
(modified by #cherryblossom)

Categories

Resources