issue with creating role and channel automatically from private message with bot - node.js

Not sure how the create channel and create role isn't working inside the following code, towards the bottom. (EDIT: Nothing is sent to the console and nothing happens regardng the code. It is like it is entirely ignored.) This is a snippet from code that User A challenges User B. User B is messaged, alerting them that a challenge has been issued to them via a Private Message. If the challenge is accepted, I want the bot to 1)Make a role specifically for User A and User B named "User A vs User B" 2) take User A and User B and put them both into that new role and 3) Make a battlefield named "User A vs User B" inside a specific category inside the server the bot is on.
I am unsure if the problem lies in how the bot is trying to make the role and channel in a sever while the bot is talking to the user in a private message instead of on the server. I thought putting the "server" variable as the server ID would help but it doesn't seem to do anything after the accept message.
// Awaits reply from user
if (message.channel.id === '541736552582086656') return target.send("Do you accept the challenge? Please reply with 'accept' or 'deny'.")
.then((newmsg) => {
newmsg.channel.awaitMessages(response => response.content, {
max: 1,
time: 150000,
errors: ['time'],
}).then((collected) => {
// Grabs the first (and only) message from the collection.
const reply = collected.first();
if (reply.content === 'accept'){
reply.channel.send(`You have ***accepted *** the challenge from ${challenger}. Please wait while your battlefield is made...`);
message.author.send(`${target} has accepted your challenge! Please wait while the channel is made for your brawl...`)
/// Problems start here
function createChannel(message){
var server = "SERVER ID";
var name = `${target} vs ${challenger}`;
message.guild.createRole({
role: {
name: `${target} vs ${challenger}`,
color: "#00fffa",
permissions: [] }
}).then(role => {
target.addRole(role, name)
challenger.addRole(role, name)
.catch(error => client.catch(error))
}).catch(error => client.catch(error))
server.createChannel(Name, name).then(
(channel) => {
channel.setParent("CATEGORY ID")
})
} // problems end here
} else if (reply.content === 'deny') {
reply.channel.send("You have ***denied *** the challenge.")
} else {
reply.channel.send("Your response wasn't valid.");
}
})
})
}
I have been wondering if I need to go about making the channel and role in a different way since it is trying to be made from a private message and not inside the server..
Thanks for any and all help! I also apologize if I'm using stack overflow too much for problems like this... You guys are great at helping me see different ways to do things and what I'm doing wrong, so I am learning, but I don't want to feel like I'm abusing it too much.

I think the problem is the fact that you create a function called createChannel with the code to create a rol and channel, but you never call said function.
You can either call the function after you've declared it or (which is in my opinion better) you can remove the following lines
function createChannel(message){
} // problems end here

Related

Using the Twilio API, how can I check if a number is in use by a service?

I am trying to create a new messaging service using the Node.js twilio sdk. To do so, I have devised the following workflow.
I've created a new service like so.
client.messaging.v1.services.create({
friendlyName: 'test service,
inboundRequestUrl: 'https://someUrl.com',
inboundMethod: 'POST',
usecase: 'discussion'
})
I list all the numbers I own like so:
client.incomingPhoneNumbers.list()
I assign a number to my service like so (where the serviceSid is the sid of the service created in step 1 and the phoneNumberSid is the sid of one of phone numbers returned in step 2):
client.messaging.v1.services(<serviceSid>)
.phoneNumbers
.create({ phoneNumberSid: <phoneNumberSid> })
I am happy with this workflow, with the exception of one problem. You cannot assign the same number to two different messaging services, so I need to make sure the phone number whose sid I pass into step 3, doesn't already have a service. The problem is that the response I get back from step 2 doesn't tell me whether the numbers are used by another service.
All of this to say, can anyone suggest some way to modify this workflow to be more robust? Ideally, is there some way I can tell from step 2 whether or not a number is already being used by a service, so I know not to pass it in to step 3?
Thanks
Yes, there is a way to do this. To be honest, it's not very nice, but you can iterate over all messages services and test if your phone number (SID) belongs to a mapping of one of the services and then remove this mapping. Once removed, you can assign the phone number to any other messaging service.
async function unbindPhoneFromMessagingServices(phoneNumberSid) {
const allServices = await client.messaging.v1.services.list();
await Promise.all(
allServices.map(async (service) => {
const mapping = client.messaging.v1
.services(service.sid)
.phoneNumbers(phoneNumberSid);
try {
await mapping.fetch();
} catch (e) {
const RESOURCE_NOT_FOUND = e.code === 20404;
if (RESOURCE_NOT_FOUND) {
return;
}
throw e;
}
await mapping.remove();
console.log(
`The phone number was decoupled from messaging service ${service.sid}.`
);
})
);
}
PS: This snippet is taken from one of my repositories. Feel free to check out the complete code on GitHub.

Discord.js SetNickname Function Is Not Working

I am trying to make a bot that gives a role and sets nickname of it's user.
My goal is if someone types " -verify SomeNickname " on the text channel the bot will set their nickname as SomeNickname and give them a certain role.
mem.AddRole is working without any errors but .setNickname function is not working with anything.
The error is TypeError: mem.setNickname is not a function
This duplicate thread did not work for me: Change user nickname with discord.js
I also tried:
message.member.setNickname & message.author.setNickname &
client.on('message', message => {
if (message.content.startsWith('-verify')) {
message.author.setNickname({
nick: message.content.replace('-verify ', '')
});
}
});
so far.
My code is:
module.exports = bot => bot.registerCommand('verify', (message, args) => {
message.delete();
var title = args.join(' ');
var mem = message.member;
mem.addRole('560564037583241227').catch(console.error);
mem.setNickname(title);
}
The bot is giving the role without any problems but its not setting a nickname to the user.
Additional Info: Bot has every permission and im not trying to change server owner's nickname.
The message.member object looks like this:
As determined through the chat, your current code is using discord.io, not discord.js. These libraries are different, so that's the source of your various issues.
I'd recommend using discord.js from now on, but you may have to restructure your code a little bit. Documentation can be found here for future reference.
If you'd like to continue using discord.io, you can edit your question to be clearer, although from our conversation you don't intend to.

Private messaging a user

I am currently using the discord.js library and node.js to make a discord bot with one function - private messaging people.
I would like it so that when a user says something like "/talkto #bob#2301" in a channel, the bot PMs #bob#2301 with a message.
So what I would like to know is... how do I make the bot message a specific user (all I know currently is how to message the author of '/talkto'), and how do I make it so that the bot can find the user it needs to message within the command. (So that /talkto #ryan messages ryan, and /talkto #daniel messages daniel, etc.)
My current (incorrect code) is this:
client.on('message', (message) => {
if(message.content == '/talkto') {
if(messagementions.users) { //It needs to find a user mention in the message
message.author.send('Hello!'); //It needs to send this message to the mentioned user
}
}
I've read the documentation but I find it hard to understand, I would appreciate any help!
The send method can be found in a User object.. hence why you can use message.author.send... message.author refers to the user object of the person sending the message. All you need to do is instead, send to the specified user. Also, using if(message.content == "/talkto") means that its only going to run IF the whole message is /talkto. Meaning, you can't have /talkto #me. Use message.content.startsWith().
client.on('message', (message) => {
if(message.content.startsWith("/talkto")) {
let messageToSend = message.content.split(" ").slice(2).join(" ");
let userToSend = message.mentions.users.first();
//sending the message
userToSend.send(messagToSend);
}
}
Example use:
/talkto #wright Hello there this is a dm!

newbie node.js bot integration with database lookup (looking for best practice)

OK, new to Node.js and botframework. I built first bot using Azure site and downloaded the code. Chose the Luis integrated bot template.
I understand (finally) the event driven model of node.js and the concept of callbacks.
I have the code snippet below. When Luis finds an intent of "Help" it triggers this function. In turn, I have database calls to lookup the entity. Within the database I have an entity, response (if entity is bottle, answer "Recycle").
I have that code working too.
Below the first block is a function handleHelpRequester which is the callback function, I have that working as well. Where I am a little stuck (best practice) is that in this callback function I want to send something to the session object (session.send toward the bottom of the function).
Since I don't create the session object (directly) I'm not sure on the options.
Should I pass the session object to the database function, then pass it back?
Should I create a global variable and set it to the session object (I'm concerned that if multiple people are using this bot then this approach won't work).
I'm open for suggestions.
Thanks
.matches('Help', (session, args) => {
var entities = args.entities;
var itype = builder.EntityRecognizer.findEntity(args.entities, 'ItemTypes');
var respondToUser = '';
var msg = 'Initialized';
// if there is an entity provided, perform a lookup of the entity.
if (itype.entity !== null) {
//Use session.sendTyping so the user thinks something is happening rather than being ignored while we do the lookup in SharePoint.
session.sendTyping();
//perform lookup
respondToUser = sp.lookupEntity(itype.entity, handleHelpRequest);
};
})
function handleHelpRequest(err, respondToUser) {
var msg = 'uninitialized';
if (err = 'success') {
console.log('Respond to user from matches:'.concat(respondToUser));
//return from lookup
if (respondToUser === 'No match found') {
msg = 'I think you are asking for help, but I don\'t understand what you need help with.';
}
else {
msg = 'I can help you with that, \'%s\'.', respondToUser;
}
console.log(msg);
session.send(msg);
//The following two lines are for debugging
session.send('How may I assist you? ' + JSON.stringify(args));
session.send('Value of entity you said: \'%s\'.', itype.entity);
}
else {
console.log('an error occurred');
}
}
If you want to have access to the session object, then pass it as a parameter to your helper function.
Example:
function handleHelpRequest(session, err, respondToUser) {
// do session stuff
}

Facebook Messenger Bot, can someone tell me how i catch the answer of a something i asked

So i working on my Facebook Messenger Bot.
I want to know ho can i catch a answer for a question like
Bot: Enter your E-mail
User: enters e-mail
Bot: adress was added
My code looks like the sample app from Facebook
app.post('/webhook', function (req, res) {
var data = req.body;
// Make sure this is a page subscription
if (data.object == 'page') {
// Iterate over each entry
// There may be multiple if batched
data.entry.forEach(function(pageEntry) {
var pageID = pageEntry.id;
var timeOfEvent = pageEntry.time;
// Iterate over each messaging event
pageEntry.messaging.forEach(function(messagingEvent) {
if (messagingEvent.optin) {
receivedAuthentication(messagingEvent);
} else if (messagingEvent.message) {
receivedMessage(messagingEvent);
} else if (messagingEvent.delivery) {
receivedDeliveryConfirmation(messagingEvent);
} else if (messagingEvent.postback) {
receivedPostback(messagingEvent);
} else {
console.log("Webhook received unknown messagingEvent: ", messagingEvent);
}
});
});
// Assume all went well.
//
// You must send back a 200, within 20 seconds, to let us know you've
// successfully received the callback. Otherwise, the request will time out.
res.sendStatus(200);
}
});
You can set a flag for their ID that the E-Mail prompt was sent, and then after they respond check to see if it's an E-mail, and if so, then save it and echo it back to them.
If the bot is based on question/answer, what I normally do to handle response tracking is treat the bot like a finite state automata. Assign every "state" your bot can be in to some unique state identifier, and use said state identifier to determine what the user is replying to. You could also store callbacks instead of state ids, but high level this will behave the same way.
For Example:
First define a finite automata. In this case, lets assume it's:
0 --> 1 --> 2
Where 0 means new user, 1 means waiting for email response, 2 means user successfully completed registration.
User messages bot
We check our database and see it's a new user. We assume
state==0.
Because state is 0, we ignore what was sent and prompt for email
Change state to 1 to denote the email was prompted.
User replies with email.
We check database and see state==1. We use the "1" routine to do fancy stuff to verify the email and store it.
Change state to 2 to denote the email was received and the program has ended.
Note:
If the conversation id for the platform you're targeting is reset
after a certain amount of inactivity (or if you just want the bot to
mimic real conversations), store the time of each user's last
interaction and purge all inactive conversations well after the
conversation has been terminated.

Resources