Alexa skills?

Hi, has anyone created an Alex skill to read out the current conditions?

it should be possible, using the ability to create a custom output
in the needed format

I already have a custom out txt file with the data i post to facebook, i wonder if i can have alexa read it, its all very new to me so i will have to see how skillful she really is :smiley:

Manged to read my latest tweet, not ideal as they are posted every 30 minutes, its at least something.

hey, that’s cool :slight_smile:

The latest tweet wasn’t the best as it never read the latest, I think it picked one at random.

What I have manged to get working is alexa playing the weather talker file.

To do this you need to install mymedia and link your account to amazon, 7 day free then it’s about

What’s weather talker?

It’s in wd control panel, it speaks the conditions you set

I have been thinking of writing an Alexa’s skill for the PurpleAir sensor (I have not yet done any work - just reading on how I can do it).

Here is the main link to ‘Alexa Skills Kit’.

The ‘need-to-read’ documentation before creating your first skill: ‘Build Skills with the Alexa Skills Kit’.

Already been through parts, set accounts here there and every where, setup stacks and God knows what else and failed, I even tried the, ask Google hack and that didn’t work either

I found it in the Control Panel. msagent no longer is available on Microsoft’s website apparently. A search there indicates that it wasn’t available for Windows 7 and later anyway.

It looks like a dead add-on.

You will find that what is needed is available on the net :slight_smile:

I have found another way that works very well if you use twitter, its called Read My Tweets

Enable the skill, to change the tweets from the default drivel

Say “Alexa, ask read my tweets to give my secret key”, or " Alexa, ask read my tweets, for my secret code", or " Alexa, ask read my tweets to help with setup"
Alexa will give you a “Secret Key”
Then go here scroll down to the boxes and add your secret key and the 3 twitter accounts @whatever yours is, i just added mine 3 times

Mine took over 24 hours to be setup, probably because of the weekend as its only meant to take a couple of hours, but its working this morning, then all you say is, Alexa, read my tweets, and away she goes :slight_smile:

This one is by far the best i have used so far as she doesnt say a load of rubbish prior to actually reading the tweet, she just says your @account name, date and time and the contents. Others tend to say something like, reading tweets by (name of skill), then a pause then you name then the date and time and contents, i didnt like that.

The above does not update, it only says the 1st time you ask and then just repeats that one :frowning:

I have found the Weather Underground skill, it was not easy because its not for the UK and if you are outside the USA then it wont work.
You need to setup an address in the USA, when you do that, just remember, if you want to buy something, change the address back :wink:
Also, all your skills will be gone, thats a downer… you have to start again with them unless you change the address back.

https://www.amazon.com/Personal-Weather-Underground-PWS/dp/B07234WJ9B

Once you get it installed, all you do is give it your WU API key, then your station ID and then set units, its very easy.

Once up and running all you do is say, Alexa, ask personal weather, current conditions or temperature or Humidity or wind or pressure etc

I have come the the conclusion that Alexa skills are, or can be, buggy, or not work as described or does not work the way you want it to and do not work any more.

The WU skill above is perfect for what we would want, i just cannot understand why its only for the USA :frowning:

[size=50]Ive made my own skill that reads the file currentout.txt that WD uploads to my website, its not easy, i needed help but i can supply the code, but you will need to actually create the skill and lambda function, i will do my best to help below. This will not pull specific datas from the file, all it will do is read all the file, so make sure its an understandable file for speech :slight_smile:

Here it is in working order https://www.youtube.com/watch?v=G8_2ztdtC-Q

NOTE: READ IT ALL 1st and During this build, never close a tab until you have tested the skill and its working ok, reason is because theres ids thats needed

So, you need to create a lambda function, but 1st, (if you dont have one) create an AWS account here and sign in, [/size]
In the search box, type lambda, and click it
Then click create function

You want Start from scratch (should be highlighted already)
use myWeather as the function name.
Choose Node.js 6.10

Role, Choose, Create custom role, it will open a new page, just click Allow
Then click Create function
From the list on the left, choose Skills set and it will attach itself
Click the box with the name of your skill so that the script box is open below, so scroll down if needed
Now copy and paste the script thats included in this post making sure you edit line 36 and 37

Leave that tab open and open a new one going here, create an account and login or just login if you have one already

Hover over Your Alexa Consoles and choose skills
Click Create Skill
Put in the name you want, i.e. my weather, Boston Weather, bear in mind this will be the name you as Alexa for, ie. Alexa, ask Boston weather…
Make sure Custom is highlighted and click Create Skill at the top right
Make sure Start from scratch is ticked and click Choose
Click invocation name and make sure its what you wanted, ie, Alexa, ask (invocation name)
Click the + next to intents and use GetWeather in the Create Custom Intent box and click Create custom intent

Now this is where you can add all the words that you want or may use to get her to read the txt file, such as, whats the weather status, or current conditions or is it raining or whats the temp or, whats the current conditions, add what ever you may want to use, so, it will be something like this, “Alexa, ask Boston Weather, temp” or "Alexa, ask Boston Weather, whats the current conditions"and she will read that txt file, this isnt about pulling specific datas from the file, just reading the full file, ok, once you added all the utterances you can think of or want, then…
Click Interfaces on the left and choose Display interfaces.

Click Endpoint on the left
Choose AWS Lambda ARN and it will supply you with the arn code, copy that to the clipboard, leave tab open and go back to the other tab you left earlier
Scroll down and post that code in to the Skill ID and then Click Add (bottom right) (SIDE NOTE: you need this ID to go on line 36 on the script)
At the top of that page there is a ARN ID starting
arn:aws:lambda…[/size] [/size]copy that and click save
[/size]Go back to the other tab again and paste the new code in to the Default Region box, click the button Save Endpoints
[/size]Then click Invocation name again so that Save Model and Build Model shows at the top, click Save Model, then click Build Model
[/size]At this point you can now goto [/size]Alexa on your PC/mac, click here go to skills, Your skills, DEV SKILLS and you will see it in there and only in there unless you publish it, right, it should have enabled ok, so now go ahead and ask her, test with just the skill name 1st and see if she responds, if yes, then ask one of you utterances, if you are happy and its working ok then you can close the tabs.

exports.handler = (event, context, callback) => {
    try {
        //console.log(`event.session.application.applicationId=${event.session.application.applicationId}`);
        
        //if (event.session.application.applicationId !== APP_ID) {
        //     callback('Invalid Application ID');
        //}
        


        if (event.session.new) {
            onSessionStarted({ requestId: event.request.requestId }, event.session);
        }


        if (event.request.type === 'LaunchRequest') {
            onLaunch(event.request,
                event.session, (sessionAttributes, speechletResponse) => {
                    callback(null, buildResponse(sessionAttributes, speechletResponse));
                });
        } else if (event.request.type === 'IntentRequest') {
            onIntent(event.request,
                event.session,
                (sessionAttributes, speechletResponse) => {
                    callback(null, buildResponse(sessionAttributes, speechletResponse));
                });
        } else if (event.request.type === 'SessionEndedRequest') {
            onSessionEnded(event.request, event.session);
            callback();
        }
    } catch (err) {
        callback(err);
    }
};




const isDebug = false; 
const APP_ID = 'amzn1.ask.skill.xxxxxxxxxxxxxxxxxxxxxx';
const url_weather = 'http://www.yoursitehere/yourtextfile.txt';
const APP_NAME = 'Weather skill';
const STR_REPROMPT = '\nPlease ask me for the weather';






function getWeather(intent, session, callback, numLetters) {
    




    let speechOutput = ''; 
    let cardTitle = 'Weather output';
    getWebRequest(url_weather, function webResonseCallback(err, data) {
        if (err) {            
            speechOutput = `Sorry something went wrong.`;
            callback({}, buildSpeechletResponse(cardTitle, speechOutput, STR_REPROMPT));     
        } else {
            //if (isDebug) {"SolveAnagram::data = " + console.log(data)};
            speechOutput = data;            
            callback({}, buildSpeechletResponse(cardTitle, speechOutput,  STR_REPROMPT));
        }    
    });
    
    
}


//Simple welcome intent handler
function getWelcomeResponse(callback) {
    console.log("START session");
    if (isDebug) {console.log("getWelcomeResponse()")}
        
    const cardTitle = APP_NAME;
    const speechOutput = 'Welcome to '+APP_NAME+'. '+ STR_REPROMPT;
        
    // If the user either does not reply to the welcome message or says something that is not
    // understood, they will be prompted again with this text.
    const repromptText = STR_REPROMPT;
    const shouldEndSession = false;


    callback({}, buildSpeechletResponse(cardTitle, speechOutput, repromptText, shouldEndSession));
}


//Simple end session intent handler
function handleSessionEndRequest(callback) {
    console.log("END session");
    
    const cardTitle = 'Goodbye';
    const speechOutput = 'Thanks for playing with '+APP_NAME+'.';
    const shouldEndSession = true;


    callback({}, buildSpeechletResponse(cardTitle, speechOutput, null, shouldEndSession));
}








function buildSpeechletResponse(title, output, repromptText, shouldEndSession) {
    if (isDebug) {console.log(`buildSpeechletResponse(title:${title}, shouldEndSession:${shouldEndSession}, reprompt:${repromptText})`)}
    return {
        outputSpeech: {
            type: 'PlainText',
            text: output,
        },
        card: {
            type: 'Simple',
            title: `${title}`,
            content: `${output}`,
        },
        reprompt: {
            outputSpeech: {
                type: 'PlainText',
                text: repromptText,
            },
        },
        shouldEndSession,
    };
}


function buildResponse(sessionAttributes, speechletResponse) {
    return {
        version: '2.0',
        response: speechletResponse,
        sessionAttributes: sessionAttributes,        
    };
}




//----------------- Web service helper ----------------------//
var http = require('http');
 
function getWebRequest(url,doWebRequestCallBack) {
    try
    {
        http.get(url, function (res) {
            var webResponseString = '';
            if (isDebug) {console.log('Status Code: ' + res.statusCode)};
     
            if (res.statusCode != 200) {
                doWebRequestCallBack(new Error("Non 200 Response"));
                return;
            }
     
            res.on('data', function (data) {
                webResponseString += data;
            });
     
            res.on('end', function () {
                //if (isDebug) {console.log('getWebRequest::Got some data: '+ webResponseString)};     
                
                //the weather isn't JSON so just return the string
                //var webResponseObject = JSON.parse(webResponseString);   
                doWebRequestCallBack(null, webResponseString);
                
                
            });
        }).on('error', function (e) {
            if (isDebug) {console.log("Communications error: " + e.message)};
            doWebRequestCallBack(new Error(e.message));
        });
    } 
    catch(err)
    {
        doWebRequestCallBack(new Error(err.message));
    }
}






// --------------- Events -----------------------


/**
 * Called when the session starts.
 */
function onSessionStarted(sessionStartedRequest, session) {
    //console.log(`onSessionStarted requestId=${sessionStartedRequest.requestId}, sessionId=${session.sessionId}`);
}


/**
 * Called when the user launches the skill without specifying what they want.
 */
function onLaunch(launchRequest, session, callback) {
    //console.log(`onLaunch requestId=${launchRequest.requestId}, sessionId=${session.sessionId}`);


    // Dispatch to your skill's launch.
    getWelcomeResponse(callback);
}




/**
 * Called when the user specifies an intent for this skill.
 */
function onIntent(intentRequest, session, callback) {
    
    const intent = intentRequest.intent;
    const intentName = intentRequest.intent.name;
    
    console.log("  ");
    console.log("== New Intent ==");
    console.log(`onIntent(${intentName})`);


    if (intentName === 'GetWeather') {
        getWeather(intent, session, callback,1); 
    } 
    
}


/**
 * Called when the user ends the session.
 * Is not called when the skill returns shouldEndSession=true.
 */
function onSessionEnded(sessionEndedRequest, session) {
    //console.log(`onSessionEnded requestId=${sessionEndedRequest.requestId}, sessionId=${session.sessionId}`);
    // Add cleanup logic here
}

hey, thanks for sharing! :slight_smile: