twilio-run
CLI tool to locally develop and deploy to the Twilio Runtime. Part of the Serverless Toolkit
About
This project is part of the Serverless Toolkit. For a more extended documentation, check out the Twilio Docs.
Installation
You can install the CLI tool via npm
or another package manager. Ideally install it as a dev dependency instead of global:
npm install twilio-run --save-dev
node_modules/.bin/twilio-run
npx twilio-run
Usage
Check out the commands for in depth usage, but here are some things you will want to know:
Create a new project
To create a new project with the Twilio Serverless Toolkit you can use create-twilio-function
which will scaffold a new project that is ready to be used with twilio-run
.
npm init twilio-function my-project
cd my-project
You can then use twilio-run
to run a local development server to serve your functions and assets.
npx twilio-run start
Project conventions
By default JavaScript Functions should be placed in the functions
directory and assets, which can be JavaScript, images, CSS, or any static asset, should be placed in the assets
directory. You can choose other directories by providing a --functions-folder
or --assets-folder
option to twilio-run
commands.
Twilio Functions and Assets can be public, protected or private. The differences are:
- Public: Any one with the URL can visit the Function or Asset
- Protected: Twilio signs webhook requests, making a Twilio Function protected means that the Function will validate the webhook signature and reject any incoming requests that don't match
- Private: The Function or Asset doesn't a URL, it can only be required within another Function or Asset
Within twilio-run
you can make your Functions or Assets public, protected or private by adding to the function filename. Functions and Assets are public by default. To make a Function or Asset protected or private, add .protected
or .private
to the filename before the extension. For example: functions/secret.protected.js
or assets/hidden.private.jpg
.
Function templates
There are a number of pre-written Function templates that you can add to your project. The templates are available on GitHub and you can also propose your own via pull request.
To list the available templates you can run:
npx twilio-run list-templates
To add a new function into your project from a template you can run:
npx twilio-run new namespace
The command will walk you through choosing the template.
Deploy a project
To deploy a project to the Twilio infrastructure you can run the command:
npx twilio-run deploy
This will deploy your project to the "dev" environment by default. You can then promote the project from "dev" to other environments with the command:
npx twilio-run promote --from=dev --to=stage
Commands
The CLI exposes a variety of commands. The best way to find out about the flags and commands available is to run twilio-run --help
or twilio-run [command] --help
twilio-run start [dir]
- Aliases:
twilio-run dev
, twilio-run
Starts a local development server for testing and debugging of your environment. By default only variables in the .env
file will be available via process.env
or through the context
argument inside Twilio Functions.
Examples
twilio-run
twilio-run demo
PORT=9000 twilio-run
twilio-run --port=4200
twilio-run --inspect
twilio-run --ngrok
twilio-run --ngrok=subdomain
twilio-run deploy
Deploys your project to Twilio. It will read dependencies automatically from your package.json
's dependencies
field and install them. It will also upload and set the variables that are specified in your .env
file. You can point it against a different .env
file via command-line flags.
Examples
twilio-run deploy
twilio-run deploy --environment=prod
twilio-run list-templates
Lists the available templates that you can use to generate new functions and/or assets inside your current project with the twilio-run new
command below.
Examples
twilio-run list-templates
twilio-run new [namespace]
Creates a new set of functions and/or assets inside your current project based on a template.
Examples
twilio-run new demo --template=blank
twilio-run list [types]
Lists a set of available resources for different types related to your Account. Available resources that can be listed:
- Services
- Environments or Builds (requires to pass a Service)
- Functions, Assets or Variables (requires to pass a Service and Environment)
Examples
twilio-run list services
twilio-run ls functions,assets --environment=dev --service-name=demo
twilio-run ls environments --service-sid=ZSxxxxx --extended-output
twilio-run ls assets,variables,functions --properties=sid,date_updated
twilio-run activate
- Aliases:
twilio-run promote
Promotes an existing deployment to a new environment. It can also create a new environment if it doesn't exist.
Examples
twilio-run activate --environment=prod --source-environment=dev
twilio-run activate --environment=demo --create-environment --build-sid=ZB1234xxxxxxxxxx
twilio-run logs
Print logs from your Twilio Serverless project
Examples
twilio-run logs
twilio-run logs --tail
twilio-run logs --function-sid ZFXXX --environment production
API
The module also exposes two functions that you can use outside of the CLI tool to spin up local development.
If you want to interact with the Runtime API instead, check out the @twilio-labs/serverless-api
package.
runDevServer(port: number, baseDir: string): Promise<Express.Application>
This allows you to trigger running an express server that will expose all functions and assets. Example:
const { runDevServer } = require('twilio-run');
runDevServer(9000)
.then(app => {
console.log(`Server is running on port ${app.get('port')})`);
})
.catch(err => {
console.error('Something failed');
});
handleToExpressRoute(handler: TwilioHandlerFunction): Express.RequestHandler
You can take the handler
function of a Twilio Function file and expose it in an existing Express server. Example:
const express = require('express');
const bodyParser = require('body-parser');
const { handlerToExpressRoute } = require('twilio-run');
const { handler } = require('./path/to/function.js');
const app = express();
app.use(bodyParser.urlencoded({ extended: false }));
app.all(handlerToExpressRoute(handler));
app.listen(3000, () => console.log('Server running on port 3000'));
Error Handling in Dev Server
If your local Twilio Function throws an unhandled error or returns an Error
instance via the callback
method, we will return an HTTP status code of 500
and return the error object as JSON.
By default we will clean up the stack trace for you to remove internal code of the dev server and add it as at [Twilio Dev Server internals]
into the stack trace.
An example would look like this:
Error: What?
at format (/Users/dkundel/dev/twilio-run/examples/basic/functions/hello.js:5:9)
at exports.handler (/Users/dkundel/dev/twilio-run/examples/basic/functions/hello.js:13:3)
at [Twilio Dev Server internals]
If you want to have the full un-modified stack trace instead, set the following environment variable, either in your Twilio Function or via .env
:
TWILIO_SERVERLESS_FULL_ERRORS=true
This will result into a stack trace like this:
Error: What?
at format (/Users/dkundel/dev/twilio-run/examples/basic/functions/hello.js:5:9)
at exports.handler (/Users/dkundel/dev/twilio-run/examples/basic/functions/hello.js:13:3)
at twilioFunctionHandler (/Users/dkundel/dev/twilio-run/dist/runtime/route.js:125:13)
at app.all (/Users/dkundel/dev/twilio-run/dist/runtime/server.js:122:82)
at Layer.handle [as handle_request] (/Users/dkundel/dev/twilio-run/node_modules/express/lib/router/layer.js:95:5)
at next (/Users/dkundel/dev/twilio-run/node_modules/express/lib/router/route.js:137:13)
at next (/Users/dkundel/dev/twilio-run/node_modules/express/lib/router/route.js:131:14)
at next (/Users/dkundel/dev/twilio-run/node_modules/express/lib/router/route.js:131:14)
at next (/Users/dkundel/dev/twilio-run/node_modules/express/lib/router/route.js:131:14)
at next (/Users/dkundel/dev/twilio-run/node_modules/express/lib/router/route.js:131:14)
In general you'll want to use the cleaned-up stack trace since the internals might change throughout time.
Contributing
This project welcomes contributions from the community. Please see the CONTRIBUTING.md
file for more details.
Code of Conduct
Please be aware that this project has a Code of Conduct. The tldr; is to just be excellent to each other ❤️
Contributors
Thanks goes to these wonderful people (emoji key):
This project follows the all-contributors specification. Contributions of any kind welcome!
License
MIT