This is one of my very first attempts (besides Purge time I made before)
I want to play an mp3 file until I ask Alexa to stop. This is was I have so far (The same code I used for the Purge one)
const Alexa = require('ask-sdk-core');
const Util = require('./util.js');
const LaunchRequestHandler = {
canHandle(handlerInput) {
return Alexa.getRequestType(handlerInput.requestEnvelope) === 'LaunchRequest';
},
handle(handlerInput) {
const audioUrl = Util.getS3PreSignedUrl("Media/white_noise_500_hz_formatted.mp3").replace(/&/g,'&');
return handlerInput.responseBuilder
.speak(`<audio src="${audioUrl}"/>`)
.getResponse();
}
};
exports.handler = Alexa.SkillBuilders.custom().addRequestHandlers(LaunchRequestHandler).lambda();
As a complete noob, I'm a bit lost. I'd need to wait to put the MP3 in a queue before it finishes or something.
Any idea is welcome, thanks!
PS. I know there are skills for white noise and rain sounds and so on, this one if for learning purposes :D
Where you're using it as a speak item, you're limited to 240 seconds and have to send the whole thing.
You want the audio player directive. https://developer.amazon.com/en-US/docs/alexa/custom-skills/audioplayer-interface-reference.html
Related
I’m trying to set up a chat reply bot for helping admin a game discord server. I have a list of words for it to reply to and can get him reply to them no problem. The problem I’m having is that one of the words is ESP so when someone was to type the word response it picks up the word esp in the word response and replies when I don’t want him to. Another example is the work hack. When someone types hacksaw ridge in chat he replies to that to. I want it to just look for the word esp along with a few other cheating terms and not look for it in the middle of a longer word.
let cheater = ["cheating", "cheater", "aim_bot", 'esp', "hack"]
client.on('messageCreate', (message) => {
if (message.author.bot) return false;
if (cheater.some(w => message.content.toLowerCase().includes(w))) {
message.reply('if you think someone is cheating report it here <#976517390701563955>');
}
})
Any help would be greatly appreciated
Thanks.
One of ways to solve it is very simple in fact, if you want your bot to react only to full words, you can use:
if(message.content.toLowerCase().includes(` ${your_variable} `)) {
// your code
}
instead of what you have in your code
You need to look for an Array.prototype.some() to get the message in your array. To accomplish this.
client.on('messageCreate', async(message) => {
if (message.author.bot) return false;
let messages = ["cheating", "cheater", "aim_bot", 'esp', "hack"]
if(messages.some(element => message.content.toLowerCase().includes(element))) {
message.reply("if you think someone is cheating report it here <#976517390701563955>")
}
})
I'm currently in the process of making a little game of TicTacToe, and the idea I had in mind is to make it so instead of the channel being spammed with constant embeds asking for the person's next move, is to simply make it reaction-based, where you get to pick 1 out of 9 reactions (And of course, you wont be able to pick it again if the other player has already picked it).
I have never really worked with requiring multiple reactions, therefore I'd like to ask your help on how exactly to make it so that the message command execution isn't a one-time thing, but will go on until there's eventually a winner.
So far, with the code I have written, this does work 2 times, but then it randomly stops and no longer works.
In addition, when I'm trying to declare a spot as an x or a circle, the spot turns completely blank.
Please help!
The code I have so far:
https://sourceb.in/S7cayfoYjp
Edit: I have now also found that the bot at first kind of skips the whole awaitReactions code. I used 'console.log(i)' for this, so that every time it loops it prints out 'i', and it seemed to be printing out the numbers 0-8 immediately, meaning it's not properly going through the code.
I think what you can use best there is a reactionCollector. It's a temporary reaction listener, attached to a message. A sample code for that would be:
const msg = await message.channel.send('tic tac toe test');
const acceptedEmojis = ['↖️', '⬆️', '↗️', '⬅️', '⏺️', '➡️', '↙️', '⬇️', '↘️']
const filter = (reaction, user) => {
return acceptedEmojis.includes(reaction.emoji.name) && user.id === turnId;
}
//here you create the collector. It has following attributes: it stops after 10 minutes or after 2 minutes of not collecting anything.
const collector = msg.createReactionCollector(filter, { time: 600000, idle: 120000});
//here you start the listener
collector.on('collect', (reaction, user) => {
if (reaction.emoji.name === '↖️') {
//remove the reaction
await msg.reactions.resolve('↖️')
acceptedEmojis.splice(acceptedEmojis.indexOf('↖️'), 1);
//rest of your code...
} else if (reaction.emoji.name === '⬆️') {
...
}
});
const Discord = require('discord.js');
const bot = new Discord.Client();
const token = '';
bot.on('ready', () =>{
console.log('This bot is online');
})
bot.on('message', msg=>{
if(msg.content === "?rates"){
msg.reply('.')
}
})
bot.login(token);
This is what I have so far it is very basic, I understand, I'm just trying to get some sort of idea how to process. What I want is as soon as a website gets updated or changed. I would like it to tag everyone and in a certain channel and specifies what has changed. I know this will be a long process but I'm in for the ride :) would appreciate any help.
You need a webhook on the website and listen to it with your bot, if you have control over the site, this may help you, otherwise you could look if the site has one or perhaps ask an owner.
A probably working but not very nice (and not very clean) solution would be to save the text of the website every 5 seconds or so and compare it to the previous save. If it changed, you notify the members through sending a message.
I have an alexa skill that plays a sound file on request and then plays a message and stops playing it when the user says stop. I use an end session statement in the stop intent. However, after saying stop once, if you say Alexa stop again it plays the message again, telling me that the skill is still active. How do you give a command to completely exit from the skill?
Here's my current stop intent:
'AMAZON.StopIntent': function() {
//output to available screen
makeTemplate.call(this, 'stop');
this.response.speak('Ok. I sent a practice tip to your Alexa app.').audioPlayerStop();
this.emit(':responseReady');
this.response.shouldEndSession(true);
},
You could take advantage of the state machine within Alexa, I would suggest to have different state, besides the default regular one, to have the StopIntent there. In this case you could switch to this state when you are playing the sound and only then your particular Stop behavior will work, there you can return to the regular state which wouldn't have a default behavior on your skill so it will run the default one from the Alexa itself closing your skill.
In this code you can have a basic idea on how this could work, though for sure there is stuff missing, but the important things are the this.handler.state which controls in what state is the session at the moment, and Alexa.CreateStateHandler(state, intents) which gets as parameter the name of a particular state and the particular behavior for the intents on that state.
const Alexa = require('alexa-sdk');
const defaultHandlers = {
PlayIntent: function() {
// move to state 'PLAY'
this.handler.state = 'PLAY'
// Code to play
}
}
const playingHanders = Alexa.CreateStateHandler('PLAY', {
PlayIntent: function() {
// Code to play
},
'AMAZON.StopIntent': function() {
//output to available screen
makeTemplate.call(this, 'stop');
// move to default state
this.handler.state = ''
this.response.speak('Ok. I sent a practice tip to your Alexa app.').audioPlayerStop();
this.emit(':responseReady');
this.response.shouldEndSession(true);
}
})
module.exports.skill = (event, context, callback) => {
const alexa = Alexa.handler(event, context, callback);
alexa.appId = APP_ID
alexa.registerHandlers(defaultHandlers, playingHanders)
alexa.execute();
}
There are many tutorials on this on internet so you can find better ideas on how to take advantage of this.
I want to accomplish the following scenario:
A small dialog between Alexa and the user, with the following 2 Intents:
NameIntent: "My name is {name}"
Where {name} is AMAZON.US_FIRST_NAME and with the slot made required and a prompt defined.
ActivityIntent: "I like {activity}"
And here it becomes more difficult. I made {activity} a custom slot and defined some values for it like "fishing, sports" and the like, but obviously there are more answers to this. If I now respond with something I don't have defined (e.g. "darts"), Alexa always goes back to the first intent, as it seems to thing it is a name.
Example:
LaunchRequest: "Welcome. What is your name?"
-> My name is Peter
NameIntent: "Welcome Peter. What do you like to do?" -> Darts
-> "Welcome Darts. What do you like to do?"
I would simply like to have Alexa accept whatever value the user says there, in Dialogflow this would be simply done with an {any} entity.
I followed this blog article from the alexa blog, and there they seem to be able to capture whatever nickname you throw at it, even ones which aren't defined, which is what I want to accomplish here.
Question: How can I capture any kind of input with Alexa, phrases beyond whatever I have defined in the skill builder? How can I make sure this phrase gets directed to the correct intent?
I am a bit frustrated with this, especially if you use ElicitSlotDirectives to specifically ask the user about a slot, and then it jumps to a completely different intent.
The code for the 2 intent handlers:
const NameIntentHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === 'IntentRequest'
&& handlerInput.requestEnvelope.request.intent.name === 'NameIntent';
},
handle(handlerInput) {
const { intent } = handlerInput.requestEnvelope.request;
const name = intent.slots.name.value;
const speechText = `Welcome ${name}. What is your favourite activity?`;
return handlerInput.responseBuilder
.speak(speechText)
.reprompt(speechText)
.withShouldEndSession(false)
.getResponse();
},
};
const ActivityIntentHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === 'IntentRequest'
&& handlerInput.requestEnvelope.request.intent.name === 'ActivityIntent';
},
handle(handlerInput) {
const { intent } = handlerInput.requestEnvelope.request;
const activity = intent.slots.activity.value;
const speechText = `You like ${activity}.`;
return handlerInput.responseBuilder
.speak(speechText)
.reprompt(speechText)
.withShouldEndSession(false)
.getResponse();
},
};
It seems that Alexa is having trouble associating activity utterances with your ActivityIntent and instead is invoking the NameIntent again. Relying on Amazon to figure out which intent to use based on slot type has not consistently worked well for me. If you post your intent code that would be very helpful.
It may help to look at a JavaScript example from Amazon here and Amazon's Voice Design Guide.
You might consider using AMAZON.LITERAL built-in custom slot type. This slot type passes the spoken words without any conversion. Although official documents suggest against using it. It was also discontinued once. From the official docs.
Note: Although you can submit new and updated English (US) skills with AMAZON.LITERAL, custom slot types provide better accuracy than AMAZON.LITERAL in most cases. Therefore, we recommend that you consider migrating to custom slot types if possible. Note that AMAZON.LITERAL is not supported for any language other than English (US).
Find more about AMAZON.LITERAL here.
https://developer.amazon.com/docs/custom-skills/literal-slot-type-reference.html