mirror of
https://github.com/jambonz/jambonz-node.git
synced 2026-01-25 02:08:15 +00:00
add initial support for REST
This commit is contained in:
61
README.md
Normal file
61
README.md
Normal 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.
|
||||
|
||||
@@ -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
30
lib/rest/calls.js
Normal 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;
|
||||
@@ -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
4
package-lock.json
generated
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "jambonz-node",
|
||||
"version": "0.0.1",
|
||||
"name": "@jambonz/node-client",
|
||||
"version": "0.0.2",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@jambonz/node-client",
|
||||
"version": "0.0.2",
|
||||
"version": "0.0.3",
|
||||
"description": "",
|
||||
"main": "lib/index.js",
|
||||
"scripts": {
|
||||
|
||||
Reference in New Issue
Block a user