{"id":17461584,"url":"https://github.com/roman-yerin/vertojs","last_synced_at":"2025-04-19T18:22:07.340Z","repository":{"id":35206453,"uuid":"213373606","full_name":"roman-yerin/vertojs","owner":"roman-yerin","description":"Typescript FreeSWITCH verto interface","archived":false,"fork":false,"pushed_at":"2023-01-07T04:22:11.000Z","size":918,"stargazers_count":33,"open_issues_count":6,"forks_count":20,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-02-19T06:12:34.410Z","etag":null,"topics":["freeswitch","verto","webrtc"],"latest_commit_sha":null,"homepage":"","language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/roman-yerin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-10-07T12:09:52.000Z","updated_at":"2024-09-06T20:20:27.000Z","dependencies_parsed_at":"2023-01-15T16:15:48.657Z","dependency_job_id":null,"html_url":"https://github.com/roman-yerin/vertojs","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/roman-yerin%2Fvertojs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/roman-yerin%2Fvertojs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/roman-yerin%2Fvertojs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/roman-yerin%2Fvertojs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/roman-yerin","download_url":"https://codeload.github.com/roman-yerin/vertojs/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239808501,"owners_count":19700448,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["freeswitch","verto","webrtc"],"created_at":"2024-10-18T07:04:01.445Z","updated_at":"2025-03-02T18:32:23.263Z","avatar_url":"https://github.com/roman-yerin.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"# vertojs\n\nVerto (VER-to) RTC is a FreeSWITCH endpoint that implements a subset of a JSON-RPC connection designed for use over secure websockets. The initial target is WebRTC to simplify coding and implementing calls from web browsers and devices to FreeSWITCH. This allows a web browser or other WebRTC client to originate a call using Verto into a FreeSWITCH installation and then out to the PSTN using SIP, SS7, or other supported protocol.\n\nThis is a zero-dependency implementation that is no need to include jquery as in an original one. It doesn't contain any html stuff inside or media handlers as well. You should\ntake care of fetch media tracks yourself (I think it is better not to hide useful features of you, browser provides a great API to handle media)\n\n## Status\n\nThis is a work in progress code. However, it is stable enough to use basic functions (calls).\n\nPull requests are welcomed.\n\n\n## Get started\n\nPackage directory content\n\n\n**/dist** \u0026mdash; contains a minified bundle exporting **Verto** symbol to a global namespace\n\n**/src** \u0026mdash; contains source Typescript files\n\nTo use this package you can either include *dist/verto.js* as a html \u0026lt;script\u0026gt; tag or import it using webpack like that\n\n```typescript\nimport { Verto } from 'vertojs'\n```\n\nCheck index.html in the package directory to find out how to use this code with a html \u0026lt;script\u0026gt; tag\n\n## Create a client instance\n\n```typescript\nlet verto = new Verto(options: VertoOptions)\n```\n\n```typescript\ninterface VertoOptions {\n  transportConfig : JsonRpcClientParams \n  // Verto transport configuration, check below\n  \n  rtcConfig?      : RTCConfiguration    \n  // RTCConfiguration object, as described here \n  // https://developer.mozilla.org/en-US/docs/Web/API/RTCConfiguration\n  // The most important thing is iceServers item that should be set to go over NAT\n  \n  debug?          : boolean\n  // Set true to get some useful debug info in browser console \n  \n  ice_timeout?    : number\n  // Milliseconds to stop waiting for ice candidates, default to 3000ms\n}\n\ninterface JsonRpcClientParams {\n  socketUrl       : string\n  // The URL where the verto interface lives\n  // wss://server.example.com:8082\n\n  login           : string\n  passwd          : string\n}\n```\n\n### Receive calls\n\nYou should register to verto to receive calls.\n\nThe following code is a simplified example of using the handler function to auto answer the first incoming call and add first received audio track to some \u0026lt;video\u0026gt; element.\n```typescript\ntry {\n  let data = await verto.login()\n} catch (error) {\n  alert(\"Access denied\")\n  return\n}\n\nlet local_stream = await navigator.mediaDevices.getUserMedia({audio:true})\n\nverto.subscribeEvent('invite', call =\u003e {\n\n  call.subscribeEvent('track', (track) =\u003e {\n    if(track.kind!='audio') return\n    \n    let stream = new MediaStream()\n    stream.addTrack(track)\n    \n    let el = document.getElementById('video')\n    el.srcObject = stream\n  })\n\n  call.answer(local_stream.getTracks())\n})\n```\n\n### Place calls\n\n\n```typescript\nlet local_stream = await navigator.mediaDevices.getUserMedia({audio:true})\n\nlet call = verto.call(local_stream.getTracks(), \"9664\")\n\ncall.subscribeEvent('track', (track) =\u003e {\n  if(track.kind!='audio') return\n  \n  let stream = new MediaStream()\n  stream.addTrack(track)\n\n  let el = document.getElementById('video')\n  el.srcObject = stream\n})\n```\n\n# API description\n\nThere's a number (pretty small number) of Classes and Interfaces provided.\n\n## Verto\n\n### Methods\n\n**constructor**\n\n```typescript\nlet verto = new Verto(options: VertoOptions)\n```\n\n```typescript\ninterface VertoOptions {\n  transportConfig : JsonRpcClientParams \n  // Verto transport configuration, check below\n  \n  rtcConfig?      : RTCConfiguration    \n  // RTCConfiguration object, as described here \n  // https://developer.mozilla.org/en-US/docs/Web/API/RTCConfiguration\n  // The most important thing is iceServers item that should be set to go over NAT\n  \n  debug?          : boolean\n  // Set true to get some useful debug info in browser console \n  \n  ice_timeout?    : number\n  // Milliseconds to stop waiting for ice candidates, default to 3000ms\n}\n\ninterface JsonRpcClientParams {\n  socketUrl       : string\n  // The URL where the verto interface lives\n  // wss://server.example.com:8082\n\n  login           : string\n  passwd          : string\n}\n```\n#### login\n\n***Parameters***\n\n- None\n\n***Returns***\n\n*Promise*, that will be resolved if the login process succeed or threw an exception otherwise.\n\n```typescript\nverto.login()\n```\n\n#### **call**\n\n***Parameters***\n\n- tracks: Array\u0026lt;[MediaStreamTrack](https://developer.mozilla.org/ru/docs/Web/API/MediaStreamTrack)\u0026gt;\n  \u003cbr\u003erepresents tracks to be sent to the remote call side\n- destination: string\n  \u003cbr\u003ean extension to be dialed\n- options?: [VertoCallOptions](#VertoCallOptions)\n  \u003cbr\u003ecall options\n\n***Returns***\n\n- [VertoCall](#VertoCall) instance\n\n```typescript\nlet call = verto.call(tracks, destination, options)\n```\n\n#### **isLogged**\n\n***Parameters***\n\n- None\n\n***Returns***\n\n- Boolean\n\n```typescript\nlet isLogged = verto.isLogged()\n```\n\n#### **logout**\n\n***Parameters***\n\n- None\n\n***Returns***\n\n- Void\n\n```typescript\nverto.logout()\n```\n### Events\n\n#### invite\n\nFires on incoming call. As a parameter handler will receive a [VertoCall](#VertoCall) instance.\n\n```typescript\nverto.subscribeEvent('invite', call =\u003e {\n\n  call.subscribeEvent('track', (track) =\u003e {\n    if(track.kind!='audio') return\n    \n    let stream = new MediaStream()\n    stream.addTrack(track)\n    \n    let el = document.getElementById('video')\n    el.srcObject = stream\n  })\n\n  call.answer(local_stream.getTracks())\n})\n```\n\n## VertoCall\n\nThis class instances should never be built manually, but using verto.call or incoming call handler.\n\n### Methods\n\n#### **answer**\n\n***Parameters***\n\n- tracks: Array\u0026lt;[MediaStreamTrack](https://developer.mozilla.org/ru/docs/Web/API/MediaStreamTrack)\u0026gt;\n  \u003cbr\u003erepresents tracks to be sent to the remote call side\n\n***Returns***\n\n- None\n\n```typescript\ncall.answer(tracks)\n```\n#### **hangup**\n\n***Parameters***\n\n- None\n\n***Returns***\n\n- None\n\n```typescript\ncall.hangup()\n```\n\n#### **dtmf**\n\n***Parameters***\n\n- String\n\n***Returns***\n\n- None\n\n```typescript\ncall.dtmf('5')\n```\n\n#### **hold**\n\n***Parameters***\n\n- None\n\n***Returns***\n\n- None\n\n```typescript\ncall.hold()\n```\n\n#### **unhold**\n\n***Parameters***\n\n- None\n\n***Returns***\n\n- None\n\n```typescript\ncall.unhold()\n```\n\n#### **toggleHold**\n\n***Parameters***\n\n- None\n\n***Returns***\n\n- None\n\n```typescript\ncall.toggleHold()\n```\n\n#### **getStats**\n\n***Parameters***\n\n- None\n\n***Returns***\n\nhttps://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/getStats\n\n### Instance variables\n\n#### **id**\n\n- *String* \u0026mdash; the call id\n\n#### **options**\n\n- *[VertoCallOptions](#VertoCallOptions)*\n\n#### **direction**\n\n- *[CallDirection](#CallDirection)*\n\n\n### Events\n\n#### answer\n\nFires when the call is answered.\n\n```typescript\ncall.subscribeEvent('answer', () =\u003e {\n// Do something on answer\n})\n```\n\n#### track\n\nFires when a MediaStreamTrack is received\n\n```typescript\nverto.subscribeEvent('invite', call =\u003e {\n\n  call.subscribeEvent('track', (track) =\u003e {\n    if(track.kind!='audio') return\n    \n    let stream = new MediaStream()\n    stream.addTrack(track)\n    \n    let el = document.getElementById('video')\n    el.srcObject = stream\n  })\n\n  call.answer(local_stream.getTracks())\n})\n```\n\n#### bye\n\nFires when the call is ended.\n\n```typescript\ncall.subscribeEvent('bye', cause =\u003e {\n// Do something on call end\n})\n```\n\n## Interfaces\n\n#### VertoCallOptions\n\n```typescript\ninterface VertoCallOptions {\n  caller_id_number?   : string\n  caller_id_name?     : string\n  callee_id_number?   : string\n  callee_id_name?     : string\n}\n```\n\n#### VertoOptions\n```typescript\ninterface VertoOptions {\n  transportConfig : JsonRpcClientParams \n  // Verto transport configuration, check below\n  \n  rtcConfig?      : RTCConfiguration\n  // RTCConfiguration object, as described here \n  // https://developer.mozilla.org/en-US/docs/Web/API/RTCConfiguration\n  // The most important thing is iceServers item that should be set to go over NAT\n  \n  debug?          : boolean\n  // Set true to get some useful debug info in browser console \n  \n  ice_timeout?    : number\n  // Milliseconds to stop waiting for ice candidates, default to 3000ms\n}\n```\n\n#### JsonRpcClientParams\n```typescript\ninterface JsonRpcClientParams {\n  socketUrl       : string\n  // The URL where the verto interface lives\n  // wss://server.example.com:8082\n\n  login           : string\n  passwd          : string\n}\n```\n\n#### CallDirection\n```typescript\nenum CallDirection {\n  Incoming,\n  Outgoing\n}\n```\n\n## Event handling\n\nBoth [Verto](#Verto) and [VertoCall](#VertoCall) classes uses the same event handling system.\n\n**subscribeEvent**\n\n***Parameters***\n\n- name     : string\n- handler  : {(data:any):void}\n\n***Returns***\n\n- *String* identifies the handler\n\n```typescript\nlet handler_id = verto.subscribeEvent(name, handler)\n```\n\n**unsubscribeEvent**\n\n***Parameters***\n\n- name     : string\n- handler_id? : string\n  \u003cbr\u003e if ommited, all the handlers for *name* event will be deleted\n\n***Returns***\n\n- None\n\n```typescript\nverto.unsubscribeEvent(name, handler_id)\n```\n\n## License\n\nCopyright (c) 2019–2022 Roman Yerin \u0026lt;r.yerin@ion.team\u0026gt;\n\nLicensed under the 3-clause BSD license.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Froman-yerin%2Fvertojs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Froman-yerin%2Fvertojs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Froman-yerin%2Fvertojs/lists"}