Sending multiple embeds in one message - node.js

How do you send multiple embeds in one message? Sending multiple like this:
await message.channel.send({embed: { //Send a new embed
title: "Embed 1",
fields: [{
name: "Description",
value: "The Description"
}]
}},
embed: { //Send a new embed
title: "Embed 2",
fields: [{
name: "Description",
value: "The Description"
}]
}});
Gives an output of:
[object Object]
Embed 2
Description: The Description
I cant find any documentation on sending multiple embeds, there is some mention of it in the discord.js file, sending a list of embeds. Though I have tried this and it also doesn't work.

It certainly is possible by using a Webhook to send your message!
Here is the documentation for the WebhookMessageOptions, as you can see the embeds option accepts an array of MessageEmbed.
Quick example:
message.channel.createWebhook('Webhook Name', message.author.displayAvatarURL)
.then(w => w.send({embeds: [
new Discord.MessageEmbed().setAuthor('Embed 1'),
new Discord.MessageEmbed().setAuthor('Embed 2'),
]}));
This works for up to 10 embeds.

Try using Richembed, it's easier to editing and the style is better.
You need to add two or how much embeds you want to send, like this:
let bot1embed = new Discord.RichEmbed()
.setAuthor("Test Bot")
.setThumbnail(client.user.displayAvatarURL)
.setColor("#00ff00")
.addField("Hello!", "Hello World")
.addField("I'm an bot", "I'm a bot");
message.channel.send(bot1embed);
let bot2embed = new Discord.RichEmbed()
.setAuthor("Test Bot")
.setThumbnail(client.user.displayAvatarURL)
.setColor("#00ff00")
.addField("Hello!", "Hello World")
.addField("I'm an bot", "I'm a bot");
message.channel.send(bot2embed);
This way the bot will send two embeds when someone used the command.

Related

How to make a welcome message then storing it to json or database

So I was wondering how to make a welcome command.
When using /welcome (text you want to display on users join). I want to store that text in json or database so every guild would have their welcome message.
you can compose your message like that in json :
"guild"{
"000000000000000001": //guild id here
{
"content": "your message here"
},
"000000000000000001":
{
"embeds": [
{
"title": "an embed",
"description": "with description"
}
]
}
}
after that in your bot code you can do that
const welcomeMessage = require('myjson');
and when you need to display your welcome message you juste need to acces at your json like that
chanToSend.send(welcomeMessage.myserveurid);
for json editing thing I send you into this question here

How to do Autocomplete text suggestion in message box in BOT

I created a BOT with LUIS and node.js and also published in Skype Channel.
Now I wants to add Autocomplete text suggestion in message box.
Am unable to find documentation for node.js
Please assist me.
Autcomplete can be accomplished with a few different NPM packages. Here's one as an example that looks not too bad to implement: https://www.npmjs.com/package/autocompleter
Code example:
var countries = [
{ label: 'United Kingdom', value: 'UK' },
{ label: 'United States', value: 'US' }
];
autocomplete({
input: document.getElementById("country"),
fetch: function(text, update) {
text = text.toLowerCase();
// you can also use AJAX requests instead of preloaded data
var suggestions = countries.filter(n => n.label.toLowerCase().startsWith(text))
update(suggestions);
},
onSelect: function(item) {
alert(item.value); // will display 'US' or 'UK'
}
});
You'll obviously have to adapt this to your needs and exact use case, but should be easy enough to implement.

Actions on Google - handling carousel responses from dialogflow

I've created a simple Google Assistant interface using DialogFlow with several Carousels that I want to be able to chain together. Whenever I touch a carousel option though, it always goes to the first Intent that has the actions_intent_OPTION event specified. I can get to all of my screens using voice commands, but I'm not sure how to process the touch commands to send the user to right Intent.
Current code in webhook:
const party = 'party';
const cocktail = 'cocktail';
const SELECTED_ITEM_RESPONSES = {
[party]: 'You selected party',
[cocktail]: 'You selected cocktail',
};
function carousel(agent) {
//agent.add(`Item selected`);
app.intent('actions.intent.OPTION', (conv, params, option) => {
let response = 'You did not select any item from the list or carousel';
if (option && SELECTED_ITEM_RESPONSES.hasOwnProperty(option)) {
response = SELECTED_ITEM_RESPONSES[option];
} else {
response = 'You selected an unknown item from the list or carousel';
}
conv.ask(response);
});
}
If I leave the agent.add() line in, then I get "Item selected"... but if I try to use the app.intent code, it says I'm just getting an empty speech response.
I was trying to create 1 intent called CarouselHandler to process all the menu selections. I used the sample code to call the carousel() function when that intent gets hit by the event.
let intentMap = new Map();
intentMap.set('Default Welcome Intent', welcome);
intentMap.set('Default Fallback Intent', fallback);
intentMap.set('CarouselHandler', carousel);
agent.handleRequest(intentMap);
You have several questions in here about using options. Let's try to clear a few things up.
Can I get a different Intent triggered for each option?
No. The way options are reported to Dialogflow is that all options will trigger the same Intent. You're responsible for looking at the option string sent and calling another function if you wish.
As you've noted, you need to create an Intent with the Event actions_intent_OPTION.
Your code to handle this might look something like this, although there are other ways to handle it:
app.intent('list.reply.click', (conv, params, option) => {
// Get the user's selection
// Compare the user's selections to each of the item's keys
if (!option) {
conv.ask('You did not select any item from the list or carousel');
} else if (option === 'OPTION_1') {
handleOption1( conv );
} else if (option === 'OPTION_2') {
handleOption2Or3( conv );
} else if (option === 'OPTION_3') {
handleOption2Or3( conv );
} else {
conv.ask('You selected an unknown item from the list, or carousel');
}
});
Can I get a different Intent triggered for each carousel?
Yes. To do this, when you send the carousel you will set an OutgoingContext and delete any other OutgoingContexts you created for a carousel (set their lifespan to 0). Then you will create an Intent that has this Context as an IncomingContext.
The code to send a carousel might look something like this if you're using the actions-on-google library
conv.ask("Here is menu 2");
conv.ask(new List({
title: "Menu 2",
items: {
"OPTION_1": {
title: "Option 1",
description: "Description 1"
},
"OPTION_2": {
title: "Option 2",
description: "Description 2"
},
"OPTION_3": {
title: "Option 3",
description: "Description 3"
},
}
});
conv.contexts.set("menu_2",99);
conv.contexts.delete("menu_1");
conv.contexts.delete("menu_3");
// Don't forget to add suggestions, too
If you're using the dialogflow-fulfillment library, it would be similar, although there are a few differences:
let conv = agent.conv();
conv.ask("Here is menu 2");
conv.ask(new List({
title: "Menu 2",
items: {
"OPTION_1": {
title: "Option 1",
description: "Description 1"
},
"OPTION_2": {
title: "Option 2",
description: "Description 2"
},
"OPTION_3": {
title: "Option 3",
description: "Description 3"
},
}
});
agent.add(conv);
agent.setContext({name:"menu_1", lifespan:0});
agent.setContext({name:"menu_2", lifespan:99});
agent.setContext({name:"menu_3", lifespan:0});
If you were using multivocal, the response configuration might look something like this:
{
Template: {
Text: "Here is menu 2",
Option: {
Type: "carousel",
Title: "Menu 2",
Items: [
{
Title: "Option 1",
Body: "Description 1"
},
{
Title: "Option 2",
Body: "Description 2"
},
{
Title: "Option 3",
Body: "Description 3"
}
]
}
},
Context: [
{
name: "menu_1",
lifetime: 0
},
{
name: "menu_2",
lifetime: 99
},
{
name: "menu_3",
lifetime: 0
}
]
}
The Intent that would capture this option suggestion might look something like this:
Your code to handle this would be similar as above, except using the different Intent name.
If there are overlapping options between the handlers, they could call the same function that actually does the work (again, as illustrated above).
How can I handle voice and option responses the same way?
AoG, in some cases, will use the voice response to trigger the option. This is what the aliases are for. But even beyond this, if you have Intents that catch phrases from the user and an Intent that works with the Options, all you need to do is have the fulfillment code call the same function.
Why doesn't the code work?
The line
app.intent('actions.intent.OPTION', (conv, params, option) => {
Probably doesn't do what you think it does. Unless this is the name for the Intent in Dialogflow, the string actions.intent.OPTION won't be seen in your handler. It is also how you register an Intent handler with the actions-on-google library.
It also looks like you're mixing the dialogflow-fulfillment library way of registering Intent handlers with the actions-on-google library way of registering Intent handlers through your carousel() function. Don't do this. (This may also be part of the cause about why replies aren't getting back correctly.)

Container Builder Slack Notifications

we're testing out CB and part of our requirements is sending messages to Slack.
This tutorial works great, but it'd be helpful if we could specify the source of the build, so we don't have to click in to the message to see what repo/trigger failed/succeeded.
Is there a variable we can pass to the cloud function in the tutorial? I couldn't find helpful documentation.
Ideally, it would be great if CB had an integration/slack GUI that made these options configurable but c'est la vie.
You can add source information to the slack message by adding a new item to the fields list within the createSlackMessage function. You need to make sure title and value are strings.
// createSlackMessage create a message from a build object.
const createSlackMessage = (build) => {
let message = {
text: `Build \`${build.id}\``,
mrkdwn: true,
attachments: [
{
title: 'Build logs',
title_link: build.logUrl,
fields: [{
title: 'Status',
value: build.status
},{
title: 'Source',
value: JSON.stringify(build.source, null, 2)
}]
}
]
};
return message
}
You can find more information on build object here.

Telegram callback_data for link buttons

I'm sending a link button throught a Telegram bot and I would like to get the callback_data after the user opens the url.
My options are:
var options = {
parse_mode: "Markdown",
reply_markup: {
inline_keyboard: btns
}
};
where btns is
[
[{ text: "Read first", url: "http://any", callback_data: "any_relevant_data }]
]
The button shows perfectly, the link works, but no callback is triggered and I never hit
bot.on('callback_query', (callback_message) => { //any action });
Is this a missing feature or it's me, doing something wrong?
According to API Document, you can't use url and text in the same time.
This object represents one button of an inline keyboard.
You must use exactly one of the optional fields.

Resources