So I'm using discord.js with this code here:
client.api.interactions(interaction.id, interaction.token).callback.post({
data: {
type: 4,
data: {
content: "Getting Data..."
}
}
})
I would like to be able to edit this message afterwards, but everything I have seen requireds a message id, and I seem to be unable to get the message id off of this code.
You can edit an interaction response with this patch request (See: Followup Messages):
PATCH /webhooks/<application_id>/<interaction_token>/messages/#original
Basic example using the axios library:
axios.patch(`https://discord.com/api/v8/webhooks/${appId}/${interaction.token}/messages/#original`, { content: 'New content' });
The answer to this request will also contain the message-id.
Here is an example function that will edit the original message either as plain text or an embed object and returns the discord message object for further usage (e.g. add reply emojis etc.):
const editInteraction = async (client, interaction, response) => {
// Set the data as embed if reponse is an embed object else as content
const data = typeof response === 'object' ? { embeds: [ response ] } : { content: response };
// Get the channel object by channel id:
const channel = await client.channels.resolve(interaction.channel_id);
// Edit the original interaction response:
return axios
.patch(`https://discord.com/api/v8/webhooks/${appId}/${interaction.token}/messages/#original`, data)
.then((answer) => {
// Return the message object:
return channel.messages.fetch(answer.data.id)
})
};
Also instead of sending an initial message like "getting data..." you also can send an empty response of type 5. This is the build-in method and displays a little loading animation too :) See here (One advantage is that this way no "edited" appears.)
client.api.interactions(interaction.id, interaction.token).callback.post({
data: {
type: 5,
},
})
Related
I have this code where it gets a random post from r/memes and it get's the post's title with an image attached to it(if there is one), I got this with a lot of help and I just want it to be able to read the post's description. I want to be able to read the text if there is some in the post if I want to use this on like news subreddits or something.
if (msg.content == '-meme') {
function loadMemes() {
// Fetch JSON
return (
fetch('https://www.reddit.com/r/memes.json?limit=800&?sort=hot&t=all')
.then((res) => res.json())
// Return the actual posts
.then((json) => json.data.children)
);
}
function postRandomMeme(message) {
return loadMemes().then((posts) => {
// Get a random post's title and URL
const { title, url } = posts[Math.floor(Math.random() * posts.length)].data;
// Create the embed
const embed = new Discord.RichEmbed({
title,
image: { url },
footer: { text: 'Subreddit : r/memes' },
});
// Send the embed
return message.channel.send(embed);
});
}
// Usage:
postRandomMeme(msg);
// Log all errors
//.catch(console.error);
}
There is a github repository called reddit-bot which is open source and online. you can possibly get an idea from the code provided on there.
https://github.com/lowJ/reddit-bot/blob/master/index.js
I also found this npm package specifically made to get memes and also has an open source github repository.
https://www.npmjs.com/package/#blad3mak3r/reddit-memes
I am trying to develop a bot for FB Messenger and I'm always getting stuck with their documentation. Currently, I tried to add a Greeting Text and a Get_Started button in JavaScript, so I will be able to modify it easily. It seems like most of their documentation is in PHP or they just telling you to add it by sending a POST request using CURL, which worked for me, but again, it's not so modular.
I can't find proper documentation in JavaScript. and the only one is this:
https://www.techiediaries.com/build-messenger-bot-nodejs/
But I can't find the place where you actually call the greeting or get started functions.
there is also this https://github.com/fbsamples/original-coast-clothing
but I still can't find where they trigger the Greetings and the Get_Started postbacks. Only the json file where they store it /locales/en_US.json "profile".
My code currently has
// Accepts POST requests at /webhook endpoint
app.post('/webhook', (req, res) => {
// Parse the request body from the POST
let body = req.body;
// Check the webhook event is from a Page subscription
if (body.object === 'page') {
// Iterate over each entry - there may be multiple if batched
body.entry.forEach(function(entry) {
// Get the webhook event. entry.messaging is an array, but
// will only ever contain one event, so we get index 0
let webhook_event = entry.messaging[0];
console.log(webhook_event);
// Get the sender PSID
let sender_psid = webhook_event.sender.id;
console.log('Sender PSID: ' + sender_psid);
// Check if the event is a message or postback and
// pass the event to the appropriate handler function
if (webhook_event.message) {
handleMessage(sender_psid, webhook_event.message);
} else if (webhook_event.postback) {
handlePostback(sender_psid, webhook_event.postback);
}
});
// Return a '200 OK' response to all events
res.status(200).send('EVENT_RECEIVED');
} else {
// Return a '404 Not Found' if event is not from a page subscription
res.sendStatus(404);
}
});
function setupGreetingText(res){
var messageData = {
"greeting":[
{
"locale":"default",
"text":"Greeting text for default local !"
}, {
"locale":"en_US",
"text":"Greeting text for en_US local !"
}
]};
request({
"uri": "https://graph.facebook.com/v2.6/me/messages",
"qs": { "access_token": process.env.PAGE_ACCESS_TOKEN },
"method": 'POST',
"headers": {'Content-Type': 'application/json'},
"form": messageData
},
function (error, response, body) {
if (!error && response.statusCode == 200) {
// Print out the response body
res.send(body);
} else {
// TODO: Handle errors
res.send(body);
}
});
}
but I still dont know how to trigger it.
Examples on the documentation look like this. This is how you break it down. Final result can be found below.
curl -X POST -H "Content-Type: application/json" -d '{
"get_started": {"payload": "<postback_payload>"}
}' "https://graph.facebook.com/v2.6/me/messenger_profile?access_token=<PAGE_ACCESS_TOKEN>"
Third word is the type of request you'll send and should be defined inside the method property.
Between the curly braces, is how the content inside the json property should be formatted.
The link on the last line is the link you should provide to the uri property minus the query part ?access_token=<PAGE_ACCESS_TOKEN>
SendAPI's uri is https://graph.facebook.com/v8.0/me/messages (you're using this)
MessengerProfileAPI's uri is https://graph.facebook.com/v2.6/me/messenger_profile (use this instead)
In the end, your request function should look something like this:
request(
{
"uri": "https://graph.facebook.com/v2.6/me/messenger_profile",
"qs": { "access_token": process.env.PAGE_ACCESS_TOKEN },
"method": "POST",
"json": {
"get_started": {"payload": "start"}
},
},
(err) => {
if (!err) {
console.log('request sent!');
} else {
console.error("Unable to send message:" + err);
}
}
);
Even though its been almost 3 months since this question has been asked. I hope this will still come useful.
Was struggling and frustrated as you trying to implement the examples on facebook for developers documentation but I finally got to understand it after some looking and observation at other developers webhook on github.
I might just be missing something simple, but I've never had this error before and I don't think I edited it enough to cause this problem since it was last functional. The code block below keeps giving me this error at the top of the file:
(node:17592) UnhandledPromiseRejectionWarning: TypeError: client.catch is not a function
I have specified client = new Discord.Client();
The other issue I am having is that I am trying to get the role that is being made by the bot to be the name of the two players/users (challenger vs target format) after the target has accepted the challenge posed by the challenger. It just makes a role named "new role" instead. Any help with either of these problems?
if (message.channel.id === '541736552582086656') return challenged.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...`)
var server = message.guild;
var permsName = `${target} vs ${challenger}`;
var name = `${target} vs ${challenger}`;
message.guild.createRole({
data: {
name: permsName,
hoist: true,
color: "#00fffa",
permissions: [] }
}).then(role => {
target.addRole(data, permsName)
challenger.addRole(role, permsName)
// client.catch error occurring below
.catch(error => client.catch(error))
}).catch(error => client.catch(error)).then(
server.createChannel(name, "text")).then(
(channel) => {
channel.setParent("542070913177485323")
})
} else if (reply.content === 'deny') {
reply.channel.send("You have ***denied *** the challenge.")
} else {
reply.channel.send("Your response wasn't valid.");
}
})
})
}
module.exports.help = {
name: "challenge"
}
I have tried looking up the problem and I don't see anything that has helped so far with either issue. They might be related since the catch is after the add role part? Thanks in advance for the help!
Curious if there's a template you copied for this bot? The Discord.Client object does not have any catch method, so calling client.catch() is not going to work.
To clarify, this is fine:
challenger.addRole(role, permsName)
.catch(error => /* do something with this error */);
What can you do with the error? You could print it to console, I suppose:
challenger.addRole(role, permsName)
.catch(error => console.error(error));
But you can't call client.catch(error), because that's not a real method - you can check out the docs for the Client object here.
Regarding the role name, you just have a small error: you don't want to wrap your options object in { data: }, your options object is the data. Just pass them in directly, like so:
message.guild.createRole({
name: permsName,
hoist: true,
color: "#00fffa",
permissions: []
}).then(role => {
Hope that helps!
I have set the project up as described in the blog post Twilio WhatsApp API and Flex in Minutes.
I followed the instructions and even after repeating the process twice, on two different accounts, when I send the message (through sandbox), the following error occurs:
cvc-complex-type.2.4.a: Invalid content was found starting with element 'Enqueue'. One of '{Sms, Message, Redirect}' is expected.
The task does not show in Flex.
I have tried checking what WhatsApp sends vs what is sent when SMS arrives. This is what a simple function says about trigger.message for SMS:
{
EventType=onMessageSent,
InstanceSid=IS5aa457db5a2d44049c95f2d0b2699f56,
Attributes={\"proxied\":true},
DateCreated=2019-01-16T12:37:43.664Z,
Index=3,
From=sms_g13aggbhlwpgk7tbah3llj2kyjpsvvju,
MessageSid=IM9123e909eeda41ac92890201a6c3f1b4,
Source=API,
AccountSid=ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX,
ChannelSid=CHbc79143368db4680a66c6c504103619f,
RetryCount=0,
ClientIdentity=sms_g13aggbhlwpgk7tbah3llj2kyjpsvvju,
WebhookType=studio,
To=CHbc79143368db4680a66c6c504103619f,
Body=Test Message,
ChannelAttributes={
status=ACTIVE,
forwarding=true,
serviceNumber=sms_g13aggbhlwpgk7tbah3llj2kyjpsvvju,
twilioNumber=+1228xxxxxxx,
from=+44798xxxxxxx,
channel_type=sms,
proxySession=KC1be96a19ed42aca39f9b6a9f06c26997
},
WebhookSid=WHcfc83a43a7c2424693fd0053b8b00a01
}
This is what is shows for WhatsApp message:
{
ApiVersion=2010-04-01,
SmsSid=SMb44cfdb4854c41e9ee255032a5449199,
SmsStatus=received,
SmsMessageSid=SMb44cfdb4854c41e9ee255032a5449199,
NumSegments=1,
From=whatsapp:+44798xxxxxxx,
To=whatsapp:+1228xxxxxxx,
MessageSid=SMb44cfdb4854c41e9ee255032a5449199,
Body=Test Message,
AccountSid=ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX,
NumMedia=0
}
As you can see, the ChannelAttributes and ChannelSid are missing, and this is what Flex uses.
I then tried to transform the response with a function:
exports.handler = function(context, event, callback) {
let response;
if (!event.message.ChannelAttributes) {
response = {
name: event.message.From,
channelType: 'sms',
channelSid: 'CHbc79143368db4680a66c6c504103619f'
};
}
else {
response = {
name: "WhatsApp_" + event.message.ChannelAttributes.from,
channelType: event.message.ChannelAttributes.channel_type,
channelSid: event.message.ChannelSid
};
}
const twilioResponse = new Twilio.Response();
twilioResponse.setStatusCode(200);
twilioResponse.appendHeader('Content-Type', 'application/json');
twilioResponse.setBody(response);
callback(null, twilioResponse);
};
And assign the attributes in Studio like:
{
"name":"{{widgets.MyFunction.body.name}}",
"channelType":"{{widgets.MyFunction.body.channelType}}",
"channelSid":"{{widgets.MyFunction.body.channelSid}}"
}
Unfortunately, this shows the same error.
I am using Javascript SDK for 1-1 chat in Quickblox, but somehow I am not able to store the chat history.
I am following this link.
var message = {
body: text,
type: 'chat',
extension: {
nick: chatUser.email,
// token from session is set on window object
token: window.token,
// MyChat is a custom class_name
class_name: 'MyChat'
}
};
I am passing the class_name and token since I saw the android sdk following the same pattern.
private Message createMsgWithAdditionalInfo(int userId, String body, Map<?, ?> addinfoParams){
Message message = new Message(QBChatUtils.getChatLoginFull(userId), Message.Type.chat);
String addInfo = ToStringHelper.toString(addinfoParams, "", Consts.ESCAPED_AMPERSAND);
//
MessageExtension messageExtension = new MessageExtension(Consts.QB_INFO, "");
try {
messageExtension.setValue("token", QBAuth.getBaseService().getToken());
messageExtension.setValue("class_name", "ChatMessage");
messageExtension.setValue("additional", addInfo);
} catch (BaseServiceException e) {
e.printStackTrace();
}
message.addExtension(messageExtension);
message.setBody(body);
return message;
}
Also in instructions I see this.
<message id="123" type="chat" to="291-92#chat.quickblox.com" from="292-92#chat.quickblox.com"><body>Hi there</body><quickblox xmlns=""><token>848d4bf336d99532deff6bf7c8bb4b7e7b1a71f9</token><class_name>ChatMessage</class_name></quickblox></message>
Here also I see token & class passed so I am guessing how to I structure in my message object so that I get it to work.
The way I have created chatService is this.
chatService = new QBChat(params);
// to send message I am using sendMessage function
// message object is same as defined above.
chatService.sendMessage(recipientID, message);
This is an old and deprecated method to store chat history
Look at this guide http://quickblox.com/developers/Chat#Server-side_chat_history
var msg = {
body: "Hey",
extension: {
save_to_history: 1
},
senderId: currentUser.id,
};
You have to use 'save_to_history' to store a message
You can use this branch as a basis
https://github.com/QuickBlox/quickblox-javascript-sdk/tree/develop.chat/samples/chat