Twilio Functions Utils
About
This lib was created with the aim of simplifying the use of serverless Twilio, reducing the need to apply frequent try-catches and improving context management, making it no longer necessary to return the callback() method in all functions.
How it works
useInjection
The useInjection method takes two parameters. The first to apply as a handler and the last is an object of configuration options.
[useInjection] Options
Can contain providers that will be defined, which act as use cases to perform internal actions in the handler function through the "this" method.
You can pass validateToken
equal true too, to force Token validation using Twilio Flex Token Validator
useInjection(yourFunction,
{
providers: { create, remove },
validateToken: true
}
);
When using Token Validator, the Request body must contain a valid Token from Twilio.
{
Token: "Twilio-Token-Here"
}
Response
The responses coming from the function destined to the handler must be returned as an instance of Response.
Response receives a string and a number (status code):
return new Response('Your pretty answer.', 200);
There are two failure response models, BadRequest and NotFound. Its use follows the same model.
const notFound = new NotFoundError('Your error message here.');
const badRequest = new BadRequestError('Your error message here.');
TwiMLResponse
There is a proper response template to use with the TwiML format:
const twimlVoice = new Twilio.twiml
.VoiceResponse();
const enqueueVoice = twimlVoice
.enqueue({
action,
workflowSid,
})
.task('{}');
return new TwiMLResponse(twimlVoice, 201)
Install
npm install twilio-functions-utils
Usage
IMPORTANT TO USE REGULAR FUNCTIONS ➜
function yourFunctionName() {
}
With arrow functions it doesn't work as expected as 'this' cannot be injected correctly.
.
exports.create = async function (event) {
const { client, env } = this
return new Promise((resolve, reject) => {
const random = Math.random();
if (random >= 0.5) {
return resolve({ sucess: 'Resolved' });
}
return reject(new Error('Unresolved'));
});
};
const { useInjection, Response } = require('twilio-functions-utils');
const { create } = require(Runtime.getAssets()['/create.js'].path)
async function createAction(event) {
const { cookies, request, env } = this
const providerResult = await this.providers.create(event)
return new Response(providerResult, 201);
}
exports.handler = useInjection(createAction, {
providers: {
create,
},
validateToken: true,
});
Testing with useMock
The Twilio Serverless structure make it hard for testing sometimes. So this provides a method that works perfectly with useInjection ready functions. The useMock
act like useInjection but mocking some required fragments as getAssets
and getFunctions
.
Your files structures must be as:
| /root
| - package.json
| - src
| -- functions
| -- assets
or:
| /root
| - package.json
| - functions
| - assets
Exports your function:
async function functionToBeTested(event) {
const something = await this.providers.myCustomProvider(event)
return Response(something)
}
const handler = useInjection(functionToBeTested, {
providers: {
myCustomProvider,
},
});
module.exports = { functionToBeTested, handler };
You always need to import the twilio.mock for Response Twilio Global object on your testing files begining. (Required)
require('twilio-functions-utils/lib/twilio.mock');
Use Twilio Functions Utils useMock
to do the hard job and just write your tests with the generated function.
require('twilio-functions-utils/lib/twilio.mock');
const { useMock, Response } = require('twilio-functions-utils');
const { functionToBeTested } = require('../../functions/functionToBeTested');
const fn = useMock(functionToBeTested, {
providers: {
myCustomProvider: async (sid) => ({ sid }),
},
});
describe('Function functionToBeTested', () => {
it('if {"someValue": true}', async () => {
const request = { TaskSid: '1234567', TaskAttributes: '{"someValue": true}' };
const res = await fn(request);
expect(res).toBeInstanceOf(Response);
expect(res.body).not.toEqual(request);
expect(res.body).toEqual({ sid: '1234567' });
});
});
Author