Skip to content

Commit 3966820

Browse files
committed
Use JSON as a config instead of .env files.
1 parent d730fe0 commit 3966820

File tree

8 files changed

+162
-48
lines changed

8 files changed

+162
-48
lines changed

.env

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,4 @@ AWS_HANDLER=index.handler
22
AWS_RUNTIME=nodejs6.10
33
EVENT_FILE=test_events/sickbeard_find_show.json
44
EXCLUDE_GLOBS=docs interaction_model src scripts test_events .babelrc .DS_Store .eslintignore .eslintrc context.json default.env event.json *.zip
5-
6-
SB_URL=http://url-to-couch-potato-server
7-
SB_API_KEY=apiKey
5+
NODE_CONFIG_DIR=./config

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
.DS_Store
22
deploy.env
33
alexa-sickbeard.zip
4+
config/local.json
45
dist/
56
node_modules/

README.md

Lines changed: 82 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -13,43 +13,93 @@ Kit](https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/gettin
1313
[Developing an Alexa Skill as a Lambda
1414
Function](https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/developing-an-alexa-skill-as-a-lambda-function) to get familiar with the process.
1515

16+
You can download a [pre-packaged version of the
17+
app](https://github.com/josephschmitt/alexa-sickbeard/releases/latest/) if you don't want to run
18+
from source..
19+
1620
## Configuring The Skill
1721

18-
To configure the skill, open up the `.env` file and fill in the correct values for `SB_URL`, which
19-
should point to your SickBeard server, and `SB_API_KEY` which should have your server's API key.
22+
Open the `config/default.json` file and fill in the right values for your server configuration.
2023

21-
## Testing The Skill Locally
24+
If you don't want to accidentally commit your configuration, then make a duplicate of the
25+
`default.json` file and call it `local.json`. It will override any configuration from default and
26+
is ignored by git.
2227

23-
You can use [node-lambda](https://github.com/motdotla/node-lambda) to test this skill locally. In
24-
the `test_events` directory are several event files you can use for testing, and they should map
25-
pretty well to each Intent. To test an intent, simply copy the contents of one of the json files in
26-
that directory and overwrite the contents of `event.json`. Then run `node-lambda run` from the
27-
command line.
28+
## Creating a Lambda function
29+
30+
The skill is built to be easily hosted on Amazon's [AWS Lambda
31+
service](https://aws.amazon.com/lambda/). You'll need to create an Amazon AWS account, and then head
32+
over to the [Lambda Dashboard](https://console.aws.amazon.com/lambda/home). Once there, click
33+
"Create a Lambda function", and provide the following settings:
34+
35+
1. **Select blueprint**: Click on _Blank Function_.
36+
2. **Configure triggers**: This one can be easy to miss. You should see a dotted out rounded square
37+
to the left of the Lambda logo. Click on it and from the dropdown, choose _Alexa Skills Kit_.
38+
3. **Configure function**:
39+
- Name: `alexa-sickbeard`. Honestly this can be whatever you want, but if you want to use the
40+
deploy function later, it's best to use the same name as the project here.
41+
- Description: Doesn't matter. Feel free to copy the project description.
42+
- Runtime: _Node.js 6.10_. You can choose the older version if you want, but if you do make
43+
sure to update the `.babelrc` file to tell babel to target the older verison of Node. If you
44+
don't know what that means, just go with 6.10.
45+
- Code entry type: _Upload a .ZIP file_. (Instructions on generating this ZIP file are below)
46+
- Lambda function handler and role: Under **Existing role** choose `lambda_basic_execution`.
47+
48+
Click Create lambda function and you're done. After you've created your Lambda function, look at the
49+
top right of the page to get your Lambda ARN number. You'll need this in the next step, so either
50+
write that number down, or keep this page open.
51+
52+
## Deploying the Skill
53+
54+
If you don't care about the nitty-gritty of NodeJS projects, you can just download the
55+
`alexa-sickbeard.zip` file from the [latest
56+
release](https://github.com/josephschmitt/alexa-sickbeard/releases/latest/), update the
57+
`config/default.json` file with your server settings, re-zip, and upload to lambda.
58+
59+
_If you want more control, or to make your own updates to the project, check out the master branch
60+
and then do an `npm install` at the project root. Once all the dependencies are installed, run
61+
`npm run package`, which will create an `alexa-sickbeard.zip` file in your project directory.
62+
Back in the Lambda dashboard, look to see where it says "Upload" next to "Function package". Click
63+
upload, choose the zip file, and click save._
64+
65+
_You can also use [node-lambda](https://github.com/motdotla/node-lambda) to deploy to your Lambda
66+
function directly from the command line. Simply add a deploy.env file with your environment
67+
configuration (and double check the supplied `.env file` in this repository) and then run
68+
`npm run deploy`. Please visit the [node-lambda](https://github.com/motdotla/node-lambda)
69+
project page for more information on deploying from the command line._
2870

2971
## Setting up the Skill
3072

3173
To set up the skill, head on over to [Alexa skills kit
32-
development console](https://developer.amazon.com/edw/home.html) and add a new skill. Fill in the
33-
basic skill information however you choose. For Endpoint, you'll need to fill in your Lambda ARN
34-
which you'll get in the next step. Next, head on over to Interaction Model. In the Intent
35-
Schema field, copy and paste the contents of the `interaction_model/intent_schema.json` file. Then
36-
in the Sample Utterances field, copy and paste the contents of
37-
`interaction_model/sample_utterances.txt`.
38-
39-
## Hosting the Skill
40-
41-
The skill is built to be easily hosted on Amazon's [AWS
42-
Lambda service](https://aws.amazon.com/lambda/). Create your Lambda function (using the
43-
alexa-skills-kit-color-expert blueprint) and make sure you choose Node.js as the runtime. After
44-
you've created your Lambda function, look at the top right of the page to get your Lambda ARN
45-
number and put that in the Alexa Skill Information Endpoint field.
46-
47-
To deploy to Lambda, first makes sure you do an `npm install` at the root of the project.
48-
Once all the dependencies are installed, run `npm run bundle`, which will create a lambda.zip file.
49-
You can then upload that zip file to Lambda for use in your function and skill.
50-
51-
You can also use [node-lambda](https://github.com/motdotla/node-lambda) to deploy to your Lambda
52-
function directly from the command line. Simply add a deploy.env file with your environment
53-
configuration (and double check the supplied .env file in this repository) and then run
54-
`node-lambda deploy`. Please visit the [node-lambda](https://github.com/motdotla/node-lambda)
55-
project page for more information on deploying from the command line.
74+
development console](https://developer.amazon.com/edw/home.html) and add a new skill by following
75+
these steps:
76+
77+
1. **Skill Information**: Fill in the basic skill information however you choose. If you're feeling
78+
uncreative, you can put `alexa-sickbeard` for the name, and `sick beard` for the _Invocation
79+
Name_.
80+
2. **Interaction Model**: In the Intent Schema field, copy the contents of the
81+
`interaction_model/intent_schema.json` file and paste them in. Then in the Sample Utterances field,
82+
copy the contents of `interaction_model/sample_utterances.txt` and paste those in. Make sure to Save
83+
your changes.
84+
3. **Configuration**: Set the Service Endpoint Type to AWS Lambda ARN, and choose your region. Now
85+
comes the time to grab the ARN from the previous step that you hopefully either wrote down or kept
86+
open in a different tab or browser window.
87+
4. **Test**: Make sure the toggle at the top is Enabled. You should now be able to test to make sure
88+
everything's working. Scroll down to the Service Simulator and in the Enter Utterance field, try
89+
asking Sick Beard one of the phrases from up top, like "is Silicon Valley on the list". If
90+
everything's working correctly, you should see data get filled in on both the Request and Response
91+
boxes. If you do, then you're pretty much done and all set.
92+
5. **Publishing Information**: This isn't necessary, but it helps the skill look nice in your Alexa
93+
app. You can fill in as much of the metadata as you like, but the one I'd really recommend is
94+
uploading an icon. An icon is included in this project and should work well for the 108x108 small
95+
icon slot.
96+
97+
And that's it, all done.
98+
99+
## Testing The Skill Locally
100+
101+
You can use [node-lambda](https://github.com/motdotla/node-lambda) to test this skill locally. In
102+
the `test_events` directory are several event files you can use for testing, and they should map
103+
pretty well to each Intent. To test an intent, simply update the `EVENT_FILE` value in your `.env`
104+
config file to point to the event to test against. Make sure you run `npm install` from the command
105+
line to get the the latest npm packages, and then run `npm start`.

_config.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
title: Alexa SickBeard
2+
description: A skill to ask Alexa about your SickBeard queue.
3+
google_analytics:
4+
show_downloads: true
5+
theme: jekyll-theme-cayman
6+
7+
gems:
8+
- jekyll-mentions

config/default.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"alexa-sickbeard": {
3+
"server": {
4+
"url": "http://localhost:9090",
5+
"apikey": ""
6+
}
7+
}
8+
}

package.json

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
{
22
"name": "alexa-sickbeard",
3-
"version": "1.0.3",
3+
"version": "1.1.0",
44
"description": "A skill to ask Alexa about your SickBeard queue.",
55
"main": "dist/index.js",
66
"scripts": {
77
"build": "babel src -d dist",
88
"deploy": "npm run prepare; node-lambda deploy",
99
"package": "npm run prepare; node-lambda package --packageDirectory=./",
10-
"prepare": "npm run build",
10+
"prepare": "npm run build; npm run upgrade-config",
1111
"prepublishOnly": "npm run package",
12-
"start": "npm run prepare; node-lambda run"
12+
"start": "npm run prepare; node-lambda run",
13+
"upgrade-config": "node ./scripts/upgrade-config.js"
1314
},
1415
"author": "Joe Schmitt",
1516
"license": "MIT",
@@ -19,16 +20,17 @@
1920
},
2021
"dependencies": {
2122
"alexa-app": "^2.4.0",
22-
"dotenv": "^2.0.0",
23-
"node-sickbeard": "0.0.1",
24-
"underscore": "^1.8.3"
23+
"config": "^1.26.1",
24+
"node-sickbeard": "0.0.1"
2525
},
2626
"devDependencies": {
2727
"babel-cli": "^6.24.1",
2828
"babel-plugin-root-import": "^5.1.0",
2929
"babel-preset-env": "^1.5.1",
30+
"dotenv": "^2.0.0",
3031
"eslint": "^3.19.0",
3132
"eslint-plugin-import": "^2.3.0",
33+
"fs-extra": "^3.0.1",
3234
"node-lambda": "^0.8.15"
3335
}
3436
}

scripts/upgrade-config.js

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/**
2+
* Copy server settings from old .env file to new config json file.
3+
*/
4+
5+
const chalk = require('chalk');
6+
const config = require('dotenv').config();
7+
const fs = require('fs-extra');
8+
const path = require('path');
9+
10+
const configFileDir = process.env.NODE_CONFIG_DIR;
11+
const configFilePath = path.join(configFileDir, 'default.json');
12+
const localConfigFilePath = path.join(configFileDir, 'local.json');
13+
const configJson = {};
14+
15+
let needsUpgrade = false;
16+
17+
if (config.hasOwnProperty('SB_URL')) {
18+
configJson.url = config.SB_URL;
19+
needsUpgrade = true;
20+
}
21+
22+
if (config.hasOwnProperty('SB_API_KEY')) {
23+
configJson.apikey = config.SB_API_KEY;
24+
needsUpgrade = true;
25+
}
26+
27+
if (needsUpgrade) {
28+
console.log('Your configuration settings need updating. Attempting to update automatically...');
29+
30+
fs.pathExists(localConfigFilePath).then((exists) => {
31+
if (!exists) {
32+
fs.readJson(configFilePath).then((configObj) => {
33+
configObj['alexa-sickbeard'].server = Object.assign(configObj['alexa-sickbeard'].server,
34+
configJson);
35+
36+
// Output new local.json file
37+
fs.outputFile(localConfigFilePath, JSON.stringify(configObj, null, 2)).then(() => {
38+
console.log(`Config saved to ${chalk.green(path.resolve(localConfigFilePath))}`);
39+
console.log('Please ' + chalk.yellow('remove your SB settings from the .env file') +
40+
' to prevent this from running again in the future.');
41+
});
42+
});
43+
}
44+
else {
45+
console.log(chalk.green(path.resolve(localConfigFilePath)) + ' file ' +
46+
chalk.red('already exists') + '!');
47+
console.log('Please ' + chalk.yellow('remove your SB settings from the .env file') +
48+
' to prevent this from running again in the future.');
49+
}
50+
});
51+
}

src/lib/handlers.js

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import _ from 'underscore';
1+
import config from 'config';
22
import SickBeard from 'node-sickbeard';
33

44
import buildPrompt from './buildPrompt.js';
@@ -11,11 +11,7 @@ import {
1111
WELCOME_DESCRIPTION
1212
} from './responses.js';
1313

14-
const config = require('dotenv').config();
15-
const sb = new SickBeard({
16-
url: config.SB_URL,
17-
apikey: config.SB_API_KEY
18-
});
14+
const sb = new SickBeard(config.get('alexa-sickbeard.server'));
1915

2016
export default function handleLaunchIntent(req, resp) {
2117
resp
@@ -29,7 +25,7 @@ export function handleFindShowIntent(req, resp) {
2925

3026
return sb.cmd('shows').then((searchResp) => {
3127
const shows = searchResp.data;
32-
const result = shows && Object.keys(shows).length ? _.find(shows, (show) => {
28+
const result = shows && Object.keys(shows).length ? shows.find((show) => {
3329
return show.show_name.toLowerCase().indexOf(showName.toLowerCase()) >= 0;
3430
}) : null;
3531

0 commit comments

Comments
 (0)