Deploy Your Laravel Forge Sites With Your Voice
Let me show you, how you can create your own Amazon Alexa skill to have a voice powered deployment system for Laravel Forge.
What You Need #
In order to get started, you first need to create an account at https://developer.amazon.com.
Once you have that, we'll start by creating a new BotMan project - this will power our chatbot and drastically simplifies the code that we're going to write.
composer create-project botman/studio alexa-forge-bot
This will create a folder called "alexa-forge-bot" and the basic BotMan Studio installation.
Next, we're going to add the Amazon Alexa BotMan driver, in order to support Alexa requests / responses.
composer require botman/driver-amazon-alexa
And since we're going to use the Laravel Forge API, we will install the official Forge SDK too:
composer require themsaid/forge-sdk
Also make sure that you have your Laravel Forge API token at hand, we're going to need it later.
In order to test your chatbot with Amazon Alexa, you'll also need to access your chatbot from a publicly accessible URL running over HTTPS.
The easiest way to do this is by using valet share
- if you're not familiar with Laravel Valet - take a look at the documentation to get started.
Configuring The Skill #
Go to the Amazon Developer page and click on "Alexa" and select "Get started" at the Alexa Skills-Kit section.
Now we need to create a new Alexa Skill and configure it.
When creating the Alexa skill, you can change the Language of your skill, the name and the invocation name - that's the name you're going to use when talking to Alexa. Like "Alexa ask Laravel Forge to ...".
Your Interaction Model #
The interaction model is the actual "brain" of your Alexa Skill - it determines how your Alexa skill will work and what it will react to. You can of course use the Skill Builder to visually build your Alexa skill, but for the sake of simplicity, here's an example Intent Schema you can use:
{
"intents": [
{
"slots": [
{
"name": "domain",
"type": "AMAZON.LITERAL"
}
],
"intent": "DeployForgeSite"
}
]
}
So all we do is, we tell Alexa that we can trigger a custom intent called "DeployForgeSite" which has a "slot" called "domain". You can basically just think of "slots" as variables - in our case it's just a string that we get along with the intent, this will be the domain name that we're going to deploy.
Sample Utterances #
Next up, you need to define a couple of sample utterances that will trigger the custom skill. They get prefixed with the intent name, that you want to trigger with the sentence.
These are mine:
DeployForgeSite Deploy {laravel.com|domain}
DeployForgeSite Start deployment for {laravel.com|domain}
DeployForgeSite Ship {laravel.com|domain}
Modify them as you wish :)
Endpoint Configuration #
On the next page, you will need to provide your HTTPS endpoint, that you received from "valet share".
Change the endpoint type to "HTTPS" and paste the URL into the "Default" field and append a "/botman" - this is the default route for all incoming bot requests, that BotMan will handle.
SSL Certificate #
If you are using valet share / ngrok to test your alexa skill, make sure to select the second option regarding the SSL certificate:
My development endpoint is a sub-domain of a domain that has a wildcard certificate from a certificate authority
Your Chatbot Logic #
All that is left to implement is the actual chatbot logic in our application. Open up the "routes/botman.php" file - this is the file that holds your entire chatbot logic.
Edit it so it looks like the following:
<?php
use Themsaid\Forge\Forge;
$botman = resolve('botman');
$botman->hears('DeployForgeSite', function ($bot) {
$domainSlot = $bot->getMessage()->getExtras('slots')->get('domain');
$domain = $domainSlot['value'];
$site = find_site_by_name($domain);
if (is_null($site)) {
$bot->reply('Sorry, I could not find a site called '.$domain);
} else {
$forge = new Forge(env('FORGE_TOKEN'));
$forge->deploySite($site->serverId, $site->id);
$bot->reply('Deploying '.$domain.'! Ship it!');
}
});
function find_site_by_name($domain) {
$forge = new Forge(env('FORGE_TOKEN'));
foreach ($forge->servers() AS $server) {
$site = collect($forge->sites($server->id))->first(function ($site) use ($domain) {
return $site->name === $domain;
});
if ($site !== null) {
return $site;
}
}
return null;
}
Let's take a look at the code, step by step.
$botman->hears('DeployForgeSite', function ($bot) {
This tells our chatbot: When Alexa hears a message for the DeployForgeSite intent, we want the closure to be executed.
$domainSlot = $bot->getMessage()->getExtras('slots')->get('domain');
$domain = $domainSlot['value'];
Using the getExtras('slots')
method, we can access the value of the "slot" that we defined earlier in the Alexa Skill builder. This way, we can access the domain that we need to deploy.
$site = find_site_by_name($domain);
if (is_null($site)) {
$bot->reply('Sorry, I could not find a site called '.$domain);
} else {
$forge = new Forge(env('FORGE_TOKEN'));
$forge->deploySite($site->serverId, $site->id);
$bot->reply('Deploying '.$domain.'! Ship it!');
}
This is pretty straightforward - we use the custom "find_site_by_name" method to determine the site_id and server_id that we will need to send to the Laravel Forge API - then we're deploying the site and use the $bot->reply
method to reply text back to the user.
This text will then be sent to Alexa as a response, so Alexa knows what to reply.
As you can see, I placed my Laravel Forge API token in a FORGE_TOKEN
environment variable in my .env
file.
Testing #
In order to test your Alexa Skill, head back to the Amazon Developer page and go to the "Test" tab at your Skill page. Here you can either type the text that you want Alexa to hear, or you can enable testing your skill locally and use it on your Alexa device right away.
Wrapping Up #
That's it - you built your first Alexa Skill using BotMan! :) If you want to learn more about Chatbots and how to build them with BotMan, be sure to take a look at Build A Chatbot - my upcoming video course.