npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@ecromaneli/true-skill

v1.0.0-beta2

Published

Skills for Alexa in a Nutshell

Downloads

20

Readme

What is Alexa

Alexa is Amazon’s cloud-based voice service (...). You can build natural voice experiences that offer customers a more intuitive way to interact with the technology they use every day (...).

What is a Skill

In this context, a Skill is the name assigned to an application designed to enhance Alexa's functionalities.

Learn more about Skills on Alexa Skills Kit.

The True Skill Library

True Skill Library or just True Skill is a fast, friendly and easy-to-use Skill Creation Helper for JavaScript. It makes the creation of an custom skill less repetitive and more intuitive, working side-by-side with the ASK Core. An perfect combination of what you want and what you write.

Install

When you creating your skill, just import ask-sdk-core, ask-sdk-model and true-skill into your package.json, or alternatively run:

    npm i ask-sdk-core
    npm i ask-sdk-model
    npm i @ecromaneli/true-skill

Last tested:

    "ask-sdk-core": "^2.7.0",
    "ask-sdk-model": "^1.19.0",

Comparison

Just a simple example of basic work:

  • ASK Core
    const Alexa = require('ask-sdk-core');

    const LaunchRequestHandler = {
        canHandle(handlerInput) {
            return Alexa.getRequestType(handlerInput.requestEnvelope) === 'LaunchRequest';
        },
        handle(handlerInput) {
            const speakOutput = 'Hello World!';
            return handlerInput.responseBuilder
                .speak(speakOutput)
                .getResponse();
        }
    };

    const SomeIntentWithSlotHandler = {
        canHandle(handlerInput) {
            return handlerInput.requestEnvelope.request.type === 'IntentRequest'
                && handlerInput.requestEnvelope.request.intent.name === 'SomeIntent'
                && handlerInput.requestEnvelope.request.intent.slots.someSlot !== void 0;
        },
        handle(handlerInput) {
            const someSlotValue = handlerInput.requestEnvelope.request.intent.slots.someSlot.value; 
            const speechText = `someSlot value is ${someSlotValue}.`;

            return handlerInput.responseBuilder
                .speak(speechText)
                .getResponse();
        }
    };

    const SomeIntentWithoutSlotHandler = {
        canHandle(handlerInput) {
            return handlerInput.requestEnvelope.request.type === 'IntentRequest'
                && handlerInput.requestEnvelope.request.intent.name === 'SomeIntent';
        },
        handle(handlerInput) {            
            const speechText = 'What is someSlot value?';
            const repromptText = 'What?';
            return handlerInput.responseBuilder
                .speak(speechText)
                .reprompt(repromptText)
                .getResponse();
        }
    };

    exports.handler = Alexa.SkillBuilders.custom()
        .addRequestHandlers(
            LaunchRequestHandler, 
            SomeIntentWithSlotHandler,
            SomeIntentWithoutSlotHandler)
        .lambda();
  • True Skill
    const { Skill } = require('@ecromaneli/true-skill'); // or { TrueSkill }

    exports.handler = Skill(($) => {
        $.launch((context) => {
            context.default(response => response.say('Hello World!'));
        });

        // Can be used 'SomeIntent: IntentRequest' too
        $.on('SomeIntent', (context) => {
            context.hasSlot('someSlot').do(response => response.say('someSlot value is {{someSlot}}.')); 
            context.default(response => response.ask('What is someSlot value?', 'What?'));
        });
    });

    // [EXTRA]
    // You can also access slots with data parameter
    (...)
        context.hasSlot('someSlot').do((response, data) => {
            response.say('someSlot value is {{someSlot}}.');
            console.log(data.slot('someSlot'));
        }); 
    (...)

Get Started

To start using TrueSkill you need to:

  • Import TrueSkill into your project;
  • Create you handlers using Request Selectors, the order is important;
  • Configure your persistence adapter if needed;
  • Test you Skill.

Importing

Import Skill or TrueSkill and set your global lambda variable (default is handler) to Skill return.

    const { Skill } = require('@ecromaneli/true-skill'); // or { TrueSkill }

    exports.handler = Skill($ => {
        // Your skill code here...
    });

How to Handle Requests

First thing first, you need to know how to use Request Selectors.

Handler Selectors

With TrueSkill you can use the Request Selectors to say for the application, what request you want to handle.

The pattern to handle directly an Request Type, is :RequestType. For example, you can handle Launch requests using:

    $.on(':LaunchRequest', requestHandler);

or the shortcut:

    $.launch(requestHandler);

For handle an intent, you don't need to specify an request type, that's because the IntentRequest is the default type. For that, just use the intent name. See the example below:

    $.on('FooIntent', requestHandler);

Shortcuts

Some shortcuts has been implemented based on default request types and built-in intents. See the list below:

    // :LaunchRequest
    launch(contextHandler: ContextHandler): Core;
    launch(onlyDefaultContext: true, requestHandler: RequestHandler): Core;

    // :SessionEndedRequest
    sessionEnded(contextHandler: ContextHandler): Core;
    sessionEnded(onlyDefaultContext: true, requestHandler: RequestHandler): Core;

    // Amazon Help Intent
    help(contextHandler: ContextHandler): Core;
    help(onlyDefaultContext: true, requestHandler: RequestHandler): Core;

    // Amazon Cancel Intent
    cancel(contextHandler: ContextHandler): Core;
    cancel(onlyDefaultContext: true, requestHandler: RequestHandler): Core;

    // Amazon Stop Intent
    stop(contextHandler: ContextHandler): Core;
    stop(onlyDefaultContext: true, requestHandler: RequestHandler): Core;

    // Handle any request
    intent(contextHandler: ContextHandler): Core;
    intent(onlyDefaultContext: true, requestHandler: RequestHandler): Core;

See more about onlyDefaultContext bellow.

Controlling your Context

After learn how to use the Selectors, you need to know how to separate the different contexts of the captured Request. For example, if you have a persistent attribute or slot, and you want to give a different answer to your user, you need to specify that.

When you use the .on() or any shortcut (see the section above), you need to pass an handler. This handler receive as parameter an attribute called Context. The Context are responsible to identify what RequestHandler will be called based on your Rules. For example, you can do:

    (...)
        $.launch(context => {
            context.when(data => data.persistentAttr('firstTime') === false).do((response) => {
                response.say('Hello again!');
            });

            context.default(async (response, data) => {
                data.persistentAttr('firstTime', false);
                await data.savePersistentAttr();
                response.say('First time!');
            });
        });
    (...)

In this example, on the first time, the Alexa will say First time! and set an persistent attribute called firstTime as false. When your Skill been called again, the Alexa will say Hello again! because the .when() rule.

To create an Rule, you can use some of that functions and shortcuts:

    // Test the condition passed as parameter. Can return promise.
    when(condition: (data) => boolean | Promise<boolean>): this;

    // Negate any rule passed
    not(): this;

     // Verify if any (or specified) slot exists
    hasSlot(): this;
    hasSlot(slotNames?: string | string[]): this;

    // Verify if any (or specified) request attribute exists
    hasRequestAttr(): this;
    hasRequestAttr(attrNames?: string | string[]): this;

    // Verify if any (or specified) request attribute exists
    hasSessionAttr(): this;
    hasSessionAttr(attrNames?: string | string[]): this;

    // Verify if any (or specified) request attribute exists
    hasPersistentAttr(): this;
    hasPersistentAttr(attrNames?: string | string[]): this;

    // Verify if any (or specified) attribute exists with the type specified
    // NOTE: AttributeType can be imported by @ecromaneli/TrueSkill package too.
    hasAttr(): this;
    hasAttr(type: AttributeType, attrNames?: string | string[]): this;

If you context has only the default case, you can short your .on() call passing true to onlyDefaultContext parameter.

    $.on('selector', /* onlyDefaultContext */ true, RequestHandler)

With this, you no longer pass an ContextHandler as parameter, you pass the RequestHandler directly.

Handle Requests

Now, with your set of rules, it's time to respond the Request. When a rule condition returns true, an RequestHandler is called. He, is the responsible to perform an response.

The RequestHandler have 2 parameters, Response and Data. The Response are directly responsible to send the Request Response at final of your handler execution. And the Data, responsible to provide any important information (slots and attributes) retrieved by the request or persisted into your application.

Example:

speak()

    $.on('fooIntent', (context) => {
        context.default((response, data) => {
            data.sessionAttr('key', 'value');
            response.say('The session attribute key = {{value}}');
        });
    });

.reprompt()

    $.on('fooIntent', (context) => {
        context.default((response, data) => {
            response.ask('speak', 'reprompt');
        });
    });

Progress

First stable

  • Structure and topology [DONE];
  • Launch and intents [DONE];
  • Context cases [DONE];
  • Slots and session attributes [DONE];
  • Persistent attributes [DONE];
  • Help and other defaults responses [DONE];
  • Interceptors [DONE];
  • PersistentAdapter [DONE]; (See FSPersistenceAdapter project too)
  • Testing... [IN PROGRESS].

Beta Objectives

  • Usage;
  • Documentation.

Future

  • Smart Home Module;
  • Infinite possibilities *-*.

Author

License

Under MIT License