Git Product home page Git Product logo

alexa-app's Introduction

AlexaApp

Latest Version Total Downloads Software License StyleCI

Set of classes to make creating simple Amazon Echo Alexa Apps easier with Laravel and Lumen (note that 5.2.x Lumen has a known issue that needs addressing)

Major Update - 0.2.0 - call me beta

I've recently refactored nearly all of this package to make it Laravel compatible, and to avoid the previous heavy handed solution of completely replace the default Lumen Application. I've also made a number of changes I feel are for the best, for instance I've decoupled the Laravel/Lumen Session with the Alexa AlexaSkillsKit specific session data, and I've created a single interface to make it possible to handle most Alexa interactions through a single facade. But that's mainly related to the refactor - there are also a bunch of new features, including most importantly support for Amazon's AlexaSkillsKit security related requirements.

Main Features

  1. Allows Laravel/Lumen style routing for intent, launch, and session end requests.
  2. Handles verification of all security requirements put forth by Amazon, including certificate/signature verification, timestamp verification, etc
  3. Provides access to Alexa AlexaSkillsKit session data through familiar Laravel style interface
  4. Populates the response with Laravel session data to maintain a 1:1 set of session data between Lumen and Alexa
  5. Provides classes to easily return Alexa friendly responses, including Speech, Card, and Re-prompt responses
  6. Optionally provides a way to easily retrieve information about the connected Echo device ($device = Alexa::device();)

For a quick example:

AlexaRoute::intent('/alexa-end-point', 'GetAntiJoke', function(){
    Alexa::say("Why was the little boy crying? Because he had a frog stapled to his face!");
});

Demo

I'll be recording a number of new tutorial videos soon.

Installation

Prerequisites

The only thing that is required for AlexaApp is the Laravel or Lumen (versions based on 5.2) framework.

After installing via composer (i.e. composer require develpr/alexa-app):

1 : Auto-load the appropriate service provider for your framework

The Develpr\AlexaApp\Provider\LaravelServiceProvider needs to be added to the array of auto-loaded service providers

Laravel

In the config/app.php configuration file, add:

'providers' => [
    ...snip...
    \Develpr\AlexaApp\Provider\LaravelServiceProvider::class,
    ...snip...
],

Lumen

In your application's bootstrap/app.php file, add:

$app->register(\Develpr\AlexaApp\Provider\LumenServiceProvider::class);

2: Adding the facades/aliases for Alexa and AlexaRoute (optional)

This is not required, but it can be very handy. If you'd prefer, you can inject an instance of the \Develpr\AlexaApp\Alexa or \Develpr\AlexaApp\Routing\AlexaRouter class, or grab them with $app['alexa'] or $app['alexa.router'], respectively.

Laravel

If you'd like to use facades/aliases you'll need to add two separate alias configurations in the config/app.php file.

    'aliases' => [
        ...
        'AlexaRoute' => \Develpr\AlexaApp\Facades\AlexaRouter::class,
        'Alexa' => \Develpr\AlexaApp\Facades\Alexa::class,
        ...
    ],

Lumen

The truth is I'm not 100% sure if there is an "official" way of adding aliases/facades in Lumen, and I generally don't use custom facades with Lumen, however as mentioned in this stackexchange post, this should work:

First make sure aliases/facades are enabled in your bootstrap/app.php file by uncommenting $app->withFacades(); and then after this add

class_alias(\Develpr\AlexaApp\Facades\AlexaRouter::class, 'AlexaRoute');
class_alias(\Develpr\AlexaApp\Facades\Alexa::class, 'Alexa');

For lumen it might be easier to simply use $app['alexa.router'] or inject an instance of one of the above classes into your class.

3: Register Certificate middleware for verifying request comes from Amazon/AlexaSkillsKit (optional)

For any production application, it's important and in fact required by Amazon that you protect your application as described in their documentation. You do not need to register this middleware however, and for certain testing may choose not to.

This package makes this easy by providing middleware that will meet all required security parameters provided by Amazon. At this time, if you'd like to enable this functionality you'll need to register the Certificate middleware as outlined by the Laravel/Lumen documentation.

If you'd like to protect all routes in your application you can simply add the Certificate middleware to your global middleware as show below, else you can protect certain end points (i.e. only run the certificate/security check at /alexa-api-endpoint).

Laravel

To protect all routes, in your app/Http/Kernal.php file:

protected $middleware = [
    ...
    \Develpr\AlexaApp\Http\Middleware\Certificate::class,
    ...
];

Lumen

To protect all routes, in your bootstrap/app.php file:

$app->middleware([
    ...snip...
    \Develpr\AlexaApp\Http\Middleware\Certificate::class,
    ...snip...
]);

Everything is installed

At this point, everything should "work" (see below for more information on Usage), but there are a number of elements that may need to be configured.

#Configuration

A number of things can be modified, or may even need to be modified depending on your application, most importantly, the security options will need to be setup to match your AppId, etc. Most if not all of these modifications work the same way regardless if you're using Laravel or Lumen, and all configuration values should be definable in a config/ file, or by using a/an .env file.

If you're using Laravel, you can use the console artisan command to publish the AlexaApp configuration file to your applications configuration directory using artisan vendor:publish, or if you prefer (or are using Lumen) you can manually copy this file over from vendor/develpr/alexa-app/config/alexa.php.

There are quite a few comments in the alexa.php config file, so please read through this for much more information on specific options! - I'll only cover the more important, broader options here.

Certificate/Security

There are a few simple configuration options that need to be set for AlexaApp to successfully verify a request is valid/from Amazon/AlexaSkillsKit.

Amazon / AlexaSkillsKit "applicationId"s

This is your AlexaSkillsKit's application id and is used to verify the request is for your application. If you're not sure of what your application id is, the easiest way (for me at least) to find it is by taking a look at a sample request going to your web server from your application. Part of the json body will include ..."application":{"applicationId":"amzn1.echo-sdk-ams.app.9ec3744a-d1b2-48f2-8e08-3b2045c00616"},... - the applicationId you'll want to enter in the configuration is this applicationId.

The applicationIds configuration value can be set with the ALEXA__APPLICATION_IDS key in an .env file, or in the configuration file directly. Note that the configuration file accepts an array of applicationIds in case you are planning on serving multiple applications from one Laravel/Lumen application. The .env file method only allows a single applicationId to be specified.

Request timestamp tolerance

As of this writing Amazon specifies that requests should be no older then 150 seconds to prevent replay attacks. This is the default that is set within the default configuration but if you should wish to change this you can do so here. Also note that if you set this value to 0, the request age will not be checked - this is useful for testing if you have a sample request that you'd like to keep testing with.

Changes to this can be made in the config file ('timestampTolerance') or by setting ALEXA_TIMESTAMP_TOLERANCE in the .env file

Certificate provider

By default, AlexaApp will use file storage for locally caching Amazon's remote certificate file. Other providers will be supported shortly, including redis, database, and eloquent. These related options can be seen/configured in the config file.

Alexa Device

If you'd like to use the device functionality (i.e. Alexa::device()), you will more then likely need to configure a number of options.

Essentially, you need to tell Alexa app about where you are persistent and how to access the device information - two providers are supplied at this time, eloquent and database. If you use the eloquent provider you'll need to be sure eloquent is enabled if you're using Lumen.

Device Provider

Currently only database and eloquent options are supported, but more providers could easily be supported by implementing the \Develpr\AlexaApp\Contracts\DeviceProvider contract.

The default device provider is Eloquent, and there is a sample Device in /vendor/develpr/alexa-app/Device/Device.php that can be copied to your app directory and modified for your purposes. This model can be thought of as similar to the User model provided with a base installation of Laravel.

Sample migration

There is a sample migration provided with AlexaApp that can be copied to your migrations folder (manually or using console command in Laravel php artisan vendor:publish --tag="migrations") and once migrated, will work "out of the box" with the included DeviceProviders. If you'd prefer not to use this migration that's 100% fine, but you'll want to make sure to take a look at the config file to be sure you modify/understand any options you may need to update for your storage schema.

Usage

In the following sections you can see how you might use this package. Note please that while I may use facades/aliases in most of the examples below, you certainly don't need to! Check out the Installation section -> facades/aliases if you want to read more.

Routing

There are three types of requests that will be made from the Amazon AlexaApp middleware to your application. Those are

  1. LaunchRequest (happens when your application is "opened")
  2. SessionEndedRequest (send to your application with the application is closed)
  3. IntentRequest (these are the all of the requests that are not one of the above - likely the "bread and butter" of your application - most meaningful interactions)

These three types of requests can be routed within your application just like normal LaravelLumen requests using the new functionality provided by this package! All of these samples would be in your app/Http/routes.php most likely.

LaunchRequest

AlexaRoute::launch('/your-app-uri', 'App\Http\Controllers\AnyController@anyMethod');

or

$app['alexa.router']->launch('/your-app-uri', 'App\Http\Controllers\AnyController@anyMethod');

SessionEndedRequest

AlexaRoute::sessionEnded('/your-app-uri', function() use ($app) {
    return '{"version":"1.0","response":{"shouldEndSession":true}}';
});

or

$app['alexa.router']->sessionEnded('/your-app-uri', function() use ($app) {
    return '{"version":"1.0","response":{"shouldEndSession":true}}';
});

IntentRequest

AlexaRoute::intent('/your-app-uri', 'GetZodiacHoroscopeIntent', 'App\Http\Controllers\AnyController@anyMethod');

or

$app['alexa.router']->intent('/your-app-uri', 'GetZodiacHoroscopeIntent', 'App\Http\Controllers\AnyController@anyMethod');

Note that in these examples both a closure and a controller was used to handle the request, but there is no specific requirement to use one vs. another based on the request type.

Note that the other get, post, put, patch, delete, etc options are still available an are unchanged

Session

Session values are passed to and from your application in the json payload from Amazon / AlexaSkillsKit. These are accessible in the AlexaRequest, or using the Alexa facade/alias.

to retrieve a session value

$previousChoice = Alexa::session('previousChoice');

to retrieve all session values

Alexa::session();

to set a session value

Alexa::session('previousChoice', "Pizza");

or

Alexa::setSession('previousChoice', "Pizza");

to unset a session value

Alexa::unsetSession('previousChoice');

Session values will also be included in the response json, but only if you are using the AlexaResponse class!.

Slots

You can retrieve the value of a slot (only applicable for IntentRequests as of this moment):

$usersChoice = Alexa::slot('choice');

If the slot is empty, null will be returned. You can change this default value to something else by passing in your preferred default as the second parameter:

$usersChoice = Alexa::slot('choice', 'foo');

Responses

You can use this package and the Alexa facade to easily create valid responses from your application, but it's worth knowing about the classes behind the facade. The most important thing to know is that Alexa::say("Hello"); is simply returning a new \Develpr\AlexaApp\Response\AlexaResponse object with a \Develpr\AlexaApp\Response\Speech object inside.

Using the Alexa facade/alias

The easiest way to send a valid response to Amazon/AlexaSkillsKit/an end user is

return Alexa::say("Oh hi Denny");

As mentioned above, at the end of the day an AlexaResponse is being generated and returned, so you can chain other methods to add other response features. For example...

return Alexa::say("Oh hi Denny")->withCard(new Card("Hello message"))->endSession();

...will return a spoken message ("Oh hi Denny"), a card that has a title of "Hello message", and it will end the session.

The AlexaResponse

There are a number of useful classes that can be used to generate valid Amazon Echo friendly json responses. There is nothing particularly complex or magical about these classes, they simply make it easier to create valid responses without having to think too much.

The main class is AlexaResponse - I intended that an instance of this class would be returned at all times to the Echo. There are a number of useful things you can do.

You can return an instance of this class without doing anything else and that will be a valid response (albeit fairly useless!)

return new AlexaResponse;

You can tell the Echo that the session should be ended

$alexaResponse = new AlexaResponse;
$alexaResponse->endSession();

return $alexaResponse;

Or, you can add one (or both) Speech/Card/Reprompt objects to have spoken text or a card sent back to the end Echo user (note that you don't need to return both!).

$alexaResponse = new AlexaResponse;
$alexaResponse->withSpeech(new Speech("Hello!!"));

$alexaResponse->withCard(new Card("Hello Title", "Hello Subtitle", "Hello content here!"));

return $alexaResponse;

You can always return this in a single line,

return new AlexaResponse(new Speech("Hello!!"), new Card("Hello Title", "Hello Subtitle", "Hello content here!"), true);

Here the third parameter, when set to true, will end the session.

Tests

 $ phpunit --configuration phpunit.xml

Thanks

Thanks to @jasonlewis - I re-used a lot of the ideas for some of the routing pieces from his ding/api package.

Thanks to all for checking this out. I'm guessing over the next weeks/months/year many things will change (quickly) with the Amazon Echo developer community, the developer APIs, etc, but I'll do my best to keep up with things and will certainly look at and appreciate any pull requests, feature requests, etc.

##//todo

I'd consider this currently to be in a beta. I have no doubt bugs will pop up as I continue to really test this and I'd really appreciate any feedback, bug reports, feature requests, or comments. There are a number of aspects I'm still not sure I won't change a bit (for instance the Alexa:: facade if you use it does a lot of different things and I'm thinking I might be wise to split up some functionality.

  1. Find some way of not requiring replacing the default Application!
  2. Add the sessions to the response without requiring the user return an instance of AlexaResponse
  3. Tests!!!!
  4. Add some sort of simple authentication option for authenticating Echo devices/user based on the userIds
  5. Figure out the best way to verify the request is coming from Amazon - not sure this is possible or will be possible, but hopefully soon
  6. Add basic helpers for parsing speech from Alexa - not exactly "done", but I've added some options to help. I'd be very interested in your opinion on how this might be done to be helpful!

alexa-app's People

Contributors

amenk avatar arranjacques avatar colinodell avatar develpr avatar f-liva avatar f2m2rd avatar jissereitsma avatar michaeljhopkins avatar olofguard avatar schnoop avatar wertmenschen avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

alexa-app's Issues

My Alexa Routes are not found (Laravel)

I am trying to get a "hello world" up and running

  • Laravel 5.5
  • i have configured aliases and providers as documented
  • the alexa.php config file is in my config.folder
  • regular routes work

in web.php I have included:
\AlexaRoute::launch('/your-app-uri', 'App\Http\Controllers\AnyController@anyMethod');

And created AnyController and anyMethod.

When I launch /your-app-uri I am getting a 404. Same when I post something against this URL using Postman. artisan route:list does not show your-app-uri as valid url.

Is this supposed to be like this? Did I miss anything to get the AlexaRouter working?

Compatibility issues with Lumen 5.2.8?

I'm pretty sure I've configured this library correctly, but when I send requests into Lumen I get this exception:

[2016-08-10 22:00:36] lumen.ERROR: exception 'ReflectionException' with message 'Class alexa.router.middleware does not exist' in /srv/www/alexa-project/vendor/illuminate/container/Container.php:734
Stack trace:
#0 /srv/www/alexa-project/vendor/illuminate/container/Container.php(734): ReflectionClass->__construct('alexa.router.mi...')
#1 /srv/www/alexa-project/vendor/illuminate/container/Container.php(629): Illuminate\Container\Container->build('alexa.router.mi...', Array)
#2 /srv/www/alexa-project/vendor/laravel/lumen-framework/src/Application.php(206): Illuminate\Container\Container->make('alexa.router.mi...', Array)
#3 /srv/www/alexa-project/vendor/illuminate/container/Container.php(1174): Laravel\Lumen\Application->make('alexa.router.mi...')
#4 /srv/www/alexa-project/vendor/develpr/alexa-app/src/Provider/AlexaServiceProvider.php(97): Illuminate\Container\Container->offsetGet('alexa.router.mi...')
#5 /srv/www/alexa-project/vendor/illuminate/container/Container.php(731): Develpr\AlexaApp\Provider\AlexaServiceProvider->Develpr\AlexaApp\Provider\{closure}(Object(Laravel\Lumen\Application), Array)
#6 /srv/www/alexa-project/vendor/illuminate/container/Container.php(629): Illuminate\Container\Container->build(Object(Closure), Array)
#7 /srv/www/alexa-project/vendor/laravel/lumen-framework/src/Application.php(206): Illuminate\Container\Container->make('Develpr\\AlexaAp...', Array)
#8 /srv/www/alexa-project/vendor/laravel/lumen-framework/src/Concerns/RoutesRequests.php(362): Laravel\Lumen\Application->make('Develpr\\AlexaAp...')
#9 /srv/www/alexa-project/vendor/laravel/lumen-framework/src/Concerns/RoutesRequests.php(343): Laravel\Lumen\Application->callTerminableMiddleware(Object(Illuminate\Http\Response))
#10 /srv/www/alexa-project/public/index.php(28): Laravel\Lumen\Application->run()
#11 {main}  

From what I can tell, alexa.router.middleware is only defined in the LaravelServiceProvider. In LumenServiceProvider there's a app.middleware defined instead.

I tried changing this app.middleware string to alexa.router.middleware but that led to another exception:

[2016-08-10 22:04:29] lumen.ERROR: exception 'ErrorException' with message 'Argument 1 passed to Develpr\AlexaApp\Http\Middleware\Request::__construct() must be an instance of Illuminate\Contracts\Foundation\Application, instance of Laravel\Lumen\Application given, called in /srv/www/alexa-project/vendor/develpr/alexa-app/src/Provider/AlexaServiceProvider.php on line 97 and defined' in /srv/www/alexa-project/vendor/develpr/alexa-app/src/Http/Middleware/Request.php:44
Stack trace:
#0 /srv/www/alexa-project/vendor/develpr/alexa-app/src/Http/Middleware/Request.php(44): Laravel\Lumen\Application->Laravel\Lumen\Concerns\{closure}(4096, 'Argument 1 pass...', '/srv/www/alexa....', 44, Array)
#1 /srv/www/alexa-project/vendor/develpr/alexa-app/src/Provider/AlexaServiceProvider.php(97): Develpr\AlexaApp\Http\Middleware\Request->__construct(Object(Laravel\Lumen\Application), Object(Develpr\AlexaApp\Http\Routing\AlexaRouter), Object(Develpr\AlexaApp\Request\AlexaRequest), Array)
#2 /srv/www/alexa-project/vendor/illuminate/container/Container.php(731): Develpr\AlexaApp\Provider\AlexaServiceProvider->Develpr\AlexaApp\Provider\{closure}(Object(Laravel\Lumen\Application), Array)
#3 /srv/www/alexa-project/vendor/illuminate/container/Container.php(629): Illuminate\Container\Container->build(Object(Closure), Array)
#4 /srv/www/alexa-project/vendor/laravel/lumen-framework/src/Application.php(206): Illuminate\Container\Container->make('Develpr\\AlexaAp...', Array)
#5 /srv/www/alexa-project/vendor/laravel/lumen-framework/src/Concerns/RoutesRequests.php(362): Laravel\Lumen\Application->make('Develpr\\AlexaAp...')
#6 /srv/www/alexa-project/vendor/laravel/lumen-framework/src/Concerns/RoutesRequests.php(343): Laravel\Lumen\Application->callTerminableMiddleware(Object(Illuminate\Http\Response))
#7 /srv/www/alexa-project/public/index.php(28): Laravel\Lumen\Application->run()
#8 {main}

Any thoughts or guidance would be really appreciated - this is my first time working on a Laravel/Lumen application, so I'm a bit over my head.

Edit: Removed the first exception, I think that was the result of me messing around with things.

Not possible to use route:cache

First of all: Thanks for this repository.

I noticed that i can't use php artisan route:cache anymore, because the following part in LaravelServiceProvider @ 22 is using a closure.

    if ($this->app['config']['alexa.audio.proxy.enabled'])
    {
        Route::get($this->app['config']['alexa.audio.proxy.route'] . '/{audiofile}', function($audiofile) {
            return response(base64_decode($audiofile))
                ->header('Content-Type', 'application/x-mpegurl');
        });
    }

Maybe there is a chance to fix that.
Thanks in advance and keep up the good work.

Laravel: 5.5.4
PHP: 7.1.15

Getting ConfirmIntents to work.

Hello,

Thanks for the great library. I'm currently trying to get Confirm Intent to work, but Alexa seems to hate the syntax or something.

I'm doing the following;

if ($request->getConfirmationStatus() == 'NONE') {
            $speech = new Speech('Are you sure?');
            return $response->setSpeech($speech)->withDirective(new ConfirmIntent())->endSession(false);
}

Which gives the response;

{
    "version": "1.0",
    "response": {
        "outputSpeech": {
            "type": "PlainText",
            "text": "Are you sure? This will reset your existing game."
        },
        "directives": [
            {
                "type": "Dialog.ConfirmIntent",
                "updatedIntent": {
                    "name": "NewGameIntent",
                    "confirmationStatus": "NONE",
                    "slots": []
                }
            }
        ],
        "shouldEndSession": false
    }
}

This is how it's set up in the Skill Builder.

I just get the classic exception occurred session ended request back;

request": {
        "type": "SessionEndedRequest",
        "requestId": "amzn1.echo-api.request.e5abdcaa-66c0-4bf1-s11d-aab0f6d1ee1a",
        "timestamp": "2017-10-19T15:49:30Z",
        "locale": "en-GB",
        "reason": "ERROR",
        "error": {
            "type": "INVALID_RESPONSE",
            "message": "An exception occurred while dispatching the request to the skill."
        }
    }

I've read through the Amazon docs on the Dialog Model etc but still struggling to grasp what I'm doing wrong.

Any assistance would be fantastic!

SSML generated by app cannot be played by echo (probably wrong usage of lib)

I am trying to use SSML. This is what I have so far:

$out = 'Test <say-as interpret-as="interjection"> abracadabra!</say-as> Something else';
return \Alexa::say($out, "SSML")->endSession(false);

In the simulator this arrives as:

"outputSpeech": {
      "ssml": "Test <say-as interpret-as=\"interjection\"> abracadabra!</say-as> Something else",
      "type": "SSML"
    },

The simulator can output this, the real device refuses to do that ("problem has occured" -> don't know the correct error msg in English).

Questions:

  • is it correct that the output is not enclosed in a speak-Tag?
  • is it correct that there are backslashes around "interjection"?

In other words: How can I bring SSML to life with this library?

Yes or No ConfirmIntent

@kevin-mitchell

First of all thanks for a great package.

It really helps a lot to learn.

I am working on a demo that has multiple result around 3.

Now I need to Alexa to speak each of those result and have user responded to it by saying yes or no.

I couldn’t find a way and it always came as sorry but something went wrong with the request.

I would appreciate your help on the same.

Thanks
Vik

Can't get middleware Certificate::class to work on routes

Laravel 5.6
This package has been excellent - really well put together and easy to use. However, I have hit a snag.

I need to use the Certificate class middleware on a group of routes, but cannot get it to 'construct' or 'handle' in any of the routes I have tried.

I have the middleware registered as:

protected $routeMiddleware = [
   'alexa' => \Develpr\AlexaApp\Http\Middleware\Certificate::class,
];

Tried routes configurations like:

Route::middleware('alexa')->group(function () ...
AlexaRoute::middleware('alexa')->group(function () ...
Route::group(['middleware' => 'alexa'], function() ...
AlexaRoute::intent(...)->middleware('alexa');

...and have tried it in the constructor of the Controller I use:
$this->middleware('alexa');

None cause the middleware to be hit. I've kind of run out of ideas on what I should do next. Any ideas?

Route for Messaging.MessageReceived

I am having trouble registering routes for 'type': 'Messaging.MessageReceived'.

same goes for the intent AMAZON.StopIntent

Can you please support?

Alexa and Alexa Route Facades do not work...laravel5.4

Ive gone over everything and I cannot get a AlexaRoute::launch to work it seems this is the same issue I had about a year ago when I tried this with 5.3.

I am however able to get a response as you do in your video but by using ROUTE::POST using the postman app I send a post request with the launch request I get from the alexa skill kit and I get {"version":"1.0","response":{"shouldEndSession":true}} but honestly I dont know if that is saying anything or not. I havent been able to write a response where it will return anything more.

route not found on Laravel 5.5

I am trying to use this package in an app, but every time I add it my POST route gives not found exception NotFoundHttpException when used with a JSON payload.

Route::post('/talk', 'ConversationController@talk')->name('talk');

The error is the following

{
"message": "",
"exception": "Symfony\Component\HttpKernel\Exception\NotFoundHttpException",
"file": "/home/vagrant/lizuk/vendor/laravel/framework/src/Illuminate/Routing/RouteCollection.php",
"line": 179,
"trace": [
{
"file": "/home/vagrant/lizuk/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
"line": 612,
"function": "match",
"class": "Illuminate\Routing\RouteCollection",
"type": "->"
},
{
"file": "/home/vagrant/lizuk/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
"line": 601,
"function": "findRoute",
"class": "Illuminate\Routing\Router",
"type": "->"
},
{
"file": "/home/vagrant/lizuk/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
"line": 590,
"function": "dispatchToRoute",
"class": "Illuminate\Routing\Router",
"type": "->"
},
{
"file": "/home/vagrant/lizuk/vendor/develpr/alexa-app/src/Http/Middleware/Request.php",
"line": 83,
"function": "dispatch",
"class": "Illuminate\Routing\Router",
"type": "->"
},
{
"file": "/home/vagrant/lizuk/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
"line": 114,
"function": "Develpr\AlexaApp\Http\Middleware\{closure}",
"class": "Develpr\AlexaApp\Http\Middleware\Request",
"type": "->"
},
{
"file": "/home/vagrant/lizuk/vendor/fideloper/proxy/src/TrustProxies.php",
"line": 56,
"function": "Illuminate\Pipeline\{closure}",
"class": "Illuminate\Pipeline\Pipeline",
"type": "->"
},
{
"file": "/home/vagrant/lizuk/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
"line": 149,
"function": "handle",
"class": "Fideloper\Proxy\TrustProxies",
"type": "->"
},
{
"file": "/home/vagrant/lizuk/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php",
"line": 30,
"function": "Illuminate\Pipeline\{closure}",
"class": "Illuminate\Pipeline\Pipeline",
"type": "->"
},
{
"file": "/home/vagrant/lizuk/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
"line": 149,
"function": "handle",
"class": "Illuminate\Foundation\Http\Middleware\TransformsRequest",
"type": "->"
},
{
"file": "/home/vagrant/lizuk/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php",
"line": 30,
"function": "Illuminate\Pipeline\{closure}",
"class": "Illuminate\Pipeline\Pipeline",
"type": "->"
},
{
"file": "/home/vagrant/lizuk/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
"line": 149,
"function": "handle",
"class": "Illuminate\Foundation\Http\Middleware\TransformsRequest",
"type": "->"
},
{
"file": "/home/vagrant/lizuk/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php",
"line": 27,
"function": "Illuminate\Pipeline\{closure}",
"class": "Illuminate\Pipeline\Pipeline",
"type": "->"
},
{
"file": "/home/vagrant/lizuk/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
"line": 149,
"function": "handle",
"class": "Illuminate\Foundation\Http\Middleware\ValidatePostSize",
"type": "->"
},
{
"file": "/home/vagrant/lizuk/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/CheckForMaintenanceMode.php",
"line": 46,
"function": "Illuminate\Pipeline\{closure}",
"class": "Illuminate\Pipeline\Pipeline",
"type": "->"
},
{
"file": "/home/vagrant/lizuk/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
"line": 149,
"function": "handle",
"class": "Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode",
"type": "->"
},
{
"file": "/home/vagrant/lizuk/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
"line": 102,
"function": "Illuminate\Pipeline\{closure}",
"class": "Illuminate\Pipeline\Pipeline",
"type": "->"
},
{
"file": "/home/vagrant/lizuk/vendor/develpr/alexa-app/src/Http/Middleware/Request.php",
"line": 84,
"function": "then",
"class": "Illuminate\Pipeline\Pipeline",
"type": "->"
},
{
"file": "/home/vagrant/lizuk/vendor/develpr/alexa-app/src/Http/Middleware/Request.php",
"line": 65,
"function": "sendRequestThroughRouter",
"class": "Develpr\AlexaApp\Http\Middleware\Request",
"type": "->"
},
{
"file": "/home/vagrant/lizuk/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
"line": 149,
"function": "handle",
"class": "Develpr\AlexaApp\Http\Middleware\Request",
"type": "->"
},
{
"file": "/home/vagrant/lizuk/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php",
"line": 53,
"function": "Illuminate\Pipeline\{closure}",
"class": "Illuminate\Pipeline\Pipeline",
"type": "->"
},
{
"file": "/home/vagrant/lizuk/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
"line": 102,
"function": "Illuminate\Routing\{closure}",
"class": "Illuminate\Routing\Pipeline",
"type": "->"
},
{
"file": "/home/vagrant/lizuk/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php",
"line": 151,
"function": "then",
"class": "Illuminate\Pipeline\Pipeline",
"type": "->"
},
{
"file": "/home/vagrant/lizuk/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php",
"line": 116,
"function": "sendRequestThroughRouter",
"class": "Illuminate\Foundation\Http\Kernel",
"type": "->"
},
{
"file": "/home/vagrant/lizuk/public/index.php",
"line": 55,
"function": "handle",
"class": "Illuminate\Foundation\Http\Kernel",
"type": "->"
}
]
}

If I remove the package everything is working fine. I am using Laravel 5.5.32

Do you have any insight into this?

Any way to try this with 5.3?

I would like to try this out to make an alexa app. when I try to install it it says framework needs to be 5.3.* Is this something I can just change a setting on to try it or will it not work at all? It seems a lot of the files are integrated into my project but I cant get the Develpr\App or the Bootstrap middleware to work.

Update to work with Laravel 7.x

This library isn't exactly SUPER popular but it seems like there is still some interest in using it. I've been off in enterprise Java world for a while but it sounds useful to update this and improve it / add some more automated testing.

Facades/Aliases do not work? (Laravel 5.5)

hi,

i am using:
"laravel/installer": "^2.0"
"php": ">=7.0.0",
"develpr/alexa-app": "^0.3.5",
"fideloper/proxy": "~3.3",
"laravel/framework": "5.5.*",
"laravel/tinker": "~1.0"

I configured everything according to the Readme and it partly works.

In config/web.php:

WORKS:
AlexaRoute::intent('/alexa-end-point', 'TestIntent', function(){
return Alexa::say("Hello World!");
});

DOES NOT WORK:
AlexaRoute::intent('/alexa-end-point', 'TestIntent', 'App\Http\Controllers\AlexaController@alexaIntent');

Error message in storage/log/laravel.log:
[2018-02-05 16:33:00] local.ERROR: Class 'App\Http\Controllers\Alexa' not found {"exception":"[object] (Symfony\Component\Debug\Exception\FatalThrowableError(code: 0): Class 'App\Http\Controllers\Alexa' not found at /data/web/e10622/html/alexa/test/app/Http/Controllers/AlexaController.php:14)

my full AlexaController.php:

Update documentation

Documentation needs to be updated with new changes, and in the interest of full disclosure the docs need to reflect any feature gaps between what Amazon let's us do with ASK and what the this library / package will support easily (for example there could be better support for oauth, etc)

withAudio directive doesn't cache audio url

Unlike AlexaResponse::play, the AlexaResponse::withAudio method does not cache the stream url, making it impossible to resume the stream after the pause or stop.

Is this a desired behavior or can I prepare a pull request to fix the problem?

Route not found exception Laravel 5.7

{
"message": "",
"exception": "Shttps://github.com/develpr/alexa-app/issues/60ymfony\Component\HttpKernel\Exception\NotFoundHttpException",
"file": "{my-root-path}/vendor/laravel/framework/src/Illuminate/Routing/RouteCollection.php",
"line": 179,
"trace": [
{
"file": "{my-root-path}/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
"line": 636,
"function": "match",
"class": "Illuminate\Routing\RouteCollection",
"type": "->"
},
{
"file": "{my-root-path}/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
"line": 625,
"function": "findRoute",
"class": "Illuminate\Routing\Router",
"type": "->"
},
.................
]
}

Api.php

AlexaRouter::launch('/alexa', 'AlexaController@alexalaunch');
AlexaRouter::intent('/alexa', 'GetAntiJoke', 'AlexaController@alexaGetJoke' );
AlexaRouter::intent('/alexa', 'GetColorIntent', 'AlexaController@alexaGetColor' );
AlexaRouter::intent('/alexa', 'TellColorIntent', 'AlexaController@alexaTellColor' );
AlexaRoute::sessionEnded ('/alexa', function () {
        return '{"version":"1.0","response":{"shouldEndSession":true}}';
    });

AlexaController.php --path=App\Http\Controllers
`<?php

namespace App\Http\Controllers;

use Develpr\AlexaApp\Request\AlexaRequest;
use Illuminate\Http\Request;
use Develpr\AlexaApp\Facades\Alexa;
use Develpr\AlexaApp\Response\AlexaResponse;
use App\Http\Controllers\BaseApiController;

class AlexaController extends Controller {

function test () {
	dd('test');
}

/**
 * Alexa launch request.
 * @var alexa request data
 * @return json
 */
function alexalaunch(AlexaRequest $alexarequest) {
	return Alexa::ask ( "Hello, welcome to support center. You can ask say my color is red" )
	->endSession ( 'false' );
}
/**
 * Alexa intent request.
 * @var alexa request data
 * @return json
 */
function alexaGetColor(AlexaRequest $alexarequest) {
	$color = $alexarequest->slot ( "color" );
	$session = Alexa::session ( 'color', $color );
	return Alexa::say ( "Great, your color is " . $color . ". Now you can ask me what's my color." )->endSession ( 'false' );
}

/**
 * Alexa intent request.
 * @var alexa request data
 * @return json
 */
function alexaGetJoke(AlexaRequest $alexarequest) {
	return Alexa::ask ( "Hello, welcome to support center. You can ask say my color is red" )
	->endSession ( 'false' );
}

/**
 * Alexa intent request.
 * @var alexa request data
 * @return json
 */
function alexaTellColor() {
	$color = Alexa::session( 'color' );
	return Alexa::say ( 'I remember your color is ' . $color . ". Good Bye." )->endSession (‘true’);
}

/**
 * Alexa termination intent request.
 * @var alexa request data
 * @return json
 */
function alexaTerminate(AlexaRequest $alexarequest) {
	return Alexa::ask ( "Goodbye, have a nice day." )->endSession ();
}

}`

I seen many solution but not a single is working. can anyone please help with this?

laravel 5.8 and launch request and even intent is always 404

Hi,

im using laravel 5.8 and launch request and even intent is always 404. Im sure i follow the correct installation i.e.

config/app.php
'providers' => [
\Develpr\AlexaApp\Provider\LaravelServiceProvider::class,
],

'aliases' => [
'AlexaRoute' => \Develpr\AlexaApp\Facades\AlexaRouter::class,
'Alexa' => \Develpr\AlexaApp\Facades\Alexa::class,
],

routes/web.php
AlexaRoute::launch('/alexa', 'App\Http\Controllers\AlexaController@launch');

AlexaRoute::sessionEnded('/alexa', function() {
return '{"version":"1.0","response":{"shouldEndSession":true}}';
});

AlexaRoute::intent('/alexa', 'HelloWorldIntent', 'App\Http\Controllers\AlexaController@helloWorldIntent');

app/Http/Controllers/AlexaController.php
namespace App\Http\Controllers;

use Illuminate\Http\Request;

use Alexa;

class AlexaController extends Controller
{
public function launch(){
return Alexa::say("This is launch intent");
}

public function helloWorldIntent(){
  return Alexa::say("This is hello world intent");
}

}

What am i missing?

Thanks in advance

Not working with Laravel 5.3/5.4

This does not work with a fresh install on Laravel 5.3/5.4 due to requiring illuminate/routing v5.2.* in composer.json. May you please update the dependency or will this cause any issues?

Thanks & best regards
Sebastian

Laravel 5.3 Issues

Have you done any testing with Laravel 5.3? I forked and updated the illuminate/routing dependency to 5.3.* and am able to get things in a mostly functional state.

The largest issue I've run into so far is that it doesn't appear that routes are being created with the attributes from their parent group. I have a Route::group statement with a route prefix and namespace defined in my RouteServiceProvider.php file, which then includes a file containing an AlexaRoute route. That route is returning a 404 when attempting to access the route including the prefix, but working when defining the AlexaRoute with the prefix. When not including the namespace that was already defined on the group the route also returns an error.

For example with this group in my route service provider:

Route::group([
    'middleware' => 'integrations',
    'namespace' => $this->namespace . '\Integrations',
    'prefix' => 'integrations',
    'as' => 'integrations.',
], function ($router) {
    require base_path('routes/integrations.php');
});

This configuration does not work:

AlexaRoute::intent('alexa', 'intent', 'AlexaController@intent');

While this configuration does work:

AlexaRoute::intent('integrations/alexa', 'intent', 'App\Http\Controllers\Integrations\AlexaController@intent');

Non-static functions

In implementing this I have run into numerous issues, but the central issue I'm seeing seems to relate to the fact that all of the functions in src/Alexa.php are public, non-static functions, yet your readme indicates that they should be called statically. You list Alexa::say("Hello") and Alexa::slot('choice') in your readme, but both functions are non-static. Simply changing say() to a public static function resolves the issue for that function, but the slot() function references $this within itself, and therefore cannot be changed to a static function. Are there unpushed commits or something else I am missing here?

Publish new version of alexa-app

It seems that recent version was published long time ago. Much improvements are contributed in library after that. There are much new features which are awesome but we can't use it. Hope you will publish it ASAP.

Facades cause Ide-Helper to throw 'Segmentation Fault'

Running ide-helper:generate causes a segmentation fault to be thrown when the faces are enabled from this app? Any idea what might be causing this? I wish I had more to give but there isn't much given to me.

http://i.imgur.com/DRaptgQ.png

EDIT: it looks like it's specifically the AlexaRoute facade that causes issue
EDIT: the issue also occurs with neither facade (only the service provider) when running ide-helper:meta

The skill end-point is not accepting valid signed requests.

I've added the certificate middleware to the laravel global http middleware stack

protected $middleware = [
     \Develpr\AlexaApp\Http\Middleware\Certificate::class,
];

Additionally I've set the ALEXA_VERIFY_APP_ID variable in my .env file.

After submitting the skill to Amazon I got this rejection:

The skill end-point is not accepting valid signed requests. Please make sure that your signature URL validation is correct. Please refer to our documentation on how to build your Alexa Skill as a web service and validate requests and signatures.

Did I forgot something?

Suggestion: have AlexaResponse end the session by default

I experienced "strange" behavior when trying to implement Alexa::say() in my controller per the README. After reading out the response text, Alexa would:

  • Keep the blue ring lit
  • Continue listening to me
  • Say there was an error with the skill
  • Show a card on my Alexa app about the skill returning a 404 error

I eventually determined this happened because the session was not closed - I didn't call $request->endSession() after creating the response. This was not obvious to me.

IMO, AlexaResponse should provide the simplest usage by default and allow you to enable extra features like cards, reprompts, etc. by simply making additional calls or setting additional parameters. This does seem to be the case for everything except whether the session is kept open.

For example, if I want Alexa to simply say something aloud, Alexa::say('Hello World') should just work. Needing to add ->endSession() adds unnecessary complexity for this simple case.

On the other hand, if I do want to keep the session open, I'd perceive this as being more complex and would therefore expect the need to call ->endSession(false) to "enable" this extra functionality.

I'd therefore like to propose changing the default value of $shouldSessionEnd to true.

(Hopefully I'm making sense, even if you disagree haha)

Amazon responds with a 404

Hi,
I'm getting a 404 in the Amazon Service Simulator. I don't know if it is a bug or not, but I have seen in some discussions that many developers have problems with this package.
My Utterance is just "Open ......" (the launchIntent). My middleware logs all requests and responses.
The request type is "LaunchRequest"
Response:

    \"exception\": \"Symfony\\\\Component\\\\HttpKernel\\\\Exception\\\\NotFoundHttpException\",
    \"file\": \"/var/www/alexa/vendor/laravel/framework/src/Illuminate/Routing/RouteCollection.php\",
    \"line\": 179,

I defined my endpoint at amazon developers page as https://alexa.mydomain.de/alexa

My routes\web.php looks like this:

AlexaRoute::launch('/alexa', function () {
    return Alexa::say("Oh yes")->endSession();
});

Can someone help me please?
Thanks

Edit: Laravel Framework 5.5.28

no routes with laravel 5.6

i know, this issue about missing routes is nothing new. but i didn´t find any helpful hints in all these issues with that topic. is someone able to see the routes with laravel 5.6 ?

Add Card Type Standard with Image support

There is a third Card Type "Standard" (Simple, LinkAccount are already implemented) which includes Image URLs to display on Fire TV Sticks or the new Alexa Show.

Security issue in route authorization using passport

I'm using passport to authenticate the Alexa routes with account linking functionality.

Actual (What I'm doing)

I have api.php routes file as below and my api driver is set to passport,

<?php


Route::group(['prefix' => 'api'], function () {

	require 'alexa.php';

	Route::get('/user',function (){

	   return response()->json(['status' => 'I am In!']);
    });
});

my alexa.php is as below,

<?php

AlexaRoute::launch('/alexa', '\App\Http\Controllers\AlexaController@start');
....
?>

Issues

  • When I need to provide endpoint it should be https://my-app.dev/api/alexa but, I have to provide it as https://my-app.dev/alexa as prefixing dose not seems to work, same way if I want to access user route it works as expected.

  • As my api drivers are set to passport in config\auth.php then my alexa.php routes should be authenticated right? But they wont! I setup account linking and everything works fine too but, if I remove account linking and try to envoke the skill with only endpoint provided, it works!!
    As I have provided alexa routes in closure with passport authentication they should not be invoked without authentication.

Expected

  • Prefix should work. (It took me day to figure out what is wrong with url. For first time users it is very confusing)
  • After setup of passport and account linking everything works great, but user will be in impression that their routes are authenticated. But they are not!!! Anyone can access same alexa routes without authentication.

Is there any work around to get authentication issue fixed? as I can see Router is extended for use and maybe there would be any work around.

Thanks
Happy Coding

Code style and repo best-practices

Would you be opposed to me cleaning up the code style to be PSR-2 compliant (so that it passes StyleCI checks)?

I'd also like to perform some minor housekeeping like:

  • Using consistent indentation in composer.json (spaces instead of tabs)
  • Adding a branch alias for dev-master (like I do here for league/commonmark)
  • Adding a LICENSE file to the repo root
  • Adding a CHANGELOG and populating it for you

Stuff like that.

I just don't want to start on this work if you're not interested :)

Routing order does matter?!

If I use routes for sessionEnded and intent and sessionEnded is after intent, it fails with a 404.
If sessionEnded is on top, it works.

Sebastian

PlaybackController Events

Echo Show or Echo Spot provides a touch Interface. If you stream an audio stream you can control the playback with touch events, e.g. "PlaybackController.NextCommandIssued" if you touch the next Button.

https://developer.amazon.com/de/docs/alexa-voice-service/playbackcontroller.html

There is no way to listen for this, because this is no intent / audioPlayer / launch event. And if you don't handle this Amazon gives you a "INVALID_RESPONSE" response.

Is it possible to make a route like "AlexaRoute::playback()" for this purpose? Or maybe a general function to add Alexa routes for the future (addAlexaRoute() is protected).

Thanks
Jörg

Can't install it on 5.5

Using version ^0.3.4 for develpr/alexa-app
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.

Problem 1
- Installation request for develpr/alexa-app ^0.3.4 -> satisfiable by develpr/alexa-app[0.3.4].
- Conclusion: remove laravel/framework v5.5.3
- Conclusion: don't install laravel/framework v5.5.3
- develpr/alexa-app 0.3.4 requires illuminate/routing 5.4.* -> satisfiable by illuminate/routing[v5.4.0, v5.4.13, v5.4.17, v5.4.19, v5.4.27, v5.4.36, v5.4.9].
- don't install illuminate/routing v5.4.0|don't install laravel/framework v5.5.3
- don't install illuminate/routing v5.4.13|don't install laravel/framework v5.5.3
- don't install illuminate/routing v5.4.17|don't install laravel/framework v5.5.3
- don't install illuminate/routing v5.4.19|don't install laravel/framework v5.5.3
- don't install illuminate/routing v5.4.27|don't install laravel/framework v5.5.3
- don't install illuminate/routing v5.4.36|don't install laravel/framework v5.5.3
- don't install illuminate/routing v5.4.9|don't install laravel/framework v5.5.3
- Installation request for laravel/framework (locked at v5.5.3, required as 5.5.*) -> satisfiable by laravel/framework[v5.5.3].

Installation failed, reverting ./composer.json to its original content.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.