Skip to content

Commit

Permalink
Merge branch 'main' into update-call-asyncAmd-type-to-boolean
Browse files Browse the repository at this point in the history
  • Loading branch information
atralvarez authored Dec 20, 2024
2 parents f1de2d9 + 419b33c commit fd4e01f
Show file tree
Hide file tree
Showing 551 changed files with 10,461 additions and 4,049 deletions.
9 changes: 8 additions & 1 deletion .github/workflows/test-and-deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
timeout-minutes: 20
strategy:
matrix:
node: [ 14, 16, 18, lts/* ]
node: [ 14, 16, 18, 20, 22, lts/* ]
steps:
- name: Checkout twilio-node
uses: actions/checkout@v3
Expand All @@ -41,6 +41,13 @@ jobs:
TWILIO_API_SECRET: ${{ secrets.TWILIO_CLUSTER_TEST_API_KEY_SECRET }}
TWILIO_FROM_NUMBER: ${{ secrets.TWILIO_FROM_NUMBER }}
TWILIO_TO_NUMBER: ${{ secrets.TWILIO_TO_NUMBER }}
TWILIO_ORGS_CLIENT_ID: ${{ secrets.TWILIO_ORGS_CLIENT_ID }}
TWILIO_ORGS_CLIENT_SECRET: ${{ secrets.TWILIO_ORGS_CLIENT_SECRET }}
TWILIO_ORGS_USER_ID: ${{ secrets.TWILIO_ORGS_USER_ID }}
TWILIO_ORG_SID: ${{ secrets.TWILIO_ORG_SID }}
TWILIO_CLIENT_ID: ${{ secrets.TWILIO_CLIENT_ID }}
TWILIO_CLIENT_SECRET: ${{ secrets.TWILIO_CLIENT_SECRET }}
TWILIO_MESSAGE_SID: ${{ secrets.TWILIO_MESSAGE_SID }}
run: |
npm pack
tar -xzf twilio*.tgz
Expand Down
82 changes: 82 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,88 @@
twilio-node changelog
=====================

[2024-12-12] Version 5.4.0
--------------------------
**Library - Chore**
- [PR #1058](https://github.com/twilio/twilio-node/pull/1058): add v22 support. Thanks to [@manisha1997](https://github.com/manisha1997)!

**Library - Feature**
- [PR #1057](https://github.com/twilio/twilio-node/pull/1057): add support for OAuth and Orgs API. Thanks to [@tiwarishubham635](https://github.com/tiwarishubham635)!


[2024-12-05] Version 5.3.7
--------------------------
**Api**
- Add optional parameter `intelligence_service` to `transcription`
- Updated `phone_number_sid` to be populated for sip trunking terminating calls.

**Numbers**
- Add Update Hosted Number Order V2 API endpoint
- Update Port in docs

**Twiml**
- Add optional parameter `intelligence_service` to `<Transcription>`
- Add support for new `<ConversationRelay>` and `<Assistant>` noun
- Add `events` attribute to `<Dial>` verb


[2024-11-15] Version 5.3.6
--------------------------
**Library - Chore**
- [PR #1040](https://github.com/twilio/twilio-node/pull/1040): pass http agent options to client. Thanks to [@tiwarishubham635](https://github.com/tiwarishubham635)!
- [PR #1041](https://github.com/twilio/twilio-node/pull/1041): remove preview sync api. Thanks to [@sbansla](https://github.com/sbansla)!

**Api**
- Added `ivr-virtual-agent-custom-voices` and `ivr-virtual-agent-genai` to `usage_record` API.
- Add open-api file tag to realtime_transcriptions

**Taskrouter**
- Add `api-tag` property to workers reservation
- Add `api-tag` property to task reservation


[2024-10-24] Version 5.3.5
--------------------------
**Conversations**
- Expose ConversationWithParticipants resource that allows creating a conversation with participants


[2024-10-17] Version 5.3.4
--------------------------
**Api**
- Add response key `country` to fetch AvailablePhoneNumber resource by specific country.

**Messaging**
- Make library and doc public for requestManagedCert Endpoint


[2024-10-03] Version 5.3.3
--------------------------
**Messaging**
- Add A2P external campaign CnpMigration flag

**Numbers**
- Add address sid to portability API

**Verify**
- Add `SnaClientToken` optional parameter on Verification check.
- Add `EnableSnaClientToken` optional parameter for Verification creation.


[2024-09-25] Version 5.3.2
--------------------------
**Library - Chore**
- [PR #1037](https://github.com/twilio/twilio-node/pull/1037): Sync for IoT has reached EOL; removing reference to Deployed Devices. Thanks to [@wanjunsli](https://github.com/wanjunsli)!

**Accounts**
- Update docs and mounts.
- Change library visibility to public
- Enable consent and contact bulk upsert APIs in prod.

**Serverless**
- Add is_plugin parameter in deployments api to check if it is plugins deployment


[2024-09-18] Version 5.3.1
--------------------------
**Intelligence**
Expand Down
28 changes: 28 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,13 @@ After a brief delay, you will receive the text message on your phone.
> **Warning**
> It's okay to hardcode your credentials when testing locally, but you should use environment variables to keep them secret before committing any code or deploying to production. Check out [How to Set Environment Variables](https://www.twilio.com/blog/2017/01/how-to-set-environment-variables.html) for more information.
## OAuth Feature for Twilio APIs
We are introducing Client Credentials Flow-based OAuth 2.0 authentication. This feature is currently in beta and its implementation is subject to change.

API examples [here](https://github.com/twilio/twilio-node/blob/main/examples/public_oauth.js)

Organisation API examples [here](https://github.com/twilio/twilio-node/blob/main/examples/orgs_api.js)

## Usage

Check out these [code examples](examples) in JavaScript and TypeScript to get up and running quickly.
Expand Down Expand Up @@ -113,6 +120,27 @@ const client = require('twilio')(accountSid, authToken, {
});
```

### Set HTTP Agent Options

`twilio-node` allows you to set HTTP Agent Options in the Request Client. This feature allows you to re-use your connections. To enable this feature, instantiate the Twilio client with the `keepAlive` flag set to `true`.

Optionally, the socket timeout and maximum number of sockets can also be set. See the example below:

```javascript
const accountSid = process.env.TWILIO_ACCOUNT_SID;
const authToken = process.env.TWILIO_AUTH_TOKEN;

const client = require('twilio')(accountSid, authToken, {
timeout: 30000, // HTTPS agent's socket timeout in milliseconds, default is 30000
keepAlive: true, // https.Agent keepAlive option, default is false
keepAliveMsecs: 1000, // https.Agent keepAliveMsecs option in milliseconds, default is 1000
maxSockets: 20, // https.Agent maxSockets option, default is 20
maxTotalSockets: 100, // https.Agent maxTotalSockets option, default is 100
maxFreeSockets: 5, // https.Agent maxFreeSockets option, default is 5
scheduling: "lifo", // https.Agent scheduling option, default is 'lifo'
});
```

### Specify Region and/or Edge

To take advantage of Twilio's [Global Infrastructure](https://www.twilio.com/docs/global-infrastructure), specify the target Region and/or Edge for the client:
Expand Down
37 changes: 37 additions & 0 deletions examples/orgs_api.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
"use strict";
var Twilio = require("../lib");

const clientId = process.env.ORGS_CLIENT_ID;
const clientSecret = process.env.ORGS_CLIENT_SECRET;
const accountSid = process.env.TWILIO_ACCOUNT_SID;
const organizationSid = process.env.TWILIO_ORG_SID;

const orgsCredentialProvider = new Twilio.OrgsCredentialProviderBuilder()
.setClientId(clientId)
.setClientSecret(clientSecret)
.build();

const client = new Twilio();
client.setCredentialProvider(orgsCredentialProvider);
client.setAccountSid(accountSid);

client.previewIam
.organization(organizationSid)
.accounts.list()
.then((accounts) => {
console.log(accounts);
})
.catch((error) => {
console.log(error);
});

client.previewIam
.organization(organizationSid)
.accounts(accountSid)
.fetch()
.then((account) => {
console.log(account);
})
.catch((error) => {
console.log(error);
});
25 changes: 25 additions & 0 deletions examples/public_oauth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
var Twilio = require("../lib");

const clientId = process.env.OAUTH_CLIENT_ID;
const clientSecret = process.env.OAUTH_CLIENT_SECRET;
const accountSid = process.env.TWILIO_ACCOUNT_SID;

const clientCredentialProvider = new Twilio.ClientCredentialProviderBuilder()
.setClientId(clientId)
.setClientSecret(clientSecret)
.build();

const client = new Twilio();
client.setCredentialProvider(clientCredentialProvider);
client.setAccountSid(accountSid);

const messageId = "SMXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
client
.messages(messageId)
.fetch()
.then((message) => {
console.log(message);
})
.catch((error) => {
console.log(error);
});
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "twilio",
"description": "A Twilio helper library",
"version": "5.3.1",
"version": "5.4.0",
"author": "API Team <api@twilio.com>",
"contributors": [
{
Expand Down
89 changes: 89 additions & 0 deletions spec/cluster/orgs_api.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
jest.setTimeout(15000);

import twilio from "twilio";

const clientId = process.env.TWILIO_ORGS_CLIENT_ID;
const clientSecret = process.env.TWILIO_ORGS_CLIENT_SECRET;
const organizationSid = process.env.TWILIO_ORG_SID;
const accountSid = process.env.TWILIO_ACCOUNT_SID;
const userId = process.env.TWILIO_ORGS_USER_ID;

const client = twilio();
const orgsCredentialProvider = new twilio.OrgsCredentialProviderBuilder()
.setClientId(clientId)
.setClientSecret(clientSecret)
.build();
client.setCredentialProvider(orgsCredentialProvider);

test("Should generate access token", () => {
const noAuthClient = twilio();
noAuthClient.setCredentialProvider(new twilio.NoAuthCredentialProvider());
return noAuthClient.previewIam.v1.token
.create({
grantType: "client_credentials",
clientId: clientId,
clientSecret: clientSecret,
})
.then((token) => {
expect(token).not.toBeNull();
expect(token.accessToken).not.toBeUndefined();
expect(token.tokenType).toEqual("Bearer");
expect(token.expiresIn).toEqual(86400);
});
});

test("Should list accounts under an organization", () => {
return client.previewIam
.organization(organizationSid)
.accounts.list()
.then((accounts) => {
expect(accounts).not.toBeNull();
expect(accounts).not.toBeUndefined();
expect(accounts.length).toBeGreaterThanOrEqual(0);
});
});

test("Should fetch given account", () => {
return client.previewIam
.organization(organizationSid)
.accounts(accountSid)
.fetch()
.then((account) => {
expect(account).not.toBeNull();
expect(account).not.toBeUndefined();
expect(account.accountSid).toEqual(accountSid);
});
});

test("Should list users", () => {
return client.previewIam
.organization(organizationSid)
.users.list()
.then((users) => {
expect(users).not.toBeNull();
expect(users).not.toBeUndefined();
expect(users.length).toBeGreaterThanOrEqual(0);
});
});

test("Should fetch given user", () => {
return client.previewIam
.organization(organizationSid)
.users(userId)
.fetch()
.then((user) => {
expect(user).not.toBeNull();
expect(user).not.toBeUndefined();
expect(user.id).toEqual(userId);
});
});

test("Should list role assignments", () => {
client.previewIam
.organization(organizationSid)
.roleAssignments.list({ scope: accountSid })
.then((roles) => {
expect(roles).not.toBeNull();
expect(roles.length).toBeGreaterThanOrEqual(0);
});
});
28 changes: 28 additions & 0 deletions spec/cluster/public_oauth.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
jest.setTimeout(15000);

import twilio from "twilio";

const clientId = process.env.TWILIO_CLIENT_ID;
const clientSecret = process.env.TWILIO_CLIENT_SECRET;
const accountSid = process.env.TWILIO_ACCOUNT_SID;

const clientCredentialProvider = new twilio.ClientCredentialProviderBuilder()
.setClientId(clientId)
.setClientSecret(clientSecret)
.build();

const client = twilio();
client.setCredentialProvider(clientCredentialProvider);
client.setAccountSid(accountSid);

test("Should fetch message", () => {
const messageId = process.env.TWILIO_MESSAGE_SID;
return client
.messages(messageId)
.fetch()
.then((message) => {
expect(message).not.toBeNull();
expect(message).not.toBeUndefined();
expect(message.sid).toEqual(messageId);
});
});
23 changes: 23 additions & 0 deletions spec/unit/auth_strategy/BasicAuthStrategy.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import BasicAuthStrategy from "../../../src/auth_strategy/BasicAuthStrategy";

describe("BasicAuthStrategy constructor", function () {
const username = "username";
const password = "password";
const basicAuthStrategy = new BasicAuthStrategy(username, password);

it("Should have basic as its authType", function () {
expect(basicAuthStrategy.getAuthType()).toEqual("basic");
});

it("Should return basic auth string", function (done) {
const auth = Buffer.from(username + ":" + password).toString("base64");
basicAuthStrategy.getAuthString().then(function (authString) {
expect(authString).toEqual(`Basic ${auth}`);
done();
});
});

it("Should return true for requiresAuthentication", function () {
expect(basicAuthStrategy.requiresAuthentication()).toBe(true);
});
});
20 changes: 20 additions & 0 deletions spec/unit/auth_strategy/NoAuthStrategy.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import NoAuthStrategy from "../../../src/auth_strategy/NoAuthStrategy";

describe("NoAuthStrategy constructor", function () {
const noAuthStrategy = new NoAuthStrategy();

it("Should have noauth as its authType", function () {
expect(noAuthStrategy.getAuthType()).toEqual("noauth");
});

it("Should return an empty string for getAuthString", function (done) {
noAuthStrategy.getAuthString().then(function (authString) {
expect(authString).toEqual("");
done();
});
});

it("Should return false for requiresAuthentication", function () {
expect(noAuthStrategy.requiresAuthentication()).toBe(false);
});
});
Loading

0 comments on commit fd4e01f

Please sign in to comment.