
Security News
Axios Maintainer Confirms Social Engineering Attack Behind npm Compromise
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.
Build Alexa Skills with TypeScript using this lib simply and powerfully. This integrates with a suite of ask-gib libs, including ssml-gib for easy SSML generation and lex-gib for robust i18n and voice variety that gives Alexa some much-needed dynamicism i
This lib allows you to create Alexa Skills using TypeScript and an (IMO) easier approach to request/response architecture.
Use in combination with...
Install with npm:
npm install --save ask-gib
Import ES6 style:
import * as ask from 'ask-gib';
let h = new ask.Helper(); // If you want to use the helper
FuncyAlexaSkill class.Inherit from FuncyAlexaSkill. In ctor, map each intent to an array of transforms that will be executed in order. Be sure to initialize the launch request handler as well.
export interface FooStore extends ask.BaseSkillStore {
foo: string;
}
export class FooSkill extends ask.FuncyAlexaSkill<FooStore> {
constructor(appId: string, dynamoDbTableName: string) {
super(appId, dynamoDbTableName, lexData); // see lex-gib for lexData info
// Creates first-non-null-wins request handling pipelines
// I personally name these `transform___` but not necessary.
t.transformsByName = {
"FooIntent": [t.transformFooBar, t.transformFooBaz, t.transformHelpDefault],
"AMAZON.HelpIntent": [t.transformHelpBar, t.transformHelpDefault],
"AMAZON.FallbackIntent": [t.transformHelpDefault],
"AMAZON.RepeatIntent": [t.transformRepeat],
"AMAZON.CancelIntent": [t.transformGoodbye],
"AMAZON.StopIntent": [t.transformGoodbye]
}
// Launch is special. Define pipeline for it here.
t.transformsByName[t.getLaunchRequestName()] = [t.transformWelcome];
}
...
}
Inside each transform, check the state, most often in the _store property. Check to see if you want your transform to handle the incoming stimulus. If yes, return the next SkillState. If no (i.e. the transform doesn't apply), return null.
transformFooBar: ask.SkillTransform = (
stimulus: ask.Stimulus,
history: ask.SkillState[]
): ask.SkillState => { // Can also use Promise<ask.SkillState>
// Check to see if this transform applies, if not return null.
if (!this._store || this._store.foo !== "bar") {
return null;
}
// Create your speech, mixing plain text, ssml, with ssml helpers.
// lex provides powerful i18n, 'hi' -> hello, howdy, Guten Tag, etc.
// But here is also shown hard-coded text.
let hi = this.lex._('hi');
let output = ask.SpeechBuilder.with()
.ssml(hi.ssml)
.text("Build some speech with plain text...")
.ssml(`<p>${Ssml.emphasis("Emphasize", "strong")} with some ssml.</p>`)
.text("Would you like to foo?")
.outputSpeech();
let reprompt = ask.SpeechBuilder.with()
.text("Maybe you didn't hear me...")
.existing(output) // reuses existing speech output
.outputSpeech();
// Create interaction object, which represents the entire request
// & response. The JSON response object sent back to Alexa will
// be built automatically from this.
let interaction: ask.Interaction = {
stimulus: stimulus,
type: "ask",
output: output,
reprompt: reprompt,
// If you include `cardTitle/Content`, it will automatically
// incorporate this into your response with a simple card,
// e.g. `TellWithCard`, `AskWithCard`.
cardTitle: "My Title",
cardContent: output.text,
}
// The final bit of plumbing
let nextSkillState: ask.SkillState = {
id: h.generateUUID(),
interaction: interaction,
location: "a1"
}
// Optionally store some global state for this user.
// Anything that is stored in the _store object is persisted across
// sessions, and you can extend `BaseStore` for type-safety.
this._store.foo = "baz";
return nextSkillState;
}
Put this in your handler in your index.ts file.
// Create the handler that responds to the Alexa Request.
export var handler = async function (
event: ask.RequestBody,
context: ask.Context,
callback: (error: any, response: ask.ResponseBody) => void
) {
try {
// Create an instance of the skill.
var skill = new FooSkill(APP_ID, DB_NAME);
// I await execute, which is not necessary WRT the callback.
// Async execute is convenient to write, and the callback
// actually is called just before the await will return.
await skill.execute(event, context, callback);
h.logFuncComplete(lc);
} catch (errExec) {
h.logError(`errExec`, errExec, lc);
}
}
FuncyAlexaSkill
SpeechBuilder
OutputSpeech objects with a fluent manner.DynamoDBHelper
DynamoRecord based on user id and db table name.I also wanted to mention that you can create a nice workflow for DevOps.
With a single keystroke chord ctrl+shift+B, vscode executes the default build task, which is npm run build.
This...
tsc.bin folder.bin.zip to the Lambda function (which uses aliases for production so I can't harm any live skills).I also update my models and check status via npm scripts as well,
which can get/update models and more. ctrl+~ brings up the vscode bash shell which
makes this a breeze.
I highly recommend using the npm scripts + aws and ask CLIs. (Needs updated to task version 2.0.0)
Here is the relevant code:
.vscode/tasks.json:
{
"version": "0.1.0",
"tasks": [
{
"taskName": "tsc",
"isBuildCommand": true,
"isShellCommand": true,
"command": "npm",
"args": [ "run", "build" ],
"showOutput": "silent",
"problemMatcher": "$tsc"
},
{
"taskName": "mochatest",
"isShellCommand": true,
"command": "npm",
"args": [ "run", "test" ],
"showOutput": "always"
}
]
}
package.json:
{
...
"scripts": {
"build": "npm run build:ts",
"build:ts": "tsc -p .",
"postbuild": "npm run do-node-modules && npm run zip:bin && npm run aws-push",
"zip:bin": "cd bin && pwd && rm bin.zip && zip -r bin.zip * && cd .. && pwd",
"do-node-modules": "rm -rf bin/node_modules && cp -r node_modules bin/node_modules",
"aws-push": "aws lambda update-function-code --function-name skillGibA --zip-file fileb://bin/bin.zip --profile alexa",
"aws-push-eu": "aws lambda update-function-code --function-name skillGibA_EU --zip-file fileb://bin/bin.zip --profile alexa-eu",
"ask-get-models": "ask api get-model -s $SKILL_SID -l en-US > models_tmp/en-US.json --profile alexa && ask api get-model -s $SKILL_SID -l en-IN > models_tmp/en-IN.json --profile alexa && ask api get-model -s $SKILL_SID -l en-CA > models_tmp/en-CA.json --profile alexa && ask api get-model -s $SKILL_SID -l en-GB > models_tmp/en-GB.json --profile alexa && ask api get-model -s $SKILL_SID -l en-AU > models_tmp/en-AU.json --profile alexa",
"ask-update-models": "ask api update-model -s $SKILL_SID -l en-US --file models/en-US.json --profile alexa && ask api update-model -s $SKILL_SID -l en-IN --file models/en-IN.json --profile alexa && ask api update-model -s $SKILL_SID -l en-CA --file models/en-CA.json --profile alexa && ask api update-model -s $SKILL_SID -l en-GB --file models/en-GB.json --profile alexa && ask api update-model -s $SKILL_SID -l en-AU --file models/en-AU.json --profile alexa",
"ask-get-model-statuses": "ask api get-model-status -s $SKILL_SID -l en-US --profile alexa && ask api get-model-status -s $SKILL_SID -l en-IN --profile alexa && ask api get-model-status -s $SKILL_SID -l en-CA --profile alexa && ask api get-model-status -s $SKILL_SID -l en-GB --profile alexa && ask api get-model-status -s $SKILL_SID -l en-AU --profile alexa"
},
...
}
FAQs
Build Alexa Skills with TypeScript using this lib simply and powerfully. This integrates with a suite of ask-gib libs, including ssml-gib for easy SSML generation and lex-gib for robust i18n and voice variety that gives Alexa some much-needed dynamicism i
We found that ask-gib demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.

Security News
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.