Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
The Telnyx Node library provides convenient access to the Telnyx API from applications written in server-side JavaScript.
See the Node API docs.
telnyx-node
uses a slightly modified version of Semantic Versioning for all changes. See this document for details.
Install the package with:
npm install telnyx --save
The package needs to be configured with your account's API key which is available in your the Telnyx Mission Control Portal. Require it with the key's value:
import Telnyx from 'telnyx';
const telnyx = new Telnyx('KEY123456...');
const messagingProfile = await telnyx.messagingProfiles.create({
name: 'Summer Campaign',
});
Every method returns a chainable promise which can be used instead of a regular callback:
// Create a new messaging profile and then send a message using that profile:
telnyx.messagingProfiles
.create({
name: 'Summer Campaign',
})
.then((messagingProfile) => {
return telnyx.messagingPhoneNumbers.update('+18005554000', {
messaging_profile_id: messagingProfile.data.id,
});
})
.catch((err) => {
// Deal with an error
});
Request timeout is configurable (the default is Node's default of 120 seconds):
telnyx.setTimeout(20000); // in ms (this is 20 seconds)
An https-proxy-agent can be configured with
setHttpAgent
.
To use telnyx behind a proxy you can pass to sdk:
import ProxyAgent from 'https-proxy-agent';
if (process.env.http_proxy) {
telnyx.setHttpAgent(new ProxyAgent(process.env.http_proxy));
}
Automatic network retries can be enabled with setMaxNetworkRetries
. This will
retry requests n
times with exponential backoff if they fail due to an
intermittent network problem.
// Retry a request once before giving up
telnyx.setMaxNetworkRetries(1);
Some information about the response which generated a resource is available
with the lastResponse
property:
messagingProfile.lastResponse.requestId; // see: https://telnyx.com/docs/api/node#request_ids
messagingProfile.lastResponse.statusCode;
request
and response
eventsThe Telnyx object emits request
and response
events. You can use them like this:
import Telnyx from 'telnyx';
const telnyx = new Telnyx('KEY...');
const onRequest = (request) => {
// Do something.
};
// Add the event handler function:
telnyx.on('request', onRequest);
// Remove the event handler function:
telnyx.off('request', onRequest);
request
object{
method: 'POST',
path: '/v2/messaging_profiles'
}
response
object{
method: 'POST',
path: '/v2/messaging_profiles',
status: 200,
request_id: 'Ghc9r26ts73DRf',
elapsed: 445 // Elapsed time in milliseconds
}
Telnyx signs the webhook events it sends to your endpoint, allowing you to validate that they were not sent by a third-party. You can read more about it here.
Please note that you must pass the raw request body, exactly as received from
Telnyx, to the constructEvent()
function; this will not work with a parsed
(i.e., JSON) request body.
You can find an example of how to use this with Express
in the examples/webhook-signing
folder, but here's
what it looks like:
const event = telnyx.webhooks.constructEvent(
webhookRawBody,
webhookTelnyxSignatureHeader,
webhookTelnyxTimestampHeader,
publicKey,
);
TeXML sends webhooks as form-encoded payloads instead of JSON. To validate the signature, use the telnyx.webhooks.signature.verifySignature
method.
You can find an example of how to use this with Express in the examples/webhook-signing
folder.
const timeToleranceInSeconds = 300; // Will validate signatures of webhooks up to 5 minutes after Telnyx sent the request
try {
telnyx.webhooks.signature.verifySignature(
webhookRawBody,
webhookTelnyxSignatureHeader,
webhookTelnyxTimestampHeader,
publicKey,
timeToleranceInSeconds,
);
} catch (e) {
console.log('Failed to validate the signature');
console.log(e);
}
If you're writing a plugin that uses the library, we'd appreciate it if you identified using telnyx.setAppInfo()
:
telnyx.setAppInfo({
name: 'MyAwesomePlugin',
version: '1.2.34', // Optional
url: 'https://myawesomeplugin.info', // Optional
});
This information is passed along when the library makes calls to the Telnyx API.
You can auto-paginate list methods. We provide a few different APIs for this to aid with a variety of node versions and styles.
for-await-of
)If you are in a Node environment that has support for async iteration, such as Node 10+ or babel, the following will auto-paginate:
for await (const messagingProfile of telnyx.messagingProfiles.list()) {
doSomething(messagingProfile);
if (shouldStop()) {
break;
}
}
autoPagingEach
If you are in a Node environment that has support for await
, such as Node 7.9 and greater,
you may pass an async function to .autoPagingEach
:
await telnyx.messagingProfiles
.list()
.autoPagingEach(async (messagingProfile) => {
await doSomething(messagingProfile);
if (shouldBreak()) {
return false;
}
});
console.log('Done iterating.');
Equivalently, without await
, you may return a Promise, which can resolve to false
to break:
telnyx.messagingProfiles
.list()
.autoPagingEach((messagingProfile) => {
return doSomething(messagingProfile).then(() => {
if (shouldBreak()) {
return false;
}
});
})
.then(() => {
console.log('Done iterating.');
})
.catch(handleError);
If you prefer callbacks to promises, you may also use a next
callback and a second onDone
callback:
telnyx.messagingProfiles.list().autoPagingEach(
function onItem(messagingProfile, next) {
doSomething(messagingProfile, function (err, result) {
if (shouldStop(result)) {
next(false); // Passing `false` breaks out of the loop.
} else {
next();
}
});
},
function onDone(err) {
if (err) {
console.error(err);
} else {
console.log('Done iterating.');
}
},
);
If your onItem
function does not accept a next
callback parameter or return a Promise,
the return value is used to decide whether to continue (false
breaks, anything else continues).
autoPagingToArray
This is a convenience for cases where you expect the number of items
to be relatively small; accordingly, you must pass a limit
option
to prevent runaway list growth from consuming too much memory.
Returns a promise of an array of all items across pages for a list request.
const allMessagingProfiles = await telnyx.messagingProfiles
.list()
.autoPagingToArray({limit: 10000});
If you need help installing or using the library, please check the Telnyx Documentation first, and contact Telnyx support if you don't find an answer to your question.
If you've instead found a bug in the library or would like new features added, go ahead and open issues or pull requests against this repo!
Bug fixes, docs, and library improvements are always welcome. Please refer to our Contributing Guide for detailed information on how you can contribute.
Note: Please be aware that a good share of the files are auto-generated. You are welcome to suggest changes and submit PRs illustrating the changes. However, we'll have to make the changes in the underlying tool. You can find more info about this in the Contributing Guide.
If you're not familiar with the GitHub pull request/contribution process, this is a nice tutorial.
Run the following to create your env file
cp .env.local .env
Don't forget to update your
.env
values accordingly.
Now inject envs into terminal:
. ./setup_env.sh
Feel free to use Node
--env-file
parameter to setup envs if you prefer
The test suite depends on the Prism Mock Server.
Start the prism mock service with the following command:
npx prism mock https://raw.githubusercontent.com/team-telnyx/openapi/master/openapi/spec3.json
One final step -- because the Node SDK originally expected to reach the legacy telnyx-mock
service at port 12111 (in addition to providing a /v2/
base path), we need to setup the Telnyx mock proxy server to modify the request path and forward along to the prism mock server.
# In new terminal window
git clone git@github.com:team-telnyx/telnyx-prism-mock.git
cd telnyx-prism-mock/proxy
npm install
node index.js
$ npm install
$ npm test
Run all tests with a custom telnyx-mock
port:
$ TELNYX_MOCK_PORT=12111 npm test
Run a single test suite:
$ npm test -- test/Error.test.ts
Run a single test (case sensitive):
$ npm test -- test/Error.test.ts -t 'Populates with type'
If you wish, you may run tests using your Telnyx Test API key by setting the
environment variable TELNYX_TEST_API_KEY
before running the tests:
$ export TELNYX_TEST_API_KEY='KEY....'
$ export TELNYX_MOCK_PORT='12...'
$ npm test
To inspect values in tests first import debug:
import Debug from 'debug';
const debug = Debug('foo');
//...
debug(result);
Then run the tests with:
$ DEBUG=foo npm test
To view verbose debugging for nock
run the tests with:
$ DEBUG=nock.* npm test
Run:
npm run build
Then check output in dist folder
Add an editor integration or:
$ npm run fix
The contributors and maintainers of Telnyx Node would like to extend their deep gratitude to the authors of Stripe Node, upon which this project is based. Thank you for developing such elegant, usable, extensible code and for sharing it with the community.
FAQs
Telnyx API Node SDK
We found that telnyx demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.