add initial support for REST

This commit is contained in:
Dave Horton
2021-02-18 15:57:46 -05:00
parent d0972145f0
commit 356ae693cc
6 changed files with 113 additions and 6 deletions

61
README.md Normal file
View File

@@ -0,0 +1,61 @@
# @jambonz/node-client
A Node.js SDK for the open source [jambonz](docs.jambonz.org) CPaaS platform. Node.js applications can use this library to respond to [jambonz webhooks](https://docs.jambonz.org/jambonz/) and to make [REST API calls](https://docs.jambonz.org/rest/) to a jambonz platform.
### Webooks
To respond to webhooks, you will need a lightweight http server. An example is shown below using [express](expressjs.com).
```
const WebhookResponse = require('@jambonz/node-client').WebhookResponse;
const express = require('express');
const app = express();
app.use(express.json());
app.post('/my-app', (req, res) => {
const jambonz = new WebhookResponse();
jambonz
.pause({length: 1.5})
.say({
text: 'Good morning. This is a simple test of text to speech functionality. That is all. Goodbye',
synthesizer: {
vendor: 'google',
language: 'en-US'
}
});
res.status(200).json(app);
});
app.listen(port, () => {
logger.info(`listening at http://localhost:${port}`);
});
```
[See here](https://docs.jambonz.org/jambonz/) for information on the available verbs you can use in a jambonz application, and for their associated properties.
### REST API calls
To use the REST API you need to know your account sid (which you can see in the jambonz portal), and an api key (which you can generate in the jambonz portal). You generate a REST client as shown below.
```
const client = require('@jambonz/node-client')(<my-account-sid>, <my-api-key>, {
baseUrl: http://<my-jambonz-sbc>
});
```
All of the above parameters are required (account sid, api key, and baseUrl);
An example of using the client to perform live control to play a whisper prompt to the caller is shown below:
```
await client.calls.update(<my-call-sid>, {
whisper: {
verb: 'say',
text: 'You have 30 seconds remaining on this call.'
}
}
});
```
### Example
See [here]() for a full-featured example application built using this API.
### Status
This project is under active development and is currently very much pre-beta.

View File

@@ -21,6 +21,7 @@ class WebhookResponse {
addVerb(verb, payload) {
validate(verb, payload);
this.payload.push({verb, ...payload});
return this;
}
}

30
lib/rest/calls.js Normal file
View File

@@ -0,0 +1,30 @@
const assert = require('assert');
class Calls {
constructor(accountSid, apiKey, opts) {
this.accountSid = accountSid;
this.apiKey = apiKey;
['post', 'put', 'get', 'del'].forEach((m) => this[m] = opts[m]);
}
async update(callSid, opts) {
const {call_hook, call_status, listen_status, mute_status, whisper} = opts;
assert.ok(call_hook || call_status || listen_status || mute_status || whisper,
`calls.update: invalid request ${JSON.stringify(opts)}`);
if (call_status) assert.ok(['completed', 'no-answer'].includes(call_status),
`invalid call_status: ${call_status}, must be 'completed' or 'no-answer'`);
if (mute_status) assert.ok(['mute', 'unmute'].includes(mute_status),
`invalid mute_status: ${mute_status}, must be 'mute' or 'unmute'`);
if (whisper) assert.ok(whisper.verb,
`invalid whisper: ${JSON.stringify(whisper)}, must be a 'play' or 'say' verb`);
await this.post(`Accounts/${this.accountSid}/Calls/${callSid}`, opts);
}
}
module.exports = Calls;

View File

@@ -1,13 +1,28 @@
const assert = require('assert');
const bent = require('bent');
const Calls = require('./calls');
class Jambonz {
constructor(accountSid, apiKey, opts) {
assert.ok(typeof accountSid === 'string', 'accountSid required');
assert.ok(typeof apiKey === 'string', 'apiKey required');
opts = opts || {};
this.endpoint = opts.endpoint;
assert.ok(opts.baseUrl, 'opts.baseUrl required when instantiating jambon REST client');
// TODO: test credentials, throw exception on failure
let baseUrl = opts.baseUrl;
if (opts.baseUrl.endsWith('/v1')) baseUrl = `${opts.baseUrl}/`;
else if (opts.baseUrl.endsWith('/v1/')) {}
else if (opts.baseUrl.endsWith('/')) baseUrl = `${opts.baseUrl}v1/`;
else baseUrl = `${opts.baseUrl}/v1/`;
const headers = {'Authorization': `Bearer ${apiKey}`};
const post = bent(baseUrl, 'POST', 'buffer', headers, 200, 201, 202);
const put = bent(baseUrl, 'POST', 'buffer', headers, 204);
const get = bent(baseUrl, 'GET', 'buffer', headers, 200);
const del = bent(baseUrl, 'DELETE', 'buffer', headers, 204);
this.calls = new Calls(accountSid, apiKey, {baseUrl, post, put, get, del});
}
}

4
package-lock.json generated
View File

@@ -1,6 +1,6 @@
{
"name": "jambonz-node",
"version": "0.0.1",
"name": "@jambonz/node-client",
"version": "0.0.2",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

View File

@@ -1,6 +1,6 @@
{
"name": "@jambonz/node-client",
"version": "0.0.2",
"version": "0.0.3",
"description": "",
"main": "lib/index.js",
"scripts": {