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

alexa-bootstrap

v0.4.4

Published

A framework to develop scalable and production ready Alexa Skills

Downloads

20

Readme

alexa-bootstrap

Build Status Coverage Status Standard - JavaScript Style Guide node npm npm

Installation

yarn add alexa-bootstrap or npm i alexa-bootstrap


Settings

All settings are optional.

const Alexa = require('alexa-bootstrap')

const alexa = new Alexa({
  tags: {
    WELCOME: 'WELCOME'
  },
  repeat: true,
  messages: {
    source: {
      WELCOME: 'Hi, how can I help you?'
    },
    globals: {
      now: new Date()
    },
  },
  storage: 'https://s3....',
  applicationId: 'amzn1.echo-sdk-ams.app...',
  shouldEndSession: false

})
  • tags - an object with tags one might want to apply to a request to make it easier to identify it in the subsequent request. Read more on res.tag() and req.tag()
  • repeat - saves the last response in the session (__repeat) for a use in the the next request by req.repeat(). Default: true
  • reprompt - save the last message in the session (__reprompt) and automatically used when the user does not respond after some seconds.
  • messages - object with speech settings.
    • source - object used by res.say(res.msg.*) [e.g: res.say(res.msg.WELCOME)]
    • globals - object used merged in the second parameter of res.say(text, meta)
  • storage - used by StandardCard while generating the images urls.
  • applicationId - it's the applicationId displayed on the Developer Console > Alexa. If present, it will block requests with different applicationId.
  • shouldEndSession - define if the session should be ended after each response (default: false).

Intent Example

alexa.intent('Booking', (req, res) => {
  const meta = {vehicle: 'car', city: {name: 'San Francisco'}}

  res.say('Your {vehicle} is in {city.name}. Do you confirm?', meta)
  .reprompt('I cant hear you. Say yes or no.')
})

Example using Express

Your Express setup might be more robust than the one below. It's a good practice to split the code below into files such as: server, routes and skills/intents.

const Alexa = require('alexa-bootstrap')
const Express = require('express')
const BodyParser = require('body-parser')

const port = process.env.PORT || 8080
const alexa = new Alexa()
const router = Express.Router()
const express = Express()

/**
 * Setup webserver
 */
express.set('port', port)

/**
 * Setup middlewares
 */
express.use(BodyParser.urlencoded({ extended: true }))
express.use(BodyParser.json())


/**
 * Setup Alexa Skill
 */
alexa.pre((req, res) => {
  res.session().set('city', 'New York')
})

alexa.launch((req, res) => {
  console.log('Launch Intent')
})

alexa.intent('Food', (req, res) => {
  res.say('Do you want to order {food}?', {food: 'pizza'})
})

/**
 * Endpoint used by Alexa (POST) - setup in the Amazon Developer Console
 * Change it to a name that best suits your needs.
 */
router.post('/skill', (req, res) => {
  alexa.request(req.body).then(response => {
    res.json(response)
  }, response => {
    res.status(500).send('Server Error')
  })
})

/**
 * Setup the router middleware
 */
express.use('/', router)

/**
 * Start server
 * Webhooks must be available via SSL with a certificate signed by a valid
 * certificate authority. Use Ngrok or similar for development.
 */
express.listen(port, () => {
  console.log(`Alexa app is running on port ${port}`)
})

Pre / Post Request Hooks

  • .pre()
  • .post()

.pre((req, res) => {})

It runs before every request.

alexa.pre((req, res) => {
  console.log('Pre request')
})

.post((req, res) => {})

It runs after every request. Even if the request has been aborted using res.abort() (more about this later).

alexa.post((req, res) => {
  console.log('Post request')
  res.say('Hello, how can I help you?')
})

Intents

  • .launch()
  • .sessionEnded()
  • .intent()

.launch((req, res) => {})

The user invokes the skill but doesn't map to any specific intent.

alexa.launch((req, res) => {
  console.log('LaunchIntent')
})

.sessionEnded(req, res)

The session is ended by Alexa. For example, when the user doesn't respond for some seconds.

alexa.SessionEnded((req, res) => {
  console.log('SessionEnded')
})

.intent(name, (req, res, slots) => {})

The user has a clear intent to perform an action.

alexa.intent('Booking', (req, res, slots) => {
  // Accessing slots...
  console.log('You are going to ' + slots.City)

  // ...It's equivalent to
  console.log('You are going to ' + req.slot('City'))

  // Using default values to slots
  console.log('You are going to ' + req.slot('City', '... Hmm, which city?'))
})

Response

  • .say()
  • .reprompt()
  • .card()
  • .linkAccount()
  • .abort()
  • .end()
  • .tag()
  • .session()

.say(ssml, vars)

alexa.intent('Hotel', (req, res) => {
  res.say('I love {city}', {city: 'London'})

  // You can add SSML tags
  res.say('Hmm. <break time="1s" /> I love {city}', {city: 'London'})
})

.reprompt(ssml, vars)

alexa.intent('Food', (req, res) => {
  res.say('Do you want {food}?', {food: 'pizza'})
  .reprompt('Tell me if you want {food}', {food: 'pizza'})
})

.card(title, body, imageUrls, vars)

  • title: string (required)
  • body: string (required)
  • imageUrls: string or array of strings (optional)
  • vars: object (optional)
alexa.intent('Job', (req, res) => {
  // Add images to the card
  const images = ['url small image', 'url large image']

  res.say('There is a job for you')
  .card('Jobs in {city}', 'There are 50 jobs in {city}', images, {food: 'pizza'})
})

.linkAccount()

Create a card in the Alexa App where the user can link his Alexa account with his account on your service. This card will display a link to the Login page you have set up in the Alexa Skill Developer Portal.

alexa.intent('Account', (req, res) => {
  // Example 1
  // Creates an account linking card
  res.linkAccount()

  // Example 2
  // Validate if user has a token
  if (!req.accessToken()) {
    res.linkAccount()
  }
})

.abort()

You can abort the request in the .pre() hook if it doesn't match your business rules. However, the .post() hook will still be executed.

alexa.pre((req, res) => {
  res.abort()
})

.end()

Ends the session. It sets shouldEndSession to true.

alexa.intent('Restaurant', (req, res) => {
  res.say('Your reservation is confirmed.').end()
})

.tag(code)

It applies a tag to the response that will be returned in the next request. It's useful to track the conversation.

// Request 1
alexa.intent('Restaurant', (req, res) => {
  res.say('Do you want to confirm your reservation?').tag('confirm_reservation')
})

// Request 2
alexa.intent('AMAZON.YesIntent', (req, res) => {
  if (req.tag('confirm_reservation')) {
    res.say('Ok. Your reservation is confirmed.')  
  }
})

.globals(data)

It adds an object data to the global message scope.

.session()

Returns the session if there is any.

alexa.intent('Flight', (req, res) => {
  // Get the session
  const session = res.session()

  // Add values to the session (method 1)
  session.set('from', 'SFO')
  session.set('to', 'JFK')

  // Add values to the session (method 2)
  session.set('from', 'SFO').set('to', 'JFK')

  // Get values from session
  const from = session.get('from')
  const to = session.get('to')

  // Clear session keys
  session.clear('from')

  // Clear entire session
  session.clear()
})

Request

  • .raw()
  • .id()
  • .type()
  • .timestamp()
  • .locale()
  • .context()
  • .userId()
  • .accessToken()
  • .applicationId()
  • .intent()
  • .slot()
  • .reason()
  • .error()
  • .session()
  • .tag()

.raw()

Returns the raw request.

.id()

Returns the request id.

.type()

Returns the request type.

.timestamp()

Returns the timestamp.

.locale()

Returns the locale.

.context()

Returns the context object. Some requests do not have the context and will return and empty object.

.userId()

Returns the user id. It does the lookup in the context and session objects.

.accessToken()

Returns the user access token. It does the lookup in the context and session objects.

.applicationId()

Returns the application id. It does the lookup in the context and session objects.

.intent()

Returns the intent name.

.slot(name, default)

  • name: optional
  • default: optional (same type as the slot)

.reason()

Returns the reason of the error occurred in SessionEndedRequest().

.error()

Returns the error occurred in SessionEndedRequest().

.session()

Returns the session in the request object.

.repeat()

Returns the repeat message set in the previous response (if any). Otherwise, null.

.tag(name)

  • name: optional

Returns the tag name or does an assert.

alexa.intent('Flight', (req, res) => {
  // Get the tag name
  req.tag()

  // Assert the tag
  if (req.tag('confirm_reservation')) {
    // do something...
  }

})

Todo

  • Add support for AudioPlayer
  • Add support for PlaybackController