Home

Awesome

AlexaRuby

Gem Version Build Status CircleCI Code Climate Coverage Status


Since I have now some spare time, I plan to completely revise this project and make it at least up to date with the latest Alexa custom skills API.
Maybe even more.


Originally forked from damianFC's AlexaRubykit, this gem implements a convenient back-end service for interaction with Amazon Alexa API.

Installation

To install and use gem in your project just add this to your Gemfile:

gem 'alexa_ruby'

And bundle it with:

$ bundle install

Or install it as a separate gem:

$ gem install alexa_ruby

Docs

ResourceURL
Amazon Alexa Skill Kit docshttps://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/alexa-skills-kit-interface-reference
Rubydochttp://www.rubydoc.info/gems/alexa_ruby
Sourcehttps://github.com/mulev/alexa-ruby
Bugshttps://github.com/mulev/alexa-ruby/issues

Usage

Gem provides a possibility to easily handle requests from Amazon Alexa service and build responses to given requests.

Getting started

AlexaRuby usage is quite simple, to start you need to require gem in your ruby file and pass it JSON request from Amazon Alexa service.
Here and below all examples will be based on Roda routing tree framework, but you can use any other -- AlexaRuby is a framework independent gem.

require 'roda'
require 'alexa_ruby'

class App < Roda
  route do |r|
    r.post do
      r.on 'alexa' do
        alexa = AlexaRuby.new(r.body.read)
      end
    end
  end
end

Request structure validations can be disabled:

AlexaRuby.new(request, disable_validations: true)

If needed, you can validate request signature and Amazon SSL certificates chain. To do so specify several parameters:

AlexaRuby.new(
  request,
  certificates_chain_url: url,
  request_signature: signature
)

After initializing new AlexaRuby instance you will have a possibility to access all parameters of the received request.

General request parameters

Access pathDescription
alexa.request.jsongiven JSON request
alexa.request.versionrequest version, typically "1.0"
alexa.request.typerequest type, can be :launch, :intent, :session_ended or :audio_player
alexa.request.idrequest ID
alexa.request.timestamprequest timestamp
alexa.request.localerequest locale

Session parameters

Notice that user data exists in two scopes -- session and context.

Access pathDescription
alexa.request.session.idsession ID
alexa.request.session.attributesarray with all session attributes
alexa.request.session.end_reasonsession end reason, can be :user_quit, :processing_error or :user_idle
alexa.request.session.errorhash with session error info
alexa.request.session.statecurrent session state, can be :new, :old or :ended
alexa.request.session.user.idskill user ID
alexa.request.session.user.access_tokenuser access token if account linking is enabled and user is authenticated
alexa.request.session.user.permissions_tokenuser permissions token

Context parameters

Notice that user data exists in two scopes -- session and context.

Access pathDescription
alexa.request.context.app_idAlexa application ID
alexa.request.context.api_endpointAlexa API endpoint
alexa.request.context.user.idskill user ID
alexa.request.context.user.access_tokenuser access token if account linking is enabled and user is authenticated
alexa.request.context.user.permissions_tokenuser permissions token
alexa.request.context.device.iduser device ID
alexa.request.context.device.interfacesinterfaces, supported by user device

Intent request parameters

Access pathDescription
alexa.request.intent_namegiven intent name
alexa.request.dialog_statestate of dialog with user, can be :started, :in_progress or :completed
alexa.request.confirmation_statususer confirmation status, can be :unknown, :confirmed or :denied
alexa.request.slotsarray with all slots from intent

Audio player request parameters

Access pathDescription
alexa.request.playback_statecurrent playback state
alexa.request.playback_offsetcurrent playback offset in milliseconds
alexa.request.error_typeplayback error type
alexa.request.error_messageplayback error message explaining error
alexa.request.error_playback_tokenaudio player token of failed playback
alexa.request.error_player_activityaudio player activity in moment of failure

Building response

To build a response take your freshly initialized alexa and start using alexa.response methods.

Add session attributes

It is possible to add one attribute to session scope:

alexa.response.add_session_attribute('key', 'value')

Exception will be raised if attribute already exists in the session scope.
If you want to overwrite it, call:

alexa.response.add_session_attribute('key', 'value_2', true)

You can also add a pack of attributes. To overwrite all existing ones call:

alexa.response.add_session_attributes(key: 'value', key_2: 'value_2')

To add new attributes and save existing ones call:

alexa.response.merge_session_attributes(key: 'value', key_2: 'value_2')

Add card

Supported card types are: Simple, Standard and LinkAccount.

card = {
  type: 'Standard', title: 'Test', content: 'test',
  small_image_url: 'https://test.ru/example_small.jpg',
  large_image_url: 'https://test.ru/example_large.jpg'
}
alexa.response.add_card(card)

Add audio player directive

Supported directives:

To start the whole new playback call:

params = { url: 'https://my-site.com/my-stream', token: 'test', offset: 0 }
alexa.response.add_audio_player_directive(:start, params)

To enqueue new audio file call:

params = { url: 'https://my-site.com/my-stream', token: 'test', offset: 0, play_behavior: :enqueue }
alexa.response.add_audio_player_directive(:start, params)

To replace all previously enqueued audio files call:

params = { url: 'https://my-site.com/my-stream', token: 'test', offset: 0, play_behavior: :replace_enqueued }
alexa.response.add_audio_player_directive(:start, params)

To clear all:

alexa.response.add_audio_player_directive(:clear)

To clear only enqueued tracks and keep the playing one:

alexa.response.add_audio_player_directive(
  :clear,
  clear_behavior: :clear_queue
)

To stop playback call:

alexa.response.add_audio_player_directive(:stop)

Get current state of response encoded in JSON

alexa.response.json

Add output speech to response

Ask user a question and wait for response (session will remain open):

question = 'What can I do for you?'

alexa.response.ask(question)                  # will add outputSpeech node
alexa.response.ask(question, question)        # outputSpeech node and reprompt node
alexa.response.ask(question, question, true)  # outputSpeech node, reprompt node and both will be converted into SSML

alexa.response.ask!(question)                 # will add outputSpeech node and return JSON encoded response object

Tell something to user and end conversation (session will be closed):

speech = 'You are awesome!'

alexa.response.tell(speech)               # will add outputSpeech node
alexa.response.tell(speech, speech)       # outputSpeech node and reprompt node
alexa.response.tell(speech, speech, true) # outputSpeech node, reprompt node and both will be converted into SSML

alexa.response.tell!(speech)              # will add outputSpeech node and return JSON encoded response object

Testing

Run all tests with:

$ rake test

Please, feel free to open an issue in case of any bugs.

Contributing

You are always welcome to open an issue with some feature request or bug report. Also you can add new features by yourself. To do so, please, follow that steps:

  1. Fork master branch of this repo
  2. Add a new feature branch in your forked repo and write code
  3. Write tests
  4. Add pull request from your branch to alexa_ruby develop branch

All development is made only in develop branch before being merged to master.

License

AlexaRuby is released under the MIT license.