Here is a sample code of it
my Intent is this https://imgur.com/a/9nG3MVD
Does anyone have an idea as to why the Alexa Simulator Test doesn't trigger my custom intent?
const MyCustomHandler = {
canHandle(handlerInput) {
return Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest'
&& Alexa.getIntentName(handlerInput.requestEnvelope) === 'MyCustomIntent';
},
handle(handlerInput) {
let speakOutput = 'Place Call Intent';
return handlerInput.responseBuilder
.speak(speakOutput)
.getResponse();
}
};
/**
* This handler acts as the entry point for your skill, routing all request and response
* payloads to the handlers above. Make sure any new handlers or interceptors you've
* defined are included below. The order matters - they're processed top to bottom
* */
exports.handler = Alexa.SkillBuilders.custom()
.addRequestHandlers(
LaunchRequestHandler,
MyCustomHandler,
HelpIntentHandler,
CancelAndStopIntentHandler,
FallbackIntentHandler,
SessionEndedRequestHandler,
IntentReflectorHandler,
).addErrorHandlers(
ErrorHandler
).lambda();
Related
I have a raw event:
this.on('raw', packet => {
if (!['MESSAGE_REACTION_ADD', 'MESSAGE_REACTION_REMOVE'].includes(packet.t)) return;
const channel = this.channels.cache.get(packet.d.channel_id);
if (channel.messages.cache.has(packet.d.message_id)) return;
channel.messages.fetch(packet.d.message_id).then(message => {
const emoji = packet.d.emoji.id ? `${packet.d.emoji.name}:${packet.d.emoji.id}` : packet.d.emoji.name;
const reaction = message.reactions.cache.get(emoji);
if (reaction) reaction.users.cache.set(packet.d.user_id, this.users.cache.get(packet.d.user_id));
if (packet.t === 'MESSAGE_REACTION_ADD') {
this.emit('messageReactionAdd', reaction, this.users.cache.get(packet.d.user_id));
}
if (packet.t === 'MESSAGE_REACTION_REMOVE') {
this.emit('messageReactionRemove', reaction, this.users.cache.get(packet.d.user_id));
}
});
});
This event spams continuously when one reaction is added, I want to make it so if you react it will run once. How can I do this?
You should not use the raw event past discord.js version 12. As there are some issues when your bot grows.
Instead use Partials as explained in the offical Discord.js Guide
const Discord = require('discord.js');
const client = new Discord.Client({ partials: ['MESSAGE', 'CHANNEL', 'REACTION'] });
client.on('messageReactionAdd', async (reaction, user) => {
// When we receive a reaction we check if the reaction is partial or not
if (reaction.partial) {
// If the message this reaction belongs to was removed the fetching might result in an API error, which we need to handle
try {
await reaction.fetch();
} catch (error) {
console.error('Something went wrong when fetching the message: ', error);
// Return as `reaction.message.author` may be undefined/null
return;
}
}
// Now the message has been cached and is fully available
console.log(`${reaction.message.author}'s message "${reaction.message.content}" gained a reaction!`);
// The reaction is now also fully available and the properties will be reflected accurately:
console.log(`${reaction.count} user(s) have given the same reaction to this message!`);
});
Source and more information: https://discordjs.guide/popular-topics/reactions.html#listening-for-reactions-on-old-messages
I've been trying to create a Discord bot. A lot of interactions are done through reactions, and I've been aware of the fact that only cached messages triggered the messageReactionAdd event. So I picked the following piece of code that is supposed to emit the packets corresponding to reactions added to "old" (not cached) messages. But it seems to completely block any packets concerning reactions adding because now none is emitted. Is there something that I've been doing wrong ?
Thanks.
My "raw.js" file :
module.exports = {
run: (client, packet) => {
// We don't want this to run on unrelated packets
if (!['MESSAGE_REACTION_ADD', 'MESSAGE_REACTION_REMOVE'].includes(packet.t)) return;
// Grab the channel to check the message from
const channel = client.guilds.cache.get(packet.d.guild_id).channels.cache.get(packet.d.channel_id);
const messageID = packet.d.message_id;
// There's no need to emit if the message is cached, because the event will fire anyway for that
if (channel.messages.has(messageID)) return;
// Since we have confirmed the message is not cached, let's fetch it
channel.messages.fetch(messageID).then(message => {
// Emojis can have identifiers of name:id format, so we have to account for that case as well
const emoji = packet.d.emoji.id ? `${packet.d.emoji.name}:${packet.d.emoji.id}` : packet.d.emoji.name;
// This gives us the reaction we need to emit the event properly, in top of the message object
const reaction = message.reactions.get(emoji);
// Adds the currently reacting user to the reaction's users collection.
if (reaction) reaction.users.set(packet.d.user_id, client.users.get(packet.d.user_id));
// Check which type of event it is before emitting
if (packet.t === 'MESSAGE_REACTION_ADD') {
client.emit('messageReactionAdd', reaction, client.users.get(packet.d.user_id));
}
if (packet.t === 'MESSAGE_REACTION_REMOVE') {
client.emit('messageReactionRemove', reaction, client.users.get(packet.d.user_id));
}
});
}
};
My "event fetcher" :
const fs = require('fs')
fs.readdir('./events/', (err, files) => {
if (err) return console.error(err);
files.forEach((file) => {
const eventFunction = require(`./events/${file}`);
if (eventFunction.disabled) return;
const event = eventFunction.event || file.split('.')[0];
const emitter = (typeof eventFunction.emitter === 'string' ? client[eventFunction.emitter] : eventFunction.emitter) || client;
const { once } = eventFunction;
try {
emitter[once ? 'once' : 'on'](event, (...args) => eventFunction.run(client, ...args));
} catch (error) {
console.error(error.stack);
}
});
});
From the discord.js discord server's #faq channel:
Bug:
• 'messageReactionAdd' does not fire despite proper partials enabled
PR: https://github.com/discordjs/discord.js/pull/4969 (merged, waiting for release)
Temporary fix is to ensure the addition of GUILD_MEMBER partial in the client definition
new Discord.Client({
partials: ['USER', 'GUILD_MEMBER', 'CHANNEL', 'MESSAGE', 'REACTION'],
});
Hello I'm trying to use cheerio in a Alexa Skill to get data from website and add in skill.
The code of intent
const HelloWorldIntentHandler = {
canHandle(handlerInput) {
return Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest'
&& Alexa.getIntentName(handlerInput.requestEnvelope) === 'all_titles';
},
handle(handlerInput) {
//Lógica para speak output
var options = {
uri: 'https://es.pagetest.com/',
transform: function (body) {
return cheerio.load(body);
}
};
rp(options)
.then(function ($) {
var arr_response = []
var titles = $('.ms-short-title');
titles.each((i, a) =>{
if(a.parent.attribs.title !== undefined)arr_response.push(a.parent.attribs.title);
});
const speakOutput = insert_in_string(arr_response);
return handlerInput.responseBuilder
.speak(speakOutput)
//.reprompt('add a reprompt if you want to keep the session open for the user to respond')
.getResponse();
function insert_in_string (arr_titulars){
var string_text = '';
for(var titular of arr_titulars){
string_text += titular + ' Siguiente titular. ';
}
return string_text;
}
})
.catch(function (err) {
return err;
});
}
};
I have tested the logic locally and it works ok, by putting it in alexa code editor, in test, return error message, but not a trace
¿Any idea? Thanks
If you are using Alexa-hosted Skills, you will have CloudWatch integration already built-in. Simply go to your Amazon Developer Console, navigate to your Skill's Code tab, scroll to the bottom and click the Logs: Amazon CloudWatch link on the bottom left.
Now, every time that you console.log, it will be sent to CloudWatch. So, in your catch handler, add console.log(err) and you should be able to see what's going wrong.
This blog post might also help: https://developer.amazon.com/blogs/alexa/post/71ac4c05-9e33-41d2-abbf-472ba66126cb/3-tips-to-troubleshoot-your-custom-alexa-skill-s-back-end
I'm writing a discord bot using discord.js, and I've recently added a //translate command that utilizes the Google Translate API to translate between all the languages supported by Google Translate. I want to add the ability to quickly re-translate the translation back into English using reactions, and I want the bot to check if 1 person has reacted to the post with the provided reaction, and if they have, re-translate the translation back to English.
I'm really close, but I've run into the problem that I can't get the bot to check if it itself sent the reaction, so it auto-retranslates back to English because it's detecting it's own reaction. I want for it to only re-translate when A PERSON reacts, and only ONCE.
I'm not super familiar with this area of discord.js yet, so I can't really figure out how to do it.
Here is the code:
if (msg.content.startsWith(`${prefix}translate`) || msg.content.startsWith(`${prefix}t`)) {
const text = args.slice(1).join(` `);
if (!text) return msg.channel.send(`Nothing to translate provided! Languages codes are at https://cloud.google.com/translate/docs/languages !\n Command syntax: \`${prefix}translate\` or \`${prefix}t\` [text] [language code]`);
const text1 = text.substring(0, text.length - 2)
const target = text.substring(text.length - 2, text.length) || languages
translate
.translate(text1, target)
.then(results => {
const translation = results[0];
msg.channel.send(`Translation: ${translation}`).then(sentText => {
sentText.react(`🔀`);
const filter = (reaction, user) => {
return ['🔀'].includes(reaction.emoji.name);
};
sentText.awaitReactions(filter, { max: 2, time: 5000, errors: ['time'] })
.then(collected => {
const reaction = collected.first();
if (reaction.emoji.name === '🔀' && sentText.react.me === false) {
const target = `en`
translate
.translate(text1, target)
.then(results => {
const translation = results[0];
msg.channel.send(`Translation: ${translation}`);
})
.catch(err => {
console.log(err);
})
}
})
})
})
//code for command continues below this line, but it is irrelevant to what I'm trying to achieve
Expected result: Bot re-translates back to English if a user reacts with the provided reaction, and only once.
Actual result: Bot does nothing, or, if I remove the && sentText.react.me === false, the bot re-translates back to English because it's detecting its own reaction.
Any help would be appreciated!
In your filter, you can check to make sure the user isn't the client, like so...
const filter = (reaction, user) => reaction.emoji.name === '🔀' && user.id !== client.user.id;
That way, only reactions that are not added by the client are collected.
You'll have to change your max option in the collector to 1, since the client's own reaction won't be collected. You can also remove the if statement comparing reaction.emoji.name.
Is it possible to have a RequestInterceptor abort the Session based on some logic inside the RequestInterceptor?
I have a routine coded that verifies the validity of a User. If the validity check fails, I want to play a message to the USer and abort the session.
What I see happening is that the LaunchRequest still runs even though I try and kill the seesion in the RequestInterceptor
A simplified version is as follows
const Alexa = require('ask-sdk-core');
const requestInterceptor = {
var isUserOk = false;
if(!isUserOk){
process(handlerInput) {
return handlerInput.responseBuilder
.speak("You are inside the Request Interceptor")
.withShouldEndSession(true)
.getResponse();
}
}
}
const launchRequestHandler = {
canHandle(handlerInput) {
return (handlerInput.requestEnvelope.session.new &&
handlerInput.requestEnvelope.request.type === 'LaunchRequest');
},
handle(handlerInput) {
return handlerInput.responseBuilder
.speak("Hi, welcome to the test skill. What is your name?")
.reprompt("You did not respond. Please tell me your name")
.getResponse();
}
};
const skillBuilder = Alexa.SkillBuilders.custom();
exports.handler = skillBuilder
.addRequestHandlers(
launchRequestHandler,
)
.addRequestInterceptors(
requestInterceptor
)
.lambda();
Can anyone tell me if it is possible to have the logic in the RequestInterceptor kill off the Session and prevent the LaunchRequest handler from running?
Thanks
-bc
It doesn't work because interceptors do not return responses (note that the interceptor method is called process() and not handle()) In the interceptor, instead of trying to close the session, use the handlerInput to set a session attribute named e.g. validUser:
let attributes = handlerInput.attributesManager.getSessionAttributes();
attributes.validUser = isUserOk(); //call your user check function here
handlerInput.attributesManager.setSessionAttributes(attributes);
Now create a launchRequestBadUserHandler where in the canHandle() you require that session attribute to be false:
const attributes = handlerInput.attributesManager.getSessionAttributes();
const isUserOk = attributes.validUser;
canHandle(handlerInput) {
return (handlerInput.requestEnvelope.session.new &&
handlerInput.requestEnvelope.request.type === 'LaunchRequest' &&
!isUserOk);
In this handler handle() function send the response you originally planned for the interceptor. Don't forget to call this handler before your original launch request handler in addRequestHandlers()