Private message to user - javascript

How to make a bot be able to send a private message to a specific person? (using user ID)
no, message.author is not what I need!
I'm using discord.js and node.js

client.users.fetch('123456789').then((user) => {
user.send("My Message");
});
Dont forget replace "123456789" with the user id :D

Make sure this code is inside of an async function
// Getting the user object
const user = await <Client>.users.fetch('userID');
if (user) user.send('message').catch(error => {
// code if error occurs
});

This can be done with the User.send() method.
Here's an example of how it can be done by fetching the user
Make sure this is an async function, or the await will return an error.
const user = await <client>.users.fetch("USER ID"); // Replace <client> with your client variable (usually client or bot)
user.send("Message to send");

Related

TypeOrm: handle .save() that is called twice at the exact same time in an express API context

I have a getUser function that return a User entity after being saved into the database for caching reasons. Here is the pseudo-code for it:
export const getUser = async (userId: string): Promise<User> => {
if (userStoredInDatabase) return userStoredInDatabase // <- pseudo code
// ...if no user stored -> fetch external services to get user name, avatar, ...
const user = new User()
user.id = userId // <- PRIMARY KEY
// ...add data to the user
return getManager().save(user)
}
I use this function in 2 distinct routes of a simple expressjs API:
app.get('/users/:userId/profile', async (req, res) => {
const user = await getUser(req.params.userId)
// ...
})
app.get('/users/:userId/profile-small', async (req, res) => {
const user = await getUser(req.params.userId)
// ...
})
So far so good until I came to the problem that my frontend need to fetch /users/:userId/profile and /users/:userId/profile-small at the exact same time to show the 2 profiles. If the user is not yet cached in the database, the .save(user) will be called twice almost at the same time and I will respond for one of the 2 with an error due to an invalid sql insertion as the given user.id already exists.
I know I could just delay one of the request to make it work good enough but I'm not in the favor of this hack.
Do you have any idea how to concurrently .save() a User even if it is called at the same time from 2 different contexts so that TypeOrm knows for one of the 2 calls that user.id already exist and therefore do an update instead of an insert?
Using delay will not solve the prolm since the user can open 3 tabs at the same time. Concurency has to be handled.
Catch if there is a primary key violation (Someone already has stored the user between the get user and persist user code block)
Here is an example:
export const getUser = async (userId: string): Promise<User> => {
try {
if (userStoredInDatabase) return userStoredInDatabase // <- pseudo code
// ...if no user stored -> fetch external services to get user name, avatar, ...
const user = new User()
user.id = userId // <- PRIMARY KEY
// ...add data to the user
return getManager().save(user)
} catch (e) {
const isDuplicatePrimaryKey = //identify it is a duplicate key based on e prop,this may differ depending on the SQL Engine that you use. Debugging will help
if (isDuplicatePrimaryKey) {
return await //load user from db
}
throw e; // since e is not a duplicate primary key, the issue is somewhere else
}
}

Saving variable of a message in discord.js

i like to save my sended DM to a user in a local variable. How can I do this?
I would like to react on that message, but if I use .then() after or before the required .catch()-block, the log says "Cannot send messages to this user", without it, I can send the message..
Thank you!!
Code:
client.users.cache
.get(memb.id)
.send(emb5)
.catch((msb) => {
write("Error");
})
.then((msg) => {
msg.react(one);
});
one is the emoji...
If you are in an async function you can put the message in a variable like this:
const user = await client.users.fetch(mem.id); // Fetching the user
const awaitedMessage = await user.send(emb5); // Send the message to the user
awaitedMessage.react(one); // React the sent message

Check if user is a server member

I want to check if certain user is a server member using their ID, but when I try to check it - my bot says user is not a server member even when he clearly is!
Here is what I tried:
if(message.guild.members.cache.get('ID')) {
// ...code
}
What can I do to check it?
The member isn't cached. Always fetch a user and don't rely on the cache.
const targetMember = await message.guild.members.fetch('ID');
if (targetMember) {
// Member is in the guild
} else {
// Member is not in the guild
}

How to delete other user using Firebase functions?

As I understand, it is not possible for one user to delete another user in the firebase. From previous topic I learn that I can use firebase functions for that. Each user has a document in the cloud firebase (path: /users/userPhoneNumber/{age,height,...}). Once the document is deleted, I want to delete the user from the firebase authentication. I know how to catch a change in the cloud firebase using function (although I'm not sure how to catch a deletion), but the problem I'm having is how can I delete the user? I'm using Java for my app side and javascript for my funcations side. As I understand, the user should have the app installed on the phone in order to delete his authentication.
Since the user's Firestore document ID is the user's phone number, you can write a Cloud Function as follows, by using the Admin SDK getUserByPhoneNumber() and deleteUser() methods.
exports.deleteUser = functions.firestore
.document('users/{userPhoneNbr}')
.onDelete(async (snap, context) => {
try {
const userPhoneNbr = context.params.userPhoneNbr;
const userRecord = await admin.auth().getUserByPhoneNumber(userPhoneNbr);
await admin.auth().deleteUser(userRecord.uid);
return null;
} catch (error) {
// ....
}
});

Await reply in private message discord.js

So, this works ALMOST as intended. I have the bot private messaging the user who uses the correct command in the correct channel of the server. Instead of clogging up the server with profile creation messages, I have the bot do profile creation privately. I know/think the problem is with the message.channel.awaitMessages, because it only sees the replies in the original channel on the server where the command was put into place.
I am not sure what I should replace the message.channel.awaitMessages with in order for it to pick up on the reply in the private message conversation rather than the original profile creation channel on the server.
I have not tested the sql message yet. I haven't tested what I have but I am pretty sure it won't work. I want the reply that is given by the user in the private message to be inserted (updated maybe?) into a mysql database I have already set up and properly got working. The users ID and username has been put into this table with the rest of the profile related questions being null at this moment. As they reply to these questions, those fields can be filled out/updated. Any ideas/suggestions are welcome!
module.exports.run = async (bot, message, args) => {
if(message.channel.id === '460633878244229120') return message.author.send(`Greetings, ${message.author.username}! FIRST QUESTION, **What is the name of your Brawler or Character?**`)
.then(function(){
message.channel.awaitMessages(response => message.content, {
max: 1,
time: 5000,
errors: ['time'],
})
.then((collected) => {
message.author.send(`Your Name is: ${collected.first().content}`);
var sql = (`UPDATE profile SET name = '${message.content}' WHERE id = ${message.author.id}`);
})
.catch(function(){
message.author.send('Please submit a name for your character. To restart Profile creation, please type "!profilecreate" command in Profile Creation channel on the server.');
});
});
}
Thanks in advance for your time!
I don't use SQL so, since the question is not specifically on that, don't ask me.
When you're using message.channel.awaitMessages, message is still the first one that you passed in the module.exports.run function, not the one that comes from send(). When send is resolved, it passes a new message, that you have to include in the arguments of the function you put inside then: so, instead of .then(function() {}) you'll need something like .then(function(new_message_sent_in_private) {})
This should fix the problem:
module.exports.run = async (bot, message, args) => {
if(message.channel.id === '460633878244229120') return message.author.send(`Greetings, ${message.author.username}! FIRST QUESTION, **What is the name of your Brawler or Character?**`)
.then((newmsg) => { //Now newmsg is the message you sent
newmsg.channel.awaitMessages(response => response.content, {
max: 1,
time: 5000,
errors: ['time'],
}).then((collected) => {
newmsg.channel.send(`Your Name is: ${collected.first().content}`);
var sql = (`UPDATE profile SET name = '${message.content}' WHERE id = ${message.author.id}`);
}).catch(() => {
newmsg.channel.send('Please submit a name for your character. To restart Profile creation, please type "!profilecreate" command in Profile Creation channel on the server.');
});
});
}
Let me now if that worked :)

Categories

Resources