Skip to content

Commit

Permalink
Merge pull request #302 from umts/werebus/am-eve-split
Browse files Browse the repository at this point in the history
AM/EVE split serverless functions
  • Loading branch information
werebus authored Aug 25, 2023
2 parents 7ca16b6 + 70f9cba commit 0439c15
Show file tree
Hide file tree
Showing 12 changed files with 5,353 additions and 0 deletions.
7 changes: 7 additions & 0 deletions contrib/am-eve-split/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
ACCOUNT_SID=GetFromDeveloperConsole
AUTH_TOKEN=GetFromDeveloperConsole
SWITCHOVER_HOUR=15
DAY_START_HOUR=4
DAY_ROSTER_ID=1
EVE_ROSTER_ID=2
ROSTER_URL="http://localhost:3333/rosters/:id:/twilio/:type:.xml"
13 changes: 13 additions & 0 deletions contrib/am-eve-split/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"env": {
"es6": true,
"node": true
},
"extends": ["google"],
"root": true,
"rules": {
"comma-dangle": "off",
"curly": ["error", "multi-or-nest"],
"max-len": ["error", { "code": 120 }]
}
}
32 changes: 32 additions & 0 deletions contrib/am-eve-split/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Twilio Serverless
.twiliodeployinfo

# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Dependency directories
node_modules/

# Optional npm cache directory
.npm

# Yarn Integrity file
.yarn-integrity

# dotenv environment variable files
.env
.env.*
!.env.example
1 change: 1 addition & 0 deletions contrib/am-eve-split/.node-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
16.20.2
1 change: 1 addition & 0 deletions contrib/am-eve-split/.nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
16
49 changes: 49 additions & 0 deletions contrib/am-eve-split/.twilioserverlessrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
{
"commands": {},
"environments": {
"dev": {
"env": ".env.dev"
},
"ops": {
"env": ".env.ops"
}
},
"projects": {},
// "assets": true /* Upload assets. Can be turned off with --no-assets */,
// "assetsFolder": null /* Specific folder name to be used for static assets */,
// "buildSid": null /* An existing Build SID to deploy to the new environment */,
// "createEnvironment": false /* Creates environment if it couldn't find it. */,
// "cwd": null /* Sets the directory of your existing Serverless project. Defaults to current directory */,
// "detailedLogs": false /* Toggles detailed request logging by showing request body and query params */,
// "edge": null /* Twilio API Region */,
// "env": null /* Path to .env file for environment variables that should be installed */,
// "environment": "dev" /* The environment name (domain suffix) you want to use for your deployment. Alternatively you can specify an environment SID starting with ZE. */,
// "extendedOutput": false /* Show an extended set of properties on the output */,
// "force": false /* Will run deployment in force mode. Can be dangerous. */,
// "forkProcess": true /* Disable forking function processes to emulate production environment */,
// "functionSid": null /* Specific Function SID to retrieve logs for */,
// "functions": true /* Upload functions. Can be turned off with --no-functions */,
// "functionsFolder": null /* Specific folder name to be used for static functions */,
// "inspect": null /* Enables Node.js debugging protocol */,
// "inspectBrk": null /* Enables Node.js debugging protocol, stops execution until debugger is attached */,
// "legacyMode": false /* Enables legacy mode, it will prefix your asset paths with /assets */,
// "live": true /* Always serve from the current functions (no caching) */,
// "loadLocalEnv": false /* Includes the local environment variables */,
// "loadSystemEnv": false /* Uses system environment variables as fallback for variables specified in your .env file. Needs to be used with --env explicitly specified. */,
// "logCacheSize": null /* Tailing the log endpoint will cache previously seen entries to avoid duplicates. The cache is topped at a maximum of 1000 by default. This option can change that. */,
// "logLevel": "info" /* Level of logging messages. */,
// "logs": true /* Toggles request logging */,
// "ngrok": null /* Uses ngrok to create a public url. Pass a string to set the subdomain (requires a paid-for ngrok account). */,
// "outputFormat": "" /* Output the results in a different format */,
// "overrideExistingProject": false /* Deploys Serverless project to existing service if a naming conflict has been found. */,
// "port": "3000" /* Override default port of 3000 */,
// "production": false /* Promote build to the production environment (no domain suffix). Overrides environment flag */,
// "properties": null /* Specify the output properties you want to see. Works best on single types */,
// "region": null /* Twilio API Region */,
"runtime": "node16" /* The version of Node.js to deploy the build to. (node16) */,
// "serviceName": null /* Overrides the name of the Serverless project. Default: the name field in your package.json */,
// "serviceSid": null /* SID of the Twilio Serverless Service to deploy to */,
// "sourceEnvironment": null /* SID or suffix of an existing environment you want to deploy from. */,
// "tail": false /* Continuously stream the logs */,
// "template": null /* undefined */,
}
64 changes: 64 additions & 0 deletions contrib/am-eve-split/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# AM/EVE Split Twilio Function

This directory contains a pair of Twilio functions to route to two different
rosters depending on the time of day.

## Development

This application is developed using the [Twilio Serverless Toolkit][tst] and
deployed as a [Serverless Function][sf].

### Requirements

* `node.js`/`npm` matching the version in the `.node-version` file (just run
`nodenv install` if using nodenv)

### Setup

```sh
npm install # bundle dependencies
```

Copy the `.env.example` file to `.env.dev` and edit values as appropriate:

* `ACCOUNT_SID` and `AUTH_TOKEN`: Belong to the account that these functions
will be deployed under. Get them from the [developer's console][dc]. Note,
however, that these aren't actually needed unless you're looking to deploy
to "dev" for testing purposes.
* `DAY_START_HOUR`: What hour the "day" starts at. Calls before this time will
be considered "eve" calls, likely for the day before.
* `SWITCHOVER_HOUR`: What hour the "eve" starts at. Calls after this time will
be considered "eve" calls. This should probably match your "eve" roster's
switch-over hour.
* `DAY_ROSTER_ID`: the id of the "day" roster in the Rails app.
* `EVE_ROSTER_ID`: the id of the "eve" roster in the Rails app.
* `ROSTER_URL`: the URL in the Rails app that responds to Twilio web hooks.
The string, "`:id:`", will be replaced with the appropriate roster ID, the
string, "`:type:`", will be replaced with "`voice`" or "`text`" depending on
the function.

### Development

```sh
npm run start # Starts a development server
npm run start -- --ngrok # Same server, but exposed via ngrok
npm run start -- --help # See this for other dev server options
```

### Deployment

Copy the `.env.example` file to `.env.ops` (for example, I used the department
name as the "environment" name) and edit values as appropriate. This time you
should use production values, and you _do_ need the `ACCOUNT_SID` and
`AUTH_TOKEN`.

```sh
npm run deploy -- --to ops
```

Now you should be able to connect a phone number to the appropriate
functions/environment in the number settings.

[tst]: https://www.twilio.com/docs/labs/serverless-toolkit
[sf]: https://www.twilio.com/docs/serverless/functions-assets
[dc]: https://console.twilio.com/
19 changes: 19 additions & 0 deletions contrib/am-eve-split/assets/redirect.private.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
const redirect = (twiml, context, type) => {
const now = new Date();
const formatOptions = {
hour: 'numeric',
hour12: false,
weekday: 'long',
timeZone: 'America/New_York',
};
const formatter = new Intl.DateTimeFormat('en-US', formatOptions);

const formattedDate = formatter.format(now).split(', ');
const hour = Number(formattedDate[1]);
const isEve = (hour >= context.SWITCHOVER_HOUR || hour < context.DAY_START_HOUR);
const rosterId = isEve ? context.EVE_ROSTER_ID : context.DAY_ROSTER_ID;

twiml.redirect({method: 'GET'}, context.ROSTER_URL.replace(':id:', rosterId).replace(':type:', type));
};

module.exports = redirect;
9 changes: 9 additions & 0 deletions contrib/am-eve-split/functions/text.protected.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
exports.handler = (context, event, callback) => {
const assets = Runtime.getAssets();
const redirect = require(assets['/redirect.js'].path);

const twiml = new Twilio.twiml.MessagingResponse();

redirect(twiml, context, 'text');
return callback(null, twiml);
};
9 changes: 9 additions & 0 deletions contrib/am-eve-split/functions/voice.protected.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
exports.handler = (context, event, callback) => {
const assets = Runtime.getAssets();
const redirect = require(assets['/redirect.js'].path);

const twiml = new Twilio.twiml.VoiceResponse();

redirect(twiml, context, 'call');
return callback(null, twiml);
};
Loading

0 comments on commit 0439c15

Please sign in to comment.