@telnyx/webrtc
Version:
Telnyx WebRTC Client
445 lines (322 loc) • 11.8 kB
Markdown
# @telnyx/webrtc
 [](https://joinslack.telnyx.com/)
## Summary
The Telnyx WebRTC Client provides all the functionality you need to start making voice & video calls from a browser.
- [Installation](#Installation)
- [Usage](#Usage)
- [Examples](#Examples)
- [Vanilla JavaScript](#vanilla-javascript)
- [React.js](#reactjs)
- [Browser support](#Browser-support)
- [Development](#Development)
---
## Installation
Install the package with:
```
npm install @telnyx/webrtc --save
```
As long as you can import npm packages with a bundler like [Webpack](https://webpack.js.org/), you're ready to import `TelnyxRTC` and begin:
```js
import { TelnyxRTC } from '@telnyx/webrtc';
```
## Usage
To initialize the WebRTC client, you'll need to authenticate using a Telnyx SIP Connection. Follow our [quickstart guide](https://developers.telnyx.com/docs/v2/webrtc/quickstart) to create **JWTs** (JSON Web Tokens) to authenticate. You can also authenticate directly with the SIP Connection `username` and `password`.
### Client
```js
// Initialize the client
const client = new TelnyxRTC({
/* Use a JWT to authenticate (recommended) */
login_token: login_token,
/* or use your Connection credentials */
// login: username,
// password: password,
});
// Connect and login
client.connect();
// You can call client.disconnect() when you're done.
// Note: When you call `client.disconnect()` you need to remove all ON event methods you've had attached before.
// Disconnecting and Removing listeners.
// client.disconnect();
// client.off('telnyx.ready')
// client.off('telnyx.notification');
```
> See ON [Events](https://github.com/team-telnyx/webrtc/tree/main/packages/js#events)
> See [TelnyxRTC#constructor](./docs/ts/classes/telnyxrtc.md#constructor) for all options.
Important: You should treat Connection credentials as sensitive data and should not hardcode credentials into your frontend web application. Check out the [app examples](./examples) for sample code that handles username and password by prompting the user.
To hear/view calls in the browser, you'll need to specify an HTML media element:
```js
client.remoteElement = 'remoteMedia';
```
The corresponding HTML:
```html
<audio id="remoteMedia" autoplay="true" />
<!-- or for video: -->
<!-- <video id="remoteMedia" autoplay="true" playsinline="true" /> -->
```
### Events
```js
// Create a variable to track the current call
let activeCall;
// Attach event listeners
client
.on('telnyx.ready', () => console.log('ready to call'))
.on('telnyx.error', () => console.log('error'))
// Events are fired on both session and call updates
// ex: when the session has been established
// ex: when there's an incoming call
.on('telnyx.notification', (notification) => {
if (notification.type === 'callUpdate') {
activeCall = notification.call;
}
});
```
> See [TelnyxRTC.on](./docs/ts/classes/telnyxrtc.md#on) for all events.
### Calls
To initiate an outgoing call:
```js
const call = client.newCall({
// Destination is required and can be a phone number or SIP URI
destinationNumber: '18004377950',
callerNumber: '155531234567',
});
```
To enable video when calling:
```js
const videoCall = client.newCall({
destinationNumber: 'sip:example@sip.example.com',
video: true,
});
// And in your HTML, replace the audio element with video.
// <video id="remoteMedia" autoplay="true" playsinline="true" />
```
> See [TelnyxRTC.newCall](./docs/ts/classes/telnyxrtc.md#newCall) for all options.
To answer an incoming call:
```js
client.on('telnyx.notification', (notification) => {
const call = notification.call;
if (notification.type === 'callUpdate' && call.state === 'ringing') {
call.answer();
}
});
```
Both the outgoing and incoming `Call` instance has methods that can be hooked up to your UI:
```js
// Hangup or reject an incoming call
call.hangup();
// Send digits and keypresses
call.dtmf('1234');
// Call states that can be toggled
call.hold();
call.muteAudio();
```
> See [Call#methods](./docs/ts/classes/call.md#methods) for all methods.
### Debugging
In order to have a better idea on what is going on under the hood you can gather webrtc metrics for a call:
```js
const call = client.newCall({
// Destination is required and can be a phone number or SIP URI
destinationNumber: '18004377950',
callerNumber: '155531234567',
debug: true // Default is false,
debugOutput: 'socket' // Possible values are 'socket' | 'file'
});
// The debug dump is set to be sent to telnyx by default, if you want to save the debug data to disk
// You can change the debugOutput option to 'file'
```
### In-Call Quality Metrics
To be able to get the in-call quality metrics you have to first enable debugging for the call and then listen for the `telnyx.stats.frame` event.
```js
const call = client.newCall({
// Destination is required and can be a phone number or SIP URI
destinationNumber: '18004377950',
debug: true, // it is required to enable debugging for the call,
});
client.on('telnyx.stats.frame', (stats) => {
console.log(stats);
});
```
### Pre-Call Diagnosis
To be able to run pre-call diagnosis you can use the `PreCallDiagnosis.run` method.
```js
import { PreCallDiagnosis } from '@telnyx/webrtc';
PreCallDiagnosis.run({
credentials: {
login: clientOptions.login,
password: clientOptions.password,
loginToken: clientOptions.login_token,
},
texMLApplicationNumber: '+1-240-775-8982',
})
.then((report) => {
console.log(report);
})
.catch((error) => {
console.error(error);
});
```
### Setting Preferred Codec
You can pass `preferred_codecs` to the `newCall` method to set codec preference during the call.
`preferred_codecs` is a sub-array of the codecs returned by [RTCRtpReceiver.getCapabilities('audio')](https://developer.mozilla.org/en-US/docs/Web/API/RTCRtpReceiver/getCapabilities_static#codecs)
```js
const allCodecs = RTCRtpReceiver.getCapabilities('audio').codecs;
const PCMACodec = allCodecs.find((c) =>
c.mimeType.toLowerCase().includes('pcma')
);
client.newCall({
destinationNumber: '123',
preferred_codecs: [PCMACodec],
});
```
### Getting the Registration State
To retrieve the registration state from the server gateway you can
use `client.getIsRegistered` method
```js
client.getIsRegistered().then(isRegistered => {...})
```
### Anonymous Login for AI assistant
The TelnyxRTC client can be used with an AI assistant by using the `anonymous_login` method. This allows you to authenticate without a SIP connection, making it easier to integrate with AI assistants.
**Note:** In order for anonymous login to work, you have to set `telephony_settings.supports_unauthenticated_web_calls` to `true` via the API or in the assistant's telephony settings tab in the portal.
```js
const client = new TelnyxRTC({
anonymous_login: {
/** Your AI assistant's ID */
target_id: 'assistant-UUID',
target_type: 'ai_assistant',
},
});
client.connect();
```
### Making Calls to AI Assistants
Making calls to the AI assistant is similar to making calls with a SIP connection. You can use the `newCall` method to initiate a call, the destination number can be left blank.
```js
const call = client.newCall({
destinationNumber: '',
remoteElement: 'remoteElement',
/** other call options. */
});
```
Its recommended that you set the preferred codec to `opus` by passing the `preferred_codecs` option to the `newCall` method when calling AI assistants.
```js
const allCodecs = RTCRtpReceiver.getCapabilities('audio').codecs;
const opusCodec = allCodecs.find((c) =>
c.mimeType.toLowerCase().includes('opus')
);
client.newCall({
destinationNumber: '',
preferred_codecs: [opusCodec],
});
```
---
## Examples
We've included a few [examples in vanilla JavaScript (ES6) and React](https://github.com/team-telnyx/webrtc-examples/tree/main/js) to help you get started.
> _Looking for more examples in React? Check out our React client packages:_
>
> - [@telnyx/react-client](../react-client)
---
## Browser support
The following table indicates the browsers supported by TelnyxRTC.
We support the most recent (N) versions of these browsers unless otherwise indicated.
| | Chrome | Firefox | Safari | Edge |
| ------- | ------ | ------- | ------ | ---- |
| Android | [-] | [-] | [ ] | [ ] |
| iOS | [ ] | [ ] | [x] | [ ] |
| Linux | [x] | [-] | [ ] | [ ] |
| MacOS | [x] | [-] | [x] | [-] |
| Windows | [x] | [-] | [ ] | [-] |
[x] supports audio and video
[-] supports only audio
[ ] not supported
To extend support to other browsers, install and import [webrtc-adapter](https://www.npmjs.com/package/webrtc-adapter) before importing `TelnyxRTC`. For example:
```js
import 'webrtc-adapter';
import { TelnyxRTC } from '@telnyx/webrtc';
```
To check whether your browser supports TelnyxRTC, use [`TelnyxRTC.webRTCInfo`](./docs/ts/classes/telnyxrtc.md#webRTCInfo).
---
## Development
_**Requirement** Node v11.15.0 or later_
This library is written in [TypeScript](https://www.typescriptlang.org/) to define a clear API with optional typechecking benefits.
To contribute, clone this repo and install locally:
```
npm install
```
Afterwards, you're ready to make changes to files in `src`.
To run all tests:
```
npm test
```
### Documentation
[TypeScript documentation](./docs/ts) is automatically generated from TSDoc-style comments on merge to `main`.
Only code symbols with a symbol-level TSDoc comment will appear in the docs. Use `@category` to group symbols. For example:
```ts
// `PublicUseModule` will appear in docs due to the class-level TSDoc comment.
/**
* A module for public consumption
* @category Public Modules
*/
class PublicUseModule {
// `getSomething` WILL appear in docs because
// there is a TSDoc comment
/**
* Gets something.
*/
getSomething() {}
// `getSomethingElse` will NOT appear in docs
// because of the `@ignore` tag
/**
* Adds another thing
* @ignore
*/
getSomethingElse() {}
// `addAnotherThing` will NOT appear in docs
// because there is no TSDoc comment
addAnotherThing() {}
// `updateSomething` will NOT appear in docs
// because of the `private` keyword
private updateSomething() {}
// `deleteSomething` will NOT appear in docs
// because of the `protected` keyword
protected deleteSomething() {}
}
// `InternalUseModule` will NOT appear in docs,
// even if its members are documented, because
// there is no class-level TSDoc comment.
class InternalUseModule {
doThis() {}
doThat() {}
}
```
If you've added comments and still do not see documentation as expected, check the `typedocOptions.exclude` config in `tsconfig.json`.
#### Supported tags
In addition to the tags [supported by Typedoc](https://typedoc.org/guides/doccomments/#supported-tags), we use `apialias`, `example`/`examples` and `internalnote`.
_Note: `@link` is not supported in public-facing documentation at this time._
##### `@apialias`
Use `apialias` to display a different name in public documentation.
```ts
/**
* @apialias PublicObject
*/
interface IPublicObject {}
```
##### `@examples`
Precede code samples with `examples`.
````ts
/**
* @examples
* ```js
* new PublicUseModule(options);
* ```
*/
````
##### `@internalnote`
Precede internal notes that should not be rendered with `internalnote`.
```ts
/**
* @internalnote {@see InternalUseModule} for implementation
*/
```
---
## Contributing
See [Contribution Guide](../../docs/Contributing.md)
## License
[MIT](../../LICENSE) © [Telnyx](https://github.com/team-telnyx)