diff --git a/.circleci/config.yml b/.circleci/config.yml
deleted file mode 100644
index 237fcd369ea..00000000000
--- a/.circleci/config.yml
+++ /dev/null
@@ -1,555 +0,0 @@
-# Required Env Vars
-# NPM_TOKEN
-
-version: 2.1
-# reusable environment for all jobs
-executors:
- main-executor:
- working_directory: ~/webex-js-sdk
- docker:
- - image: cimg/node:16.16.0-browsers
-
-# orbs
-orbs:
- browser-tools: circleci/browser-tools@1.4.2
-
-# Reusable commands for jobs
-commands:
- install_graphicsmagick_and_libgcrypt:
- description: "Install graphicsmagick and libgcrypt"
- steps:
- - run: |
- sudo apt-get update
- sudo apt-get install -y graphicsmagick libgcrypt-dev
- checkout_and_fetch_tags:
- description: "Checkout and fetch tags"
- steps:
- - checkout
- - run: git remote add upstream git@github.com:webex/webex-js-sdk.git
- - run: git fetch upstream --tags
- restore_node_modules:
- description: "Restore the node_modules dependencies cache"
- steps:
- - restore_cache:
- keys:
- - node-modules-cache-node-Gallium-npm-6-{{ .Environment.CACHE_VERSION }}-{{ checksum "yarn.lock" }}
- - node-modules-cache-node-Gallium-npm-6-{{ .Environment.CACHE_VERSION }}-
- # Cache workaround to cache patch changes
- # https://github.com/ds300/patch-package#docker-and-ci
- - run:
- name: "Hash patch-package patches"
- command: cat patches/* | md5sum > patches.hash
- restore_built_packages:
- description: "Restore built packages"
- steps:
- - attach_workspace:
- at: ~/webex-js-sdk
- skip_check:
- description: "Check to see if testing needs to be skipped"
- steps:
- - run:
- name: Check if we need to skip
- command: if [[ -z $(node tooling/modified-packages.js) ]]; then circleci step halt; fi
-
-jobs:
- yarn_install:
- executor: main-executor
- environment:
- SAUCE_CONNECT_DOWNLOAD_ON_INSTALL: true
- steps:
- - install_graphicsmagick_and_libgcrypt
- - checkout_and_fetch_tags
- - run:
- name: "Install dependencies"
- command: yarn
- # Cache workaround to cache patch changes
- # https://github.com/ds300/patch-package#docker-and-ci
- - run:
- name: "Hash patch-package patches"
- command: cat patches/* | md5sum > patches.hash
- # Cache node_modules across different internal jobs in the workflow and across different circleci runs
- - save_cache:
- key: node-modules-cache-node-Gallium-npm-6-{{ .Environment.CACHE_VERSION }}-{{ checksum "yarn.lock" }}
- paths:
- - node_modules
- - run:
- name: "Save yarn install log"
- command: yarn info --json > /tmp/yarn_install.log || true
- - store_artifacts:
- path: /tmp/yarn_install.log
- destination: yarn-install
-
- build:
- executor: main-executor
- parameters:
- env:
- type: string
- default: "test"
- environment:
- NODE_ENV: << parameters.env >>
- steps:
- - install_graphicsmagick_and_libgcrypt
- - checkout_and_fetch_tags
- - restore_node_modules
- - run:
- name: "Build all packages"
- command: yarn run build
- # Save the dist/ folder of the packages for other jobs in the workflow
- - persist_to_workspace:
- root: ~/webex-js-sdk
- paths:
- - packages
-
- build_production:
- executor: main-executor
- environment:
- NODE_ENV: production
- ATLAS_SERVICE_URL: "https://atlas-a.wbx2.com/admin/api/v1"
- CONVERSATION_SERVICE: "https://conv-a.wbx2.com/conversation/api/v1"
- ENCRYPTION_SERVICE_URL: "https://encryption-a.wbx2.com"
- HYDRA_SERVICE_URL: "https://api.ciscospark.com/v1/"
- IDBROKER_BASE_URL: "https://idbroker.webex.com"
- IDENTITY_BASE_URL: "https://identity.webex.com"
- U2C_SERVICE_URL: "https://u2c.wbx2.com/u2c/api/v1"
- WDM_SERVICE_URL: "https://wdm-a.wbx2.com/wdm/api/v1"
- WHISTLER_API_SERVICE_URL: "https://whistler-prod.allnint.ciscospark.com/api/v1"
- WEBEX_TEST_USERS_CI_GATEWAY_SERVICE_URL: "https://cig-service-a.wbx2.com/cig-service/api/v1"
- WEBEX_CONVERSATION_DEFAULT_CLUSTER: "urn:TEAM:us-east-2_a:identityLookup"
- steps:
- - install_graphicsmagick_and_libgcrypt
- - checkout_and_fetch_tags
- - restore_node_modules
- - run:
- name: "Build all packages"
- command: yarn run build
- # Save the dist/ folder of the packages for other jobs in the workflow
- - persist_to_workspace:
- root: ~/webex-js-sdk
- paths:
- - packages
-
- static_analysis:
- executor: main-executor
- steps:
- - checkout_and_fetch_tags
- - restore_node_modules
- - restore_built_packages
- - run:
- name: "Run ESLint"
- command: yarn run lint
- - store_test_results:
- path: reports/style
- - store_artifacts:
- path: reports/style
- destination: style
-
- # Sometimes the output of the modified packages script gets lost
- # in a long output of the tests. This is simply a helper for PRs.
- list_changed_packages:
- executor: main-executor
- steps:
- - checkout_and_fetch_tags
- - restore_node_modules
- - restore_built_packages
- - run:
- name: "List Modified Packages"
- command: |
- PACKAGES=$(node tooling/modified-packages.js --single-line)
-
- echo "Modified Packages:"
- echo "${PACKAGES}"
-
- # Run unit tests for modified packages only with `--unit` flag
- # Tested against Chrome and Firefox on Mac and Windows
- unit_tests:
- executor: main-executor
- environment:
- COVERAGE: true
- steps:
- - checkout_and_fetch_tags
- - restore_node_modules
- - restore_built_packages
- - skip_check
- # Generate build number for a single identifier for SauceLabs
- - run:
- name: "Generate Build Number"
- command: echo "export BUILD_NUMBER=CircleCI-${CIRCLE_PR_USERNAME}-${CIRCLE_PR_REPONAME}-${CIRCLE_PR_NUMBER}_${CIRCLE_WORKFLOW_ID}" >> $BASH_ENV
- # Run unit tests on modified packages
- - run:
- name: "Test Modified Packages"
- command: |
- PACKAGES=$(node tooling/modified-packages.js --single-line)
-
- echo "Modified Packages:"
- echo "${PACKAGES}"
-
- VAR1="@webex/plugin-meetings"
- VAR2="webex"
- for PACKAGE in ${PACKAGES}; do
- if [[ "$PACKAGE" == "$VAR1" || "$PACKAGE" == "$VAR2" ]]; then
- yarn run test:unit --silent --packages "${PACKAGE}"
- echo "DONE TESTING ${PACKAGE} ON MOCHA"
- fi
- done
-
- yarn run jest --selectProjects ${PACKAGES} --passWithNoTests --maxWorkers=2
- echo "DONE TESTING"
- # This script parses all the XML files generated by mocha and karma to see if any tests failed/errored out
- # The reason this script exists is that all tests are "exec"'d and running in a single process instead of a parallel
- # So if a failure happens it will continue to the next test suite in the queue
- - run:
- name: "Check if any unit tests failed"
- command: |
- mkdir -p reports/junit/mocha
- FAILURES=$(find reports/junit/mocha/ -iname '*.xml' -print0 | xargs -0 sed -n 's/.*failures=\"\([^\"]*\).*/\1/p' | xargs)
-
- echo Failures $FAILURES
-
- if [[ $FAILURES =~ ^([0 ])*$ ]]; then
- echo 'Unit tests succeeded'
- else
- echo 'Unit tests failed'
- exit 1
- fi
- - store_test_results:
- path: reports/junit
- - store_artifacts:
- path: reports/junit
- destination: junit
- - store_artifacts:
- path: sauce.log
- destination: sauce
-
- samples:
- working_directory: ~/webex-js-sdk
- docker:
- - image: circleci/node:gallium
- environment:
- NODE_ENV: "test"
- COVERAGE: true
- steps:
- - checkout_and_fetch_tags
- - restore_node_modules
- - restore_built_packages
- # Generate build number for a single identifier for SauceLabs
- - run:
- name: "Generate Build Number"
- command: echo "export BUILD_NUMBER=CircleCI-${CIRCLE_PR_USERNAME}-${CIRCLE_PR_REPONAME}-${CIRCLE_PR_NUMBER}_${CIRCLE_WORKFLOW_ID}" >> $BASH_ENV
- # Test Samples on SauceLabs
- - run:
- name: "Test Samples"
- command: yarn run samples:test
- - store_test_results:
- path: reports/junit
- - store_artifacts:
- path: sauce.log
- destination: sauce
- - store_artifacts:
- path: reports/junit/wdio
- destination: wdio
- - store_artifacts:
- path: reports/cobertura.xml
- destination: cobertura.xml
- - store_artifacts:
- path: /home/circleci/.yarn/_logs/
- destination: yarn-logs
-
- # Run integration tests on modified packages with `--integration` flag
- # Tested against Chrome and Firefox on Mac and Windows
- integration_tests:
- executor: main-executor
- environment:
- COVERAGE: true
- steps:
- - checkout_and_fetch_tags
- - browser-tools/install-browser-tools
- - install_graphicsmagick_and_libgcrypt
- - restore_node_modules
- - restore_built_packages
- - skip_check
- # Generate build number for a single identifier for SauceLabs
- - run:
- name: "Generate Build Number"
- command: echo "export BUILD_NUMBER=CircleCI-${CIRCLE_PR_USERNAME}-${CIRCLE_PR_REPONAME}-${CIRCLE_PR_NUMBER}_${CIRCLE_WORKFLOW_ID}" >> $BASH_ENV
- # Run integration tests on modified packages with `--integration` flag
- # Tested against Chrome and Firefox on Mac and Windows
- - run:
- name: "Test Integration - Run integration tests on modified packages on Chrome and Firefox"
- command: |
- PACKAGES=$(node tooling/modified-packages.js)
-
- echo "Modified Packages:"
- echo "${PACKAGES}"
-
- for PACKAGE in ${PACKAGES}; do
- yarn run test:integration --silent --packages "${PACKAGE}" --integration
- done
- # This script parses all the XML files generated by mocha and karma to see if any tests failed/errored out
- # The reason this script exists is that all tests are "exec"'d and running in a single process instead of a parallel
- # So if a failure happens it will continue to the next test suite in the queue
- - run:
- name: "Check if any integration tests failed"
- command: |
- mkdir -p reports/junit/karma
- FAILURES=$(find reports/junit/karma/ -iname '*.xml' -print0 | xargs -0 sed -n 's/.*failures=\"\([^\"]*\).*/\1/p' | xargs)
-
- echo Failures $FAILURES
-
- if [[ $FAILURES =~ ^([0 ])*$ ]]; then
- echo 'Integration tests succeeded'
- else
- echo 'Integration tests failed'
- exit 1
- fi
- - store_test_results:
- path: reports/junit
- - store_artifacts:
- path: reports/junit
- destination: junit
- - store_artifacts:
- path: sauce.log
- destination: sauce
-
- versioning_and_publish:
- executor: main-executor
- steps:
- - checkout_and_fetch_tags
- - restore_node_modules
- - add_ssh_keys:
- fingerprints:
- - "89:ed:56:33:f5:1b:7b:b6:a1:04:02:a0:f9:47:13:0a"
- - run:
- name: "Temporary change origin url to HTTPS for documentation generation"
- command: git remote set-url origin https://github.com/webex/webex-js-sdk.git
- - run:
- name: "Build Docs"
- command: yarn run build:docs
- - run:
- name: "Change origin url back to ssh"
- command: git remote set-url origin git@github.com:webex/webex-js-sdk.git
- - run:
- name: "Build Samples"
- command: yarn run samples:build
- - run:
- name: "Publish Docs Folder"
- command: |
- # Check if there's anything to commit before committing
- if [ -n "$(git status --porcelain)" ]; then
- git add docs/
- git add -f docs/samples/webex.min.js*
- git add -f docs/samples/meetings.min.js*
- git commit -m "docs(api): update docs [skip ci]"
- git push upstream HEAD:master
- fi
- - run:
- name: "Check if we need to skip version bumping and publishing to npm [skip npm]"
- command: |
- # Grab the 2nd to last commit message from the log for [skip npm]
- # Last commit is the update docs
- MESSAGE=$(git log -n 1 --skip 1 --pretty=format:%s)
-
- if [[ "$MESSAGE" == *\["skip npm"\]* ]]; then
- circleci step halt
- fi
- - run: echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> ~/.npmrc
- - run:
- name: "Grab Current Version Number"
- command: echo "export CURRENT_VERSION=$(node -p "require('./package.json').version")" >> $BASH_ENV
- - run:
- name: "Check if we need to bump"
- command: |
- if ! \
- { git log "$( git describe --tags --abbrev=0 )..HEAD" --format='%s' | cut -d: -f1 | sort -u | sed -e 's/([^)]*)//' | grep -q -i -E '^feat|fix|perf|revert$' ; } || \
- { git log "$( git describe --tags --abbrev=0 )..HEAD" --format='%s' | cut -d: -f1 | sort -u | sed -e 's/([^)]*)//' | grep -q -E '\!$' ; } || \
- { git log "$( git describe --tags --abbrev=0 )..HEAD" --format='%b' | grep -q -E '^BREAKING CHANGE:' ; }
- then
- echo "No applicable changes since the previous tag, skipping..."
- circleci step halt
- fi
- - run:
- name: "Run standard-version"
- command: yarn run release
- - run:
- name: "Grab Upcoming Version Number"
- command: echo "export UPCOMING_VERSION=$(node -p "require('./package.json').version")" >> $BASH_ENV
- - run:
- name: "Check if we need to publish a new version"
- command: |
- echo "Current Version: $CURRENT_VERSION"
- echo "Upcoming Version: $UPCOMING_VERSION"
-
- if [[ "$CURRENT_VERSION" == "$UPCOMING_VERSION" ]]; then
- circleci step halt
- fi
- - run:
- name: "Publish to NPM"
- command: |
- echo "replace yarn workspace environment variables "
- yarn run deps:generate
-
- echo "Publish to NPM"
- npm run tooling -- exec --cmd bash -- -c 'npm publish --access public || true'
- - run:
- name: "Push to upstream/master"
- command: git push --follow-tags upstream master
- tap:
- executor: main-executor
- parameters:
- package:
- type: string
- environment:
- COVERAGE: true
- EU_PRIMARY_ORG_ID: "d9b9d739-c7e4-4956-809e-5da447a3b8ca"
- IDBROKER_BASE_URL: "https://idbroker.webex.com"
- IDENTITY_BASE_URL: "https://identity.webex.com"
- U2C_SERVICE_URL: "https://u2c.wbx2.com/u2c/api/v1"
- WDM_SERVICE_URL: "https://wdm-a.wbx2.com/wdm/api/v1"
- WHISTLER_API_SERVICE_URL: "https://whistler-prod.allnint.ciscospark.com/api/v1"
- WEBEX_TEST_USERS_CI_GATEWAY_SERVICE_URL: "https://cig-service-a.wbx2.com/cig-service/api/v1"
- WEBEX_CONVERSATION_DEFAULT_CLUSTER: "urn:TEAM:us-east-2_a:identityLookup"
- steps:
- - install_graphicsmagick_and_libgcrypt
- - checkout_and_fetch_tags
- - restore_node_modules
- - restore_built_packages
- - run:
- name: "Generate Build Number"
- command: echo "export BUILD_NUMBER=CircleCI-SDK-TAP-<< parameters.package >>_${CIRCLE_WORKFLOW_ID}" >> $BASH_ENV
- - run: yarn run test:integration --silent --packages << parameters.package >> defaults
- - run:
- name: 'Check if tap test for "<< parameters.package >>" failed'
- command: |
- mkdir -p reports/junit/karma
- FAILURES=$(find reports/junit/karma/ -iname '*.xml' -print0 | xargs -0 sed -n 's/.*failures=\"\([^\"]*\).*/\1/p' | xargs)
-
- echo Failures $FAILURES
-
- if [[ $FAILURES =~ ^([0 ])*$ ]]; then
- echo 'Tap test for "<< parameters.package >>" succeeded'
- else
- echo 'Tap test for "<< parameters.package >>" failed'
- exit 1
- fi
- - store_test_results:
- path: reports/junit
- - store_artifacts:
- path: reports/junit
- destination: junit
- # - run:
- # name: 'Create Incident on PagerDuty'
- # when: on_fail
- # command: |
- # # Easier way of assigning variables in a json object without escaping double quotes in the curl command
- # generate_incident_data() {
- # # '\<<' must be escaped in v2.1+ due to yaml conflicts
- # # https://discuss.circleci.com/t/2-1-config-and-build-processing/24102/31
- # cat \<> TAP Test",
- # "source": "CircleCI - Webex JS SDK",
- # "severity": "critical"
- # },
- # "links": [
- # {
- # "href": "${CIRCLE_BUILD_URL}",
- # "text": "CircleCI - << parameters.package >> TAP Test - Build #${CIRCLE_BUILD_NUM}"
- # }
- # ],
- # "client": "CircleCI - Webex-JS-SDK TAP Test - Build #${CIRCLE_BUILD_NUM}",
- # "client_url": "${CIRCLE_BUILD_URL}"
- # }
- # EOF
- # }
- # curl -X POST --header 'Content-Type: application/json' -d "$(generate_incident_data)" https://events.pagerduty.com/v2/enqueue
-
-workflows:
- github_checks:
- jobs:
- - yarn_install:
- filters:
- branches:
- ignore:
- - master
- - build:
- requires:
- - yarn_install
- - static_analysis:
- requires:
- - yarn_install
- - list_changed_packages:
- requires:
- - yarn_install
- - unit_tests:
- requires:
- - build
- - static_analysis
- - integration_tests:
- requires:
- - build
- - static_analysis
- - samples:
- requires:
- - build
- - static_analysis
- build_for_release:
- jobs:
- - yarn_install:
- filters:
- branches:
- only: master
- - versioning_and_publish:
- filters:
- branches:
- only: master
- requires:
- - yarn_install
- tap_tests:
- triggers:
- - schedule:
- # Everyday @ 6:15PM UTC | 3:15PM EST | 2:15PM EDT | 12:15PM PST | 11:15AM PDT
- cron: "15 18 * * 1-5"
- filters:
- branches:
- only:
- - master
- jobs:
- - yarn_install:
- filters:
- branches:
- only: master
- - build_production:
- requires:
- - yarn_install
- - tap:
- name: "@webex/webex-core tap"
- package: "@webex/webex-core"
- requires:
- - build_production
- - tap:
- name: "@webex/plugin-meetings tap"
- package: "@webex/plugin-meetings"
- requires:
- - build_production
- - tap:
- name: "@webex/internal-plugin-conversation tap"
- package: "@webex/internal-plugin-conversation"
- requires:
- - build_production
- - tap:
- name: "@webex/internal-plugin-encryption tap"
- package: "@webex/internal-plugin-encryption"
- requires:
- - build_production
- - tap:
- name: "@webex/internal-plugin-locus tap"
- package: "@webex/internal-plugin-locus"
- requires:
- - build_production
- - tap:
- name: "@webex/internal-plugin-mercury tap"
- package: "@webex/internal-plugin-mercury"
- requires:
- - build_production
\ No newline at end of file
diff --git a/.circleci/local.config.yml b/.circleci/local.config.yml
deleted file mode 100644
index f494b642676..00000000000
--- a/.circleci/local.config.yml
+++ /dev/null
@@ -1,88 +0,0 @@
-version: 2
-
-jobs:
- build:
- docker:
- - image: circleci/node:dubnium-browsers
- working_directory: ~/webex-js-sdk
- environment:
- - NODE_ENV: test
- - SAUCE_CONNECT_DOWNLOAD_ON_INSTALL: true
- - ATLAS_SERVICE_URL: https://atlas-intb.ciscospark.com/admin/api/v1
- - CONVERSATION_SERVICE: https://conversation-intb.ciscospark.com/conversation/api/v1
- - ENCRYPTION_SERVICE_URL: https://encryption-intb.ciscospark.com/encryption/api/v1
- - HYDRA_SERVICE_URL: https://apialpha.ciscospark.com/v1/
- - IDBROKER_BASE_URL: https://idbrokerbts.webex.com
- - IDENTITY_BASE_URL: https://identitybts.webex.com
- - U2C_SERVICE_URL: https://u2c-intb.ciscospark.com/u2c/api/v1
- - WDM_SERVICE_URL: https://wdm-intb.ciscospark.com/wdm/api/v1
- - WHISTLER_API_SERVICE_URL: https://whistler.allnint.ciscospark.com/api/v1
- steps:
- - run:
- name: 'Install graphicsmagick and libgcrypt'
- command: |
- sudo apt-get update
- sudo apt-get install graphicsmagick libgcrypt-dev
- - checkout
- - run:
- name: 'Update NPM and Install dependencies'
- command: sudo npm install -g npm@6
- - run:
- name: 'Install dependencies'
- command: yarn
- - run:
- name: 'Run linting'
- command: yarn run lint
- - run:
- name: 'Build all packages'
- command: yarn run build
- - run:
- # Run unit tests on modified packages
- name: 'Test modified packages'
- command: if [[ $(node tooling/modified-packages.js) ]]; then npm run test:ci:github; fi
- # This script parses all the XML files generated by mocha and karma to see if any tests failed/errored out
- # The reason this script exists is that all tests are "exec"'d and running in a single process instead of a parallel
- # So if a failure happens it will continue to the next test suite in the queue
- - run:
- name: 'Check if any unit tests failed'
- command: |
- FAILURES=$(find reports -iname 'webex*.xml' -print0 | xargs -0 sed -n 's/.*failures=\"\([^\"]*\).*/\1/p' | xargs)
- ERRORS=$(find reports -iname 'webex*.xml' -print0 | xargs -0 sed -n 's/.*errors=\"\([^\"]*\).*/\1/p' | xargs)
-
- echo Failures $FAILURES
- echo Errors $ERRORS
-
- if [[ "$FAILURES" -ne *0* ]] || [[ "$ERRORS" -ne *0* ]]; then
- echo 'Unit tests failed'
- exit 1
- fi
- - run:
- name: 'Test Samples'
- command: npm run samples:test
- # Run integration tests on modified packages with `--integration` flag
- # Tested against Chrome and Firefox on Mac and Windows
- - run:
- name: 'Test Integration - run all integration tests on Mac and Windows version of Chrome and Firefox'
- command: if [[ $(node tooling/modified-packages.js) ]]; then npm run test:ci:integration; fi
- # This script parses all the XML files generated by mocha and karma to see if any tests failed/errored out
- # The reason this script exists is that all tests are "exec"'d and running in a single process instead of a parallel
- # So if a failure happens it will continue to the next test suite in the queue
- - run:
- name: 'Check if any integration tests failed'
- command: |
- FAILURES=$(find reports -iname 'webex*.xml' -print0 | xargs -0 sed -n 's/.*failures=\"\([^\"]*\).*/\1/p' | xargs)
- ERRORS=$(find reports -iname 'webex*.xml' -print0 | xargs -0 sed -n 's/.*errors=\"\([^\"]*\).*/\1/p' | xargs)
-
- echo Failures $FAILURES
- echo Errors $ERRORS
-
- if [[ "$FAILURES" -ne *0* ]] || [[ "$ERRORS" -ne *0* ]]; then
- echo 'Unit tests failed'
- exit 1
- fi
-
-workflows:
- version: 2
- workflow:
- jobs:
- - build
diff --git a/.coveralls.yml b/.coveralls.yml
deleted file mode 100644
index 11d031f1867..00000000000
--- a/.coveralls.yml
+++ /dev/null
@@ -1,2 +0,0 @@
-service_name: circleci
-repo_token: 1k681GkllIiA3wQhT4ynmFKrgSEODm59O
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
new file mode 100644
index 00000000000..aa216c7c6a3
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -0,0 +1,33 @@
+---
+name: Bug report
+about: Create a report to help us improve
+title: ''
+labels: bug
+assignees: ''
+
+---
+
+**Describe the bug**
+A clear and concise description of what the bug is.
+
+**To Reproduce**
+Steps to reproduce the behavior:
+1. Go to '...'
+2. Click on '....'
+3. Scroll down to '....'
+4. See error
+
+**Expected behavior**
+A clear and concise description of what you expected to happen.
+
+**Screenshots**
+If applicable, add screenshots to help explain your problem.
+
+**Platform (please complete the following information):**
+ - OS: [e.g. iOS]
+ - Browser [e.g. chrome, safari]
+ - Version [e.g. 22]
+ - Device Type [e.g. Desktop/Mobile (Android/iOS)]
+
+**Additional context**
+Add any other context about the problem here such as logs and HAR files.
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
index 665938f75cd..f19bbee1cd5 100644
--- a/.github/ISSUE_TEMPLATE/config.yml
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -1,8 +1,81 @@
blank_issues_enabled: false
-contact_links:
- - name: π Bug reports, βοΈβ Questions & π Support
- url: https://developer.webex.com/support
- about: Something going wrong? Do you have a question? Checkout https://developer.webex.com/support
- - name: β‘οΈ Feature Requests and Ideas
- url: https://ciscocollaboration.aha.io/
- about: Got a suggestion? Please use https://ciscocollaboration.aha.io/ so others can help prioritize your awesome idea π‘
+issue_templates:
+ - name: Bug report
+ description: File a bug report
+ labels: ["bug"]
+ body:
+ - type: dropdown
+ attributes:
+ label: Domain
+ description: Which domain does this issue belong to?
+ options:
+ - Calling
+ - Meeting
+ - Messaging
+ - Other
+
+ - type: markdown
+ attributes:
+ value: |
+ **Please describe the problem**
+ (What happened? What were you trying to do? What should have happened?)
+
+ - type: input
+ attributes:
+ label: Frequency
+ description: How often does this occur?
+ placeholder: Every time, occasionally, first time, not sure
+
+ - type: input
+ attributes:
+ label: Version
+ description: What version are you using?
+ placeholder: v1.0.0
+
+ - type: input
+ attributes:
+ label: Platform
+ description: What platform are you using?
+ placeholder: Windows 10, Mac OS X, Ubuntu 20.04
+
+ - type: textarea
+ attributes:
+ label: Steps To Recreate
+ description: Please list the steps needed to recreate the issue.
+ placeholder: Step 1, Step 2, Step 3...
+
+ - type: textarea
+ attributes:
+ label: Console Logs
+ description: Please provide the relevant console logs.
+
+ - type: textarea
+ attributes:
+ label: HAR Logs
+ description: Please provide the relevant HAR logs.
+
+ - name: Enhancement
+ description: Suggest an enhancement
+ labels: ["enhancement"]
+ body:
+ - type: dropdown
+ attributes:
+ label: Domain
+ description: Which domain does this enhancement belong to?
+ options:
+ - Calling
+ - Meeting
+ - Messaging
+ - Other
+
+ - type: textarea
+ attributes:
+ label: Describe the feature
+ description: What feature would you like to see added?
+ placeholder: Write here...
+
+ - type: textarea
+ attributes:
+ label: Use Cases
+ description: Please describe a couple of use-cases for this feature.
+ placeholder: Write here...
\ No newline at end of file
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
new file mode 100644
index 00000000000..4fe86d5ec8e
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -0,0 +1,20 @@
+---
+name: Feature request
+about: Suggest an idea for this project
+title: ''
+labels: feature
+assignees: ''
+
+---
+
+**Is your feature request related to a problem? Please describe.**
+A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
+
+**Describe the solution you'd like**
+A clear and concise description of what you want to happen.
+
+**Describe alternatives you've considered**
+A clear and concise description of any alternative solutions or features you've considered.
+
+**Additional context**
+Add any other context or screenshots about the feature request here.
diff --git a/.prettierignore b/.prettierignore
index 416468be0ac..4495a6a6ad2 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -1,7 +1,6 @@
docs
patches
coverage
-.circleci
.github
.yarn
docker
diff --git a/amplify.yml b/amplify.yml
index b42e2bf38a7..cbea46f1906 100644
--- a/amplify.yml
+++ b/amplify.yml
@@ -6,7 +6,10 @@ frontend:
- yarn install --immutable
build:
commands:
- - yarn run samples:build
+ - yarn workspaces foreach --from '@webex/*-tools' --topological-dev --parallel --verbose run build:src
+ - yarn package-tools sync --tag next
+ - yarn run build:local
+ - yarn run build:docs
artifacts:
baseDirectory: docs/
files:
diff --git a/docs/api/assets/anchor.js b/docs/api/assets/anchor.js
deleted file mode 100644
index 1f573dcbb10..00000000000
--- a/docs/api/assets/anchor.js
+++ /dev/null
@@ -1,350 +0,0 @@
-/*!
- * AnchorJS - v4.0.0 - 2017-06-02
- * https://github.com/bryanbraun/anchorjs
- * Copyright (c) 2017 Bryan Braun; Licensed MIT
- */
-/* eslint-env amd, node */
-
-// https://github.com/umdjs/umd/blob/master/templates/returnExports.js
-(function (root, factory) {
- 'use strict';
- if (typeof define === 'function' && define.amd) {
- // AMD. Register as an anonymous module.
- define([], factory);
- } else if (typeof module === 'object' && module.exports) {
- // Node. Does not work with strict CommonJS, but
- // only CommonJS-like environments that support module.exports,
- // like Node.
- module.exports = factory();
- } else {
- // Browser globals (root is window)
- root.AnchorJS = factory();
- root.anchors = new root.AnchorJS();
- }
-})(this, function () {
- 'use strict';
- function AnchorJS(options) {
- this.options = options || {};
- this.elements = [];
-
- /**
- * Assigns options to the internal options object, and provides defaults.
- * @param {Object} opts - Options object
- */
- function _applyRemainingDefaultOptions(opts) {
- opts.icon = opts.hasOwnProperty('icon') ? opts.icon : '\ue9cb'; // Accepts characters (and also URLs?), like '#', 'ΒΆ', 'β‘', or 'Β§'.
- opts.visible = opts.hasOwnProperty('visible') ? opts.visible : 'hover'; // Also accepts 'always' & 'touch'
- opts.placement = opts.hasOwnProperty('placement')
- ? opts.placement
- : 'right'; // Also accepts 'left'
- opts.class = opts.hasOwnProperty('class') ? opts.class : ''; // Accepts any class name.
- // Using Math.floor here will ensure the value is Number-cast and an integer.
- opts.truncate = opts.hasOwnProperty('truncate')
- ? Math.floor(opts.truncate)
- : 64; // Accepts any value that can be typecast to a number.
- }
-
- _applyRemainingDefaultOptions(this.options);
-
- /**
- * Checks to see if this device supports touch. Uses criteria pulled from Modernizr:
- * https://github.com/Modernizr/Modernizr/blob/da22eb27631fc4957f67607fe6042e85c0a84656/feature-detects/touchevents.js#L40
- * @returns {Boolean} - true if the current device supports touch.
- */
- this.isTouchDevice = function () {
- return !!(
- 'ontouchstart' in window ||
- (window.DocumentTouch && document instanceof DocumentTouch)
- );
- };
-
- /**
- * Add anchor links to page elements.
- * @param {String|Array|Nodelist} selector - A CSS selector for targeting the elements you wish to add anchor links
- * to. Also accepts an array or nodeList containing the relavant elements.
- * @returns {this} - The AnchorJS object
- */
- this.add = function (selector) {
- var elements,
- elsWithIds,
- idList,
- elementID,
- i,
- index,
- count,
- tidyText,
- newTidyText,
- readableID,
- anchor,
- visibleOptionToUse,
- indexesToDrop = [];
-
- // We reapply options here because somebody may have overwritten the default options object when setting options.
- // For example, this overwrites all options but visible:
- //
- // anchors.options = { visible: 'always'; }
- _applyRemainingDefaultOptions(this.options);
-
- visibleOptionToUse = this.options.visible;
- if (visibleOptionToUse === 'touch') {
- visibleOptionToUse = this.isTouchDevice() ? 'always' : 'hover';
- }
-
- // Provide a sensible default selector, if none is given.
- if (!selector) {
- selector = 'h2, h3, h4, h5, h6';
- }
-
- elements = _getElements(selector);
-
- if (elements.length === 0) {
- return this;
- }
-
- _addBaselineStyles();
-
- // We produce a list of existing IDs so we don't generate a duplicate.
- elsWithIds = document.querySelectorAll('[id]');
- idList = [].map.call(elsWithIds, function assign(el) {
- return el.id;
- });
-
- for (i = 0; i < elements.length; i++) {
- if (this.hasAnchorJSLink(elements[i])) {
- indexesToDrop.push(i);
- continue;
- }
-
- if (elements[i].hasAttribute('id')) {
- elementID = elements[i].getAttribute('id');
- } else if (elements[i].hasAttribute('data-anchor-id')) {
- elementID = elements[i].getAttribute('data-anchor-id');
- } else {
- tidyText = this.urlify(elements[i].textContent);
-
- // Compare our generated ID to existing IDs (and increment it if needed)
- // before we add it to the page.
- newTidyText = tidyText;
- count = 0;
- do {
- if (index !== undefined) {
- newTidyText = tidyText + '-' + count;
- }
-
- index = idList.indexOf(newTidyText);
- count += 1;
- } while (index !== -1);
- index = undefined;
- idList.push(newTidyText);
-
- elements[i].setAttribute('id', newTidyText);
- elementID = newTidyText;
- }
-
- readableID = elementID.replace(/-/g, ' ');
-
- // The following code builds the following DOM structure in a more effiecient (albeit opaque) way.
- // ' ';
- anchor = document.createElement('a');
- anchor.className = 'anchorjs-link ' + this.options.class;
- anchor.href = '#' + elementID;
- anchor.setAttribute('aria-label', 'Anchor link for: ' + readableID);
- anchor.setAttribute('data-anchorjs-icon', this.options.icon);
-
- if (visibleOptionToUse === 'always') {
- anchor.style.opacity = '1';
- }
-
- if (this.options.icon === '\ue9cb') {
- anchor.style.font = '1em/1 anchorjs-icons';
-
- // We set lineHeight = 1 here because the `anchorjs-icons` font family could otherwise affect the
- // height of the heading. This isn't the case for icons with `placement: left`, so we restore
- // line-height: inherit in that case, ensuring they remain positioned correctly. For more info,
- // see https://github.com/bryanbraun/anchorjs/issues/39.
- if (this.options.placement === 'left') {
- anchor.style.lineHeight = 'inherit';
- }
- }
-
- if (this.options.placement === 'left') {
- anchor.style.position = 'absolute';
- anchor.style.marginLeft = '-1em';
- anchor.style.paddingRight = '0.5em';
- elements[i].insertBefore(anchor, elements[i].firstChild);
- } else {
- // if the option provided is `right` (or anything else).
- anchor.style.paddingLeft = '0.375em';
- elements[i].appendChild(anchor);
- }
- }
-
- for (i = 0; i < indexesToDrop.length; i++) {
- elements.splice(indexesToDrop[i] - i, 1);
- }
- this.elements = this.elements.concat(elements);
-
- return this;
- };
-
- /**
- * Removes all anchorjs-links from elements targed by the selector.
- * @param {String|Array|Nodelist} selector - A CSS selector string targeting elements with anchor links,
- * OR a nodeList / array containing the DOM elements.
- * @returns {this} - The AnchorJS object
- */
- this.remove = function (selector) {
- var index,
- domAnchor,
- elements = _getElements(selector);
-
- for (var i = 0; i < elements.length; i++) {
- domAnchor = elements[i].querySelector('.anchorjs-link');
- if (domAnchor) {
- // Drop the element from our main list, if it's in there.
- index = this.elements.indexOf(elements[i]);
- if (index !== -1) {
- this.elements.splice(index, 1);
- }
- // Remove the anchor from the DOM.
- elements[i].removeChild(domAnchor);
- }
- }
- return this;
- };
-
- /**
- * Removes all anchorjs links. Mostly used for tests.
- */
- this.removeAll = function () {
- this.remove(this.elements);
- };
-
- /**
- * Urlify - Refine text so it makes a good ID.
- *
- * To do this, we remove apostrophes, replace nonsafe characters with hyphens,
- * remove extra hyphens, truncate, trim hyphens, and make lowercase.
- *
- * @param {String} text - Any text. Usually pulled from the webpage element we are linking to.
- * @returns {String} - hyphen-delimited text for use in IDs and URLs.
- */
- this.urlify = function (text) {
- // Regex for finding the nonsafe URL characters (many need escaping): & +$,:;=?@"#{}|^~[`%!'<>]./()*\
- var nonsafeChars = /[& +$,:;=?@"#{}|^~[`%!'<>\]\.\/\(\)\*\\]/g,
- urlText;
-
- // The reason we include this _applyRemainingDefaultOptions is so urlify can be called independently,
- // even after setting options. This can be useful for tests or other applications.
- if (!this.options.truncate) {
- _applyRemainingDefaultOptions(this.options);
- }
-
- // Note: we trim hyphens after truncating because truncating can cause dangling hyphens.
- // Example string: // " β‘β‘ Don't forget: URL fragments should be i18n-friendly, hyphenated, short, and clean."
- urlText = text
- .trim() // "β‘β‘ Don't forget: URL fragments should be i18n-friendly, hyphenated, short, and clean."
- .replace(/\'/gi, '') // "β‘β‘ Dont forget: URL fragments should be i18n-friendly, hyphenated, short, and clean."
- .replace(nonsafeChars, '-') // "β‘β‘-Dont-forget--URL-fragments-should-be-i18n-friendly--hyphenated--short--and-clean-"
- .replace(/-{2,}/g, '-') // "β‘β‘-Dont-forget-URL-fragments-should-be-i18n-friendly-hyphenated-short-and-clean-"
- .substring(0, this.options.truncate) // "β‘β‘-Dont-forget-URL-fragments-should-be-i18n-friendly-hyphenated-"
- .replace(/^-+|-+$/gm, '') // "β‘β‘-Dont-forget-URL-fragments-should-be-i18n-friendly-hyphenated"
- .toLowerCase(); // "β‘β‘-dont-forget-url-fragments-should-be-i18n-friendly-hyphenated"
-
- return urlText;
- };
-
- /**
- * Determines if this element already has an AnchorJS link on it.
- * Uses this technique: http://stackoverflow.com/a/5898748/1154642
- * @param {HTMLElemnt} el - a DOM node
- * @returns {Boolean} true/false
- */
- this.hasAnchorJSLink = function (el) {
- var hasLeftAnchor =
- el.firstChild &&
- (' ' + el.firstChild.className + ' ').indexOf(' anchorjs-link ') > -1,
- hasRightAnchor =
- el.lastChild &&
- (' ' + el.lastChild.className + ' ').indexOf(' anchorjs-link ') > -1;
-
- return hasLeftAnchor || hasRightAnchor || false;
- };
-
- /**
- * Turns a selector, nodeList, or array of elements into an array of elements (so we can use array methods).
- * It also throws errors on any other inputs. Used to handle inputs to .add and .remove.
- * @param {String|Array|Nodelist} input - A CSS selector string targeting elements with anchor links,
- * OR a nodeList / array containing the DOM elements.
- * @returns {Array} - An array containing the elements we want.
- */
- function _getElements(input) {
- var elements;
- if (typeof input === 'string' || input instanceof String) {
- // See https://davidwalsh.name/nodelist-array for the technique transforming nodeList -> Array.
- elements = [].slice.call(document.querySelectorAll(input));
- // I checked the 'input instanceof NodeList' test in IE9 and modern browsers and it worked for me.
- } else if (Array.isArray(input) || input instanceof NodeList) {
- elements = [].slice.call(input);
- } else {
- throw new Error('The selector provided to AnchorJS was invalid.');
- }
- return elements;
- }
-
- /**
- * _addBaselineStyles
- * Adds baseline styles to the page, used by all AnchorJS links irregardless of configuration.
- */
- function _addBaselineStyles() {
- // We don't want to add global baseline styles if they've been added before.
- if (document.head.querySelector('style.anchorjs') !== null) {
- return;
- }
-
- var style = document.createElement('style'),
- linkRule =
- ' .anchorjs-link {' +
- ' opacity: 0;' +
- ' text-decoration: none;' +
- ' -webkit-font-smoothing: antialiased;' +
- ' -moz-osx-font-smoothing: grayscale;' +
- ' }',
- hoverRule =
- ' *:hover > .anchorjs-link,' +
- ' .anchorjs-link:focus {' +
- ' opacity: 1;' +
- ' }',
- anchorjsLinkFontFace =
- ' @font-face {' +
- ' font-family: "anchorjs-icons";' + // Icon from icomoon; 10px wide & 10px tall; 2 empty below & 4 above
- ' src: url(data:n/a;base64,AAEAAAALAIAAAwAwT1MvMg8yG2cAAAE4AAAAYGNtYXDp3gC3AAABpAAAAExnYXNwAAAAEAAAA9wAAAAIZ2x5ZlQCcfwAAAH4AAABCGhlYWQHFvHyAAAAvAAAADZoaGVhBnACFwAAAPQAAAAkaG10eASAADEAAAGYAAAADGxvY2EACACEAAAB8AAAAAhtYXhwAAYAVwAAARgAAAAgbmFtZQGOH9cAAAMAAAAAunBvc3QAAwAAAAADvAAAACAAAQAAAAEAAHzE2p9fDzz1AAkEAAAAAADRecUWAAAAANQA6R8AAAAAAoACwAAAAAgAAgAAAAAAAAABAAADwP/AAAACgAAA/9MCrQABAAAAAAAAAAAAAAAAAAAAAwABAAAAAwBVAAIAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAMCQAGQAAUAAAKZAswAAACPApkCzAAAAesAMwEJAAAAAAAAAAAAAAAAAAAAARAAAAAAAAAAAAAAAAAAAAAAQAAg//0DwP/AAEADwABAAAAAAQAAAAAAAAAAAAAAIAAAAAAAAAIAAAACgAAxAAAAAwAAAAMAAAAcAAEAAwAAABwAAwABAAAAHAAEADAAAAAIAAgAAgAAACDpy//9//8AAAAg6cv//f///+EWNwADAAEAAAAAAAAAAAAAAAAACACEAAEAAAAAAAAAAAAAAAAxAAACAAQARAKAAsAAKwBUAAABIiYnJjQ3NzY2MzIWFxYUBwcGIicmNDc3NjQnJiYjIgYHBwYUFxYUBwYGIwciJicmNDc3NjIXFhQHBwYUFxYWMzI2Nzc2NCcmNDc2MhcWFAcHBgYjARQGDAUtLXoWOR8fORYtLTgKGwoKCjgaGg0gEhIgDXoaGgkJBQwHdR85Fi0tOAobCgoKOBoaDSASEiANehoaCQkKGwotLXoWOR8BMwUFLYEuehYXFxYugC44CQkKGwo4GkoaDQ0NDXoaShoKGwoFBe8XFi6ALjgJCQobCjgaShoNDQ0NehpKGgobCgoKLYEuehYXAAAADACWAAEAAAAAAAEACAAAAAEAAAAAAAIAAwAIAAEAAAAAAAMACAAAAAEAAAAAAAQACAAAAAEAAAAAAAUAAQALAAEAAAAAAAYACAAAAAMAAQQJAAEAEAAMAAMAAQQJAAIABgAcAAMAAQQJAAMAEAAMAAMAAQQJAAQAEAAMAAMAAQQJAAUAAgAiAAMAAQQJAAYAEAAMYW5jaG9yanM0MDBAAGEAbgBjAGgAbwByAGoAcwA0ADAAMABAAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAH//wAP) format("truetype");' +
- ' }',
- pseudoElContent =
- ' [data-anchorjs-icon]::after {' +
- ' content: attr(data-anchorjs-icon);' +
- ' }',
- firstStyleEl;
-
- style.className = 'anchorjs';
- style.appendChild(document.createTextNode('')); // Necessary for Webkit.
-
- // We place it in the head with the other style tags, if possible, so as to
- // not look out of place. We insert before the others so these styles can be
- // overridden if necessary.
- firstStyleEl = document.head.querySelector('[rel="stylesheet"], style');
- if (firstStyleEl === undefined) {
- document.head.appendChild(style);
- } else {
- document.head.insertBefore(style, firstStyleEl);
- }
-
- style.sheet.insertRule(linkRule, style.sheet.cssRules.length);
- style.sheet.insertRule(hoverRule, style.sheet.cssRules.length);
- style.sheet.insertRule(pseudoElContent, style.sheet.cssRules.length);
- style.sheet.insertRule(anchorjsLinkFontFace, style.sheet.cssRules.length);
- }
- }
-
- return AnchorJS;
-});
diff --git a/docs/api/assets/bass-addons.css b/docs/api/assets/bass-addons.css
deleted file mode 100644
index c27e96d8618..00000000000
--- a/docs/api/assets/bass-addons.css
+++ /dev/null
@@ -1,12 +0,0 @@
-.input {
- font-family: inherit;
- display: block;
- width: 100%;
- height: 2rem;
- padding: .5rem;
- margin-bottom: 1rem;
- border: 1px solid #ccc;
- font-size: .875rem;
- border-radius: 3px;
- box-sizing: border-box;
-}
diff --git a/docs/api/assets/bass.css b/docs/api/assets/bass.css
deleted file mode 100644
index 2d860c56e3f..00000000000
--- a/docs/api/assets/bass.css
+++ /dev/null
@@ -1,544 +0,0 @@
-/*! Basscss | http://basscss.com | MIT License */
-
-.h1{ font-size: 2rem }
-.h2{ font-size: 1.5rem }
-.h3{ font-size: 1.25rem }
-.h4{ font-size: 1rem }
-.h5{ font-size: .875rem }
-.h6{ font-size: .75rem }
-
-.font-family-inherit{ font-family:inherit }
-.font-size-inherit{ font-size:inherit }
-.text-decoration-none{ text-decoration:none }
-
-.bold{ font-weight: bold; font-weight: bold }
-.regular{ font-weight:normal }
-.italic{ font-style:italic }
-.caps{ text-transform:uppercase; letter-spacing: .2em; }
-
-.left-align{ text-align:left }
-.center{ text-align:center }
-.right-align{ text-align:right }
-.justify{ text-align:justify }
-
-.nowrap{ white-space:nowrap }
-.break-word{ word-wrap:break-word }
-
-.line-height-1{ line-height: 1 }
-.line-height-2{ line-height: 1.125 }
-.line-height-3{ line-height: 1.25 }
-.line-height-4{ line-height: 1.5 }
-
-.list-style-none{ list-style:none }
-.underline{ text-decoration:underline }
-
-.truncate{
- max-width:100%;
- overflow:hidden;
- text-overflow:ellipsis;
- white-space:nowrap;
-}
-
-.list-reset{
- list-style:none;
- padding-left:0;
-}
-
-.inline{ display:inline }
-.block{ display:block }
-.inline-block{ display:inline-block }
-.table{ display:table }
-.table-cell{ display:table-cell }
-
-.overflow-hidden{ overflow:hidden }
-.overflow-scroll{ overflow:scroll }
-.overflow-auto{ overflow:auto }
-
-.clearfix:before,
-.clearfix:after{
- content:" ";
- display:table
-}
-.clearfix:after{ clear:both }
-
-.left{ float:left }
-.right{ float:right }
-
-.fit{ max-width:100% }
-
-.max-width-1{ max-width: 24rem }
-.max-width-2{ max-width: 32rem }
-.max-width-3{ max-width: 48rem }
-.max-width-4{ max-width: 64rem }
-
-.border-box{ box-sizing:border-box }
-
-.align-baseline{ vertical-align:baseline }
-.align-top{ vertical-align:top }
-.align-middle{ vertical-align:middle }
-.align-bottom{ vertical-align:bottom }
-
-.m0{ margin:0 }
-.mt0{ margin-top:0 }
-.mr0{ margin-right:0 }
-.mb0{ margin-bottom:0 }
-.ml0{ margin-left:0 }
-.mx0{ margin-left:0; margin-right:0 }
-.my0{ margin-top:0; margin-bottom:0 }
-
-.m1{ margin: .5rem }
-.mt1{ margin-top: .5rem }
-.mr1{ margin-right: .5rem }
-.mb1{ margin-bottom: .5rem }
-.ml1{ margin-left: .5rem }
-.mx1{ margin-left: .5rem; margin-right: .5rem }
-.my1{ margin-top: .5rem; margin-bottom: .5rem }
-
-.m2{ margin: 1rem }
-.mt2{ margin-top: 1rem }
-.mr2{ margin-right: 1rem }
-.mb2{ margin-bottom: 1rem }
-.ml2{ margin-left: 1rem }
-.mx2{ margin-left: 1rem; margin-right: 1rem }
-.my2{ margin-top: 1rem; margin-bottom: 1rem }
-
-.m3{ margin: 2rem }
-.mt3{ margin-top: 2rem }
-.mr3{ margin-right: 2rem }
-.mb3{ margin-bottom: 2rem }
-.ml3{ margin-left: 2rem }
-.mx3{ margin-left: 2rem; margin-right: 2rem }
-.my3{ margin-top: 2rem; margin-bottom: 2rem }
-
-.m4{ margin: 4rem }
-.mt4{ margin-top: 4rem }
-.mr4{ margin-right: 4rem }
-.mb4{ margin-bottom: 4rem }
-.ml4{ margin-left: 4rem }
-.mx4{ margin-left: 4rem; margin-right: 4rem }
-.my4{ margin-top: 4rem; margin-bottom: 4rem }
-
-.mxn1{ margin-left: -.5rem; margin-right: -.5rem; }
-.mxn2{ margin-left: -1rem; margin-right: -1rem; }
-.mxn3{ margin-left: -2rem; margin-right: -2rem; }
-.mxn4{ margin-left: -4rem; margin-right: -4rem; }
-
-.ml-auto{ margin-left:auto }
-.mr-auto{ margin-right:auto }
-.mx-auto{ margin-left:auto; margin-right:auto; }
-
-.p0{ padding:0 }
-.pt0{ padding-top:0 }
-.pr0{ padding-right:0 }
-.pb0{ padding-bottom:0 }
-.pl0{ padding-left:0 }
-.px0{ padding-left:0; padding-right:0 }
-.py0{ padding-top:0; padding-bottom:0 }
-
-.p1{ padding: .5rem }
-.pt1{ padding-top: .5rem }
-.pr1{ padding-right: .5rem }
-.pb1{ padding-bottom: .5rem }
-.pl1{ padding-left: .5rem }
-.py1{ padding-top: .5rem; padding-bottom: .5rem }
-.px1{ padding-left: .5rem; padding-right: .5rem }
-
-.p2{ padding: 1rem }
-.pt2{ padding-top: 1rem }
-.pr2{ padding-right: 1rem }
-.pb2{ padding-bottom: 1rem }
-.pl2{ padding-left: 1rem }
-.py2{ padding-top: 1rem; padding-bottom: 1rem }
-.px2{ padding-left: 1rem; padding-right: 1rem }
-
-.p3{ padding: 2rem }
-.pt3{ padding-top: 2rem }
-.pr3{ padding-right: 2rem }
-.pb3{ padding-bottom: 2rem }
-.pl3{ padding-left: 2rem }
-.py3{ padding-top: 2rem; padding-bottom: 2rem }
-.px3{ padding-left: 2rem; padding-right: 2rem }
-
-.p4{ padding: 4rem }
-.pt4{ padding-top: 4rem }
-.pr4{ padding-right: 4rem }
-.pb4{ padding-bottom: 4rem }
-.pl4{ padding-left: 4rem }
-.py4{ padding-top: 4rem; padding-bottom: 4rem }
-.px4{ padding-left: 4rem; padding-right: 4rem }
-
-.col{
- float:left;
- box-sizing:border-box;
-}
-
-.col-right{
- float:right;
- box-sizing:border-box;
-}
-
-.col-1{
- width:8.33333%;
-}
-
-.col-2{
- width:16.66667%;
-}
-
-.col-3{
- width:25%;
-}
-
-.col-4{
- width:33.33333%;
-}
-
-.col-5{
- width:41.66667%;
-}
-
-.col-6{
- width:50%;
-}
-
-.col-7{
- width:58.33333%;
-}
-
-.col-8{
- width:66.66667%;
-}
-
-.col-9{
- width:75%;
-}
-
-.col-10{
- width:83.33333%;
-}
-
-.col-11{
- width:91.66667%;
-}
-
-.col-12{
- width:100%;
-}
-@media (min-width: 40em){
-
- .sm-col{
- float:left;
- box-sizing:border-box;
- }
-
- .sm-col-right{
- float:right;
- box-sizing:border-box;
- }
-
- .sm-col-1{
- width:8.33333%;
- }
-
- .sm-col-2{
- width:16.66667%;
- }
-
- .sm-col-3{
- width:25%;
- }
-
- .sm-col-4{
- width:33.33333%;
- }
-
- .sm-col-5{
- width:41.66667%;
- }
-
- .sm-col-6{
- width:50%;
- }
-
- .sm-col-7{
- width:58.33333%;
- }
-
- .sm-col-8{
- width:66.66667%;
- }
-
- .sm-col-9{
- width:75%;
- }
-
- .sm-col-10{
- width:83.33333%;
- }
-
- .sm-col-11{
- width:91.66667%;
- }
-
- .sm-col-12{
- width:100%;
- }
-
-}
-@media (min-width: 52em){
-
- .md-col{
- float:left;
- box-sizing:border-box;
- }
-
- .md-col-right{
- float:right;
- box-sizing:border-box;
- }
-
- .md-col-1{
- width:8.33333%;
- }
-
- .md-col-2{
- width:16.66667%;
- }
-
- .md-col-3{
- width:25%;
- }
-
- .md-col-4{
- width:33.33333%;
- }
-
- .md-col-5{
- width:41.66667%;
- }
-
- .md-col-6{
- width:50%;
- }
-
- .md-col-7{
- width:58.33333%;
- }
-
- .md-col-8{
- width:66.66667%;
- }
-
- .md-col-9{
- width:75%;
- }
-
- .md-col-10{
- width:83.33333%;
- }
-
- .md-col-11{
- width:91.66667%;
- }
-
- .md-col-12{
- width:100%;
- }
-
-}
-@media (min-width: 64em){
-
- .lg-col{
- float:left;
- box-sizing:border-box;
- }
-
- .lg-col-right{
- float:right;
- box-sizing:border-box;
- }
-
- .lg-col-1{
- width:8.33333%;
- }
-
- .lg-col-2{
- width:16.66667%;
- }
-
- .lg-col-3{
- width:25%;
- }
-
- .lg-col-4{
- width:33.33333%;
- }
-
- .lg-col-5{
- width:41.66667%;
- }
-
- .lg-col-6{
- width:50%;
- }
-
- .lg-col-7{
- width:58.33333%;
- }
-
- .lg-col-8{
- width:66.66667%;
- }
-
- .lg-col-9{
- width:75%;
- }
-
- .lg-col-10{
- width:83.33333%;
- }
-
- .lg-col-11{
- width:91.66667%;
- }
-
- .lg-col-12{
- width:100%;
- }
-
-}
-.flex{ display:-webkit-box; display:-webkit-flex; display:-ms-flexbox; display:flex }
-
-@media (min-width: 40em){
- .sm-flex{ display:-webkit-box; display:-webkit-flex; display:-ms-flexbox; display:flex }
-}
-
-@media (min-width: 52em){
- .md-flex{ display:-webkit-box; display:-webkit-flex; display:-ms-flexbox; display:flex }
-}
-
-@media (min-width: 64em){
- .lg-flex{ display:-webkit-box; display:-webkit-flex; display:-ms-flexbox; display:flex }
-}
-
-.flex-column{ -webkit-box-orient:vertical; -webkit-box-direction:normal; -webkit-flex-direction:column; -ms-flex-direction:column; flex-direction:column }
-.flex-wrap{ -webkit-flex-wrap:wrap; -ms-flex-wrap:wrap; flex-wrap:wrap }
-
-.items-start{ -webkit-box-align:start; -webkit-align-items:flex-start; -ms-flex-align:start; -ms-grid-row-align:flex-start; align-items:flex-start }
-.items-end{ -webkit-box-align:end; -webkit-align-items:flex-end; -ms-flex-align:end; -ms-grid-row-align:flex-end; align-items:flex-end }
-.items-center{ -webkit-box-align:center; -webkit-align-items:center; -ms-flex-align:center; -ms-grid-row-align:center; align-items:center }
-.items-baseline{ -webkit-box-align:baseline; -webkit-align-items:baseline; -ms-flex-align:baseline; -ms-grid-row-align:baseline; align-items:baseline }
-.items-stretch{ -webkit-box-align:stretch; -webkit-align-items:stretch; -ms-flex-align:stretch; -ms-grid-row-align:stretch; align-items:stretch }
-
-.self-start{ -webkit-align-self:flex-start; -ms-flex-item-align:start; align-self:flex-start }
-.self-end{ -webkit-align-self:flex-end; -ms-flex-item-align:end; align-self:flex-end }
-.self-center{ -webkit-align-self:center; -ms-flex-item-align:center; align-self:center }
-.self-baseline{ -webkit-align-self:baseline; -ms-flex-item-align:baseline; align-self:baseline }
-.self-stretch{ -webkit-align-self:stretch; -ms-flex-item-align:stretch; align-self:stretch }
-
-.justify-start{ -webkit-box-pack:start; -webkit-justify-content:flex-start; -ms-flex-pack:start; justify-content:flex-start }
-.justify-end{ -webkit-box-pack:end; -webkit-justify-content:flex-end; -ms-flex-pack:end; justify-content:flex-end }
-.justify-center{ -webkit-box-pack:center; -webkit-justify-content:center; -ms-flex-pack:center; justify-content:center }
-.justify-between{ -webkit-box-pack:justify; -webkit-justify-content:space-between; -ms-flex-pack:justify; justify-content:space-between }
-.justify-around{ -webkit-justify-content:space-around; -ms-flex-pack:distribute; justify-content:space-around }
-
-.content-start{ -webkit-align-content:flex-start; -ms-flex-line-pack:start; align-content:flex-start }
-.content-end{ -webkit-align-content:flex-end; -ms-flex-line-pack:end; align-content:flex-end }
-.content-center{ -webkit-align-content:center; -ms-flex-line-pack:center; align-content:center }
-.content-between{ -webkit-align-content:space-between; -ms-flex-line-pack:justify; align-content:space-between }
-.content-around{ -webkit-align-content:space-around; -ms-flex-line-pack:distribute; align-content:space-around }
-.content-stretch{ -webkit-align-content:stretch; -ms-flex-line-pack:stretch; align-content:stretch }
-.flex-auto{
- -webkit-box-flex:1;
- -webkit-flex:1 1 auto;
- -ms-flex:1 1 auto;
- flex:1 1 auto;
- min-width:0;
- min-height:0;
-}
-.flex-none{ -webkit-box-flex:0; -webkit-flex:none; -ms-flex:none; flex:none }
-.fs0{ flex-shrink: 0 }
-
-.order-0{ -webkit-box-ordinal-group:1; -webkit-order:0; -ms-flex-order:0; order:0 }
-.order-1{ -webkit-box-ordinal-group:2; -webkit-order:1; -ms-flex-order:1; order:1 }
-.order-2{ -webkit-box-ordinal-group:3; -webkit-order:2; -ms-flex-order:2; order:2 }
-.order-3{ -webkit-box-ordinal-group:4; -webkit-order:3; -ms-flex-order:3; order:3 }
-.order-last{ -webkit-box-ordinal-group:100000; -webkit-order:99999; -ms-flex-order:99999; order:99999 }
-
-.relative{ position:relative }
-.absolute{ position:absolute }
-.fixed{ position:fixed }
-
-.top-0{ top:0 }
-.right-0{ right:0 }
-.bottom-0{ bottom:0 }
-.left-0{ left:0 }
-
-.z1{ z-index: 1 }
-.z2{ z-index: 2 }
-.z3{ z-index: 3 }
-.z4{ z-index: 4 }
-
-.border{
- border-style:solid;
- border-width: 1px;
-}
-
-.border-top{
- border-top-style:solid;
- border-top-width: 1px;
-}
-
-.border-right{
- border-right-style:solid;
- border-right-width: 1px;
-}
-
-.border-bottom{
- border-bottom-style:solid;
- border-bottom-width: 1px;
-}
-
-.border-left{
- border-left-style:solid;
- border-left-width: 1px;
-}
-
-.border-none{ border:0 }
-
-.rounded{ border-radius: 3px }
-.circle{ border-radius:50% }
-
-.rounded-top{ border-radius: 3px 3px 0 0 }
-.rounded-right{ border-radius: 0 3px 3px 0 }
-.rounded-bottom{ border-radius: 0 0 3px 3px }
-.rounded-left{ border-radius: 3px 0 0 3px }
-
-.not-rounded{ border-radius:0 }
-
-.hide{
- position:absolute !important;
- height:1px;
- width:1px;
- overflow:hidden;
- clip:rect(1px, 1px, 1px, 1px);
-}
-
-@media (max-width: 40em){
- .xs-hide{ display:none !important }
-}
-
-@media (min-width: 40em) and (max-width: 52em){
- .sm-hide{ display:none !important }
-}
-
-@media (min-width: 52em) and (max-width: 64em){
- .md-hide{ display:none !important }
-}
-
-@media (min-width: 64em){
- .lg-hide{ display:none !important }
-}
-
-.display-none{ display:none !important }
-
diff --git a/docs/api/assets/fonts/EOT/SourceCodePro-Bold.eot b/docs/api/assets/fonts/EOT/SourceCodePro-Bold.eot
deleted file mode 100755
index d24cc39f470..00000000000
Binary files a/docs/api/assets/fonts/EOT/SourceCodePro-Bold.eot and /dev/null differ
diff --git a/docs/api/assets/fonts/EOT/SourceCodePro-Regular.eot b/docs/api/assets/fonts/EOT/SourceCodePro-Regular.eot
deleted file mode 100755
index 09e94730dbb..00000000000
Binary files a/docs/api/assets/fonts/EOT/SourceCodePro-Regular.eot and /dev/null differ
diff --git a/docs/api/assets/fonts/LICENSE.txt b/docs/api/assets/fonts/LICENSE.txt
deleted file mode 100755
index d154618a7d0..00000000000
--- a/docs/api/assets/fonts/LICENSE.txt
+++ /dev/null
@@ -1,93 +0,0 @@
-Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries.
-
-This Font Software is licensed under the SIL Open Font License, Version 1.1.
-
-This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
-
-
------------------------------------------------------------
-SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
------------------------------------------------------------
-
-PREAMBLE
-The goals of the Open Font License (OFL) are to stimulate worldwide
-development of collaborative font projects, to support the font creation
-efforts of academic and linguistic communities, and to provide a free and
-open framework in which fonts may be shared and improved in partnership
-with others.
-
-The OFL allows the licensed fonts to be used, studied, modified and
-redistributed freely as long as they are not sold by themselves. The
-fonts, including any derivative works, can be bundled, embedded,
-redistributed and/or sold with any software provided that any reserved
-names are not used by derivative works. The fonts and derivatives,
-however, cannot be released under any other type of license. The
-requirement for fonts to remain under this license does not apply
-to any document created using the fonts or their derivatives.
-
-DEFINITIONS
-"Font Software" refers to the set of files released by the Copyright
-Holder(s) under this license and clearly marked as such. This may
-include source files, build scripts and documentation.
-
-"Reserved Font Name" refers to any names specified as such after the
-copyright statement(s).
-
-"Original Version" refers to the collection of Font Software components as
-distributed by the Copyright Holder(s).
-
-"Modified Version" refers to any derivative made by adding to, deleting,
-or substituting -- in part or in whole -- any of the components of the
-Original Version, by changing formats or by porting the Font Software to a
-new environment.
-
-"Author" refers to any designer, engineer, programmer, technical
-writer or other person who contributed to the Font Software.
-
-PERMISSION & CONDITIONS
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of the Font Software, to use, study, copy, merge, embed, modify,
-redistribute, and sell modified and unmodified copies of the Font
-Software, subject to the following conditions:
-
-1) Neither the Font Software nor any of its individual components,
-in Original or Modified Versions, may be sold by itself.
-
-2) Original or Modified Versions of the Font Software may be bundled,
-redistributed and/or sold with any software, provided that each copy
-contains the above copyright notice and this license. These can be
-included either as stand-alone text files, human-readable headers or
-in the appropriate machine-readable metadata fields within text or
-binary files as long as those fields can be easily viewed by the user.
-
-3) No Modified Version of the Font Software may use the Reserved Font
-Name(s) unless explicit written permission is granted by the corresponding
-Copyright Holder. This restriction only applies to the primary font name as
-presented to the users.
-
-4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
-Software shall not be used to promote, endorse or advertise any
-Modified Version, except to acknowledge the contribution(s) of the
-Copyright Holder(s) and the Author(s) or with their explicit written
-permission.
-
-5) The Font Software, modified or unmodified, in part or in whole,
-must be distributed entirely under this license, and must not be
-distributed under any other license. The requirement for fonts to
-remain under this license does not apply to any document created
-using the Font Software.
-
-TERMINATION
-This license becomes null and void if any of the above conditions are
-not met.
-
-DISCLAIMER
-THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
-OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
-COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
-DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
-OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/docs/api/assets/fonts/OTF/SourceCodePro-Bold.otf b/docs/api/assets/fonts/OTF/SourceCodePro-Bold.otf
deleted file mode 100755
index f4e576cecf7..00000000000
Binary files a/docs/api/assets/fonts/OTF/SourceCodePro-Bold.otf and /dev/null differ
diff --git a/docs/api/assets/fonts/OTF/SourceCodePro-Regular.otf b/docs/api/assets/fonts/OTF/SourceCodePro-Regular.otf
deleted file mode 100755
index 4e3b9d0bcd9..00000000000
Binary files a/docs/api/assets/fonts/OTF/SourceCodePro-Regular.otf and /dev/null differ
diff --git a/docs/api/assets/fonts/TTF/SourceCodePro-Bold.ttf b/docs/api/assets/fonts/TTF/SourceCodePro-Bold.ttf
deleted file mode 100755
index e0c576f1b02..00000000000
Binary files a/docs/api/assets/fonts/TTF/SourceCodePro-Bold.ttf and /dev/null differ
diff --git a/docs/api/assets/fonts/TTF/SourceCodePro-Regular.ttf b/docs/api/assets/fonts/TTF/SourceCodePro-Regular.ttf
deleted file mode 100755
index 437f47280b4..00000000000
Binary files a/docs/api/assets/fonts/TTF/SourceCodePro-Regular.ttf and /dev/null differ
diff --git a/docs/api/assets/fonts/WOFF/OTF/SourceCodePro-Bold.otf.woff b/docs/api/assets/fonts/WOFF/OTF/SourceCodePro-Bold.otf.woff
deleted file mode 100755
index cf960992f69..00000000000
Binary files a/docs/api/assets/fonts/WOFF/OTF/SourceCodePro-Bold.otf.woff and /dev/null differ
diff --git a/docs/api/assets/fonts/WOFF/OTF/SourceCodePro-Regular.otf.woff b/docs/api/assets/fonts/WOFF/OTF/SourceCodePro-Regular.otf.woff
deleted file mode 100755
index 395436eb849..00000000000
Binary files a/docs/api/assets/fonts/WOFF/OTF/SourceCodePro-Regular.otf.woff and /dev/null differ
diff --git a/docs/api/assets/fonts/WOFF/TTF/SourceCodePro-Bold.ttf.woff b/docs/api/assets/fonts/WOFF/TTF/SourceCodePro-Bold.ttf.woff
deleted file mode 100755
index c65ba841a76..00000000000
Binary files a/docs/api/assets/fonts/WOFF/TTF/SourceCodePro-Bold.ttf.woff and /dev/null differ
diff --git a/docs/api/assets/fonts/WOFF/TTF/SourceCodePro-Regular.ttf.woff b/docs/api/assets/fonts/WOFF/TTF/SourceCodePro-Regular.ttf.woff
deleted file mode 100755
index 0af792a1e4b..00000000000
Binary files a/docs/api/assets/fonts/WOFF/TTF/SourceCodePro-Regular.ttf.woff and /dev/null differ
diff --git a/docs/api/assets/fonts/WOFF2/OTF/SourceCodePro-Bold.otf.woff2 b/docs/api/assets/fonts/WOFF2/OTF/SourceCodePro-Bold.otf.woff2
deleted file mode 100755
index cbe383538a9..00000000000
Binary files a/docs/api/assets/fonts/WOFF2/OTF/SourceCodePro-Bold.otf.woff2 and /dev/null differ
diff --git a/docs/api/assets/fonts/WOFF2/OTF/SourceCodePro-Regular.otf.woff2 b/docs/api/assets/fonts/WOFF2/OTF/SourceCodePro-Regular.otf.woff2
deleted file mode 100755
index 65cd591bd84..00000000000
Binary files a/docs/api/assets/fonts/WOFF2/OTF/SourceCodePro-Regular.otf.woff2 and /dev/null differ
diff --git a/docs/api/assets/fonts/WOFF2/TTF/SourceCodePro-Bold.ttf.woff2 b/docs/api/assets/fonts/WOFF2/TTF/SourceCodePro-Bold.ttf.woff2
deleted file mode 100755
index b78d5235e6a..00000000000
Binary files a/docs/api/assets/fonts/WOFF2/TTF/SourceCodePro-Bold.ttf.woff2 and /dev/null differ
diff --git a/docs/api/assets/fonts/WOFF2/TTF/SourceCodePro-Regular.ttf.woff2 b/docs/api/assets/fonts/WOFF2/TTF/SourceCodePro-Regular.ttf.woff2
deleted file mode 100755
index 18d2199ea49..00000000000
Binary files a/docs/api/assets/fonts/WOFF2/TTF/SourceCodePro-Regular.ttf.woff2 and /dev/null differ
diff --git a/docs/api/assets/fonts/source-code-pro.css b/docs/api/assets/fonts/source-code-pro.css
deleted file mode 100755
index 3abb4f0904d..00000000000
--- a/docs/api/assets/fonts/source-code-pro.css
+++ /dev/null
@@ -1,23 +0,0 @@
-@font-face{
- font-family: 'Source Code Pro';
- font-weight: 400;
- font-style: normal;
- font-stretch: normal;
- src: url('EOT/SourceCodePro-Regular.eot') format('embedded-opentype'),
- url('WOFF2/TTF/SourceCodePro-Regular.ttf.woff2') format('woff2'),
- url('WOFF/OTF/SourceCodePro-Regular.otf.woff') format('woff'),
- url('OTF/SourceCodePro-Regular.otf') format('opentype'),
- url('TTF/SourceCodePro-Regular.ttf') format('truetype');
-}
-
-@font-face{
- font-family: 'Source Code Pro';
- font-weight: 700;
- font-style: normal;
- font-stretch: normal;
- src: url('EOT/SourceCodePro-Bold.eot') format('embedded-opentype'),
- url('WOFF2/TTF/SourceCodePro-Bold.ttf.woff2') format('woff2'),
- url('WOFF/OTF/SourceCodePro-Bold.otf.woff') format('woff'),
- url('OTF/SourceCodePro-Bold.otf') format('opentype'),
- url('TTF/SourceCodePro-Bold.ttf') format('truetype');
-}
diff --git a/docs/api/assets/github.css b/docs/api/assets/github.css
deleted file mode 100644
index 8852abb4c67..00000000000
--- a/docs/api/assets/github.css
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
-
-github.com style (c) Vasily Polovnyov
-
-*/
-
-.hljs {
- display: block;
- overflow-x: auto;
- padding: 0.5em;
- color: #333;
- background: #f8f8f8;
- -webkit-text-size-adjust: none;
-}
-
-.hljs-comment,
-.diff .hljs-header,
-.hljs-javadoc {
- color: #998;
- font-style: italic;
-}
-
-.hljs-keyword,
-.css .rule .hljs-keyword,
-.hljs-winutils,
-.nginx .hljs-title,
-.hljs-subst,
-.hljs-request,
-.hljs-status {
- color: #1184CE;
-}
-
-.hljs-number,
-.hljs-hexcolor,
-.ruby .hljs-constant {
- color: #ed225d;
-}
-
-.hljs-string,
-.hljs-tag .hljs-value,
-.hljs-phpdoc,
-.hljs-dartdoc,
-.tex .hljs-formula {
- color: #ed225d;
-}
-
-.hljs-title,
-.hljs-id,
-.scss .hljs-preprocessor {
- color: #900;
- font-weight: bold;
-}
-
-.hljs-list .hljs-keyword,
-.hljs-subst {
- font-weight: normal;
-}
-
-.hljs-class .hljs-title,
-.hljs-type,
-.vhdl .hljs-literal,
-.tex .hljs-command {
- color: #458;
- font-weight: bold;
-}
-
-.hljs-tag,
-.hljs-tag .hljs-title,
-.hljs-rules .hljs-property,
-.django .hljs-tag .hljs-keyword {
- color: #000080;
- font-weight: normal;
-}
-
-.hljs-attribute,
-.hljs-variable,
-.lisp .hljs-body {
- color: #008080;
-}
-
-.hljs-regexp {
- color: #009926;
-}
-
-.hljs-symbol,
-.ruby .hljs-symbol .hljs-string,
-.lisp .hljs-keyword,
-.clojure .hljs-keyword,
-.scheme .hljs-keyword,
-.tex .hljs-special,
-.hljs-prompt {
- color: #990073;
-}
-
-.hljs-built_in {
- color: #0086b3;
-}
-
-.hljs-preprocessor,
-.hljs-pragma,
-.hljs-pi,
-.hljs-doctype,
-.hljs-shebang,
-.hljs-cdata {
- color: #999;
- font-weight: bold;
-}
-
-.hljs-deletion {
- background: #fdd;
-}
-
-.hljs-addition {
- background: #dfd;
-}
-
-.diff .hljs-change {
- background: #0086b3;
-}
-
-.hljs-chunk {
- color: #aaa;
-}
diff --git a/docs/api/assets/site.js b/docs/api/assets/site.js
deleted file mode 100644
index a624be7b2c6..00000000000
--- a/docs/api/assets/site.js
+++ /dev/null
@@ -1,168 +0,0 @@
-/* global anchors */
-
-// add anchor links to headers
-anchors.options.placement = 'left';
-anchors.add('h3');
-
-// Filter UI
-var tocElements = document.getElementById('toc').getElementsByTagName('li');
-
-document.getElementById('filter-input').addEventListener('keyup', function (e) {
- var i, element, children;
-
- // enter key
- if (e.keyCode === 13) {
- // go to the first displayed item in the toc
- for (i = 0; i < tocElements.length; i++) {
- element = tocElements[i];
- if (!element.classList.contains('display-none')) {
- location.replace(element.firstChild.href);
- return e.preventDefault();
- }
- }
- }
-
- var match = function () {
- return true;
- };
-
- var value = this.value.toLowerCase();
-
- if (!value.match(/^\s*$/)) {
- match = function (element) {
- var html = element.firstChild.innerHTML;
- return html && html.toLowerCase().indexOf(value) !== -1;
- };
- }
-
- for (i = 0; i < tocElements.length; i++) {
- element = tocElements[i];
- children = Array.from(element.getElementsByTagName('li'));
- if (match(element) || children.some(match)) {
- element.classList.remove('display-none');
- } else {
- element.classList.add('display-none');
- }
- }
-});
-
-var items = document.getElementsByClassName('toggle-sibling');
-for (var j = 0; j < items.length; j++) {
- items[j].addEventListener('click', toggleSibling);
-}
-
-function toggleSibling() {
- var stepSibling = this.parentNode.getElementsByClassName('toggle-target')[0];
- var icon = this.getElementsByClassName('icon')[0];
- var klass = 'display-none';
- if (stepSibling.classList.contains(klass)) {
- stepSibling.classList.remove(klass);
- icon.innerHTML = 'βΎ';
- } else {
- stepSibling.classList.add(klass);
- icon.innerHTML = 'βΈ';
- }
-}
-
-function showHashTarget(targetId) {
- if (targetId) {
- var hashTarget = document.getElementById(targetId);
- // new target is hidden
- if (
- hashTarget &&
- hashTarget.offsetHeight === 0 &&
- hashTarget.parentNode.parentNode.classList.contains('display-none')
- ) {
- hashTarget.parentNode.parentNode.classList.remove('display-none');
- }
- }
-}
-
-function scrollIntoView(targetId) {
- // Only scroll to element if we don't have a stored scroll position.
- if (targetId && !history.state) {
- var hashTarget = document.getElementById(targetId);
- if (hashTarget) {
- hashTarget.scrollIntoView();
- }
- }
-}
-
-function gotoCurrentTarget() {
- showHashTarget(location.hash.substring(1));
- scrollIntoView(location.hash.substring(1));
-}
-
-window.addEventListener('hashchange', gotoCurrentTarget);
-gotoCurrentTarget();
-
-var toclinks = document.getElementsByClassName('pre-open');
-for (var k = 0; k < toclinks.length; k++) {
- toclinks[k].addEventListener('mousedown', preOpen, false);
-}
-
-function preOpen() {
- showHashTarget(this.hash.substring(1));
-}
-
-var split_left = document.querySelector('#split-left');
-var split_right = document.querySelector('#split-right');
-var split_parent = split_left.parentNode;
-var cw_with_sb = split_left.clientWidth;
-split_left.style.overflow = 'hidden';
-var cw_without_sb = split_left.clientWidth;
-split_left.style.overflow = '';
-
-Split(['#split-left', '#split-right'], {
- elementStyle: function (dimension, size, gutterSize) {
- return {
- 'flex-basis': 'calc(' + size + '% - ' + gutterSize + 'px)'
- };
- },
- gutterStyle: function (dimension, gutterSize) {
- return {
- 'flex-basis': gutterSize + 'px'
- };
- },
- gutterSize: 20,
- sizes: [33, 67]
-});
-
-// Chrome doesn't remember scroll position properly so do it ourselves.
-// Also works on Firefox and Edge.
-
-function updateState() {
- history.replaceState(
- {
- left_top: split_left.scrollTop,
- right_top: split_right.scrollTop
- },
- document.title
- );
-}
-
-function loadState(ev) {
- if (ev) {
- // Edge doesn't replace change history.state on popstate.
- history.replaceState(ev.state, document.title);
- }
- if (history.state) {
- split_left.scrollTop = history.state.left_top;
- split_right.scrollTop = history.state.right_top;
- }
-}
-
-window.addEventListener('load', function () {
- // Restore after Firefox scrolls to hash.
- setTimeout(function () {
- loadState();
- // Update with initial scroll position.
- updateState();
- // Update scroll positions only after we've loaded because Firefox
- // emits an initial scroll event with 0.
- split_left.addEventListener('scroll', updateState);
- split_right.addEventListener('scroll', updateState);
- }, 1);
-});
-
-window.addEventListener('popstate', loadState);
diff --git a/docs/api/assets/split.css b/docs/api/assets/split.css
deleted file mode 100644
index 2d7779ee9b1..00000000000
--- a/docs/api/assets/split.css
+++ /dev/null
@@ -1,15 +0,0 @@
-.gutter {
- background-color: #f5f5f5;
- background-repeat: no-repeat;
- background-position: 50%;
-}
-
-.gutter.gutter-vertical {
- background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAFAQMAAABo7865AAAABlBMVEVHcEzMzMzyAv2sAAAAAXRSTlMAQObYZgAAABBJREFUeF5jOAMEEAIEEFwAn3kMwcB6I2AAAAAASUVORK5CYII=');
- cursor: ns-resize;
-}
-
-.gutter.gutter-horizontal {
- background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAeCAYAAADkftS9AAAAIklEQVQoU2M4c+bMfxAGAgYYmwGrIIiDjrELjpo5aiZeMwF+yNnOs5KSvgAAAABJRU5ErkJggg==');
- cursor: ew-resize;
-}
diff --git a/docs/api/assets/split.js b/docs/api/assets/split.js
deleted file mode 100644
index 71f9a60bd43..00000000000
--- a/docs/api/assets/split.js
+++ /dev/null
@@ -1,782 +0,0 @@
-/*! Split.js - v1.5.11 */
-
-(function (global, factory) {
- typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
- typeof define === 'function' && define.amd ? define(factory) :
- (global.Split = factory());
-}(this, (function () { 'use strict';
-
- // The programming goals of Split.js are to deliver readable, understandable and
- // maintainable code, while at the same time manually optimizing for tiny minified file size,
- // browser compatibility without additional requirements, graceful fallback (IE8 is supported)
- // and very few assumptions about the user's page layout.
- var global = window;
- var document = global.document;
-
- // Save a couple long function names that are used frequently.
- // This optimization saves around 400 bytes.
- var addEventListener = 'addEventListener';
- var removeEventListener = 'removeEventListener';
- var getBoundingClientRect = 'getBoundingClientRect';
- var gutterStartDragging = '_a';
- var aGutterSize = '_b';
- var bGutterSize = '_c';
- var HORIZONTAL = 'horizontal';
- var NOOP = function () { return false; };
-
- // Figure out if we're in IE8 or not. IE8 will still render correctly,
- // but will be static instead of draggable.
- var isIE8 = global.attachEvent && !global[addEventListener];
-
- // Helper function determines which prefixes of CSS calc we need.
- // We only need to do this once on startup, when this anonymous function is called.
- //
- // Tests -webkit, -moz and -o prefixes. Modified from StackOverflow:
- // http://stackoverflow.com/questions/16625140/js-feature-detection-to-detect-the-usage-of-webkit-calc-over-calc/16625167#16625167
- var calc = (['', '-webkit-', '-moz-', '-o-']
- .filter(function (prefix) {
- var el = document.createElement('div');
- el.style.cssText = "width:" + prefix + "calc(9px)";
-
- return !!el.style.length
- })
- .shift()) + "calc";
-
- // Helper function checks if its argument is a string-like type
- var isString = function (v) { return typeof v === 'string' || v instanceof String; };
-
- // Helper function allows elements and string selectors to be used
- // interchangeably. In either case an element is returned. This allows us to
- // do `Split([elem1, elem2])` as well as `Split(['#id1', '#id2'])`.
- var elementOrSelector = function (el) {
- if (isString(el)) {
- var ele = document.querySelector(el);
- if (!ele) {
- throw new Error(("Selector " + el + " did not match a DOM element"))
- }
- return ele
- }
-
- return el
- };
-
- // Helper function gets a property from the properties object, with a default fallback
- var getOption = function (options, propName, def) {
- var value = options[propName];
- if (value !== undefined) {
- return value
- }
- return def
- };
-
- var getGutterSize = function (gutterSize, isFirst, isLast, gutterAlign) {
- if (isFirst) {
- if (gutterAlign === 'end') {
- return 0
- }
- if (gutterAlign === 'center') {
- return gutterSize / 2
- }
- } else if (isLast) {
- if (gutterAlign === 'start') {
- return 0
- }
- if (gutterAlign === 'center') {
- return gutterSize / 2
- }
- }
-
- return gutterSize
- };
-
- // Default options
- var defaultGutterFn = function (i, gutterDirection) {
- var gut = document.createElement('div');
- gut.className = "gutter gutter-" + gutterDirection;
- return gut
- };
-
- var defaultElementStyleFn = function (dim, size, gutSize) {
- var style = {};
-
- if (!isString(size)) {
- if (!isIE8) {
- style[dim] = calc + "(" + size + "% - " + gutSize + "px)";
- } else {
- style[dim] = size + "%";
- }
- } else {
- style[dim] = size;
- }
-
- return style
- };
-
- var defaultGutterStyleFn = function (dim, gutSize) {
- var obj;
-
- return (( obj = {}, obj[dim] = (gutSize + "px"), obj ));
- };
-
- // The main function to initialize a split. Split.js thinks about each pair
- // of elements as an independant pair. Dragging the gutter between two elements
- // only changes the dimensions of elements in that pair. This is key to understanding
- // how the following functions operate, since each function is bound to a pair.
- //
- // A pair object is shaped like this:
- //
- // {
- // a: DOM element,
- // b: DOM element,
- // aMin: Number,
- // bMin: Number,
- // dragging: Boolean,
- // parent: DOM element,
- // direction: 'horizontal' | 'vertical'
- // }
- //
- // The basic sequence:
- //
- // 1. Set defaults to something sane. `options` doesn't have to be passed at all.
- // 2. Initialize a bunch of strings based on the direction we're splitting.
- // A lot of the behavior in the rest of the library is paramatized down to
- // rely on CSS strings and classes.
- // 3. Define the dragging helper functions, and a few helpers to go with them.
- // 4. Loop through the elements while pairing them off. Every pair gets an
- // `pair` object and a gutter.
- // 5. Actually size the pair elements, insert gutters and attach event listeners.
- var Split = function (idsOption, options) {
- if ( options === void 0 ) options = {};
-
- var ids = idsOption;
- var dimension;
- var clientAxis;
- var position;
- var positionEnd;
- var clientSize;
- var elements;
-
- // Allow HTMLCollection to be used as an argument when supported
- if (Array.from) {
- ids = Array.from(ids);
- }
-
- // All DOM elements in the split should have a common parent. We can grab
- // the first elements parent and hope users read the docs because the
- // behavior will be whacky otherwise.
- var firstElement = elementOrSelector(ids[0]);
- var parent = firstElement.parentNode;
- var parentStyle = getComputedStyle ? getComputedStyle(parent) : null;
- var parentFlexDirection = parentStyle ? parentStyle.flexDirection : null;
-
- // Set default options.sizes to equal percentages of the parent element.
- var sizes = getOption(options, 'sizes') || ids.map(function () { return 100 / ids.length; });
-
- // Standardize minSize to an array if it isn't already. This allows minSize
- // to be passed as a number.
- var minSize = getOption(options, 'minSize', 100);
- var minSizes = Array.isArray(minSize) ? minSize : ids.map(function () { return minSize; });
-
- // Get other options
- var expandToMin = getOption(options, 'expandToMin', false);
- var gutterSize = getOption(options, 'gutterSize', 10);
- var gutterAlign = getOption(options, 'gutterAlign', 'center');
- var snapOffset = getOption(options, 'snapOffset', 30);
- var dragInterval = getOption(options, 'dragInterval', 1);
- var direction = getOption(options, 'direction', HORIZONTAL);
- var cursor = getOption(
- options,
- 'cursor',
- direction === HORIZONTAL ? 'col-resize' : 'row-resize'
- );
- var gutter = getOption(options, 'gutter', defaultGutterFn);
- var elementStyle = getOption(
- options,
- 'elementStyle',
- defaultElementStyleFn
- );
- var gutterStyle = getOption(options, 'gutterStyle', defaultGutterStyleFn);
-
- // 2. Initialize a bunch of strings based on the direction we're splitting.
- // A lot of the behavior in the rest of the library is paramatized down to
- // rely on CSS strings and classes.
- if (direction === HORIZONTAL) {
- dimension = 'width';
- clientAxis = 'clientX';
- position = 'left';
- positionEnd = 'right';
- clientSize = 'clientWidth';
- } else if (direction === 'vertical') {
- dimension = 'height';
- clientAxis = 'clientY';
- position = 'top';
- positionEnd = 'bottom';
- clientSize = 'clientHeight';
- }
-
- // 3. Define the dragging helper functions, and a few helpers to go with them.
- // Each helper is bound to a pair object that contains its metadata. This
- // also makes it easy to store references to listeners that that will be
- // added and removed.
- //
- // Even though there are no other functions contained in them, aliasing
- // this to self saves 50 bytes or so since it's used so frequently.
- //
- // The pair object saves metadata like dragging state, position and
- // event listener references.
-
- function setElementSize(el, size, gutSize, i) {
- // Split.js allows setting sizes via numbers (ideally), or if you must,
- // by string, like '300px'. This is less than ideal, because it breaks
- // the fluid layout that `calc(% - px)` provides. You're on your own if you do that,
- // make sure you calculate the gutter size by hand.
- var style = elementStyle(dimension, size, gutSize, i);
-
- Object.keys(style).forEach(function (prop) {
- // eslint-disable-next-line no-param-reassign
- el.style[prop] = style[prop];
- });
- }
-
- function setGutterSize(gutterElement, gutSize, i) {
- var style = gutterStyle(dimension, gutSize, i);
-
- Object.keys(style).forEach(function (prop) {
- // eslint-disable-next-line no-param-reassign
- gutterElement.style[prop] = style[prop];
- });
- }
-
- function getSizes() {
- return elements.map(function (element) { return element.size; })
- }
-
- // Supports touch events, but not multitouch, so only the first
- // finger `touches[0]` is counted.
- function getMousePosition(e) {
- if ('touches' in e) { return e.touches[0][clientAxis] }
- return e[clientAxis]
- }
-
- // Actually adjust the size of elements `a` and `b` to `offset` while dragging.
- // calc is used to allow calc(percentage + gutterpx) on the whole split instance,
- // which allows the viewport to be resized without additional logic.
- // Element a's size is the same as offset. b's size is total size - a size.
- // Both sizes are calculated from the initial parent percentage,
- // then the gutter size is subtracted.
- function adjust(offset) {
- var a = elements[this.a];
- var b = elements[this.b];
- var percentage = a.size + b.size;
-
- a.size = (offset / this.size) * percentage;
- b.size = percentage - (offset / this.size) * percentage;
-
- setElementSize(a.element, a.size, this[aGutterSize], a.i);
- setElementSize(b.element, b.size, this[bGutterSize], b.i);
- }
-
- // drag, where all the magic happens. The logic is really quite simple:
- //
- // 1. Ignore if the pair is not dragging.
- // 2. Get the offset of the event.
- // 3. Snap offset to min if within snappable range (within min + snapOffset).
- // 4. Actually adjust each element in the pair to offset.
- //
- // ---------------------------------------------------------------------
- // | | <- a.minSize || b.minSize -> | |
- // | | | <- this.snapOffset || this.snapOffset -> | | |
- // | | | || | | |
- // | | | || | | |
- // ---------------------------------------------------------------------
- // | <- this.start this.size -> |
- function drag(e) {
- var offset;
- var a = elements[this.a];
- var b = elements[this.b];
-
- if (!this.dragging) { return }
-
- // Get the offset of the event from the first side of the
- // pair `this.start`. Then offset by the initial position of the
- // mouse compared to the gutter size.
- offset =
- getMousePosition(e) -
- this.start +
- (this[aGutterSize] - this.dragOffset);
-
- if (dragInterval > 1) {
- offset = Math.round(offset / dragInterval) * dragInterval;
- }
-
- // If within snapOffset of min or max, set offset to min or max.
- // snapOffset buffers a.minSize and b.minSize, so logic is opposite for both.
- // Include the appropriate gutter sizes to prevent overflows.
- if (offset <= a.minSize + snapOffset + this[aGutterSize]) {
- offset = a.minSize + this[aGutterSize];
- } else if (
- offset >=
- this.size - (b.minSize + snapOffset + this[bGutterSize])
- ) {
- offset = this.size - (b.minSize + this[bGutterSize]);
- }
-
- // Actually adjust the size.
- adjust.call(this, offset);
-
- // Call the drag callback continously. Don't do anything too intensive
- // in this callback.
- getOption(options, 'onDrag', NOOP)();
- }
-
- // Cache some important sizes when drag starts, so we don't have to do that
- // continously:
- //
- // `size`: The total size of the pair. First + second + first gutter + second gutter.
- // `start`: The leading side of the first element.
- //
- // ------------------------------------------------
- // | aGutterSize -> ||| |
- // | ||| |
- // | ||| |
- // | ||| <- bGutterSize |
- // ------------------------------------------------
- // | <- start size -> |
- function calculateSizes() {
- // Figure out the parent size minus padding.
- var a = elements[this.a].element;
- var b = elements[this.b].element;
-
- var aBounds = a[getBoundingClientRect]();
- var bBounds = b[getBoundingClientRect]();
-
- this.size =
- aBounds[dimension] +
- bBounds[dimension] +
- this[aGutterSize] +
- this[bGutterSize];
- this.start = aBounds[position];
- this.end = aBounds[positionEnd];
- }
-
- function innerSize(element) {
- // Return nothing if getComputedStyle is not supported (< IE9)
- // Or if parent element has no layout yet
- if (!getComputedStyle) { return null }
-
- var computedStyle = getComputedStyle(element);
-
- if (!computedStyle) { return null }
-
- var size = element[clientSize];
-
- if (size === 0) { return null }
-
- if (direction === HORIZONTAL) {
- size -=
- parseFloat(computedStyle.paddingLeft) +
- parseFloat(computedStyle.paddingRight);
- } else {
- size -=
- parseFloat(computedStyle.paddingTop) +
- parseFloat(computedStyle.paddingBottom);
- }
-
- return size
- }
-
- // When specifying percentage sizes that are less than the computed
- // size of the element minus the gutter, the lesser percentages must be increased
- // (and decreased from the other elements) to make space for the pixels
- // subtracted by the gutters.
- function trimToMin(sizesToTrim) {
- // Try to get inner size of parent element.
- // If it's no supported, return original sizes.
- var parentSize = innerSize(parent);
- if (parentSize === null) {
- return sizesToTrim
- }
-
- if (minSizes.reduce(function (a, b) { return a + b; }, 0) > parentSize) {
- return sizesToTrim
- }
-
- // Keep track of the excess pixels, the amount of pixels over the desired percentage
- // Also keep track of the elements with pixels to spare, to decrease after if needed
- var excessPixels = 0;
- var toSpare = [];
-
- var pixelSizes = sizesToTrim.map(function (size, i) {
- // Convert requested percentages to pixel sizes
- var pixelSize = (parentSize * size) / 100;
- var elementGutterSize = getGutterSize(
- gutterSize,
- i === 0,
- i === sizesToTrim.length - 1,
- gutterAlign
- );
- var elementMinSize = minSizes[i] + elementGutterSize;
-
- // If element is too smal, increase excess pixels by the difference
- // and mark that it has no pixels to spare
- if (pixelSize < elementMinSize) {
- excessPixels += elementMinSize - pixelSize;
- toSpare.push(0);
- return elementMinSize
- }
-
- // Otherwise, mark the pixels it has to spare and return it's original size
- toSpare.push(pixelSize - elementMinSize);
- return pixelSize
- });
-
- // If nothing was adjusted, return the original sizes
- if (excessPixels === 0) {
- return sizesToTrim
- }
-
- return pixelSizes.map(function (pixelSize, i) {
- var newPixelSize = pixelSize;
-
- // While there's still pixels to take, and there's enough pixels to spare,
- // take as many as possible up to the total excess pixels
- if (excessPixels > 0 && toSpare[i] - excessPixels > 0) {
- var takenPixels = Math.min(
- excessPixels,
- toSpare[i] - excessPixels
- );
-
- // Subtract the amount taken for the next iteration
- excessPixels -= takenPixels;
- newPixelSize = pixelSize - takenPixels;
- }
-
- // Return the pixel size adjusted as a percentage
- return (newPixelSize / parentSize) * 100
- })
- }
-
- // stopDragging is very similar to startDragging in reverse.
- function stopDragging() {
- var self = this;
- var a = elements[self.a].element;
- var b = elements[self.b].element;
-
- if (self.dragging) {
- getOption(options, 'onDragEnd', NOOP)(getSizes());
- }
-
- self.dragging = false;
-
- // Remove the stored event listeners. This is why we store them.
- global[removeEventListener]('mouseup', self.stop);
- global[removeEventListener]('touchend', self.stop);
- global[removeEventListener]('touchcancel', self.stop);
- global[removeEventListener]('mousemove', self.move);
- global[removeEventListener]('touchmove', self.move);
-
- // Clear bound function references
- self.stop = null;
- self.move = null;
-
- a[removeEventListener]('selectstart', NOOP);
- a[removeEventListener]('dragstart', NOOP);
- b[removeEventListener]('selectstart', NOOP);
- b[removeEventListener]('dragstart', NOOP);
-
- a.style.userSelect = '';
- a.style.webkitUserSelect = '';
- a.style.MozUserSelect = '';
- a.style.pointerEvents = '';
-
- b.style.userSelect = '';
- b.style.webkitUserSelect = '';
- b.style.MozUserSelect = '';
- b.style.pointerEvents = '';
-
- self.gutter.style.cursor = '';
- self.parent.style.cursor = '';
- document.body.style.cursor = '';
- }
-
- // startDragging calls `calculateSizes` to store the inital size in the pair object.
- // It also adds event listeners for mouse/touch events,
- // and prevents selection while dragging so avoid the selecting text.
- function startDragging(e) {
- // Right-clicking can't start dragging.
- if ('button' in e && e.button !== 0) {
- return
- }
-
- // Alias frequently used variables to save space. 200 bytes.
- var self = this;
- var a = elements[self.a].element;
- var b = elements[self.b].element;
-
- // Call the onDragStart callback.
- if (!self.dragging) {
- getOption(options, 'onDragStart', NOOP)(getSizes());
- }
-
- // Don't actually drag the element. We emulate that in the drag function.
- e.preventDefault();
-
- // Set the dragging property of the pair object.
- self.dragging = true;
-
- // Create two event listeners bound to the same pair object and store
- // them in the pair object.
- self.move = drag.bind(self);
- self.stop = stopDragging.bind(self);
-
- // All the binding. `window` gets the stop events in case we drag out of the elements.
- global[addEventListener]('mouseup', self.stop);
- global[addEventListener]('touchend', self.stop);
- global[addEventListener]('touchcancel', self.stop);
- global[addEventListener]('mousemove', self.move);
- global[addEventListener]('touchmove', self.move);
-
- // Disable selection. Disable!
- a[addEventListener]('selectstart', NOOP);
- a[addEventListener]('dragstart', NOOP);
- b[addEventListener]('selectstart', NOOP);
- b[addEventListener]('dragstart', NOOP);
-
- a.style.userSelect = 'none';
- a.style.webkitUserSelect = 'none';
- a.style.MozUserSelect = 'none';
- a.style.pointerEvents = 'none';
-
- b.style.userSelect = 'none';
- b.style.webkitUserSelect = 'none';
- b.style.MozUserSelect = 'none';
- b.style.pointerEvents = 'none';
-
- // Set the cursor at multiple levels
- self.gutter.style.cursor = cursor;
- self.parent.style.cursor = cursor;
- document.body.style.cursor = cursor;
-
- // Cache the initial sizes of the pair.
- calculateSizes.call(self);
-
- // Determine the position of the mouse compared to the gutter
- self.dragOffset = getMousePosition(e) - self.end;
- }
-
- // adjust sizes to ensure percentage is within min size and gutter.
- sizes = trimToMin(sizes);
-
- // 5. Create pair and element objects. Each pair has an index reference to
- // elements `a` and `b` of the pair (first and second elements).
- // Loop through the elements while pairing them off. Every pair gets a
- // `pair` object and a gutter.
- //
- // Basic logic:
- //
- // - Starting with the second element `i > 0`, create `pair` objects with
- // `a = i - 1` and `b = i`
- // - Set gutter sizes based on the _pair_ being first/last. The first and last
- // pair have gutterSize / 2, since they only have one half gutter, and not two.
- // - Create gutter elements and add event listeners.
- // - Set the size of the elements, minus the gutter sizes.
- //
- // -----------------------------------------------------------------------
- // | i=0 | i=1 | i=2 | i=3 |
- // | | | | |
- // | pair 0 pair 1 pair 2 |
- // | | | | |
- // -----------------------------------------------------------------------
- var pairs = [];
- elements = ids.map(function (id, i) {
- // Create the element object.
- var element = {
- element: elementOrSelector(id),
- size: sizes[i],
- minSize: minSizes[i],
- i: i,
- };
-
- var pair;
-
- if (i > 0) {
- // Create the pair object with its metadata.
- pair = {
- a: i - 1,
- b: i,
- dragging: false,
- direction: direction,
- parent: parent,
- };
-
- pair[aGutterSize] = getGutterSize(
- gutterSize,
- i - 1 === 0,
- false,
- gutterAlign
- );
- pair[bGutterSize] = getGutterSize(
- gutterSize,
- false,
- i === ids.length - 1,
- gutterAlign
- );
-
- // if the parent has a reverse flex-direction, switch the pair elements.
- if (
- parentFlexDirection === 'row-reverse' ||
- parentFlexDirection === 'column-reverse'
- ) {
- var temp = pair.a;
- pair.a = pair.b;
- pair.b = temp;
- }
- }
-
- // Determine the size of the current element. IE8 is supported by
- // staticly assigning sizes without draggable gutters. Assigns a string
- // to `size`.
- //
- // IE9 and above
- if (!isIE8) {
- // Create gutter elements for each pair.
- if (i > 0) {
- var gutterElement = gutter(i, direction, element.element);
- setGutterSize(gutterElement, gutterSize, i);
-
- // Save bound event listener for removal later
- pair[gutterStartDragging] = startDragging.bind(pair);
-
- // Attach bound event listener
- gutterElement[addEventListener](
- 'mousedown',
- pair[gutterStartDragging]
- );
- gutterElement[addEventListener](
- 'touchstart',
- pair[gutterStartDragging]
- );
-
- parent.insertBefore(gutterElement, element.element);
-
- pair.gutter = gutterElement;
- }
- }
-
- setElementSize(
- element.element,
- element.size,
- getGutterSize(
- gutterSize,
- i === 0,
- i === ids.length - 1,
- gutterAlign
- ),
- i
- );
-
- // After the first iteration, and we have a pair object, append it to the
- // list of pairs.
- if (i > 0) {
- pairs.push(pair);
- }
-
- return element
- });
-
- function adjustToMin(element) {
- var isLast = element.i === pairs.length;
- var pair = isLast ? pairs[element.i - 1] : pairs[element.i];
-
- calculateSizes.call(pair);
-
- var size = isLast
- ? pair.size - element.minSize - pair[bGutterSize]
- : element.minSize + pair[aGutterSize];
-
- adjust.call(pair, size);
- }
-
- elements.forEach(function (element) {
- var computedSize = element.element[getBoundingClientRect]()[dimension];
-
- if (computedSize < element.minSize) {
- if (expandToMin) {
- adjustToMin(element);
- } else {
- // eslint-disable-next-line no-param-reassign
- element.minSize = computedSize;
- }
- }
- });
-
- function setSizes(newSizes) {
- var trimmed = trimToMin(newSizes);
- trimmed.forEach(function (newSize, i) {
- if (i > 0) {
- var pair = pairs[i - 1];
-
- var a = elements[pair.a];
- var b = elements[pair.b];
-
- a.size = trimmed[i - 1];
- b.size = newSize;
-
- setElementSize(a.element, a.size, pair[aGutterSize], a.i);
- setElementSize(b.element, b.size, pair[bGutterSize], b.i);
- }
- });
- }
-
- function destroy(preserveStyles, preserveGutter) {
- pairs.forEach(function (pair) {
- if (preserveGutter !== true) {
- pair.parent.removeChild(pair.gutter);
- } else {
- pair.gutter[removeEventListener](
- 'mousedown',
- pair[gutterStartDragging]
- );
- pair.gutter[removeEventListener](
- 'touchstart',
- pair[gutterStartDragging]
- );
- }
-
- if (preserveStyles !== true) {
- var style = elementStyle(
- dimension,
- pair.a.size,
- pair[aGutterSize]
- );
-
- Object.keys(style).forEach(function (prop) {
- elements[pair.a].element.style[prop] = '';
- elements[pair.b].element.style[prop] = '';
- });
- }
- });
- }
-
- if (isIE8) {
- return {
- setSizes: setSizes,
- destroy: destroy,
- }
- }
-
- return {
- setSizes: setSizes,
- getSizes: getSizes,
- collapse: function collapse(i) {
- adjustToMin(elements[i]);
- },
- destroy: destroy,
- parent: parent,
- pairs: pairs,
- }
- };
-
- return Split;
-
-})));
diff --git a/docs/api/assets/style.css b/docs/api/assets/style.css
deleted file mode 100644
index 0618f4376f2..00000000000
--- a/docs/api/assets/style.css
+++ /dev/null
@@ -1,147 +0,0 @@
-.documentation {
- font-family: Helvetica, sans-serif;
- color: #666;
- line-height: 1.5;
- background: #f5f5f5;
-}
-
-.black {
- color: #666;
-}
-
-.bg-white {
- background-color: #fff;
-}
-
-h4 {
- margin: 20px 0 10px 0;
-}
-
-.documentation h3 {
- color: #000;
-}
-
-.border-bottom {
- border-color: #ddd;
-}
-
-a {
- color: #1184ce;
- text-decoration: none;
-}
-
-.documentation a[href]:hover {
- text-decoration: underline;
-}
-
-a:hover {
- cursor: pointer;
-}
-
-.py1-ul li {
- padding: 5px 0;
-}
-
-.max-height-100 {
- max-height: 100%;
-}
-
-.height-viewport-100 {
- height: 100vh;
-}
-
-section:target h3 {
- font-weight: 700;
-}
-
-.documentation td,
-.documentation th {
- padding: 0.25rem 0.25rem;
-}
-
-h1:hover .anchorjs-link,
-h2:hover .anchorjs-link,
-h3:hover .anchorjs-link,
-h4:hover .anchorjs-link {
- opacity: 1;
-}
-
-.fix-3 {
- width: 25%;
- max-width: 244px;
-}
-
-.fix-3 {
- width: 25%;
- max-width: 244px;
-}
-
-@media (min-width: 52em) {
- .fix-margin-3 {
- margin-left: 25%;
- }
-}
-
-.pre,
-pre,
-code,
-.code {
- font-family: Source Code Pro, Menlo, Consolas, Liberation Mono, monospace;
- font-size: 14px;
-}
-
-.fill-light {
- background: #f9f9f9;
-}
-
-.width2 {
- width: 1rem;
-}
-
-.input {
- font-family: inherit;
- display: block;
- width: 100%;
- height: 2rem;
- padding: 0.5rem;
- margin-bottom: 1rem;
- border: 1px solid #ccc;
- font-size: 0.875rem;
- border-radius: 3px;
- box-sizing: border-box;
-}
-
-table {
- border-collapse: collapse;
-}
-
-.prose table th,
-.prose table td {
- text-align: left;
- padding: 8px;
- border: 1px solid #ddd;
-}
-
-.prose table th:nth-child(1) {
- border-right: none;
-}
-.prose table th:nth-child(2) {
- border-left: none;
-}
-
-.prose table {
- border: 1px solid #ddd;
-}
-
-.prose-big {
- font-size: 18px;
- line-height: 30px;
-}
-
-.quiet {
- opacity: 0.7;
-}
-
-.minishadow {
- box-shadow: 2px 2px 10px #f3f3f3;
-}
diff --git a/docs/api/index.html b/docs/api/index.html
deleted file mode 100644
index 3322b9e13b2..00000000000
--- a/docs/api/index.html
+++ /dev/null
@@ -1,61173 +0,0 @@
-
-
-
-
- webex-js-sdk 2.58.1 | Documentation
-
-
-
-
-
-
-
-
-
-
-
-
webex-js-sdk
-
2.58.1
-
-
-
-
-
-
-
-
-
-
-
- webex-js-sdk
-
-
-
- webex
-
-The Cisco Webex JS SDK
-
-Install
-Usage
-
-All of the examples in these API docs assume you've gotten an authenticated Webex instance (unless otherwise specified) using one of the methods below.
-
-webex
has three basic modes of operation:
-
-Shell Script (Quick Start)
-This is the quickest way to get up and running with our JavaScript SDK. Simply set the environment variable WEBEX_ACCESS_TOKEN
to your access token and add the following line at the top of your JavaScript file to get a ready-to-use instance.
-
-You can get your WEBEX_ACCESS_TOKEN
from the Cisco Webex for Developers portal .
-
-
-webex/env
is also a great way to get started with bots .
-
-Browser
-Our JavaScript SDK provides out-of-the-box support for the OAuth 2.0 Implicit Grant Flow .
-
-You'll need to register an OAuth Client to get your "authorization string"
-
-Use the steps under Bundling (or something similar) to get the SDK into your browser, then use the following JavaScript to get started:
-Bundling
-You'll need to bundle the SDK to use it in a web browser. Right now, we do all our SDK testing with Browserify , but our Cisco Webex Widgets use webpack .
-The following snippet is the bare minimum to get our code into a form suitable for a web browser. You'll probably want to additionally pipe it through a minifier like UglifyJS before going to production.
-Then, just load your bundle using:
-NodeJS
-Though the implicit flow is great for single page apps, it's not ideal for integrations that might need to do things on your users' behalf months in the future. We additionally support the OAuth 2.0 Authorization Code Grant flow, but due to its complexity, there's a bit you'll need to wire up in your app to take advantage of it. The following is an example of how an Express app might do authentication.
-
-
-
-
-
-
-
-
-
-
-
-
- See Browser Guide and
-Server Guide
-
- new Webex()
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Related
-
-
- Browser Guide
-
-
-
-
- Server Guide
-
-
-
-
-
-
-
-
-
-
- Static Members
-
-
-
-
-
-
-
-
-
-
-
- Create a new Webex instance
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- attrs.config Object
-
- (optional)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Webex
:
-
-
-
-
-
-
-
-
-
-
- Example
-
-
Create a new Webex instance configured for your OAuth client
-
- const webex = Webex .init ({
- config : {
- credentials : {
- authorizationString : `<AUTHORIZATION URL FROM DEVELOPER PORTAL>`
- }
- }
-});
-
-
Create a new Webex instance configured for a Bot
-
- const webex = Webex .init ({
- credentials : `<BOT TOKEN FROM DEVELOPER PORTAL>`
-});
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Authorization
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Browser support for OAuth2. Automatically parses the URL hash for an access
-token
-
- new AuthorizationBrowser()
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Instance Members
-
-
-
-
-
-
βΈ
-
isAuthenticating
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Indicates if an Authorization Code exchange is inflight
-
- isAuthorizing
-
-
- Type:
- boolean
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
initiateLogin(options)
-
-
-
-
-
-
-
-
-
- Kicks off an oauth flow
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
initiateImplicitGrant(options)
-
-
-
-
-
-
-
-
-
- Kicks off the Authorization Code grant flow. Typically called via
-AuthorizationBrowser#initiateLogin
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
initiateAuthorizationCodeGrant(options)
-
-
-
-
-
-
-
-
-
- Kicks off the Implicit Code grant flow. Typically called via
-AuthorizationBrowser#initiateLogin
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
requestAccessTokenFromJwt(options)
-
-
-
-
-
-
-
-
-
- Requests a Webex access token for a user already authenticated into
-your product.
-Note: You'll need to supply a jwtRefreshCallback of the form
-Promise<jwt> = jwtRefreshCallback(webex)
for automatic token refresh to
-work.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- options.jwt Object
-
- This is a jwt generated by your backend that
-identifies a user in your system
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
logout(options)
-
-
-
-
-
-
-
-
-
- Called by WebexCore#logout() . Redirects to the logout page
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- options.noRedirect boolean
-
- if true, does not redirect
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- NodeJS support for OAuth2
-
- new AuthorizationNode()
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Instance Members
-
-
-
-
-
-
βΈ
-
isAuthenticating
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Indicates if an Authorization Code exchange is inflight
-
- isAuthorizing
-
-
- Type:
- boolean
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
requestAuthorizationCodeGrant(options)
-
-
-
-
-
-
-
-
-
- Exchanges an authorization code for an access token
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- options.code Object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
requestAccessTokenFromJwt(options)
-
-
-
-
-
-
-
-
-
- Requests a Webex access token for a user already authenticated into
-your product.
-Note: You'll need to supply a jwtRefreshCallback of the form
-Promise<jwt> = jwtRefreshCallback(webex)
for automatic token refresh to
-work.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- options.jwt Object
-
- This is a jwt generated by your backend that
-identifies a user in your system
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Meetings
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Maintain a cache of meetings and sync with services.
-
- new Meetings(args: ...any)
-
-
-
- Extends
-
- WebexPlugin
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
- args (...any)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Static Members
-
-
-
-
-
-
-
-
-
-
-
- Explicitly sets up the meetings plugin by registering
-the device, connecting to mercury, and listening for locus events.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Explicitly tears down the meetings plugin by deregistering
-the device, disconnecting from mercury, and stops listening to locus events
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
setReachability()
-
-
-
-
-
-
-
-
-
- initializes the reachability instance for Meetings
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- undefined
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
getReachability()
-
-
-
-
-
-
-
-
-
- gets the reachability instance for Meetings
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Reachability
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
startReachability()
-
-
-
-
-
-
-
-
-
- initializes and starts gathering reachability for Meetings
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
getPersonalMeetingRoom()
-
-
-
-
-
-
-
-
-
- gets the personal meeting room instance, for saved PMR values for this user
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- PersonalMeetingRoom
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
create(destination, type = null, useRandomDelayForInfo)
-
-
-
-
-
-
-
-
-
- Create a meeting.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
destination (string )
- sipURL, spaceId, phonenumber, or locus object}
-
-
-
-
-
-
-
-
type (string ?
- = null
)
- the optional specified type, such as locusId
-
-
-
-
-
-
-
-
useRandomDelayForInfo (Boolean
- = false
)
- whether a random delay should be added to fetching meeting info
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise <Meeting >
:
- A new Meeting.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
getMeetingByType(type, value)
-
-
-
-
-
-
-
-
-
- get a specifc meeting given it's type matched to the value, i.e., locus url
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Meeting
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
getAllMeetings(options)
-
-
-
-
-
-
-
-
-
- Get all meetings.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
options (object
- = {}as any
)
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- options.startDate object
-
- get meetings after this start date
-
-
-
-
-
-
- options.endDate object
-
- get meetings before this end date
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Object
:
- All currently active meetings.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- syncs all the meeting from server
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- undefined
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
getScheduledMeetings(options)
-
-
-
-
-
-
-
-
-
- Get all scheduled meetings.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- options.startDate object
-
- get meetings after this start date
-
-
-
-
-
-
- options.endDate object
-
- get meetings before this end date
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Object
:
- All scheduled meetings.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
getSupportedDevices
-
-
-
-
-
-
-
-
-
- Checks if the machine has at least one audio or video device
-
- getSupportedDevices
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- options.sendAudio Boolean
-
- (default true
)
-
-
-
-
-
-
-
- options.sendVideo Boolean
-
- (default true
)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Object
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Get the devices from the Media module
-
- getDevices
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
- resolves to an array of DeviceInfo
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Instance Members
-
-
-
-
-
-
βΈ
-
personalMeetingRoom
-
-
-
-
-
-
-
-
-
- The PersonalMeetingRoom object to interact with server
-
- personalMeetingRoom
-
-
- Type:
- Object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- If the meetings plugin has been registered and listening via Meetings#register
-
- registered
-
-
- Type:
- Boolean
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
uploadLogs(options)
-
-
-
-
-
-
-
-
-
- Uploads logs to the webex services for tracking
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- options.callStart String ?
-
- Call Start Time
-
-
-
-
-
-
- options.feedbackId String ?
-
- ID used for tracking
-
-
-
-
-
-
- options.locusId String ?
-
-
-
-
-
-
-
- options.correlationId String ?
-
-
-
-
-
-
-
- options.meetingId String ?
-
- webex meeting ID
-
-
-
-
-
-
- options.userId String ?
-
- userId
-
-
-
-
-
-
- options.orgId String ?
-
- org id
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- String
:
- feedback ID logs were submitted under
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Get the logger instance for plugin-meetings
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Logger
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- The property name for what collection will be stored, i.e., this.meetingInfos, this.meetings, etc.
-
- propertyName
-
-
- Type:
- String
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- The actual object for the collection
-
- propertyName
-
-
- Type:
- Object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Events
-
-
-
-
-
-
-
-
-
-
-
- Meetings Ready Event
-Emitted when the meetings instance on webex is ready
-
- meetings:ready
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
network:disconnected
-
-
-
-
-
-
-
-
-
- Meetings Network Disconnected Event
-Emitted when the meetings instance is disconnected from
-the internal mercury server
-
- network:disconnected
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
meetings:registered
-
-
-
-
-
-
-
-
-
- Meetings Registered Event
-Emitted when the meetings instance has been registered and listening
-
- meetings:registered
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
meeting:removed
-
-
-
-
-
-
-
-
-
- Meeting Removed Event
-Emitted when a meeting was removed from the cache of meetings
-
- meeting:removed
-
-
- Type:
- Object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Properties
-
-
-
-
meetingId (String )
- : the removed meeting
-
-
-
-
-
-
response (Object )
- : the server response
-
-
-
-
-
-
type (String )
- : what type of meeting it was
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Meeting Added Event
-Emitted when a meeting was added to the cache of meetings
-
- meeting:added
-
-
- Type:
- Object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Properties
-
-
-
-
meetingId (String )
- : the added meeting
-
-
-
-
-
-
type (String )
- : what type of meeting it was
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Meeting is the crux of the plugin
-
- new Meeting()
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Static Members
-
-
-
-
-
-
βΈ
-
fetchMeetingInfo(options)
-
-
-
-
-
-
-
-
-
- Fetches meeting information.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- options.password String ?
-
- (default null
)
-
- optional
-
-
-
-
-
-
- options.captchaCode String ?
-
- (default null
)
-
- optional
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
verifyPassword(password, captchaCode)
-
-
-
-
-
-
-
-
-
- Checks if the supplied password/host key is correct. It returns a promise with information whether the
-password and captcha code were correct or not.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
password (String )
- this can be either a password or a host key, can be undefined if only captcha was required
-
-
-
-
-
-
-
-
captchaCode (String )
- can be undefined if captcha was not required by the server
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise <{isPasswordValid: boolean , requiredCaptcha: boolean , failureReason: MEETING_INFO_FAILURE_REASON}>
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
refreshCaptcha()
-
-
-
-
-
-
-
-
-
- Refreshes the captcha. As a result the meeting will have new captcha id, image and audio.
-If the refresh operation fails, meeting remains with the old captcha properties.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
getAnalyzerMetricsPrePayload(options)
-
-
-
-
-
-
-
-
-
- get the metrics payload pre
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- options.event String
-
-
-
-
-
-
-
- options.trackingId String
-
-
-
-
-
-
-
- options.locus Object
-
-
-
-
-
-
-
- options.mediaConnections Array
-
-
-
-
-
-
-
- options.errors Object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Object
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
invite(invitee, alertIfActive = true)
-
-
-
-
-
-
-
-
-
- Invite a guest to the call that isn't normally part of this call
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- invitee.emailAddress String
-
-
-
-
-
-
-
- invitee.email String
-
-
-
-
-
-
-
- invitee.phoneNumber String
-
-
-
-
-
-
-
-
-
-
-
-
-
-
alertIfActive (Boolean ?
- = true
)
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
- see #members.addMember
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
cancelPhoneInvite(invitee)
-
-
-
-
-
-
-
-
-
- Cancel an outgoing phone call invitation made during a meeting
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- invitee.phoneNumber String
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
- see #members.cancelPhoneInvite
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
admit(memberIds)
-
-
-
-
-
-
-
-
-
- Admit the guest(s) to the call once they are waiting
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Promise
:
- see #members.admitMembers
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
remove(memberId)
-
-
-
-
-
-
-
-
-
- Remove the member from the meeting, boot them
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Promise
:
- see #members.removeMember
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
mute(memberId, mute)
-
-
-
-
-
-
-
-
-
- Mute another member from the meeting
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Promise
:
- see #members.muteMember
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
transfer(memberId, moderator)
-
-
-
-
-
-
-
-
-
- Transfer the moderator role to another eligible member
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Promise
:
- see #members.transferHostToMember
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Reference to the Members object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Members
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
isAudioConnected()
-
-
-
-
-
-
-
-
-
- Truthy when a meeting has an audio connection established
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Boolean
:
- true if meeting audio is connected otherwise false
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Convenience function to tell whether a meeting is muted
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Boolean
:
- if meeting audio muted or not
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Convenience function to tell if the end user last changed the audio state
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Boolean
:
- if audio was manipulated by the end user
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
isVideoConnected()
-
-
-
-
-
-
-
-
-
- Truthy when a meeting has a video connection established
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Boolean
:
- true if meeting video connected otherwise false
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Convenience function to tell whether video is muted
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Boolean
:
- if meeting video is muted or not
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Convenience function to tell whether the end user changed the video state
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Boolean
:
- if meeting video is muted or not
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
setRemoteStream(pc)
-
-
-
-
-
-
-
-
-
- Sets the remote stream on the class instance and emits and
-event to developers
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
pc (Object )
- The remote stream peer connection
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- undefined
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
uploadLogs(options)
-
-
-
-
-
-
-
-
-
- Upload logs for the current meeting
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
options (object
- = {file:'meeting/index',function:'uploadLogs'}
)
- file name and function name
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- undefined
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
unsetRemoteStream()
-
-
-
-
-
-
-
-
-
- Removes remote audio and video stream on the class instance and triggers an event
-to developers
-
-
-
-
-
- Deprecated: after v1.89.3
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- undefined
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
closeRemoteStream()
-
-
-
-
-
-
-
-
-
- Removes the remote stream on the class instance and triggers an event
-to developers
-
-
-
-
-
- Deprecated: after v1.89.3
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- undefined
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
closeRemoteTracks()
-
-
-
-
-
-
-
-
-
- Removes the remote tracks on the class instance and triggers an event
-to developers
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- undefined
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
setLocalTracks(localStream)
-
-
-
-
-
-
-
-
-
- Sets the local media stream on the class and emits an event to the developer
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
localStream (Stream )
- the local media stream
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- undefined
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
setLocalShareTrack(localShare)
-
-
-
-
-
-
-
-
-
- Sets the local media stream on the class and emits an event to the developer
-
- setLocalShareTrack(localShare: MediaStream):
undefined
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
- localShare (MediaStream)
- the local media stream
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- undefined
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
unsetLocalVideoTrack()
-
-
-
-
-
-
-
-
-
- Removes the local stream from the class and emits an event to the developer
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- undefined
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
unsetLocalShareTrack()
-
-
-
-
-
-
-
-
-
- Removes the local share from the class and emits an event to the developer
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- undefined
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
setMercuryListener()
-
-
-
-
-
-
-
-
-
- sets up listner for mercury event
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- undefined
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
closePeerConnections()
-
-
-
-
-
-
-
-
-
- Close the peer connections and remove them from the class. Triggers an event
-when each is closed.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
- returns a resolved promise with an array of closed peer connections
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
unsetPeerConnections(peerConnection)
-
-
-
-
-
-
-
-
-
- Unsets the peer connections on the class
-warning DO NOT CALL WITHOUT CLOSING PEER CONNECTIONS FIRST
-
- unsetPeerConnections(peerConnection: PeerConnection):
undefined
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
- peerConnection (PeerConnection)
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- undefined
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Mute the audio for a meeting
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
- resolves the data from muting audio {mute, self} or rejects if there is no audio set
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Unmute meeting audio
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
- resolves data from muting audio {mute, self} or rejects if there is no audio set
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Mute the video for a meeting
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
- resolves data from muting video {mute, self} or rejects if there is no video set
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Unmute meeting video
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
- resolves data from muting video {mute, self} or rejects if there is no video set
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
reconnect(options)
-
-
-
-
-
-
-
-
-
- Initiates the reconnection of the media in the meeting
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Promise
:
- resolves with {reconnect} or errors with {error}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
usePhoneAudio(phoneNumber)
-
-
-
-
-
-
-
-
-
- Use phone for meeting audio
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
phoneNumber (String )
- If provided, it will dial-out using this number. If not provided, dial-in will be used
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
- Resolves once the dial-in or dial-out request has completed, or rejects if it failed
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
disconnectPhoneAudio()
-
-
-
-
-
-
-
-
-
- Disconnect meeting audio via phone.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
- Resolves once the phone audio disconnection has completed
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
moveTo(resourceId)
-
-
-
-
-
-
-
-
-
- Moves the call to the specified resourceId
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Promise
:
- once the move has been completed
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
moveFrom(resourceId)
-
-
-
-
-
-
-
-
-
- Moves the call from the specified resourceId, back to computer
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Promise
:
- once the move has been completed
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
updateAudio(options)
-
-
-
-
-
-
-
-
-
- Update the main audio track with new parameters
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- options.sendAudio boolean
-
-
-
-
-
-
-
- options.receiveAudio boolean
-
-
-
-
-
-
-
- options.stream MediaStream
-
- Stream that contains the audio track to update
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
updateVideo(options)
-
-
-
-
-
-
-
-
-
- Update the main video track with new parameters
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- options.sendVideo boolean
-
-
-
-
-
-
-
- options.receiveVideo boolean
-
-
-
-
-
-
-
- options.stream MediaStream
-
- Stream that contains the video track to update
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
updateShare(options)
-
-
-
-
-
-
-
-
-
- Update the share streams, can be used to start sharing
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- options.sendShare boolean
-
-
-
-
-
-
-
- options.receiveShare boolean
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
acknowledge(type)
-
-
-
-
-
-
-
-
-
- Acknowledge the meeting, outgoing or incoming
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Promise
:
- resolve {message, ringing, response}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
decline(reason)
-
-
-
-
-
-
-
-
-
- Decline this meeting
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- undefined
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Leave the current meeting
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
options (Object
- = {}as any
)
- leave options
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- options.resourceId String
-
- the device with which to leave from, empty if just the computer
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
startWhiteboardShare(channelUrl, resourceToken)
-
-
-
-
-
-
-
-
-
- Start sharing whiteboard given channelUrl
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
channelUrl (string )
- whiteboard url
-
-
-
-
-
-
-
-
resourceToken (String )
- token created by authorize media injector
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
stopWhiteboardShare(channelUrl)
-
-
-
-
-
-
-
-
-
- Stop sharing whiteboard given channelUrl
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
channelUrl (string )
- whiteboard url
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
stopShare(options)
-
-
-
-
-
-
-
-
-
- Stops the screen share
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
- options (any
- = {}
)
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
- see #updateShare
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
startRecording()
-
-
-
-
-
-
-
-
-
- Intiate a recording of this meeting
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
setMuteOnEntry(enabled)
-
-
-
-
-
-
-
-
-
- set the mute on entry flag for participants if you're the host
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
setDisallowUnmute(enabled)
-
-
-
-
-
-
-
-
-
- set the disallow unmute flag for participants if you're the host
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
stopRecording()
-
-
-
-
-
-
-
-
-
- End the recording of this meeting
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
pauseRecording()
-
-
-
-
-
-
-
-
-
- Pauses the recording of this meeting
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
resumeRecording()
-
-
-
-
-
-
-
-
-
- Resumes the recording of this meeting
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Locks the current meeting if possible
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
unlockMeeting()
-
-
-
-
-
-
-
-
-
- Unlocks the current meeting if possible
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
sendDTMF(tones)
-
-
-
-
-
-
-
-
-
- Sends DTMF tones to the current meeting
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
tones (String )
- a string of one or more DTMF tones to send
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
changeVideoLayout(layoutType?, renderInfo)
-
-
-
-
-
-
-
-
-
- Sends request to change layout type for the current meeting for the specific participant/device only
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
layoutType (String ?)
- a layout type that should be available in meeting constants
-
#layout_types
-
-
-
-
-
-
-
-
renderInfo (Object
- = {}as any
)
- preferred dimensions for the remote main and content streams (server can ignore it)
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- renderInfo.main Object
-
- preferred dimensions for the remote main video stream
-
-
-
-
-
- renderInfo.main.width Number
-
- preferred width of main video stream
-
-
-
-
-
-
- renderInfo.main.height Number
-
- preferred height of main video stream
-
-
-
-
-
-
-
-
-
- renderInfo.content Object
-
- preferred dimensions for the remote content share stream
-
-
-
-
-
- renderInfo.content.width Number
-
- preferred width of content share stream
-
-
-
-
-
-
- renderInfo.content.height Number
-
- preferred height of content share stream
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
endMeetingForAll()
-
-
-
-
-
-
-
-
-
- End the current meeting for all
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
clearMeetingData
-
-
-
-
-
-
-
-
-
- clear the meeting data
-
- clearMeetingData
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- undefined
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Internal API to return status of BNR
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Boolean
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Internal API to return status of BNR
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Boolean
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Enable the audio track with BNR for a meeting
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
- resolves the data from enable bnr or rejects if there is no audio or audio is muted
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Disable the BNR for an audio track
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
- resolves the data from disable bnr or rejects if there is no audio set
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
sendReaction(reactionType, skinToneType)
-
-
-
-
-
-
-
-
-
- Send a reaction inside the meeting.
-
- sendReaction(reactionType: ReactionType, skinToneType: SkinToneType):
Promise
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
- reactionType (ReactionType)
- type of reaction to be sent. Example: "thumbs_up"
-
-
-
-
-
-
-
- skinToneType (SkinToneType)
- skin tone for the reaction. Example: "medium_dark"
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Instance Members
-
-
-
-
-
-
-
-
-
-
-
-
- id
-
-
- Type:
- String
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Correlation ID used for network tracking of meeting join
-
- correlationId
-
-
- Type:
- String
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- userId
-
-
- Type:
- String
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Organization ID
-
- orgId
-
-
- Type:
- String
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- resource
-
-
- Type:
- String
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- deviceUrl
-
-
- Type:
- String
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- meetingInfo
-
-
- Type:
- Object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- members
-
-
- Type:
- Members
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
meetingFiniteStateMachine
-
-
-
-
-
-
-
-
-
-
- meetingFiniteStateMachine
-
-
- Type:
- MeetingStateMachine
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
conversationUrl
-
-
-
-
-
-
-
-
-
-
- conversationUrl
-
-
- Type:
- String
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- locusUrl
-
-
- Type:
- String
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- sipUri
-
-
- Type:
- String
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- destination
-
-
- Type:
- String
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
destinationType
-
-
-
-
-
-
-
-
-
-
- destinationType
-
-
- Type:
- String
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- partner
-
-
- Type:
- String
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- type
-
-
- Type:
- String
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- owner
-
-
- Type:
- String
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- hostId
-
-
- Type:
- String
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- policy
-
-
- Type:
- String
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
inMeetingActions
-
-
-
-
-
-
-
-
-
-
- inMeetingActions
-
-
- Type:
- InMeetingActions
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- This is deprecated, please use shareStatus instead.
-
- isSharing
-
-
- Type:
- Boolean
-
-
-
-
- Deprecated: after v1.118.13
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- shareStatus
-
-
- Type:
- string
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- callEvents
-
-
- Type:
- Array
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- networkStatus
-
-
- Type:
- String
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- recording
-
-
- Type:
- Recording
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Password status. If it's PASSWORD_STATUS.REQUIRED then verifyPassword() needs to be called
-with the correct password before calling join()
-
- passwordStatus
-
-
- Type:
- PASSWORD_STATUS
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
requiredCaptcha
-
-
-
-
-
-
-
-
-
- Information about required captcha. If null, then no captcha is required. status. If it's PASSWORD_STATUS.REQUIRED then verifyPassword() needs to be called
-with the correct password before calling join()
-
- requiredCaptcha
-
-
- Type:
- Object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Properties
-
-
-
-
captchaId (string )
- : captcha id
-
-
-
-
-
-
verificationImageURL (string )
- : Url of the captcha image
-
-
-
-
-
-
verificationAudioURL (string )
- : Url of the captcha audio file
-
-
-
-
-
-
refreshURL (string )
- : Url used for refreshing the captcha (don't use it directly, call refreshCaptcha() instead)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
recordingController
-
-
-
-
-
-
-
-
-
- The class that helps to control recording functions: start, stop, pause, resume, etc
-
- recordingController
-
-
- Type:
- RecordingController
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
controlsOptionsManager
-
-
-
-
-
-
-
-
-
- The class that helps to control recording functions: start, stop, pause, resume, etc
-
- controlsOptionsManager
-
-
- Type:
- ControlsOptionsManager
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
unsetRemoteTracks()
-
-
-
-
-
-
-
-
-
- Removes remote audio, video and share tracks from class instance's mediaProperties
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- undefined
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
isTranscriptionSupported()
-
-
-
-
-
-
-
-
-
- Check if the meeting supports the Webex Assistant feature
-
- isTranscriptionSupported():
boolean
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- boolean
:
-
-
-
-
-
-
-
-
- Throws
-
-
- any: TranscriptionNotSupportedError
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
stopReceivingTranscription()
-
-
-
-
-
-
-
-
-
- stop recieving Transcription by closing
-the web socket connection properly
-
- stopReceivingTranscription(): void
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- void
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
setLocalVideoQuality(level)
-
-
-
-
-
-
-
-
-
- Sets the quality of the local video stream
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
level (String )
- {LOW|MEDIUM|HIGH}
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise <MediaStream>
:
- localStream
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
setRemoteQualityLevel(level)
-
-
-
-
-
-
-
-
-
- Sets the quality level of the remote incoming media
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
level (String )
- {LOW|MEDIUM|HIGH}
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
setMeetingQuality(level)
-
-
-
-
-
-
-
-
-
- This is deprecated, please use setLocalVideoQuality for setting local and setRemoteQualityLevel for remote
-
-
-
-
-
- Deprecated: After FHD support
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
level (String )
- {LOW|MEDIUM|HIGH}
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
shareScreen(options)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
options (Object
- = {}as any
)
- parameter
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- options.sendAudio Boolean
-
- send audio from the display share
-
-
-
-
-
-
- options.sendShare Boolean
-
- send video from the display share
-
-
-
-
-
-
- options.sharePreferences Object
-
-
-
-
-
-
- options.sharePreferences.shareConstraints MediaTrackConstraints
-
- constraints to apply to video
-
-
-
-
-
-
- options.sharePreferences.highFrameRate Boolean
-
- if shareConstraints isn't provided, set default values based off of this boolean
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
- Related
-
-
- https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackConstraints
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
setStartSetupDelay(typeMedia)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
typeMedia (string )
- 'audio' or 'video'
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- undefined
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
setEndSetupDelay(typeMedia)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
typeMedia (string )
- 'audio' or 'video'
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- undefined
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
getSetupDelayDuration(typeMedia)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
typeMedia (string )
- 'audio' or 'video'
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- string
:
- duration between start and end of setup
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
setStartLocalSDPGenRemoteSDPRecvDelay()
-
-
-
-
-
-
-
-
-
-
- setStartLocalSDPGenRemoteSDPRecvDelay():
undefined
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- undefined
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
setEndLocalSDPGenRemoteSDPRecvDelay()
-
-
-
-
-
-
-
-
-
-
- setEndLocalSDPGenRemoteSDPRecvDelay():
undefined
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- undefined
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
getLocalSDPGenRemoteSDPRecvDelay()
-
-
-
-
-
-
-
-
-
-
- getLocalSDPGenRemoteSDPRecvDelay():
string
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- string
:
- duration between local SDP generation and remote SDP reception
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
setStartCallInitiateJoinReq()
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- undefined
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
setEndCallInitiateJoinReq()
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- undefined
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
getCallInitiateJoinReq()
-
-
-
-
-
-
-
-
-
-
- getCallInitiateJoinReq():
string
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- string
:
- duration between call initiate and sending join request to locus
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
setStartJoinReqResp()
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- undefined
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
setEndJoinReqResp()
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- undefined
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
getJoinReqResp()
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- string
:
- duration between sending locus join request and receiving join response
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- string
:
- duration between call initiate and successful locus join (even if it is in lobby)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Events
-
-
-
-
-
-
βΈ
-
meeting:stateChange
-
-
-
-
-
-
-
-
-
- Meeting State Change Event
-Emitted when ever there is a meeting state change
-
- meeting:stateChange
-
-
- Type:
- Object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Properties
-
-
-
-
currentState (String )
- : current state of the meeting
-
-
-
-
-
-
previousState (String )
- : previous state of the meeting
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
meeting:ringing
-
-
-
-
-
-
-
-
-
- Meeting Ringing Event
-Emitted when this client should play a ringing sound, because this member is getting an incoming meeting
-or sending out an incoming meeting
-
- meeting:ringing
-
-
- Type:
- Object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Properties
-
-
-
-
type (String )
- : // INCOMING or JOIN
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
meeting:ringingStop
-
-
-
-
-
-
-
-
-
- Meeting Ringing Stop Event
-Emitted when this client should stop playing a ringing sound
-
- meeting:ringingStop
-
-
- Type:
- Object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Properties
-
-
-
-
type (Object )
-
-
-
-
- type.remoteAnswered
Boolean
-
-
-
- type.remoteDeclined
Boolean
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
meeting:startedSharingLocal
-
-
-
-
-
-
-
-
-
- Meeting Started Sharing Local Event
-Emitted when this member starts sharing
-
- meeting:startedSharingLocal
-
-
- Type:
- Object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
meeting:stoppedSharingLocal
-
-
-
-
-
-
-
-
-
- Meeting Stopped Sharing Local Event
-Emitted when this member stops sharing
-
- meeting:stoppedSharingLocal
-
-
- Type:
- Object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
meeting:startedSharingRemote
-
-
-
-
-
-
-
-
-
- Meeting Started Sharing Remote Event
-Emitted when remote sharing starts
-
- meeting:startedSharingRemote
-
-
- Type:
- Object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Properties
-
-
-
-
memberId (Boolean )
- : id of the meeting member that started screen share
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
meeting:stoppedSharingRemote
-
-
-
-
-
-
-
-
-
- Meeting Stopped Sharing Remote Event
-Emitted when remote screen sharing ends
-
- meeting:stoppedSharingRemote
-
-
- Type:
- Object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Meeting Locked Event
-Emitted when a meeting is locked
-
- meeting:locked
-
-
- Type:
- Object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Properties
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
meeting:unlocked
-
-
-
-
-
-
-
-
-
- Meeting Unlocked Event
-Emitted when a meeting is unlocked
-
- meeting:unlocked
-
-
- Type:
- Object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Properties
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
meeting:actionsUpdate
-
-
-
-
-
-
-
-
-
- Meeting Actions Update Event
-Emitted when a user can take actions on a meeting such as lock, unlock, assign host
-
- meeting:actionsUpdate
-
-
- Type:
- Object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Properties
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
meeting:self:unmutedByOthers
-
-
-
-
-
-
-
-
-
- Meeting Unmuted By Others Event
-Emitted when a member is unmuted by another member
-
- meeting:self:unmutedByOthers
-
-
- Type:
- Object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Properties
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
meeting:self:mutedByOthers
-
-
-
-
-
-
-
-
-
- Meeting Muted By Others Event
-Emitted when a member is muted by another member
-
- meeting:self:mutedByOthers
-
-
- Type:
- Object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Properties
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
meeting:self:requestedToUnmute
-
-
-
-
-
-
-
-
-
- Meeting Muted By Others Event
-Emitted when the host(moderator)/co-host requests a user to unmute
-
- meeting:self:requestedToUnmute
-
-
- Type:
- Object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Properties
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
meeting:self:guestAdmitted
-
-
-
-
-
-
-
-
-
- Meeting Self Guest Admitted Event
-Emitted when a joined user get admitted to the meeting by another member or host
-
- meeting:self:guestAdmitted
-
-
- Type:
- Object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Properties
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
meeting:self:lobbyWaiting
-
-
-
-
-
-
-
-
-
- Meeting Self Lobby Waiting Event
-Emitted when joined user enters the lobby and is waiting for the webex meeting to begin
-
- meeting:self:lobbyWaiting
-
-
- Type:
- Object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Properties
-
-
-
-
reason (Object )
- : Reason why user left the meeting
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
meeting:self:left
-
-
-
-
-
-
-
-
-
- Meeting Self Left State
-Emitted when user is inactive for more then 40 seconds, User can rejoin the meeting again
-
- meeting:self:left
-
-
- Type:
- Object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Properties
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
meeting:reconnectionStarting
-
-
-
-
-
-
-
-
-
- Reconnection Starting Event
-Emitted when reconnection of media to the active meeting was successful
-
- meeting:reconnectionStarting
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
meeting:reconnectionSuccess
-
-
-
-
-
-
-
-
-
- Reconnection Success Event
-Emitted when reconnection of media to the active meeting was successful
-
- meeting:reconnectionSuccess
-
-
- Type:
- Object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Properties
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
meeting:reconnectionFailure
-
-
-
-
-
-
-
-
-
- Reconnection Failure Event
-Emitted when reconnection of media to the active meeting was successful
-
- meeting:reconnectionFailure
-
-
- Type:
- Object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Properties
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
network:quality
-
-
-
-
-
-
-
-
-
- Meeting network quality event
-Emitted on each interval of retrieving stats Analyzer data
-
- network:quality
-
-
- Type:
- Object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Properties
-
-
-
-
mediaType (string )
- : {video|audio}
-
-
-
-
-
-
networkQualityScore (number )
- : {1|0} 1 indicates acceptable uplink 0 indicates unacceptable uplink based on threshold
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Messaging
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Messages are how people communicate in rooms. Each message timestamped and
-represented in Webex as a distinct block of content. Messages can contain
-plain text and a single file attachment. See the
-Message Attachments Guide
-for a list of supported media types.
-
- new Messages()
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Instance Members
-
-
-
-
-
-
-
-
-
-
-
- Register to listen for incoming attachmentAction events
-This is an alternate approach to registering for attachmentAction webhooks.
-The events passed to any registered handlers will be similar to the webhook JSON,
-but will omit webhook specific fields such as name, secret, url, etc.
-The attachmentActions.listen() event objects can also include additional fields not
-available in the webhook's JSON payload, specifically: inputs
.
-To utilize the listen()
method, the authorization token used
-will need to have spark:all
and spark:kms
scopes enabled.
-Note that by configuring your application to enable or disable spark:all
-via its configuration page will also enable or disable spark:kms
.
-See the Sample App
-for more details.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
- Example
-
-
- webex.attachmentActions .listen ()
- .then (() => {
- console .log ('listening to attachmentActions events' );
- webex.attachmentActions .on ('created' , (event ) => console .log (`Got an attachmentActions:created event:\n${event} ` ));
- })
- .catch ((e ) => console .error (`Unable to register for attachmentAction events: ${e} ` ));
-
-
-webex.attachmentActions .stopListening ();
-webex.attachmentActions .off ('created' );
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Register to listen for incoming messages events
-This is an alternate approach to registering for messages webhooks.
-The events passed to any registered handlers will be similar to the webhook JSON,
-but will omit webhook specific fields such as name, secret, url, etc.
-The messages.listen() event objects can also include additional fields not
-available in the webhook's JSON payload: text
, markdown
, and files
.
-These fields are available when their details are included in the web socket's
-activity
object. Retrieving other fields, such as the html
field,
-will require a manual request to get the corresponding message object.
-To utilize the listen()
method, the authorization token used
-will need to have spark:all
and spark:kms
scopes enabled.
-Note that by configuring your application to enable or disable spark:all
-via its configuration page will also enable or disable spark:kms
.
-See the Sample App
-for more details.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
- Example
-
-
- webex.messages .listen ()
- .then (() => {
- console .log ('listening to message events' );
- webex.messages .on ('created' , (event ) => console .log (`Got a message:created event:\n${event} ` ));
- webex.messages .on ('deleted' , (event ) => console .log (`Got a message:deleted event:\n${event} ` ));
- })
- .catch ((e ) => console .error (`Unable to register for message events: ${e} ` ));
-
-
-webex.messages .stopListening ();
-webex.messages .off ('created' );
-webex.messages .off ('deleted' );
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
create(message)
-
-
-
-
-
-
-
-
-
- Post a new message and/or media content into a room.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Promise <MessageObject >
:
-
-
-
-
-
-
-
-
-
-
- Example
-
-
- webex.rooms .create ({title : 'Create Message Example' })
- .then (function (room ) {
- return webex.messages .create ({
- text : 'Howdy!' ,
- roomId : room.id
- });
- })
- .then (function (message ) {
- var assert = require ('assert' );
- assert (message.id );
- assert (message.personId );
- assert (message.personEmail );
- assert (message.roomId );
- assert (message.created );
- return 'success' ;
- });
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
update(message, altMessage)
-
-
-
-
-
-
-
-
-
- Put an updated message and/or media content into a room instead of existing message.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Promise <MessageObject >
:
-
-
-
-
-
-
-
-
-
-
- Example
-
-
- webex.rooms .create ({title : 'Create Message Example' })
- .then (function (room ) {
- return webex.messages .create ({
- text : 'Howdy!' ,
- roomId : room.id
- });
- })
- .then (function (m ) {
- message = m;
- return webex.messages .update (message,{markdown :`**What up**` });
- })
- .then (function (m ) {
- message = m;
- return webex.messages .update (message.id ,{roomId :message.roomId ,text :'Howdy!' });
- })
- .then (function (message ) {
- var assert = require ('assert' );
- assert (message.id );
- assert (message.personId );
- assert (message.personEmail );
- assert (message.roomId );
- assert (message.created );
- return 'success' ;
- });
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns a single message.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Promise <MessageObject >
:
-
-
-
-
-
-
-
-
-
-
- Example
-
-
- var message;
-webex.rooms .create ({title : 'Get Message Example' })
- .then (function (room ) {
- return webex.messages .create ({
- text : 'Howdy!' ,
- roomId : room.id
- });
- })
- .then (function (m ) {
- message = m;
- return webex.messages .get (message.id );
- })
- .then (function (message2 ) {
- var assert = require ('assert' );
- assert.deepEqual (message2, message);
- return 'success' ;
- });
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns a list of messages. In most cases the results will only contain
-messages posted in rooms that the authenticated user is a member of.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- options.roomId string
-
-
-
-
-
-
-
- options.max number
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise <Page<MessageObject >>
:
-
-
-
-
-
-
-
-
-
-
- Example
-
-
- var message1, message2, room;
-webex.rooms .create ({title : 'List Messages Example' })
- .then (function (r ) {
- room = r;
- return webex.messages .create ({
- text : 'Howdy!' ,
- roomId : room.id
- });
- })
- .then (function (m ) {
- message1 = m;
- return webex.messages .create ({
- text : 'How are you?' ,
- roomId : room.id
- });
- })
- .then (function (m ) {
- message2 = m;
- return webex.messages .list ({roomId : room.id });
- })
- .then (function (messages ) {
- var assert = require ('assert' );
- assert.equal (messages.length , 2 );
- assert.equal (messages.items [0 ].id , message2.id );
- assert.equal (messages.items [1 ].id , message1.id );
- return 'success' ;
- });
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
remove(message)
-
-
-
-
-
-
-
-
-
- Deletes a single message. Deleting a message will notify all members of the
-room that the authenticated user deleted the message. Generally, users can
-only delete their own messages except for the case of Moderated Rooms and
-Org Administrators.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Promise
:
- }
-
-
-
-
-
-
-
-
-
-
- Example
-
-
- var message1, room;
-webex.rooms .create ({title : 'Messages Example' })
- .then (function (r ) {
- room = r;
- return webex.messages .create ({
- text : 'Howdy!' ,
- roomId : room.id
- });
- })
- .then (function (m ) {
- message1 = m;
- return webex.messages .create ({
- text : 'How are you?' ,
- roomId : room.id
- });
- })
- .then (function ( ) {
- return webex.messages .remove (message1);
- })
- .then (function ( ) {
- return webex.messages .list ({roomId : room.id });
- })
- .then (function (messages ) {
- var assert = require ('assert' );
- assert.equal (messages.items .length , 1 );
- assert (messages.items [0 ].id !== message1.id );
- return 'success' ;
- });
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Resources
-
-
-
- These are the resources provided by Webex instances for interacting with our developer API
-
-
-
-
-
-
-
-
-
-
-
-
- Memberships represent a person's relationship to a room. Use this API to list
-members of any room that you're in or create memberships to invite someone
-to a room. Memberships can also be updated to make someone a moderator
-or deleted to remove them from the room.
-
- new Memberships()
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Instance Members
-
-
-
-
-
-
-
-
-
-
-
- Register to listen for incoming membership events
-This is an alternate approach to registering for membership webhooks.
-The events passed to any registered handlers will be similar to the webhook JSON,
-but will omit webhook specific fields such as name, secret, url, etc.
-To utilize the listen()
method, the authorization token used
-will need to have spark:all
and spark:kms
scopes enabled.
-Note that by configuring your application to enable or disable spark:all
-via its configuration page will also enable or disable spark:kms
.
-See the Sample App
-for more details.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
- Example
-
-
- webex.memberships .listen ()
- .then (() => {
- console .log ('listening to membership events' );
- webex.memberships .on ('created' , (event ) => {
- console .log (`Got a membership:created event:\n${event} ` );
- }
- webex.memberships .on ('updated' , (event ) => {
- console .log (`Got a membership:updated event:\n${event} ` );
- }
- webex.memberships .on ('seen' , (event ) => {
-
-
-
- console .log (`Got a membership:seen event:\n${event} ` );
- }
- webex.memberships .on ('deleted' , (event ) => => {
- console .log (`Got a membership:created event:\n${event} ` );
- }
- })
- .catch ((e ) => console .error (`Unable to register for membership events: ${e} ` ));
-
-
-webex.memberships .stopListening ();
-webex.memberships .off ('created' );
-webex.memberships .off ('updated' );
-webex.memberships .off ('seen' );
-webex.memberships .off ('deleted' );
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
create(membership)
-
-
-
-
-
-
-
-
-
- Adds a person to a room. The person can be added by ID (personId
) or by
-Email Address (personEmail
). The person can be optionally added to the room
-as a moderator.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Promise <MembershipObject >
:
-
-
-
-
-
-
-
-
-
-
- Example
-
-
- webex.rooms .create ({title : 'Create Membership Example' })
- .then (function (room ) {
- return webex.memberships .create ({
- personEmail : 'alice@example.com' ,
- roomId : room.id
- });
- })
- .then (function (membership ) {
- var assert = require ('assert' );
- assert (membership.id );
- assert (membership.roomId );
- assert (membership.personId );
- assert (membership.personEmail );
- assert ('isModerator' in membership);
- assert ('isMonitor' in membership);
- assert (membership.created );
- return 'success' ;
- });
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
get(membership)
-
-
-
-
-
-
-
-
-
- Returns a single membership.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Promise <MembershipObject >
:
-
-
-
-
-
-
-
-
-
-
- Example
-
-
- var membership;
-webex.rooms .create ({title : 'Get Membership Example' })
- .then (function (room ) {
- return webex.memberships .create ({
- personEmail : 'alice@example.com' ,
- roomId : room.id
- });
- })
- .then (function (m ) {
- membership = m;
- return webex.memberships .get (m.id );
- })
- .then (function (m ) {
- var assert = require ('assert' );
- assert.deepEqual (m, membership);
- return 'success' ;
- });
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns a list of memberships. In most cases the results will only contain
-rooms that the authenticated user is a member of. You can filter the results
-by room to list people in a room or by person to find rooms that a
-specific person is a member of.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- options.personId string
-
-
-
-
-
-
-
- options.personEmail string
-
-
-
-
-
-
-
- options.roomId string
-
-
-
-
-
-
-
- options.max number
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise <Page<MembershipObject >>
:
-
-
-
-
-
-
-
-
-
-
- Example
-
-
- var room;
-webex.rooms .create ({title : 'List Membership Example' })
- .then (function (r ) {
- room = r;
- return webex.memberships .create ({
- personEmail : 'alice@example.com' ,
- roomId : room.id
- });
- })
- .then (function ( ) {
- return webex.memberships .list ({roomId : room.id });
- })
- .then (function (memberships ) {
- var assert = require ('assert' );
- assert.equal (memberships.length , 2 );
- for (var i = 0 ; i < memberships.length ; i+= 1 ) {
- assert.equal (memberships.items [i].roomId , room.id );
- }
- return 'success' ;
- });
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
listWithReadStatus(options)
-
-
-
-
-
-
-
-
-
- Returns a list of memberships with details about the lastSeenId for each
-user, allowing a client to indicate "read status" in a space GUI
-This differs from the memberships.list() function in the following ways:
--- it accepts only a room or object with a valid roomId
--- no other options, eg: max, are considered
--- results are not paginated
--- memberships in the return do not include the
-"created", "isRoomHidden", fields
--- memberships in the return do include the new
-"lastSeenId", and "lastSeenDate" fields
-these will not exist if the member has never "seen" the space
-In general this function should be used only when the
-client needs to access read status info.
-This function may be deprecated when this info is provided in the membership
-objects returned in the list function.
-
- listWithReadStatus(options:
Object ):
Promise <MembershipObjectList>
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- options.roomId string
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise <MembershipObjectList>
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
remove(membership)
-
-
-
-
-
-
-
-
-
- Deletes a single membership.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
- Example
-
-
- var membership, room;
-webex.rooms .create ({title : 'Remove Membership Example' })
- .then (function (r ) {
- room = r;
- return webex.memberships .create ({
- personEmail : 'alice@example.com' ,
- roomId : room.id
- });
- })
- .then (function (m ) {
- membership = m;
- return webex.memberships .list ({roomId : room.id });
- })
- .then (function (memberships ) {
- var assert = require ('assert' );
- assert.equal (memberships.length , 2 );
- return webex.memberships .remove (membership);
- })
- .then (function ( ) {
- return webex.memberships .list ({roomId : room.id });
- })
- .then (function (memberships ) {
- var assert = require ('assert' );
- assert.equal (memberships.length , 1 );
- return 'success' ;
- });
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
update(membership)
-
-
-
-
-
-
-
-
-
- Used to update a single membership's properties
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Promise <MembershipObject >
:
-
-
-
-
-
-
-
-
-
-
- Example
-
-
-
-var membership, room;
-webex.rooms .create ({title : 'Memberships Example' })
- .then (function (r ) {
- room = r;
- return webex.memberships .list ({roomId : room.id });
- })
- .then (function (memberships ) {
- membership = memberships.items [0 ];
- var assert = require ('assert' );
- assert.equal (membership.isModerator , false );
- membership.isModerator = true ;
- return webex.memberships .update (membership);
- })
- .then (function ( ) {
- return webex.memberships .get (membership.id );
- })
- .then (function (membership ) {
- var assert = require ('assert' );
- assert.equal (membership.isModerator , true );
- return 'success' ;
- });
-
-
-
-
-var assert = require ('assert' );
-var membership, myId;
-webex.people .get ('me' )
- .then (function (person ) {
- myId = personId;
- return webex.messages .create ({
- toPersonEmail : 'otherUser@acme.com' ,
- text : 'This message will create a 1-1 space'
- });
- })
- then (function (message ) {
- return webex.memberships .list ({
- roomId : message.roomId ,
- personId : myId
- });
- })
- .then ((memberships ) => {
- membership = memberships.items [0 ];
- assert.equal (membership.isRoomHidden , false );
- membership.isRoomHidden = true ;
-
-
- return webex.memberships .update (membership);
- })
- .then (function (membership ) {
- assert.equal (membership.isRoomHidden , true );
- return 'success' ;
- });
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
updateLastSeen(message)
-
-
-
-
-
-
-
-
-
- Updates the lastSeenId attribute of a membership.
-Call this method to send a "read receipt" for a given message.
-This will update the lastSeenId for the user's membership in
-space where the message is.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Promise <MembershipObject >
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- new People()
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Instance Members
-
-
-
-
-
-
-
-
-
-
-
- Returns a single person by ID
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Promise <PersonObject >
:
-
-
-
-
-
-
-
-
-
-
- Example
-
-
- webex.rooms .create ({title : 'Get Person Example' })
- .then (function (room ) {
- return webex.memberships .create ({
- personEmail : 'alice@example.com' ,
- roomId : room.id
- });
- })
- .then (function (membership ) {
- return webex.people .get (membership.personId );
- })
- .then (function (alice ) {
- var assert = require ('assert' );
- assert (alice.id );
- assert (Array .isArray (alice.emails ));
- assert.equal (alice.emails .filter (function (email ) {
- return email === 'alice@example.com' ;
- }).length , 1 );
- assert (alice.displayName );
- assert (alice.created );
- return 'success' ;
- });
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
list(options, showAllTypes)
-
-
-
-
-
-
-
-
-
- Returns a list of people
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
options ((Object | Array <uuid>))
- or array of uuids
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- options.email email
-
- Returns people with an email that contains this string
-
-
-
-
-
-
- options.displayName string
-
- Returns people with a name that contains this string
-
-
-
-
-
-
-
-
-
-
-
-
- showAllTypes (bool)
- optional flag that requires Hydra to send every type field,
-even if the type is not "person" (e.g.: SX10, webhook_integration, etc.)
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise <Page<PersonObject >>
:
-
-
-
-
-
-
-
-
-
-
- Example
-
-
- var room;
-webex.rooms .create ({title : 'List People Example' })
- .then (function (r ) {
- room = r;
- return webex.memberships .create ({
- personEmail : 'alice@example.com' ,
- roomId : room.id
- });
- })
- .then (function ( ) {
- return webex.memberships .create ({
- personEmail : 'bob@example.com' ,
- roomId : room.id
- });
- })
- .then (function ( ) {
- return webex.people .list ({email : 'alice@example.com' });
- })
- .then (function (people ) {
- var assert = require ('assert' );
- assert.equal (people.length , 1 );
- var person = people.items [0 ];
- assert (person.id );
- assert (Array .isArray (person.emails ));
- assert (person.displayName );
- assert (person.created );
- return 'success' ;
- });
-
-
-
Example usage of array method
-
- var room;
-var aliceId;
-var bobId;
-webex.rooms .create ({title : 'List People Array Example' })
- .then (function (r ) {
- room = r;
- return webex.memberships .create ({
- personEmail : 'alice@example.com' ,
- roomId : room.id
- });
- })
- .then (function (membership ) {
- aliceId = membership.personId ;
- })
- .then (function ( ) {
- return webex.memberships .create ({
- personEmail : 'bob@example.com' ,
- roomId : room.id
- });
- })
- .then (function (membership ) {
- bobId = membership.personId ;
- })
- .then (function ( ) {
- return webex.people .list ([aliceId, bobId]);
- })
- .then (function (people ) {
- var assert = require ('assert' );
- assert.equal (people.length , 2 );
- var person = people.items [0 ];
- assert (person.id );
- assert (Array .isArray (person.emails ));
- assert (person.displayName );
- assert (person.created );
- return 'success' ;
- });
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Rooms are virtual meeting places for getting stuff done. This resource
-represents the room itself. Check out the Memberships API to learn
-how to add and remove people from rooms and the Messages API for
-posting and managing content.
-
- new Rooms()
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Instance Members
-
-
-
-
-
-
-
-
-
-
-
- Register to listen for incoming rooms events
-This is an alternate approach to registering for rooms webhooks.
-The events passed to any registered handlers will be similar to the webhook JSON,
-but will omit webhook specific fields such as name, secret, url, etc.
-To utilize the listen()
method, the authorization token used
-will need to have spark:all
and spark:kms
scopes enabled.
-Note that by configuring your application to enable or disable spark:all
-via its configuration page will also enable or disable spark:kms
.
-See the Sample App
-for more details.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
- Example
-
-
- webex.rooms .listen ()
- .then (() => {
- console .log ('listening to room events' );
- webex.rooms .on ('created' , (event ) => console .log (`Got a room:created event:\n${event} ` );
- webex.rooms .on ('updated' , (event ) => console .log (`Got a room:updated event:\n${event} ` );
- })
- .catch ((e ) => console .error (`Unable to register for room events: ${e} ` ));
-
-
-webex.rooms .stopListening ();
-webex.rooms .off ('created' );
-webex.rooms .off ('updated' );
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Creates a new room. The authenticated user is automatically added as a
-member of the room. See the Memberships API to learn how to add
-more people to the room.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Promise <RoomObject >
:
-
-
-
-
-
-
-
-
-
-
- Example
-
-
- webex.rooms .create ({title : 'Create Room Example' })
- .then (function (room ) {
- var assert = require ('assert' )
- assert (typeof room.created === 'string' );
- assert (typeof room.id === 'string' );
- assert (room.title === 'Create Room Example' );
- console .log (room.title );
- return 'success' ;
- });
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
get(room, options)
-
-
-
-
-
-
-
-
-
- Returns a single room.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Promise <RoomObject >
:
-
-
-
-
-
-
-
-
-
-
- Example
-
-
- var room;
-webex.rooms .create ({title : 'Get Room Example' })
- .then (function (r ) {
- room = r
- return webex.rooms .get (room.id )
- })
- .then (function (r ) {
- var assert = require ('assert' );
- assert.deepEqual (r, room);
- return 'success' ;
- });
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns a list of rooms. In most cases the results will only contain rooms
-that the authenticated user is a member of.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- options.max Object
-
- Limit the maximum number of rooms in the
-response.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise <Page<RoomObject >>
:
-
-
-
-
-
-
-
-
-
-
- Example
-
-
- var createdRooms;
-Promise .all ([
- webex.rooms .create ({title : 'List Rooms Example 1' }),
- webex.rooms .create ({title : 'List Rooms Example 2' }),
- webex.rooms .create ({title : 'List Rooms Example 3' })
-])
- .then (function (r ) {
- createdRooms = r;
- return webex.rooms .list ({max : 3 })
- .then (function (rooms ) {
- var assert = require ('assert' );
- assert (rooms.length === 3 );
- for (var i = 0 ; i < rooms.items .length ; i+= 1 ) {
- assert (createdRooms.filter (function (room ) {
- return room.id === rooms.items [i].id ;
- }).length === 1 );
- }
- return 'success' ;
- });
- });
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
listWithReadStatus(maxRecent)
-
-
-
-
-
-
-
-
-
- Returns a list of rooms with details about the data of the last
-activity in the room, and the date of the users last presences in
-the room. The list is sorted with this with most recent activity first
-For rooms where lastActivityDate > lastSeenDate the space
-can be considered to be "unread"
-This differs from the rooms.list() function in the following ways:
--- when called with no parameters it returns an array of all
-spaces, up to 1000, that the user is a member of
--- pagination is not supported. ALL rooms are returned which
-can result in a large payload
--- For users with hundreds of spaces, this API can take some time to
-to return, for this reason it supports an optional maxRecent parameter.
-If set this will return only the specified number of spaces with activity
-in the last two weeks. Recommended value is 30. Max supported is 100.
--- only "id", "type", "lastActivityDate", and "lastSeenDate" are
-guaranteed to be available for each room in the list
--- "title" is usually returned, but not guaranteed
-In general this function should be used only when the client needs to
-access read status info, for example on startup.
-After startup, clients should track message and membership:seen events
-to maintain read status client side.
-Since this API can take some time to return up to 1000 spaces, it is
-recommended that custom clients call this first with the maxRecent parameter
-set to 30, so that they can display some of the more recents spaces. Calling
-this API a second time with no parameters will return all the spaces.
-Not all spaces may be returned, for example when users in more than 1000
-spaces, or when a new spaces is added after this function is called,
-but before it returns. Custom clients should be prepared to gracefully
-handle cases where an event occurs in a space not returned by this call,
-by querying rooms.getWithReadStatus() with the id of the room in question
-This function may be deprecated when this info is provided in the membership
-objects returned in the list function.
-
- listWithReadStatus(maxRecent: int):
Promise <RoomInfoObjectList>
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
- maxRecent (int
- = 0
)
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise <RoomInfoObjectList>
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
getWithReadStatus(roomId)
-
-
-
-
-
-
-
-
-
- Returns a single room object with details about the data of the last
-activity in the room, and the date of the users last presence in
-the room.
-For rooms where lastActivityDate > lastSeenDate the room
-can be considered to be "unread"
-This differs from the rooms.get() function in the following ways:
--- it takes a single roomId parameter to fetch
--- no other options are considered
--- only "id", "type", "lastActivityDate", and "lastSeenDate" are
-guaranteed to be available in the return object
--- "title" is usually returned, but not guaranteed
-In general clients should use the listWithReadStatus() method on startup
-to get the initial roomStatus and then update their client side copy by
-responding to message, membership and room events.
-This function allows a custom client to be "nimble" if it is responding
-to an event with a roomId that was not in the original fetch. The
-anticipated behavior is that getWithReadStats is called "just in time",
-with the resulting room object being added to the list of cached room
-objects on the client side.
-This function may be deprecated when this info is provided in the room
-object returned in the get function.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Promise <RoomInfoObject>
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Deletes a single room.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
- Example
-
-
- var room;
-webex.rooms .create ({title : 'Remove Room Example' })
- .then (function (r ) {
- room = r;
- return webex.rooms .remove (room.id );
- })
- .then (function ( ) {
- return webex.rooms .get (room.id );
- })
- .then (function ( ) {
- var assert = require ('assert' );
- assert (false , 'the previous get should have failed' );
- })
- .catch (function (reason ) {
- var assert = require ('assert' );
- assert.equal (reason.statusCode , 404 );
- return 'success'
- });
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Used to update a single room's properties.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Promise <RoomObject >
:
-
-
-
-
-
-
-
-
-
-
- Example
-
-
- var room;
-webex.rooms .update ({title : 'Update Room Example' })
- .then (function (r ) {
- room = r;
- room.title = 'Update Room Example (Updated Title)' ;
- return webex.rooms .update (room);
- })
- .then (function ( ) {
- return webex.rooms .get (room.id );
- })
- .then (function (room ) {
- var assert = require ('assert' );
- assert.equal (room.title , 'Update Room Example (Updated Title)' );
- return 'success' ;
- });
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- new Teams()
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Instance Members
-
-
-
-
-
-
-
-
-
-
-
- Create a new team.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Promise <TeamObject >
:
-
-
-
-
-
-
-
-
-
-
- Example
-
-
- webex.teams .create ({name : 'Create Team Example' })
- .then (function (team ) {
- var assert = require ('assert' );
- assert (team.id );
- assert (team.name );
- assert (team.created );
- return 'success' ;
- });
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
get(team, options)
-
-
-
-
-
-
-
-
-
- Returns a single team
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Promise <TeamObject >
:
-
-
-
-
-
-
-
-
-
-
- Example
-
-
- var team;
-webex.teams .create ({name : 'Get Team Example' })
- .then (function (r ) {
- team = r;
- return webex.teams .get (team.id );
- })
- .then (function (team2 ) {
- var assert = require ('assert' );
- assert.equal (team2.id , team.id );
- return 'success' ;
- });
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- List teams.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- options.max object
-
- Limit the maximum number of teams in the
-response.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise <Page<TeamObject >>
:
-
-
-
-
-
-
-
-
-
-
- Example
-
-
- var createdRooms;
-Promise .all ([
- webex.teams .create ({name : 'List Teams Example 1' }),
- webex.teams .create ({name : 'List Teams Example 2' }),
- webex.teams .create ({name : 'List Teams Example 3' })
-])
- .then (function (r ) {
- createdRooms = r;
- return webex.teams .list ({max : 3 });
- })
- .then (function (teams ) {
- var assert = require ('assert' );
- assert (teams.length === 3 );
- for (var i = 0 ; i < teams.items .length ; i+= 1 ) {
- assert (createdRooms.filter (function (room ) {
- return room.id === teams.items [i].id ;
- }).length === 1 );
- }
- return 'success' ;
- });
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Update a team.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Promise <TeamObject >
:
-
-
-
-
-
-
-
-
-
-
- Example
-
-
- var teams;
-webex.teams .create ({name : 'Update Team Example' })
- .then (function (r ) {
- teams = r;
- teams.name = 'Teams Example (Updated Title)' ;
- return webex.teams .update (teams);
- })
- .then (function ( ) {
- return webex.teams .get (teams.id );
- })
- .then (function (teams ) {
- var assert = require ('assert' );
- assert.equal (teams.name , 'Teams Example (Updated Title)' );
- return 'success' ;
- });
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Team Memberships represent a person's relationship to a team. Use this API to
-list members of any team that you're in or create memberships to invite
-someone to a team. Team memberships can also be updated to make someone a
-moderator or deleted to remove them from the team.
-Just like in the Webex app, you must be a member of the team in order to list
-its memberships or invite people.
-
- new TeamMemberships()
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Instance Members
-
-
-
-
-
-
βΈ
-
create(membership)
-
-
-
-
-
-
-
-
-
- Add someone to a team by Person ID or email address; optionally making them
-a moderator.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Promise <TeamMembershipObject >
:
-
-
-
-
-
-
-
-
-
-
- Example
-
-
- webex.teams .create ({name : 'Create Team Membership Example' })
- .then (function (team ) {
- return webex.teamMemberships .create ({
- personEmail : 'alice@example.com' ,
- teamId : team.id
- });
- })
- .then (function (membership ) {
- var assert = require ('assert' );
- assert (membership.id );
- assert (membership.teamId );
- assert (membership.personId );
- assert (membership.personEmail );
- assert ('isModerator' in membership);
- assert (membership.created );
- return 'success' ;
- });
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
get(membership)
-
-
-
-
-
-
-
-
-
- Get details for a membership by ID.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Promise <TeamMembershipObject >
:
-
-
-
-
-
-
-
-
-
-
- Example
-
-
- var membership;
-webex.teams .create ({name : 'Get Team Memberships Example' })
- .then (function (team ) {
- return webex.teamMemberships .create ({
- personEmail : 'alice@example.com' ,
- teamId : team.id
- });
- })
- .then (function (m ) {
- membership = m;
- return webex.teamMemberships .get (m.id );
- })
- .then (function (m ) {
- var assert = require ('assert' );
- assert.deepEqual (m, membership);
- return 'success' ;
- });
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Lists all team memberships. By default, lists memberships for teams to
-which the authenticated user belongs.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- options.max string
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- [type]
:
-
-
-
-
-
-
-
-
-
-
- Example
-
-
- var team;
-webex.teams .create ({name : 'List Team Memberships Example' })
- .then (function (t ) {
- team = t;
- return webex.teamMemberships .create ({
- personEmail : 'alice@example.com' ,
- teamId : team.id
- });
- })
- .then (function ( ) {
- return webex.teamMemberships .list ({teamId : team.id });
- })
- .then (function (teamMemberships ) {
- var assert = require ('assert' );
- assert.equal (teamMemberships.length , 2 );
- for (var i = 0 ; i < teamMemberships.length ; i+= 1 ) {
- assert.equal (teamMemberships.items [i].teamId , team.id );
- }
- return 'success' ;
- });
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
remove(membership)
-
-
-
-
-
-
-
-
-
- Deletes a membership by ID.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
- Example
-
-
- var membership, team;
-webex.teams .create ({name : 'Remove Team Memberships Example' })
- .then (function (t ) {
- team = t;
- return webex.teamMemberships .create ({
- personEmail : 'alice@example.com' ,
- teamId : team.id
- });
- })
- .then (function (m ) {
- membership = m;
- return webex.teamMemberships .list ({teamId : team.id });
- })
- .then (function (teamMemberships ) {
- var assert = require ('assert' );
- assert.equal (teamMemberships.length , 2 );
- return webex.teamMemberships .remove (membership);
- })
- .then (function ( ) {
- return webex.teamMemberships .list ({teamId : team.id });
- })
- .then (function (teamMemberships ) {
- var assert = require ('assert' );
- assert.equal (teamMemberships.length , 1 );
- return 'success' ;
- });
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
update(membership)
-
-
-
-
-
-
-
-
-
- Updates properties for a membership.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Promise <TeamMembershipObject >
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Webhooks allow your app to be notified via HTTP when a specific event
-occurs on Webex. For example, your app can register a webhook to be
-notified when a new message is posted into a specific room.
-
- new Webhooks()
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Instance Members
-
-
-
-
-
-
βΈ
-
create(webhook)
-
-
-
-
-
-
-
-
-
- Posts a webhook.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Promise <Webhook>
:
-
-
-
-
-
-
-
-
-
-
- Example
-
-
- webex.rooms .create ({title : 'Create Webhook Example' })
- .then (function (room ) {
- return webex.webhooks .create ({
- resource : 'messages' ,
- event : 'created' ,
- filter : 'roomId=' + room.id ,
- targetUrl : 'https://example.com/webhook' ,
- name : 'Test Webhook'
- });
- })
- .then (function (webhook ) {
- var assert = require ('assert' );
- assert (webhook.id );
- assert (webhook.resource );
- assert (webhook.event );
- assert (webhook.filter );
- assert (webhook.targetUrl );
- assert (webhook.name );
- return 'success' ;
- });
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Shows details for a webhook.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
webhook ((Webhook | string ))
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise <Webhook>
:
-
-
-
-
-
-
-
-
-
-
- Example
-
-
- var webhook;
-webex.rooms .create ({title : 'Get Webhook Example' })
- .then (function (room ) {
- return webex.webhooks .create ({
- resource : 'messages' ,
- event : 'created' ,
- filter : 'roomId=' + room.id ,
- targetUrl : 'https://example.com/webhook' ,
- name : 'Test Webhook'
- });
- })
- .then (function (w ) {
- webhook = w;
- return webex.webhooks .get (webhook.id );
- })
- .then (function (webhook2 ) {
- var assert = require ('assert' );
- assert.deepEqual (webhook2, webhook);
- return 'success' ;
- });
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Lists all webhooks.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- options.max integer
-
- Limit the maximum number of webhooks in the response.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise <Array <Webhook>>
:
-
-
-
-
-
-
-
-
-
-
- Example
-
-
- var room, webhook;
-webex.rooms .create ({title : 'List Webhooks Example' })
- .then (function (r ) {
- room = r;
- return webex.webhooks .create ({
- resource : 'messages' ,
- event : 'created' ,
- filter : 'roomId=' + room.id ,
- targetUrl : 'https://example.com/webhook' ,
- name : 'Test Webhook'
- });
- })
- .then (function (w ) {
- webhook = w;
- return webex.webhooks .list ();
- })
- .then (function (webhooks ) {
- var assert = require ('assert' );
- assert.equal (webhooks.items .filter (function (w ) {
- return w.id === webhook.id ;
- }).length , 1 );
- return 'success' ;
- });
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
remove(webhook)
-
-
-
-
-
-
-
-
-
- Delete a webhook.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
webhook ((Webhook | string ))
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
- Example
-
-
- var room, webhook;
-webex.rooms .create ({title : 'Remove Webhook Example' })
- .then (function (r ) {
- room = r;
- return webex.webhooks .create ({
- resource : 'messages' ,
- event : 'created' ,
- filter : 'roomId=' + room.id ,
- targetUrl : 'https://example.com/webhook' ,
- name : 'Test Webhook'
- });
- })
- .then (function (w ) {
- webhook = w;
- return webex.webhooks .remove (webhook);
- })
- .then (function ( ) {
- return webex.webhooks .list ();
- })
- .then (function (webhooks ) {
- var assert = require ('assert' );
- assert.equal (webhooks.items .filter (function (w ) {
- return w.id === webhook.id ;
- }).length , 0 );
- return 'success' ;
- });
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
update(webhook)
-
-
-
-
-
-
-
-
-
- Update a webhook.
-
- update(webhook: Webhook):
Promise <Webhook>
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
- webhook (Webhook)
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise <Webhook>
:
-
-
-
-
-
-
-
-
-
-
- Example
-
-
- var webhook;
-webex.rooms .create ({title : 'Webhook Example' })
- .then (function (room ) {
- return webex.webhooks .create ({
- resource : 'messages' ,
- event : 'created' ,
- filter : 'roomId=' + room.id ,
- targetUrl : 'https://example.com/webhook' ,
- name : 'Test Webhook'
- });
- })
- .then (function (w ) {
- webhook = w;
- webhook.targetUrl = 'https://example.com/webhook/newtarget' ;
- return webex.webhooks .update (webhook);
- })
- .then (function ( ) {
- return webex.webhooks .get (webhook);
- })
- .then (function (webhook ) {
- var assert = require ('assert' );
- assert.equal (webhook.targetUrl , 'https://example.com/webhook/newtarget' );
- return 'success' ;
- });
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Logging
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- new Logger()
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Instance Members
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- LoggerConfig
-
-
- Type:
- Object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Properties
-
-
-
-
level (string ?)
- : Maximum log level that
-should be printed to the console. One of
-silent|error|warn|log|info|debug|trace
-
-
-
-
-
-
historyLength (number ?)
- : Maximum number of entries to store in the log buffer.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Example
-
-
- {
- level : process.env .WEBEX_LOG_LEVEL ,
- historyLength : 1000
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Types
-
-
-
- The following typedefs describes the responses of the various API calls.
-
-
-
-
-
-
-
-
-
-
-
-
-
- MembershipObject
-
-
- Type:
- Object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Properties
-
-
-
-
id (string )
- : Unique identifier for the membership
-
-
-
-
-
-
roomId (string )
- : The room ID
-
-
-
-
-
-
personId (string )
- : The person ID
-
-
-
-
-
-
personEmail (email )
- : The email address of the person / room member
-
-
-
-
-
-
isModerator (boolean )
- : Indicates whether the specified person should be a room moderator
-
-
-
-
-
-
isMonitor (boolean )
- : Indicates whether the specified member is a room monitor
-
-
-
-
-
-
created (isoDate )
- : The date and time that this membership was created
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- MessageObject
-
-
- Type:
- Object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Properties
-
-
-
-
id (string )
- : (server generated) Unique identifier for the message
-
-
-
-
-
-
personId (string )
- : The ID for the author of the message
-
-
-
-
-
-
personEmail (email )
- : The email for the author of the message
-
-
-
-
-
-
roomId (string )
- : The ID for the room of the message
-
-
-
-
-
-
text (string )
- : The message posted to the room in plain text
-
-
-
-
-
-
markdown (string )
- : The message posted to the room in markdown
-
-
-
-
-
-
files (Array <string >)
- : The source URL(s) for the message attachment(s).
-See the
-
Message Attachments
-
-Guide for a list of supported media types.
-
-
-
-
-
-
created (isoDate )
- : (server generated) The date and time that the message was created
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- PersonObject
-
-
- Type:
- Object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Properties
-
-
-
-
id (string )
- : (server generated) Unique identifier for the person
-
-
-
-
-
-
emails (Array <email >)
- : Email addresses of the person
-
-
-
-
-
-
displayName (string )
- : Display name of the person
-
-
-
-
-
-
created (isoDate )
- : (server generated) The date and time that the person was created
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- RoomObject
-
-
- Type:
- Object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Properties
-
-
-
-
id (string )
- : (server generated) Unique identifier for the room
-
-
-
-
-
-
title (string )
- : The display name for the room. All room members
-will see the title so make it something good
-
-
-
-
-
-
teamId (string )
- : (optional) The ID of the team to which the room
-belongs
-
-
-
-
-
-
created (isoDate )
- : (server generated) The date and time that the
-room was created
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- TeamObject
-
-
- Type:
- Object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Properties
-
-
-
-
id (string )
- : (server generated) Unique identifier for the team
-
-
-
-
-
-
name (string )
- : The name of the team
-
-
-
-
-
-
created (isoDate )
- : (server generated) The date and time that the
-team was created
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- TeamMembershipObject
-
-
- Type:
- Object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Properties
-
-
-
-
id (string )
- : (server generated) Unique identifier for the team membership
-
-
-
-
-
-
teamId (string )
- : The team ID
-
-
-
-
-
-
personId (string )
- : The person ID
-
-
-
-
-
-
personEmail (string )
- : The email address of the person
-
-
-
-
-
-
isModerator (boolean )
- : Set to
-
true
- to make the person a team
-moderator
-
-
-
-
-
-
created (string )
- : (server generated) The date and time that the team membership was created
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- WebhookObject
-
-
- Type:
- Object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Properties
-
-
-
-
id (string )
- : (server generated) Unique identifier for the webhook
-
-
-
-
-
-
resource (string )
- : The resource type for the webhook
-
-
-
-
-
-
event (string )
- : The event type for the webhook
-
-
-
-
-
-
filter (string )
- : The filter that defines the webhook scope
-
-
-
-
-
-
targetUrl (string )
- : The URL that receives POST requests for each event
-
-
-
-
-
-
name (string )
- : A user-friendly name for this webhook
-
-
-
-
-
-
created (string )
- : (server generated) The date and time that the webhook was created
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- An email address, as a string.
-
- email
-
-
- Type:
- string
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- The date and time, specified in ISO 8601 extended offset date/time
-format (e.g. 2015-10-18T14:26:16+00:00
).
-
- isoDate
-
-
- Type:
- string
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- AttachmentActionObject
-
-
- Type:
- Object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Properties
-
-
-
-
id (string )
- : (server generated) Unique identifier for the attachment action
-
-
-
-
-
-
messageId (string )
- : The ID of the message in which attachment action is to be performed
-
-
-
-
-
-
type (string )
- : The type of attachment action eg., submit
-
-
-
-
-
-
inputs (Object )
- : The inputs for form fields in attachment message
-
-
-
-
-
-
personId (string )
- : (server generated) The ID for the author of the attachment action
-
-
-
-
-
-
roomId (string )
- : (server generated) The ID for the room of the message
-
-
-
-
-
-
created (isoDate )
- : (server generated) The date and time that the message was created
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- AttachmentActions are events that communicate information when a user clicks on an
-Action.Submit button in a card displayed in Webex
-Information conveyed in an AttachmentAction includes details about the user that
-clicked the button along with any card specific inputs. See the
-Attachments Actions API Documentation
-for more details
-
- new AttachmentActions()
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Instance Members
-
-
-
-
-
-
βΈ
-
create(attachmentAction)
-
-
-
-
-
-
-
-
-
- Post a new attachment action for a message with attachment.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Promise <AttachmentActionObject >
:
-
-
-
-
-
-
-
-
-
-
- Example
-
-
- webex.rooms .create ({title : 'Create Message with card Example' })
- .then (function (room ) {
- return webex.messages .create ({
- text : 'Howdy!' ,
- roomId : room.id ,
- attachments :[ {
- contentType : 'application/vnd.microsoft.card.adaptive' ,
- content : {
- type : 'AdaptiveCard' ,
- version : '1.0' ,
- body : [
- {
- type : 'TextBlock' ,
- text : '' ,
- size : 'large'
- },
- {
- type : 'TextBlock' ,
- text : 'Adaptive Cards' ,
- separation : 'none'
- }
- {
- type : 'Input.Date' ,
- id : 'dueDate'
- }
- ],
- actions : [
- {
- type : 'Action.Submit' ,
- title : 'Due Date'
- }
- ]
- }
- }]
- });
- })
- .then (function (message ) {
- return webex.attachmentActions .create ({
- type : 'submit' ,
- messageId : message.id ,
- inputs :{
- dueDate : '26/06/1995'
- }
- })
- .then (function (attachmentAction) ){
- var assert = require ('assert' );
- assert (attachmentAction.id );
- assert (attachmentAction.type );
- assert (attachmentAction.personId );
- assert (attachmentAction.inputs );
- assert (attachmentAction.messageId );
- assert (attachmentAction.roomId );
- assert (attachmentAction.created );
- return 'success' ;
- }
- });
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
get(attachmentAction)
-
-
-
-
-
-
-
-
-
- Returns a single attachment action.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
attachmentAction (string )
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise <AttachmentActionObject >
:
-
-
-
-
-
-
-
-
-
-
- Example
-
-
- var attachmentAction;
-webex.rooms .create ({title : 'Get Message Example' })
- .then (function (room ) {
- return webex.messages .create ({
- text : 'Howdy!' ,
- roomId : room.id ,
- attachments :[ {
- contentType : 'application/vnd.microsoft.card.adaptive' ,
- content : {
- type : 'AdaptiveCard' ,
- version : '1.0' ,
- body : [
- {
- type : 'TextBlock' ,
- text : '' ,
- size : 'large'
- },
- {
- type : 'TextBlock' ,
- text : 'Adaptive Cards' ,
- separation : 'none'
- },
- {
- type : 'Input.Date' ,
- id : 'dueDate'
- }
- ],
- actions : [
- {
- type : 'Action.Submit' ,
- title : 'Due Date'
- }
- ]
- }
- }]
- });
- })
- .then (function (message ) {
- return webex.attachmentActions .create ({
- type : 'submit' ,
- messageId : message.id ,
- inputs :{
- dueDate : '26/06/1995'
- });
- })
- .then (function (attachmentAction ) {
- return webex.attachmentActions .get (attachmentAction.id )
- })
- .then (function (attachmentAction ){
- var assert = require ('assert' );
- assert.deepEqual (attachmentAction, attachmentAction);
- return 'success' ;
- })
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Gets a list of all recent devices associated with the user
-the device list gets populated from Redis
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise <Device>
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Gets a list of all recent devices associated with the user
-the device list gets populated from Redis
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise <Device>
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Search for a device by name
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- options.searchQuery string
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise <Device>
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Caches the device info and also registers to Redis for subsequent fetches
-
- upsert(device:
Object ): deviceInfo
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- device.id string
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- deviceInfo
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Retreives device info of a particular device
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Promise <deviceInfo>
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Unregisters the device from Redis, will not fetch in subsequent loads,
-similar to space.deleteBinding()
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Promise <deviceInfo>
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Requests to display PIN on the device
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- options.data object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise <deviceInfo>
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- pairs the device with the user (manual pairing), also adds it to
-user's recents list for subsequent fetches.
-similar to space.join()
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- options.pin number
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise <deviceInfo>
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- unpairs the device with the user (manual/ultrasonic pairing), but still
-keeps in the recents list/does not remove from Redis
-options.removeAllDevices will remove all associated devices to user
-similar to space.leave()
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- options.removeAllDevices boolean
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise <deviceInfo>
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- binds the space to the paired device (if supported)
-similar to space.bindConversation()
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- options.url boolean
-
- , conversation url
-
-
-
-
-
-
- options.kmsResourceObjectUrl boolean
-
- of the convo
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise <deviceInfo>
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- unbinds the space to the paired device (if supported)
-similar to space.unbindConversation()
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise <deviceInfo>
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Gets the audio state of the paired device
-similar to device.getAudioState()
-
- getAudioState():
Promise <audioState>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise <audioState>
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Updates audio state of the paired device, should be called every 10 minutes
-or when mic or volume state is changed
-similar to device.putAudioState()
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
audioState (object
- = {}
)
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise <audioState>
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Mutes paired device
-similar to device.mute()
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise <audioState>
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Unmutes paired device
-similar to device.unmute()
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise <audioState>
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Increases paired device's volume
-similar to device.increaseVolume()
-
- increaseVolume():
Promise <audioState>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise <audioState>
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Decreases paired device's volume
-similar to device.decreaseVolume()
-
- decreaseVolume():
Promise <audioState>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise <audioState>
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Sets paired device's volume but should use increase and decrease api instead
-similar to device.setVolume()
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Promise <audioState>
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Utility function to update decrypted device name on device object
-
- _updateDeviceMetadata(deviceArray:
Array ): device
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
deviceArray (Array
- = []
)
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- device
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Utility function to update decrypted device name on device object
-
- _decryptDeviceName(inDevice:
object ): device
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
inDevice (object
- = {}
)
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- device
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Utility function to update device info on mercury updates
-
- _receiveDeviceUpdates(device:
object ): device
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- device
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Metrics handles all the call metrics events
-
- new Metrics()
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Static Members
-
-
-
-
-
- Instance Members
-
-
-
-
-
-
βΈ
-
initialSetup(meetingCollection, webex)
-
-
-
-
-
-
-
-
-
- Initializes the Metrics singleton with a meeting Collection.
-
- initialSetup(meetingCollection:
Object , webex:
Object ): void
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
meetingCollection (Object )
- meetings object
-
-
-
-
-
-
-
-
webex (Object )
- webex SDK object
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- void
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
postEvent(options)
-
-
-
-
-
-
-
-
-
- poste Meeting event metrics
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
options (object )
- {meetingId/meeting} as a json object
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- options.meeting Meeting
-
- Meeting object
-
-
-
-
-
-
- options.meetingId String
-
-
-
-
-
-
-
- options.data object
-
-
-
-
-
-
-
- options.event object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- object
:
- null
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
initPayload(eventType, identifiers, options)
-
-
-
-
-
-
-
-
-
βΈ
-
parseLocusError(err, showToUser)
-
-
-
-
-
-
-
-
-
βΈ
-
userAgentToString()
-
-
-
-
-
-
-
-
-
- Returns a formated string of the user agent.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- string
:
- formatted user agent information
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
sendBehavioralMetric(metricName, metricFields, metricTags)
-
-
-
-
-
-
-
-
-
- Uploads given metric to the Metrics service as an Behavioral metric.
-Metadata about the environment such as browser, OS, SDK and their versions
-are automatically added when the metric is sent.
-The Metrics service will send an Behavioral metric to InfluxDB for
-aggregation.
-See https://confluence-eng-gpk2.cisco.com/conf/display/WBXT/Getting+started+with+Metrics+Service .
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
metricName (string )
- Name of the metric (measurement) to send
-
-
-
-
-
-
-
-
metricFields (Object
- = {}
)
- Key-valye pairs of data or values about this metric
-
-
-
-
-
-
-
-
metricTags (Object
- = {}
)
- Key-value pairs of metric metadata
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- void
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- new LogsRequest()
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Static Members
-
-
-
-
-
-
βΈ
-
uploadLogs(options)
-
-
-
-
-
-
-
-
-
- Uploads logs to the support server
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- options.feedbackId String
-
- (default uuid.v4
)
-
- ID used for tracking
-
-
-
-
-
-
- options.locusId String ?
-
-
-
-
-
-
-
- options.correlationId String ?
-
-
-
-
-
-
-
- options.callStart String ?
-
- Call Start Time
-
-
-
-
-
-
- options.meetingId String ?
-
- webex meeting ID
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise <String >
:
- Feedback ID
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- MediaDirection
-
- MediaDirection
-
-
- Type:
- Object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Properties
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- MediaDirection
-
- MediaDirection
-
-
- Type:
- Object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Properties
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- SendOptions
-
- SendOptions
-
-
- Type:
- Object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Properties
-
-
-
-
sharePreferences (Object )
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- SendOptions
-
- SendOptions
-
-
- Type:
- Object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Properties
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Media
-
-
- Type:
- any
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Static Members
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- pc
-
-
- Type:
- any
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Static Members
-
-
-
-
-
-
βΈ
-
setContentSlides(screenPc)
-
-
-
-
-
-
-
-
-
- makes sure the screen pc sdp has content:slides for server
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- RTCPeerConnection
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
iceCandidate(peerConnection, options)
-
-
-
-
-
-
-
-
-
- handles ice trickling and establishes ICE connection onto peer connection object
-
- iceCandidate(peerConnection:
Object , options:
Object ): Promise.RTCPeerConnection
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- options.remoteQualityLevel String
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise.RTCPeerConnection
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
replaceTrack(peerConnection, track)
-
-
-
-
-
-
-
-
-
- swapping tracks
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- undefined
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
addStream(peerConnection, stream)
-
-
-
-
-
-
-
-
-
- adding streams to peerConnection
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- undefined
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
setRemoteSessionDetails(peerConnection, typeStr, remoteSdp, meetingId)
-
-
-
-
-
-
-
-
-
- setting the remote description
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- undefined
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
createOffer(peerConnection, meetingProperties)
-
-
-
-
-
-
-
-
-
- Create offer with a valid parameter
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
meetingProperties (Object )
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- meetingProperties.meetingId string
-
-
-
-
-
-
-
- meetingProperties.remoteQualityLevel string
-
- LOW|MEDIUM|HIGH
-
-
-
-
-
-
- meetingProperties.enableRtx string
-
-
-
-
-
-
-
- meetingProperties.enableExtmap string
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- RTCPeerConnection
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
rollBackLocalDescription(peerConnection)
-
-
-
-
-
-
-
-
-
- rollBack local description in peerconnection
-
- rollBackLocalDescription(peerConnection:
Object ): Promise.RTCPeerConnection
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Promise.RTCPeerConnection
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
updatePeerConnection(params, meetingProperties)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- params.offerToReceiveAudio Boolean
-
-
-
-
-
-
-
- params.offerToReceiveVideo Boolean
-
-
-
-
-
-
-
- params.offerSdp string
-
-
-
-
-
-
-
- params.stream MediaStream
-
-
-
-
-
-
-
-
-
-
-
-
-
-
meetingProperties (Object )
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- meetingProperties.meetingId string
-
-
-
-
-
-
-
- meetingProperties.remoteQualityLevel string
-
- LOW|MEDIUM|HIGH
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise <Array >
:
- [MediaSDP, ScreenSDP]
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
createAnswer(params, meetingProperties)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- params.peerConnection Object
-
-
-
-
-
-
-
- params.sdpConstraints Object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
meetingProperties (Object )
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- meetingProperties.meetingId string
-
-
-
-
-
-
-
- meetingProperties.remoteQualityLevel string
-
- LOW|MEDIUM|HIGH
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- RTCPeerConnection
:
- peerConnection
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
close(peerConnection)
-
-
-
-
-
-
-
-
-
- shut down the peer connection
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- undefined
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- munges the bandwidth limit into the sdp
-
- insertBandwidthLimit
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- String
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- needed for calliope max-fs
-
- setRemoteVideoConstraints
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
level (String
- = QUALITY_LEVELS.HIGH
)
- quality level for max-fs
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- String
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- checks that sdp has h264 codec in it
-
- checkH264Support
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- boolean
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- validates the sdp, checks port, candidates, and ice info
-
- isSdpInvalid
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- String
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- munges the bandwidth into the sdp
-
- limitBandwidth
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- String
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Convert C line to IPv4
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- string
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- estimate profile levels for max-fs & max-mbps values
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- string
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Extended Error object to signify the intent to join for unclaimed PMR scenarios
-
-
-
-
-
- Extends
-
- Error
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
message (String ?
- = ERROR_DICTIONARY.RECONNECTION.MESSAGE
)
-
-
-
-
-
-
-
-
error (Object ?
- = null
)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Extended Error object for media errors
-
-
-
-
-
- Extends
-
- Error
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
message (String ?
- = ERROR_DICTIONARY.MEDIA.MESSAGE
)
-
-
-
-
-
-
-
-
error (Object ?
- = null
)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- new MeetingNotActiveError()
-
-
-
- Extends
-
- WebexMeetingsError
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Properties
-
-
-
-
code (number )
- : 30101
-
-
-
-
-
-
message (string )
- : 'Meeting has already Ended or not Active'
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- new UserNotJoinedError()
-
-
-
- Extends
-
- WebexMeetingsError
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Properties
-
-
-
-
code (number )
- : 30102
-
-
-
-
-
-
message (string )
- : 'User has already left the meeting'
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- new NoMediaEstablishedYetError()
-
-
-
- Extends
-
- WebexMeetingsError
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Properties
-
-
-
-
code (number )
- : 30103
-
-
-
-
-
-
message (string )
- : 'User has not established media yet'
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- new UserInLobbyError()
-
-
-
- Extends
-
- WebexMeetingsError
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Properties
-
-
-
-
code (number )
- : 30104
-
-
-
-
-
-
message (string )
- : 'user is still in the lobby or not joined'
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- new InvalidSdpError()
-
-
-
- Extends
-
- WebexMeetingsError
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Properties
-
-
-
-
code (number )
- : 30201
-
-
-
-
-
-
message (string )
- : 'user is still in the lobby or not joined'
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- new IceGatheringFailed()
-
-
-
- Extends
-
- WebexMeetingsError
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Properties
-
-
-
-
code (number )
- : 30202
-
-
-
-
-
-
message (string )
- : 'user failed ice gathering check network/firewall'
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Extends
-
- Error
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
code (number )
- Error code
-
-
-
-
-
-
-
-
args (...Array <any>)
-
-
-
-
-
-
-
-
message (string ?)
- Error message
-
-
-
-
-
-
-
-
fileName (string ?)
- Name of the script file where error was generated
-
-
-
-
-
-
-
-
lineNumber (number ?)
- Line number of the script file where error was generated
-
-
-
-
-
-
-
-
-
- Properties
-
-
-
-
code (number )
- : Error code
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Instance Members
-
-
-
-
-
-
-
-
-
-
-
- Returns human readable string describing the error.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- string
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Extended Error object to signify the intent to join for unclaimed PMR scenarios
-
-
-
-
-
- Extends
-
- Error
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
message (String ?
- = ERROR_DICTIONARY.INTENT_TO_JOIN.MESSAGE
)
-
-
-
-
-
-
-
-
error (Object ?
- = null
)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Extended Error object to signify a join meeting error
-
-
-
-
-
- Extends
-
- Error
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
options (Object ?
- = {}
)
-
-
-
-
-
-
-
-
message (String ?
- = ERROR_DICTIONARY.JOIN_MEETING.MESSAGE
)
-
-
-
-
-
-
-
-
error (Object ?
- = null
)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Extended Error object for general parameter errors
-
-
-
-
-
- Extends
-
- Error
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
message (String ?
- = ERROR_DICTIONARY.PERMISSION.MESSAGE
)
-
-
-
-
-
-
-
-
error (Object ?
- = null
)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- new MeetingInfo()
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Static Members
-
-
-
-
-
-
βΈ
-
getMeetingInfo(id)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- object
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
setMeetingInfo(id, info)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- null
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
fetchInfoOptions(destination, type = null)
-
-
-
-
-
-
-
-
-
- converts hydra id into conversation url and persons Id
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
destination (String )
- one of many different types of destinations to look up info for
-
-
-
-
-
-
-
-
type (String ?
- = null
)
- to match up with the destination value
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
- destination and type
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
fetchMeetingInfo(destination, type = null)
-
-
-
-
-
-
-
-
-
- Fetches meeting info from the server
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
destination (String )
- one of many different types of destinations to look up info for
-
-
-
-
-
-
-
-
type (String ?
- = null
)
- to match up with the destination value
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
- returns a meeting info object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
fetchMeetingInfo(destination, type = null, password, captchaInfo)
-
-
-
-
-
-
-
-
-
- Fetches meeting info from the server
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
destination (String )
- one of many different types of destinations to look up info for
-
-
-
-
-
-
-
-
type (String ?
- = null
)
- to match up with the destination value
-
-
-
-
-
-
-
-
password (String
- = null
)
-
-
-
-
-
-
-
-
captchaInfo (Object
- = null
)
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- captchaInfo.code String
-
-
-
-
-
-
-
- captchaInfo.id String
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
- returns a meeting info object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
createAdhocSpaceMeeting(conversationUrl)
-
-
-
-
-
-
-
-
-
- Creates adhoc space meetings for a space by fetching the conversation infomation
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
conversationUrl (String )
- conversationUrl to start adhoc meeting on
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
- returns a meeting info object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- new MeetingInfo()
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Static Members
-
-
-
-
-
-
βΈ
-
getMeetingInfo(id)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- object
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
setMeetingInfo(id, info)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- null
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
fetchInfoOptions(destination, type = null)
-
-
-
-
-
-
-
-
-
- converts hydra id into conversation url and persons Id
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
destination (String )
- one of many different types of destinations to look up info for
-
-
-
-
-
-
-
-
type (String ?
- = null
)
- to match up with the destination value
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
- destination and type
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
fetchMeetingInfo(destination, type = null)
-
-
-
-
-
-
-
-
-
- Fetches meeting info from the server
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
destination (String )
- one of many different types of destinations to look up info for
-
-
-
-
-
-
-
-
type (String ?
- = null
)
- to match up with the destination value
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
- returns a meeting info object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
fetchMeetingInfo(destination, type = null, password, captchaInfo)
-
-
-
-
-
-
-
-
-
- Fetches meeting info from the server
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
destination (String )
- one of many different types of destinations to look up info for
-
-
-
-
-
-
-
-
type (String ?
- = null
)
- to match up with the destination value
-
-
-
-
-
-
-
-
password (String
- = null
)
-
-
-
-
-
-
-
-
captchaInfo (Object
- = null
)
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- captchaInfo.code String
-
-
-
-
-
-
-
- captchaInfo.id String
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
- returns a meeting info object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
createAdhocSpaceMeeting(conversationUrl)
-
-
-
-
-
-
-
-
-
- Creates adhoc space meetings for a space by fetching the conversation infomation
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
conversationUrl (String )
- conversationUrl to start adhoc meeting on
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
- returns a meeting info object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- new MeetingInfoCollection()
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Static Members
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
id (String )
- ID of the meeting info you wish to retreive
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- MeetingInfo
:
- returns a meeting info instance
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- new MeetingInfoRequest()
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Static Members
-
-
-
-
-
-
βΈ
-
fetchMeetingInfo(options)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
options (Object )
- with format of {type: String, desintation: String}
-where type is PERSONAL_ROOM, SIP_URI, CONVERSATION_URL, and destination is userId, sipUri, conversationUrl respectively
-type can also be specified as an option and be of the list SIP_URI,MEETING_ID,LOCUS_ID,PERSONAL_ROOM,MEETING_LINK,ONE_ON_ONE,MEDIA_SIP_URI,CONVERSATION_URL,TEMP_SIP_URI
-with the desination matching
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
- returns a promise that resolves/rejects the result of the request
-
-
-
-
-
-
-
-
- Throws
-
-
- Error : if the options are not valid and complete
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- new MeetingInfoRequest()
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Static Members
-
-
-
-
-
-
βΈ
-
fetchMeetingInfo(options)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
options (Object )
- with format of {type: String, desintation: String}
-where type is PERSONAL_ROOM, SIP_URI, CONVERSATION_URL, and destination is userId, sipUri, conversationUrl respectively
-type can also be specified as an option and be of the list SIP_URI,MEETING_ID,LOCUS_ID,PERSONAL_ROOM,MEETING_LINK,ONE_ON_ONE,MEDIA_SIP_URI,CONVERSATION_URL,TEMP_SIP_URI
-with the desination matching
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
- returns a promise that resolves/rejects the result of the request
-
-
-
-
-
-
-
-
- Throws
-
-
- Error : if the options are not valid and complete
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Helper function to check if a string matches a known meeting link pattern
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
value (String )
- string to parse and see if it matches a meeting link
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Boolean
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Helper function to check if a string matches a known meeting link pattern
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
value (String )
- string to parse and see if it matches a meeting link
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Boolean
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Helper function to build up a correct locus url depending on the value passed
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
type (String )
- One of [SIP_URI, PERSONAL_ROOM, MEETING_ID, CONVERSATION_URL, LOCUS_ID, MEETING_LINK]
-
-
-
-
-
-
-
-
value (Object )
- ?? value.value
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Object
:
- returns an object with {resource, method}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Helper function to build up a correct locus url depending on the value passed
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
options (Object )
- type and value to fetch meeting info
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- options.type String
-
- One of [SIP_URI, PERSONAL_ROOM, MEETING_ID, CONVERSATION_URL, LOCUS_ID, MEETING_LINK]
-
-
-
-
-
-
- options.destination Object
-
- ?? value.value
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Object
:
- returns an object with {resource, method}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Helper function to parse the webex site/host from a URI string.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- String
:
- the site/host part of the URI string (e.g. 'convergedats.webex.com')
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Helper function to return the direct URI for fetching meeting info (to avoid a redirect).
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
options (Object )
- type and value to fetch meeting info
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- options.type String
-
- One of [SIP_URI, PERSONAL_ROOM, MEETING_ID, CONVERSATION_URL, LOCUS_ID, MEETING_LINK]
-
-
-
-
-
-
- options.destination Object
-
- ?? value.value
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- String
:
- returns a URI string or null of there is no direct URI
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Error to indicate that wbxappapi requires a password
-
- new MeetingInfoV2PasswordError(wbxAppApiErrorCode:
Number ?, meetingInfo:
Object ?, message:
String ?)
-
-
-
- Extends
-
- Error
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
wbxAppApiErrorCode (Number ?)
-
-
-
-
-
-
-
-
-
-
message (String ?
- = PASSWORD_ERROR_DEFAULT_MESSAGE
)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Error generating a adhoc space meeting
-
- new MeetingInfoV2AdhocMeetingError(wbxAppApiErrorCode:
Number ?, message:
String ?)
-
-
-
- Extends
-
- Error
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
wbxAppApiErrorCode (Number ?)
-
-
-
-
-
-
-
-
message (String ?
- = ADHOC_MEETING_DEFAULT_ERROR
)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Error to indicate that preferred webex site not present to start adhoc meeting
-
- new MeetingInfoV2CaptchaError(wbxAppApiErrorCode:
Number ?, captchaInfo:
Object ?, message:
String ?)
-
-
-
- Extends
-
- Error
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
wbxAppApiErrorCode (Number ?)
-
-
-
-
-
-
-
-
-
-
message (String ?
- = CAPTCHA_ERROR_DEFAULT_MESSAGE
)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- AudioVideo
-
- AudioVideo
-
-
- Type:
- Object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Properties
-
-
-
-
audio (Object )
-
-
-
-
- audio.deviceId
String
-
-
-
-
-
-
-
-
-
video (Object )
-
-
-
-
- video.deviceId
String
-
-
-
- video.localVideoQuality
String
-
- // [240p, 360p, 480p, 720p, 1080p]
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- SharePreferences
-
- SharePreferences
-
-
- Type:
- Object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Properties
-
-
-
-
shareConstraints (Object ?)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- JoinOptions
-
- JoinOptions
-
-
- Type:
- Object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Properties
-
-
-
-
-
-
-
-
-
-
meetingQuality ((String | Object )?)
-
-
-
-
- meetingQuality.local
String ?
-
-
-
- meetingQuality.remote
String ?
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Recording
-
- Recording
-
-
- Type:
- Object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Properties
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- The meeting instance to execute all state changes on
-
- meeting
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Specify joining via audio (option: pstn), video, screenshare
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
options (JoinOptions
- = {}
)
- A configurable options object for joining a meeting
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
- the join response
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Stats Analyzer class that will emit events based on detected quality
-
- new StatsAnalyzer()
-
-
-
- Extends
-
- EventsScope
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Static Members
-
-
-
-
-
-
-
-
-
-
-
-
-
- captures MQA data from peerconnection
-
- sendMqaData(): void
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- void
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
startAnalyzer(peerConnection)
-
-
-
-
-
-
-
-
-
- Starts the stats analyzer on interval
-
- startAnalyzer(peerConnection: PeerConnection):
Promise
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
- peerConnection (PeerConnection)
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Cleans up the analyzer when done
-
- stopAnalyzer(): void
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- void
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Instance Members
-
-
-
-
-
-
βΈ
-
parseAudioSource(result, type)
-
-
-
-
-
-
-
-
-
- parse the audio
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- void
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- NetworkQualityMonitor class that will emit events based on detected quality
-
- new NetworkQualityMonitor()
-
-
-
- Extends
-
- EventsScope
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Static Members
-
-
-
-
-
-
βΈ
-
emitNetworkQuality()
-
-
-
-
-
-
-
-
-
- emits NETWORK_QUALITY event on meeting with payload of media type and uplinkNetworkQuality score
-
- emitNetworkQuality(): void
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- void
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
updateNetworkQualityStatus()
-
-
-
-
-
-
-
-
-
- invokes emitNetworkQuality method resets values back to default
-
- updateNetworkQualityStatus(): void
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- void
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
determineUplinkNetworkQuality(configObj)
-
-
-
-
-
-
-
-
-
- filter data to determine uplink network quality, invoked on same interval as stats analyzer remote-inbout-rtp
-
- determineUplinkNetworkQuality(configObj:
Object ): void
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- configObj.mediaType string
-
- {audio|video}
-
-
-
-
-
-
- configObj.remoteRtpResults RTCStats
-
- RTC stats remote obj
-
-
-
-
-
-
- configObj.statsAnalyzerCurrentStats Object
-
- statsResults
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- void
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Instance Members
-
-
-
-
-
-
βΈ
-
networkQualityStats
-
-
-
-
-
-
-
-
-
- Get the current status of network quaility object - networkQualityStatus
-
- networkQualityStats
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Object
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Events
-
-
-
-
-
-
βΈ
-
network:quality
-
-
-
-
-
-
-
-
-
- Meeting - network quality event
-Emitted on each interval of retrieving stats Analyzer data
-
- network:quality
-
-
- Type:
- Object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Properties
-
-
-
-
mediaType (string )
- : {video|audio}
-
-
-
-
-
-
networkQualityScore (number )
- : value determined in determineUplinkNetworkQuality
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- determines if packetLoss ratio is over threshold set in config
-sets networkQualityScore to 0 if over threshold
-
- determinePacketLoss
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- boolean
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- determines if round trip time value is over threshold set in config
-sets networkQualityScore to 0 if over threshold
-
- determineLatency
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- boolean
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- determines if jitter value is over threshold in config
-sets networkQualityScore to 0 if over threshold
-
- deterMineJitter
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- boolean
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- returns null if val is specifically undefined
-
- determineIfUndefined
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- (number | null)
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Events
-plugin-meetings local
-Used to emit events internally between modules specific to an object
-
- new EventsScope()
-
-
-
- Extends
-
- ChildEmitter
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Instance Members
-
-
-
-
-
-
βΈ
-
emit(scope, eventName, args)
-
-
-
-
-
-
-
-
-
- Emits and logs an event
-
- emit(scope: any, eventName: any, args: any):
Function
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
- eventName (any)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Function
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Roap options
-
- RoapOptions
-
-
- Type:
- Object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Properties
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- SeqOptions
-
-
- Type:
- Object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Properties
-
-
-
-
correlationId (String )
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- new RoapHandler()
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Instance Members
-
-
-
-
-
-
-
-
βΈ
-
execute(signal, session, action, meeting, prefix)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- null
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
handleAction(session, action, meeting, correlationId)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Boolean
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Boolean
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- new RoapRequest()
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Instance Members
-
-
-
-
-
-
βΈ
-
attachRechabilityData(localSdp, options)
-
-
-
-
-
-
-
-
-
- Joins a meeting via ROAP
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
- localSdp (any)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
- returns a promise that resolves/rejects whatever the request does
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
sendRoap(options)
-
-
-
-
-
-
-
-
-
- Sends a ROAP message
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- options.roapMessage Object
-
-
-
-
-
-
-
- options.locusSelfUrl String
-
-
-
-
-
-
-
- options.mediaId String
-
-
-
-
-
-
-
- options.correlationId String
-
-
-
-
-
-
-
- options.audioMuted Boolean
-
-
-
-
-
-
-
- options.videoMuted Boolean
-
-
-
-
-
-
-
- options.meetingId String
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
- returns the response/failure of the request
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Handles the process of finding out TURN server information from Linus.
-This is achieved by sending a TURN_DISCOVERY_REQUEST.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Instance Members
-
-
-
-
-
-
βΈ
-
sendRoapOK(meeting)
-
-
-
-
-
-
-
-
-
- Sends the OK message that server expects to receive
-after it sends us TURN_DISCOVERY_RESPONSE
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
doTurnDiscovery(meeting, isReconnecting)
-
-
-
-
-
-
-
-
-
- Retrieves TURN server information from the backend by doing
-a roap message exchange:
-client server
-| -----TURN_DISCOVERY_REQUEST-----> |
-| <----TURN_DISCOVERY_RESPONSE----- |
-| --------------OK----------------> |
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
isReconnecting (Boolean )
- should be set to true if this is a new
-media connection just after a reconnection
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- new MediaProperties()
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Instance Members
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Initializes the StateMachine for the meeting
-
- create(meetingRef:
Meeting ): StateMachine
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
meetingRef (Meeting )
- A reference to a meeting instance
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- StateMachine
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- remote.remoteAnswered Boolean
-
-
-
-
-
-
-
- remote.remoteDeclined Boolean
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- String
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Ring stop transition, to end the ring event for the meeting, and transition the state to ANSWERED OR DECLINED, only for outgoing meetings
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
transition (Object )
- -- FiniteStateMachine automatically passed, not used
-
-
-
-
-
-
-
-
stop (Object )
- -- {remoteAnswered: {Boolean}, remoteDeclined: {Boolean}}
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Boolean
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Ring transition, to cause the ring event for the meeting, and transition the state to RINGING, for both incoming, and outgoing meetings
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
transition (Object )
- -- FiniteStateMachine automatically passed, not used
-
-
-
-
-
-
-
-
type (String )
- -- incoming call === INCOMING / or other meetings have a ring type of JOIN
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Boolean
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- handle the entry to error state
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Boolean
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- After ANY transition occurs, we want to know what state the meeting moved to for debugging
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Boolean
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- The purpose of this class is to manage the local and remote mute state and make sure that the server state always matches
-the last requested state by the client.
-More info about Locus muting API: https://sqbu-github.cisco.com/pages/WebExSquared/locus/guides/mute.html#
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
type (String )
- audio or video
-
-
-
-
-
-
-
-
meeting (Object )
- the meeting object (used for reading current remote mute status)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Static Members
-
-
-
-
-
-
βΈ
-
handleClientRequest(meeting?, mute?)
-
-
-
-
-
-
-
-
-
- Handles mute/unmute request from the client/user. Returns a promise that's resolved once the server update is completed or
-at the point that this request becomese superseded by another client request.
-The client doesn't have to wait for the returned promise to resolve before calling handleClientRequest() again. If
-handleClientRequest() is called again before the previous one resolved, the MuteState class will make sure that eventually
-the server state will match the last requested state from the client.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
meeting (Object ?)
- the meeting object
-
-
-
-
-
-
-
-
mute (Boolean ?)
- true for muting, false for unmuting request
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
applyClientStateLocally(meeting?)
-
-
-
-
-
-
-
-
-
- Applies the current mute state to the local track (by enabling or disabling it accordingly)
-
- applyClientStateLocally(meeting:
Object ?): void
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
meeting (Object ?)
- the meeting object
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- void
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
handleServerRemoteMuteUpdate(muted?, unmuteAllowed?)
-
-
-
-
-
-
-
-
-
- This method should be called whenever the server remote mute state is changed
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
muted (Boolean ?)
- true if user is remotely muted, false otherwise
-
-
-
-
-
-
-
-
unmuteAllowed (Boolean ?)
- indicates if user is allowed to unmute self (false when "hard mute" feature is used)
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- undefined
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
handleServerLocalUnmuteRequired(meeting?)
-
-
-
-
-
-
-
-
-
- This method should be called whenever we receive from the server a requirement to locally unmute
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
meeting (Object ?)
- the meeting object
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- undefined
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns true if the user is locally or remotely muted
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Boolean
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
isLocallyMuted()
-
-
-
-
-
-
-
-
-
- Returns true if the user is locally muted
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Boolean
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns true if the user is muted as a result of the client request (and not remotely muted)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Boolean
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
isEnable (Boolean ?)
- true for enableBNR, false for disableBNR request
-
-
-
-
-
-
-
-
meeting (Object ?)
- the meeting object
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- enableBNR API
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
meeting (Object )
- the meeting object
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise <Boolean >
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- disableBNR API
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
meeting (Object )
- the meeting object
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise <Boolean >
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Stores the delta values for a changed participant.
-
- DeltaParticipant
-
-
- Type:
- Object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Properties
-
-
-
-
delta (Record<string , boolean >)
- : Contains changed streams.
-
-
-
-
-
-
person (Object )
- : Contains person data.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- handles when the locus.host is updated
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
host (Object )
- the locus.host property
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- undefined
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- handles when the locus.mediaShares is updated
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
mediaShares (Object )
- the locus.mediaShares property
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- undefined
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- handles when the locus.self is updated
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
self (Object )
- the locus.mediaShares property
-
-
-
-
-
-
-
-
participants (Array )
- the locus.participants property
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- undefined
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- parses the relevant values for self: muted, guest, moderator, mediaStatus, state, joinedWith, pstnDevices, creator, id
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- undefined
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Checks if user has joined the meeting
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- boolean
:
- isJoined
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Validate if the Meeting Layout Controls Layout has changed.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
previous (Self )
- Previous self state
-
-
-
-
-
-
-
-
current (Self )
- Current self state [per event]
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- boolean
:
- If the MEeting Layout Controls Layout has changed.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- get the id from the self object
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- String
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- get the "remote mute" property from the self object
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Boolean
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Boolean
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Boolean
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Boolean
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Boolean
:
-
-
-
-
-
-
-
-
- Throws
-
-
- Error : when self is undefined
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Boolean
:
-
-
-
-
-
-
-
-
- Throws
-
-
- Error : if changed self was undefined
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Boolean
:
-
-
-
-
-
-
-
-
- Throws
-
-
- Error : if changed self was undefined
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- extract the sipUrl from the partner
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Object
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- parse the relevant host values that we care about: id
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Object
:
- parsed host or null if host was undefined
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- get the previous and current host values parsed, as well as the boolean updates
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Object
:
- previous: {Object} old host, current: {Object} new host, updates: {isNewHost: {boolean}} boolean update values
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- determine by id if 2 hosts are different
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Boolean
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Extract the id from the host object
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- String
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Controls
-
- LocusControls
-
-
- Type:
- Object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Properties
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- parse the relevant host values that we care about: id
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Object
:
- parsedObject - parsed host or null if host was undefined
-
-
-
- Returns
- String
:
- parsedObject.recordingId
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- parses and returns previous state vs current state and triggers the changes.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Object
:
- combination of state plus the changes
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Extract the id from the record controls object
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- (String | null)
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parse the relevant values that we care about
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
embeddedApp (Object )
- raw embedded app object
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Object
:
- parsedObject - parsed embedded app object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Determines if two embedded apps arrays are similar.
-NOTE: This is a simple test for performance reasons.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
apps1 (Array <any>)
- an array of apps
-
-
-
-
-
-
-
-
apps2 (Array <any>)
- an array of apps
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- boolean
:
- true if the arrays are different
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parse the array of embedded apps
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
embeddedApps (array )
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- array
:
- result - new array of parsed embedded app objects
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- parses the relevant values for mediaShares: contentId, disposition
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- undefined
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- get the previous and current mediaShares values parsed, as well as the boolean updates
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Object
:
- previous: {Object} old share, current: {Object} new share,
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- get the content floor disposition (released, granted)
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Boolean
:
- disposition
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- get the whiteboard floor disposition (released, granted)
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Boolean
:
- disposition
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- extract the content property from media shares
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Object
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- extract the whiteboard property from media shares
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Object
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- extract the media stream floor property from content object
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Object
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- extract the content's floor from media shares
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Object
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- extract the whiteboard's floor from media shares
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Object
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- get who is sharing from media shares (content)
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Object
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- get who is sharing from media shares (whiteboard)
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Object
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- get the which whiteboard is being shared via resource url
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Object
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Compares two loci to determine which one contains the most recent state
-
- compare(current: Types~Locus, incoming: Types~Locus):
string
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
- current (Types~Locus)
-
-
-
-
-
-
-
- incoming (Types~Locus)
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- string
:
- loci comparison state
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- LociMetadata
-
-
- Type:
- object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Properties
-
-
-
-
start (number )
- : Starting sequence number
-
-
-
-
-
-
end (number )
- : Ending sequence number
-
-
-
-
-
-
first (number )
- : First sequence number
-
-
-
-
-
-
last (number )
- : Last sequence number
-
-
-
-
-
-
min (number )
- : Minimum sequence number
-
-
-
-
-
-
max (number )
- : Maximum sequence number
-
-
-
-
-
-
entries (number )
- : Loci sequence entries
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Simple queue
-
- new SimpleQueue()
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Instance Members
-
-
-
-
-
-
-
-
-
-
-
- Removes all of the elements from queue.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- undefined
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Inserts the specified element into the queue.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- undefined
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns and removes the head of the queue.
-Returns null if the queue is empty.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- (object | null)
:
- Queue item or null.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns the number of items in queue.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- number
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Used to indicate that the reconnect logic needs to be retried.
-
- new NeedsRetryError()
-
-
-
- Extends
-
- Error
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Used to indicate that the meeting needs to be rejoined, not just media reconnected
-
- new NeedsRejoinError()
-
-
-
- Extends
-
- Error
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- new ReconnectionManager()
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Static Members
-
-
-
-
-
-
βΈ
-
iceReconnected()
-
-
-
-
-
-
-
-
-
- Sets the iceState to connected and clears any disconnect timeouts and
-related timeout data within the iceState.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- undefined
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
waitForIceReconnect()
-
-
-
-
-
-
-
-
-
- Set the iceState to disconnected and generates a timeout that waits for the
-iceState to reconnect and then resolves. If the ice state is already
-processing a reconnect, it immediately resolves. Rejects if the timeout
-duration is reached.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise <undefined >
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- undefined
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- undefined
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
reconnect(reconnectOptions)
-
-
-
-
-
-
-
-
-
- Initiates a media reconnect for the active meeting
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
reconnectOptions (Object
- = {}
)
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- reconnectOptions.networkDisconnect boolean
-
- (default false
)
-
- indicates if a network disconnect event happened
-
-
-
-
-
-
- reconnectOptions.networkRetry boolean
-
- (default false
)
-
- indicates if we are retrying the reconnect
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Instance Members
-
-
-
-
-
-
βΈ
-
rejoinMeeting(wasSharing)
-
-
-
-
-
-
-
-
-
- Rejoins a meeting after detecting the member was in a LEFT state
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
wasSharing (boolean
- = false
)
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- new MeetingRequest()
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Instance Members
-
-
-
-
-
-
βΈ
-
joinMeeting(options)
-
-
-
-
-
-
-
-
-
- Make a network request to join a meeting
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- options.sipUri String
-
-
-
-
-
-
-
- options.deviceUrl String
-
-
-
-
-
-
-
- options.locusUrl String
-
-
-
-
-
-
-
- options.resourceId String
-
- ,
-
-
-
-
-
-
- options.correlationId String
-
-
-
-
-
-
-
- options.ensureConversation boolean
-
-
-
-
-
-
-
- options.moderator boolean
-
-
-
-
-
-
-
- options.pin boolean
-
-
-
-
-
-
-
- options.moveToResource boolean
-
-
-
-
-
-
-
- options.roapMessage Object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
syncMeeting(options)
-
-
-
-
-
-
-
-
-
- Syns the missed delta event
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- options.desync boolean
-
- flag to get partial or whole locus object
-
-
-
-
-
-
- options.syncUrl String
-
- sync url to get ht elatest locus delta
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
getFullLocus(options)
-
-
-
-
-
-
-
-
-
- Request to get the complete locus object
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- options.desync boolean
-
- flag to get partial or whole locus object
-
-
-
-
-
-
- options.locusUrl String
-
- sync url to get ht elatest locus delta
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
leaveMeeting(options)
-
-
-
-
-
-
-
-
-
- Make a network request to leave a meeting
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- options.locusUrl Url
-
-
-
-
-
-
-
- options.selfId String
-
-
-
-
-
-
-
- options.deviceUrl Url
-
-
-
-
-
-
-
- options.resourceId String
-
- ,
-
-
-
-
-
-
- options.correlationId String
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
acknowledgeMeeting(options)
-
-
-
-
-
-
-
-
-
- Make a network request to acknowledge a meeting
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- options.locusUrl String
-
-
-
-
-
-
-
- options.deviceUrl String
-
-
-
-
-
-
-
- options.correlationId String
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
declineMeeting(options)
-
-
-
-
-
-
-
-
-
- Make a network request to decline a meeting
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- options.locusUrl String
-
-
-
-
-
-
-
- options.deviceUrl String
-
-
-
-
-
-
-
- options.reason String
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
remoteAudioVideoToggle(options)
-
-
-
-
-
-
-
-
-
- Toggle remote audio and/or video
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
options (Object )
- options for toggling
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- options.selfId String
-
- Locus self id??
-
-
-
-
-
-
- options.locusUrl String
-
- Locus url
-
-
-
-
-
-
- options.deviceUrl String
-
- Url of a device
-
-
-
-
-
-
- options.resourceId String
-
- Populated if you are paired to a device
-
-
-
-
-
-
- options.localMedias String
-
- local sdps
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
changeMeetingFloor(options)
-
-
-
-
-
-
-
-
-
- change the content floor grant
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
options (Object )
- options for floor grant
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- options.disposition String
-
- floor action (granted/released)
-
-
-
-
-
-
- options.personUrl String
-
- personUrl who is requesting floor
-
-
-
-
-
-
- options.deviceUrl String
-
- Url of a device
-
-
-
-
-
-
- options.resourceId String
-
- Populated if you are paired to a device
-
-
-
-
-
-
- options.uri String
-
- floor grant uri
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
sendDTMF(options)
-
-
-
-
-
-
-
-
-
- Sends a request to the DTMF endpoint to send tones
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- options.locusUrl String
-
-
-
-
-
-
-
- options.deviceUrl String
-
-
-
-
-
-
-
- options.tones String
-
- a string of one or more DTMF tones to send
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
changeVideoLayout(options)
-
-
-
-
-
-
-
-
-
- Sends a request to the controls endpoint to set the video layout
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- options.locusUrl String
-
-
-
-
-
-
-
- options.deviceUrl String
-
-
-
-
-
-
-
- options.layoutType String
-
- a layout type that should be available in meeting constants
-#layout_types
-
-
-
-
-
-
- options.main Object
-
- preferred dimensions for the remote main video stream
-
-
-
-
-
- options.main.width Number
-
- preferred width of main video stream
-
-
-
-
-
-
- options.main.height Number
-
- preferred height of main video stream
-
-
-
-
-
-
-
-
-
- options.content Object
-
- preferred dimensions for the remote content share stream
-
-
-
-
-
- options.content.width Number
-
- preferred width of content share stream
-
-
-
-
-
-
- options.content.height Number
-
- preferred height of content share stream
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
endMeetingForAll(options)
-
-
-
-
-
-
-
-
-
- Make a network request to end meeting for all
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- options.locusUrl Url
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
keepAlive(options)
-
-
-
-
-
-
-
-
-
- Send a locus keepAlive (used in lobby)
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- options.keepAliveUrl Url
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
sendReaction(options)
-
-
-
-
-
-
-
-
-
- Make a network request to send a reaction.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- options.reactionChannelUrl Url
-
-
-
-
-
-
-
- options.reaction Reaction
-
-
-
-
-
-
-
- options.senderID string
-
-
-
-
-
-
-
- options.participantId any
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
getActiveMeetings()
-
-
-
-
-
-
-
-
-
- get all the active meetings for the user
-
- getActiveMeetings():
Array
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Array
:
- return locus array
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- fetch geoHit for the user
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise <object >
:
- geoHintInfo
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
getMeetingPreferences()
-
-
-
-
-
-
-
-
-
- get user meeting preference information
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise <object >
:
- getMeetingPreferences
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
determineRedirections(responseBody)
-
-
-
-
-
-
-
-
-
- Fetches indivdual locus rather then getting all at once
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
responseBody (object )
- determine the locus and fetch them if a remoteUrl is given
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
- returns locusObject array
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- new MeetingRequest()
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Instance Members
-
-
-
-
-
-
βΈ
-
joinMeeting(options)
-
-
-
-
-
-
-
-
-
- Make a network request to join a meeting
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- options.sipUri String
-
-
-
-
-
-
-
- options.deviceUrl String
-
-
-
-
-
-
-
- options.locusUrl String
-
-
-
-
-
-
-
- options.resourceId String
-
- ,
-
-
-
-
-
-
- options.correlationId String
-
-
-
-
-
-
-
- options.ensureConversation boolean
-
-
-
-
-
-
-
- options.moderator boolean
-
-
-
-
-
-
-
- options.pin boolean
-
-
-
-
-
-
-
- options.moveToResource boolean
-
-
-
-
-
-
-
- options.roapMessage Object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
syncMeeting(options)
-
-
-
-
-
-
-
-
-
- Syns the missed delta event
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- options.desync boolean
-
- flag to get partial or whole locus object
-
-
-
-
-
-
- options.syncUrl String
-
- sync url to get ht elatest locus delta
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
getFullLocus(options)
-
-
-
-
-
-
-
-
-
- Request to get the complete locus object
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- options.desync boolean
-
- flag to get partial or whole locus object
-
-
-
-
-
-
- options.locusUrl String
-
- sync url to get ht elatest locus delta
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
leaveMeeting(options)
-
-
-
-
-
-
-
-
-
- Make a network request to leave a meeting
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- options.locusUrl Url
-
-
-
-
-
-
-
- options.selfId String
-
-
-
-
-
-
-
- options.deviceUrl Url
-
-
-
-
-
-
-
- options.resourceId String
-
- ,
-
-
-
-
-
-
- options.correlationId String
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
acknowledgeMeeting(options)
-
-
-
-
-
-
-
-
-
- Make a network request to acknowledge a meeting
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- options.locusUrl String
-
-
-
-
-
-
-
- options.deviceUrl String
-
-
-
-
-
-
-
- options.correlationId String
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
declineMeeting(options)
-
-
-
-
-
-
-
-
-
- Make a network request to decline a meeting
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- options.locusUrl String
-
-
-
-
-
-
-
- options.deviceUrl String
-
-
-
-
-
-
-
- options.reason String
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
remoteAudioVideoToggle(options)
-
-
-
-
-
-
-
-
-
- Toggle remote audio and/or video
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
options (Object )
- options for toggling
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- options.selfId String
-
- Locus self id??
-
-
-
-
-
-
- options.locusUrl String
-
- Locus url
-
-
-
-
-
-
- options.deviceUrl String
-
- Url of a device
-
-
-
-
-
-
- options.resourceId String
-
- Populated if you are paired to a device
-
-
-
-
-
-
- options.localMedias String
-
- local sdps
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
changeMeetingFloor(options)
-
-
-
-
-
-
-
-
-
- change the content floor grant
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
options (Object )
- options for floor grant
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- options.disposition String
-
- floor action (granted/released)
-
-
-
-
-
-
- options.personUrl String
-
- personUrl who is requesting floor
-
-
-
-
-
-
- options.deviceUrl String
-
- Url of a device
-
-
-
-
-
-
- options.resourceId String
-
- Populated if you are paired to a device
-
-
-
-
-
-
- options.uri String
-
- floor grant uri
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
sendDTMF(options)
-
-
-
-
-
-
-
-
-
- Sends a request to the DTMF endpoint to send tones
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- options.locusUrl String
-
-
-
-
-
-
-
- options.deviceUrl String
-
-
-
-
-
-
-
- options.tones String
-
- a string of one or more DTMF tones to send
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
changeVideoLayout(options)
-
-
-
-
-
-
-
-
-
- Sends a request to the controls endpoint to set the video layout
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- options.locusUrl String
-
-
-
-
-
-
-
- options.deviceUrl String
-
-
-
-
-
-
-
- options.layoutType String
-
- a layout type that should be available in meeting constants
-#layout_types
-
-
-
-
-
-
- options.main Object
-
- preferred dimensions for the remote main video stream
-
-
-
-
-
- options.main.width Number
-
- preferred width of main video stream
-
-
-
-
-
-
- options.main.height Number
-
- preferred height of main video stream
-
-
-
-
-
-
-
-
-
- options.content Object
-
- preferred dimensions for the remote content share stream
-
-
-
-
-
- options.content.width Number
-
- preferred width of content share stream
-
-
-
-
-
-
- options.content.height Number
-
- preferred height of content share stream
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
endMeetingForAll(options)
-
-
-
-
-
-
-
-
-
- Make a network request to end meeting for all
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- options.locusUrl Url
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
keepAlive(options)
-
-
-
-
-
-
-
-
-
- Send a locus keepAlive (used in lobby)
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- options.keepAliveUrl Url
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
sendReaction(options)
-
-
-
-
-
-
-
-
-
- Make a network request to send a reaction.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- options.reactionChannelUrl Url
-
-
-
-
-
-
-
- options.reaction Reaction
-
-
-
-
-
-
-
- options.senderID string
-
-
-
-
-
-
-
- options.participantId any
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
getActiveMeetings()
-
-
-
-
-
-
-
-
-
- get all the active meetings for the user
-
- getActiveMeetings():
Array
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Array
:
- return locus array
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- fetch geoHit for the user
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise <object >
:
- geoHintInfo
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
getMeetingPreferences()
-
-
-
-
-
-
-
-
-
- get user meeting preference information
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise <object >
:
- getMeetingPreferences
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
determineRedirections(responseBody)
-
-
-
-
-
-
-
-
-
- Fetches indivdual locus rather then getting all at once
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
responseBody (object )
- determine the locus and fetch them if a remoteUrl is given
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
- returns locusObject array
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- new Members()
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Static Members
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
addMember(invitee, alertIfActive?)
-
-
-
-
-
-
-
-
-
- Adds a guest Member to the associated meeting
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
cancelPhoneInvite(invitee)
-
-
-
-
-
-
-
-
-
- Cancels an outgoing PSTN call to the associated meeting
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
admitMembers(memberIds)
-
-
-
-
-
-
-
-
-
- Admits waiting members (invited guests to meeting)
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
removeMember(memberId)
-
-
-
-
-
-
-
-
-
- Removes a member from the meeting
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
muteMember(memberId, mute = true)
-
-
-
-
-
-
-
-
-
- Audio mutes another member in a meeting
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
mute (boolean ?
- = true
)
- default true
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
raiseOrLowerHand(memberId, raise = true)
-
-
-
-
-
-
-
-
-
- Raise or lower the hand of a member in a meeting
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
raise (boolean ?
- = true
)
- to raise hand (=true) or lower (=false), default: true
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
lowerAllHands(requestingMemberId)
-
-
-
-
-
-
-
-
-
- Lower all hands of members in a meeting
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
requestingMemberId (String )
- id of the participant which requested the lower all hands
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
transferHostToMember(memberId, moderator = true)
-
-
-
-
-
-
-
-
-
- Transfers the host to another member
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
moderator (boolean ?
- = true
)
- default true
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Events
-
-
-
-
-
-
-
-
-
-
-
- Members Update Event
-Emitted when something in the roster list needs to be updated
-
- members:update
-
-
-
-
-
-
-
-
-
-
-
-
-
- Properties
-
-
-
-
delta (Object )
- : the changes to the members list
-
-
-
-
- delta.updated
Array
-
- array only the updates, includes removals, as they will have updated status and member properties
-
-
- delta.added
Array
-
- array added members to the meeting
-
-
-
-
-
-
-
-
full (Array )
- : array the full members collection
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
members:content:update
-
-
-
-
-
-
-
-
-
- Members Content Update Event
-Emitted when who is sharing changes
-
- members:content:update
-
-
-
-
-
-
-
-
-
-
-
-
-
- Properties
-
-
-
-
activeContentSharingId (String )
-
-
-
-
-
-
endedContentSharingId (String )
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
members:host:update
-
-
-
-
-
-
-
-
-
- Members Host Update Event
-Emitted when who is the host changes
-
- members:host:update
-
-
-
-
-
-
-
-
-
-
-
-
-
- Properties
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- new Member()
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Static Members
-
-
-
-
-
-
βΈ
-
setIsContentSharing(flag)
-
-
-
-
-
-
-
-
-
- set the isContentSharing on member
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- undefined
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
setIsHost(flag)
-
-
-
-
-
-
-
-
-
- set the isHost on member
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- undefined
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
setIsSelf(flag)
-
-
-
-
-
-
-
-
-
- set the isSelf on member
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- undefined
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
processIsContentSharing(participant, sharingId)
-
-
-
-
-
-
-
-
-
- determine if this member is content sharing
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- undefined
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
processIsRecording(participant, recordingId)
-
-
-
-
-
-
-
-
-
- Determine if this member is recording
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- undefined
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Instance Members
-
-
-
-
-
-
-
-
-
-
-
- The member id
-
- id
-
-
- Type:
- String
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- The member name
-
- name
-
-
- Type:
- String
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- isAudioMuted
-
-
- Type:
- Boolean
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- isVideoMuted
-
-
- Type:
- Boolean
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- isHandRaised
-
-
- Type:
- Boolean
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- isSelf
-
-
- Type:
- Boolean
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- isHost
-
-
- Type:
- Boolean
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- isGuest
-
-
- Type:
- Boolean
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- isInLobby
-
-
- Type:
- Boolean
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- isInMeeting
-
-
- Type:
- Boolean
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- isNotAdmitted
-
-
- Type:
- Boolean
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
isContentSharing
-
-
-
-
-
-
-
-
-
-
- isContentSharing
-
-
- Type:
- Boolean
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- status
-
-
- Type:
- Boolean
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- isDevice
-
-
- Type:
- Boolean
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- isUser
-
-
- Type:
- Boolean
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Is this member associated to another user by way of pairing (typical of devices)
-
- associatedUser
-
-
- Type:
- String
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- isRecording
-
-
- Type:
- Boolean
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- isMutable
-
-
- Type:
- Boolean
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- isRemovable
-
-
- Type:
- Boolean
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- isModerator
-
-
- Type:
- Boolean
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
isModeratorAssignmentProhibited
-
-
-
-
-
-
-
-
-
-
- isModeratorAssignmentProhibited
-
-
- Type:
- Boolean
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
participant (Object )
- the locus participant
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Boolean
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
participant (Object )
- the locus participant
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Boolean
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
participant (Object )
- the locus participant
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Boolean
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- checks to see if the participant id is the same as the passed id
-there are multiple ids that can be used
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
participant (Object )
- the locus participant
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Boolean
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- checks to see if the participant id is the same as the passed id for associated devices
-there are multiple ids that can be used
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
participant (Object )
- the locus participant
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Boolean
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
participant (Object )
- the locus participant
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Boolean
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
participant (Object )
- the locus participant
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Boolean
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
participant (Object )
- the locus participant
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Boolean
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
participant (Object )
- the locus participant
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Boolean
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- utility method for audio/video muted status
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Boolean
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- utility method for getting the recording member for later comparison
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- (String | null)
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
participant (Object )
- the locus participant
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Boolean
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
participant (Object )
- the locus participant
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- String
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
participant (Object )
- the locus participant
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- String
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- extracts the media status from nested participant object
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
participant (Object )
- the locus participant
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Object
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
participant (Object )
- the locus participant
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- String
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- new MembersCollection()
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Static Members
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Object
:
- returns an object map of Member instances
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Instance Members
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Member
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- new MembersRequest()
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Static Members
-
-
-
-
-
-
βΈ
-
addMembers(options)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
options (Object )
- with format of {invitee: string, locusUrl: string}
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
- Throws
-
-
- Error : if the options are not valid and complete, must have invitee with emailAddress OR email AND locusUrl
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
admitMember(options)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
- Throws
-
-
- Error : if the options are not valid and complete, must have memberIds AND locusUrl
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
cancelPhoneInvite(options)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
options (Object )
- with format of {invitee: string, locusUrl: string}
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
- Throws
-
-
- Error : if the options are not valid and complete, must have invitee with emailAddress OR email AND locusUrl
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Instance Members
-
-
-
-
-
-
βΈ
-
sendDialPadKey(options)
-
-
-
-
-
-
-
-
-
- Sends a request to the DTMF endpoint to send tones
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
-
-
-
-
-
- Name
- Description
-
-
-
-
-
- options.locusUrl String
-
-
-
-
-
-
-
- options.url String
-
- device url SIP user
-
-
-
-
-
-
- options.tones String
-
- a string of one or more DTMF tones to send
-
-
-
-
-
-
- options.memberId String
-
- ID of PSTN user
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
invitee (Object )
- with emailAddress, email or phoneNumber
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Object
:
- the format object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Object
:
- the format object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
options (Object )
- with {invitee: {emailAddress, email, phoneNumber}, alertIfActive}
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Object
:
- with {invitees: [{address}], alertIfActive}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
options (Object )
- with {memberIds}
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Object
:
- admit with {memberIds}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
format (Object )
- with {memberIds, locusUrl}
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Object
:
- the request parameters (method, uri, body) needed to make a admitMember request
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
format (Object )
- with {invitee {emailAddress, email, phoneNumber}, locusUrl, alertIfActive}
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Object
:
- the request parameters (method, uri, body) needed to make a addMember request
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Meeting Webex assistance transcription feature.
-
- new Transcription()
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Instance Members
-
-
-
-
-
-
βΈ
-
connect(token, sessionID)
-
-
-
-
-
-
-
-
-
- open the Low Latency Mercury connection
-An event parameter will be send to the callback.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- void
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
onCloseSocket(callback)
-
-
-
-
-
-
-
-
-
- Sets callback to invoke when the web socket connection is closed.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- void
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
onErrorSocket(callback)
-
-
-
-
-
-
-
-
-
- Sets callback to invoke when a web socket connection error occurs.
-An event parameter will be send to the callback.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- void
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
subscribe(callback)
-
-
-
-
-
-
-
-
-
- Sends transcription data to given callback as it arrives.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- void
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Close the LLM web socket connection
-
- closeSocket(): void
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- void
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- new ReconnectInProgress()
-
-
-
- Extends
-
- Error
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- createState(roapRef: Roap): StateMachine
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
- roapRef (Roap)
- initializes the state machine
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- StateMachine
:
- an instance of a state machine
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Method to handle the transitions between states
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
meeting (Meeting )
- instance of a Meeting
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- String
:
- new state value
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Event that fires after we've transitioned to a new state
-
- onAfterStep(transition:
Object ): null
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- null
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- IInMeetingActions
-Type for In-Meeting Actions
-
- IInMeetingActions
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- new InMeetingActions()
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Instance Members
-
-
-
-
-
-
-
-
-
-
-
- Returns all meeting action options
-
- get
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Object
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- set
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- void
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- setLocusUrl(url:
string ): void
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- void
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- setDisplayHints(hints:
Array ): void
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- void
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- setSessionId(id:
string ): void
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- void
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- setServiceUrl(url:
string ): void
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- void
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- string
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- string
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- string
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- string
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Array
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- new PersonalMeetingRoom()
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Static Members
-
-
-
-
-
-
βΈ
-
claim(link, pin, preferred = true)
-
-
-
-
-
-
-
-
-
- claims a pmr and updates the cached PMR values
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
-
-
preferred (Boolean ?
- = true
)
- defaults to true to set this claimed PMR as the preferred
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- TODO: implement TTL for syncing and caching so to not request again and again
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Instance Members
-
-
-
-
-
-
-
-
-
-
-
- The pmr server object
-
- pmr
-
-
- Type:
- Object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- The pmr sip Uri
-
- sipUri
-
-
- Type:
- String
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- The pmr link
-
- link
-
-
- Type:
- String
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- The pmr server object
-
- userId
-
-
- Type:
- Object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- The pmr name
-
- name
-
-
- Type:
- String
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
options (Object )
- with format of {userId, passcode, meetingAddress, preferred}
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
- returns a promise that resolves/rejects the result of the request
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- new Reachability()
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Static Members
-
-
-
-
-
-
βΈ
-
gatherReachability()
-
-
-
-
-
-
-
-
-
- fetches reachability data
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Object
:
- reachability data
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
isAnyClusterReachable()
-
-
-
-
-
-
-
-
-
- fetches reachability data and checks for cluster reachability
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- boolean
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- new ReachabilityRequest()
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Instance Members
-
-
-
-
-
-
-
-
-
-
-
- gets the cluster information
-
- getClusters
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
includeVideoMesh (boolean )
- whether to include the video mesh clusters in the result or not
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
βΈ
-
remoteSDPForClusters
-
-
-
-
-
-
-
-
-
- gets remote SDP For Clusters
-
- remoteSDPForClusters
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
localSDPList (Object )
- localSDPs for the cluster
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Object
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Extended Error object to signify password related errors
-
-
-
-
-
- Extends
-
- Error
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
message (String ?
- = ERROR_DICTIONARY.PASSWORD.MESSAGE
)
-
-
-
-
-
-
-
-
error (Object ?
- = null
)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Extended Error object to signify captcha related errors
-
-
-
-
-
- Extends
-
- Error
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
message (String ?
- = ERROR_DICTIONARY.CAPTCHA.MESSAGE
)
-
-
-
-
-
-
-
-
error (Object ?
- = null
)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- new MeetingCollection()
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Static Members
-
-
-
-
-
-
βΈ
-
getByKey(key, value)
-
-
-
-
-
-
-
-
-
- get a specific meeting searching for key
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
-
-
- Returns
- Meeting
:
- if found, else returns null
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- new Collection()
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Static Members
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
id (String )
- ID of the thing stuffed into the collection at id location
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Any
:
- returns whatever is being stuffed into the collection
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- set(id:
String , value: Any): Any
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
id (String )
- the id of the meeting info instance to add to the collection
-
-
-
-
-
-
-
- value (Any)
- the thing to set in the collection
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Any
:
- returns the thing just put in the collection
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- remove the thing at the id
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
id (String )
- ID of the thing you wish to delete from the collection
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- undefined
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Object
:
- returns an object map of things stuffed into the collection
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
set (Object )
- the replacement object
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Object
:
- returns an object map of things stuffed into the collection
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Meetings Media Codec Missing Event
-Emitted when H.264 codec is not
-found in the browser.
-
- media:codec:missing
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Meetings Media Codec Loaded Event
-Emitted when H.264 codec has been
-loaded in the browser.
-
- media:codec:loaded
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- @description Layout type for remote video participants. Allowed values are: Single, Equal, ActivePresence, Prominent, OnePlusN
-
- LAYOUT_TYPES
-
-
- Type:
- array
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Extended Error object for general parameter errors
-
-
-
-
-
- Extends
-
- Error
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
message (String ?
- = MEETINGCONSTANTS.ERROR_DICTIONARY.PARAMETER.MESSAGE
)
-
-
-
-
-
-
-
-
error (Object ?
- = null
)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Helper method to build a roomInfo object from a conversation object
-
- buildRoomInfo(webex:
Object , conversation: Conversation~ConversationObject):
Promise <RoomInfoObject>
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
webex (Object )
- sdk object
-
-
-
-
-
-
-
- conversation (Conversation~ConversationObject)
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise <RoomInfoObject>
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Helper method to build a list of roomInfo object from conversation list
-
- buildRoomInfoList(webex:
Object , conversations: Conversation~ConversationObjectList):
Promise <RoomInfoList>
-
-
-
-
-
-
-
-
-
-
-
- Parameters
-
-
-
-
-
webex (Object )
- sdk object
-
-
-
-
-
-
-
- conversations (Conversation~ConversationObjectList)
-
-
-
-
-
-
-
-
-
-
-
-
- Returns
- Promise <RoomInfoList>
:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/docs/samples/calling/app.js b/docs/samples/calling/app.js
index 3900d1fbfb3..4990cb2be0a 100644
--- a/docs/samples/calling/app.js
+++ b/docs/samples/calling/app.js
@@ -90,7 +90,7 @@ const bnrButton = document.getElementById('bnr_button');
let base64;
let audio64;
let call;
-let callTranferObj;
+let callTransferObj;
let broadworksCorrelationInfo;
let localAudioStream;
let effect;
@@ -125,6 +125,11 @@ function getMediaSettings() {
return settings;
}
+function updateCallControlButtons(callObject){
+ holdResumeElm.value = callObject.held ? 'Resume':'Hold'
+ muteElm.value = callObject.muted ? 'Unmute':'Mute'
+}
+
function getAudioVideoInput() {
const deviceId = (id) => devicesById[id];
const audioInput = getOptionValue(audioInputDevicesElem) || 'default';
@@ -248,11 +253,9 @@ async function initCalling(e) {
calling.on('ready', () => {
console.log('Authentication :: Calling Ready');
- registerElm.disabled = false;
callHistoryElm.disabled = false;
voicemailElm.disabled = false;
authStatusElm.innerText = 'Saved access token!';
- registerElm.classList.add('btn--green');
callHistoryElm.classList.add('btn--green');
voicemailElm.classList.add('btn--green');
dndButton.classList.add('btn--red');
@@ -264,6 +267,7 @@ async function initCalling(e) {
calling.register().then(async () => {
unregisterElm.classList.add('btn--red');
+ registerElm.classList.add('btn--green');
registerElm.disabled = false;
callingClient = window.callingClient = calling.callingClient;
@@ -282,16 +286,9 @@ async function initCalling(e) {
if (window.voicemail === undefined) {
voicemail = window.voicemail = calling.voicemailClient;
- const initResponse = await voicemail.init();
-
- console.log(`Init response `, initResponse);
}
fetchLines();
- fetchDNDSetting();
- fetchCallForwardSetting();
- fetchVoicemailSetting();
- fetchCallWaitingSetting();
});
});
@@ -300,6 +297,13 @@ async function initCalling(e) {
credentialsFormElm.addEventListener('submit', initCalling);
+function getSettings() {
+ fetchCallForwardSetting();
+ fetchVoicemailSetting();
+ fetchCallWaitingSetting();
+ fetchDNDSetting();
+}
+
function toggleDisplay(elementId, status) {
const element = document.getElementById(elementId);
@@ -343,7 +347,7 @@ function createDevice() {
calling.webex.internal.device.url !== ''
? `Registered, deviceId: ${deviceInfo.mobiusDeviceId}`
: 'Not Registered';
- // unregisterElm.disabled = false;
+ unregisterElm.disabled = false;
});
// Start listening for incoming calls
@@ -365,6 +369,7 @@ function createDevice() {
makeCallBtn.disabled = false;
endElm.disabled = true;
muteElm.value = 'Mute';
+ holdResumeElm.value = 'Hold';
answerElm.disabled = true;
});
@@ -389,42 +394,68 @@ function endCall() {
makeCallBtn.disabled = false;
endElm.disabled = true;
muteElm.value = 'Mute';
+ holdResumeElm.value = 'Hold'
imageElm.removeChild(img);
}
function endSecondCall() {
- callTranferObj.end();
- transferDetailsElm.innerText = `${callTranferObj.getCorrelationId()}: Call Disconnected`;
+ callTransferObj.end();
+ transferDetailsElm.innerText = `${callTransferObj.getCorrelationId()}: Call Disconnected`;
+ callTransferObj = null
endSecondElm.disabled = true;
- muteElm.value = 'Mute';
+ transferElm.innerHTML = 'Transfer';
+ updateCallControlButtons(call)
+ if (call.muted){
+ localAudioStream.outputStream.getAudioTracks()[0].enabled = false
+ }
imageElm.removeChild(img);
}
function muteUnmute() {
muteElm.value = muteElm.value === 'Mute' ? 'Unmute' : 'Mute';
-
- call.mute(localAudioStream);
+ if (callTransferObj){
+ callTransferObj.mute(localAudioStream)
+ }
+ else {
+ call.mute(localAudioStream);
+ }
}
function holdResume() {
- const elem = document.getElementById('hold_button');
-
- call.on('held', (correlationId) => {
- if (elem.value === 'Hold') {
- callDetailsElm.innerText = 'Call is held';
- elem.value = 'Resume';
- }
- });
-
- call.on('resumed', (correlationId) => {
- if (elem.value === 'Resume') {
- callDetailsElm.innerText = 'Call is Resumed';
- elem.value = 'Hold';
- }
- });
-
- call.doHoldResume();
+ if (callTransferObj){
+ callTransferObj.on('held', (correlationId) => {
+ if (holdResumeElm.value === 'Hold') {
+ callDetailsElm.innerText = 'Call is held';
+ holdResumeElm.value = 'Resume';
+ }
+ });
+
+ callTransferObj.on('resumed', (correlationId) => {
+ if (holdResumeElm.value === 'Resume') {
+ callDetailsElm.innerText = 'Call is Resumed';
+ holdResumeElm.value = 'Hold';
+ }
+ });
+ callTransferObj.doHoldResume()
+ }
+ else{
+ call.on('held', (correlationId) => {
+ if (holdResumeElm.value === 'Hold') {
+ callDetailsElm.innerText = 'Call is held';
+ holdResumeElm.value = 'Resume';
+ }
+ });
+
+ call.on('resumed', (correlationId) => {
+ if (holdResumeElm.value === 'Resume') {
+ callDetailsElm.innerText = 'Call is Resumed';
+ holdResumeElm.value = 'Hold';
+ }
+ });
+ call.doHoldResume();
+ }
}
+
function deleteDevice() {
line.deregister();
line.on('unregistered', () => {
@@ -432,7 +463,7 @@ function deleteDevice() {
registrationStatusElm.innerText = 'Unregistered';
})
registerElm.disabled = false;
- // unregisterElm.disabled = true;
+ unregisterElm.disabled = true;
}
function populateSourceDevices(mediaDevice) {
@@ -458,6 +489,28 @@ function populateSourceDevices(mediaDevice) {
select && select.appendChild(option);
}
+async function changeInputStream() {
+ const selectedDevice = audioInputDevicesElem.options[audioInputDevicesElem.selectedIndex].value;
+
+ const constraints = {
+ audio: true,
+ deviceId: selectedDevice ? { exact: selectedDevice } : undefined
+ };
+ const newStream = await Calling.createMicrophoneStream(constraints);
+
+ call.updateMedia(newStream);
+}
+
+async function changeOutputStream() {
+ const selectedDevice = audioOutputDevicesElem.options[audioOutputDevicesElem.selectedIndex].value;
+ mediaStreamsRemoteAudio.setSinkId(selectedDevice);
+}
+
+async function changeStream() {
+ changeInputStream();
+ changeOutputStream();
+}
+
/**
*
*/
@@ -552,37 +605,40 @@ async function getCallQuality() {
}
function commitTransfer() {
+
const digit = transferTarget.value;
transferElm.disabled = true;
if (transferOptionsElm.options[transferOptionsElm.selectedIndex].text === 'Consult Transfer') {
- callTranferObj = line.makeCall({
+ call.doHoldResume();
+ transferDetailsElm.innerText = `Placed call: ${call.getCorrelationId()} on hold and dialing Transfer target`;
+
+ callTransferObj = line.makeCall({
type: 'uri',
address: digit,
});
-
- callTranferObj.on('remote_media', (track) => {
+ updateCallControlButtons(callTransferObj)
+ callTransferObj.on('remote_media', (track) => {
document.getElementById('remote-audio').srcObject = new MediaStream([track]);
transferDetailsElm.innerText = `Got remote audio`;
});
- callTranferObj.on('established', (correlationId) => {
+ callTransferObj.on('established', (correlationId) => {
transferDetailsElm.innerText = `${correlationId}: Transfer target connected`;
endSecondElm.disabled = false;
transferElm.innerHTML = 'Commit';
transferElm.disabled = false;
});
- callTranferObj.on('disconnect', (correlationId) => {
+ callTransferObj.on('disconnect', (correlationId) => {
endSecondElm.disabled = true;
- callTranferObj = null;
+ callTransferObj = null;
});
- callTranferObj.dial(localAudioStream);
+ callTransferObj.dial(localAudioStream);
- transferDetailsElm.innerText = `Dialing Transfer target`;
} else {
console.log(`Initiating blind transfer with ${digit}`);
call.completeTransfer('BLIND', undefined, digit);
@@ -594,17 +650,12 @@ function initiateTransfer() {
transferInitiated = true;
if (!call.isHeld()) {
- call.doHoldResume();
-
- call.on('held', (correlationId) => {
- transferDetailsElm.innerText = `Placed call: ${call.getCorrelationId()} on hold`;
commitTransfer();
- });
} else {
transferDetailsElm.innerText = `Transferring call..`;
- if (callTranferObj) {
+ if (callTransferObj) {
console.log(`Completing consult transfer with ${digit}`);
- call.completeTransfer('CONSULT', callTranferObj.getCallId(), undefined);
+ call.completeTransfer('CONSULT', callTransferObj.getCallId(), undefined);
}
}
}
@@ -776,6 +827,8 @@ function definedTable(callHistoryResponse) {
EndTime
SessionType
CallbackAddress
+ RedirectionReason
+ Forwarded by
`;
callHistoryHeader.innerHTML += callHistHeaderHtml;
@@ -790,6 +843,8 @@ function definedTable(callHistoryResponse) {
${callHistoryResponse.data.userSessions[i].endTime}
${callHistoryResponse.data.userSessions[i].sessionType}
${callHistoryResponse.data.userSessions[i].other.callbackAddress}
+ ${callHistoryResponse.data.userSessions[i].callingSpecifics?.redirectionDetails?.reason === undefined ? 'NA' : callHistoryResponse.data.userSessions[i].callingSpecifics.redirectionDetails.reason}
+ ${callHistoryResponse.data.userSessions[i].callingSpecifics?.redirectionDetails?.name === undefined ? 'NA' : callHistoryResponse.data.userSessions[i].callingSpecifics.redirectionDetails.name}
`;
callHistoryTable.innerHTML += callHistoryRow;
@@ -833,6 +888,7 @@ async function createCallHistory() {
* Function to use Voice Mail API's.
*/
async function createVoiceMail() {
+ await voicemail.init();
const backendConnector = calling.webex.internal.device.callingBehavior;
if (backendConnector === 'NATIVE_SIP_CALL_TO_UCM') {
diff --git a/docs/samples/calling/index.html b/docs/samples/calling/index.html
index 0a5d2f9796c..0ad26f7d6ad 100644
--- a/docs/samples/calling/index.html
+++ b/docs/samples/calling/index.html
@@ -72,8 +72,8 @@ Authentication
- register
- unregister
+ register
+ unregister
Not Registered
@@ -203,9 +203,8 @@ Call Transfer
NOTE: Choose your sending and receiving options for the meeting.
-
Get
- Devices
-
+
Get Devices
+
Change Device
receiveAudio
@@ -332,7 +331,8 @@ Pagination
Call Settings
-
DND
+
Get Settings
+
Toggle DND
Call Waiting
diff --git a/karma-ng.conf.js b/karma-ng.conf.js
index 3ee2d60ae53..69aa7a55ff5 100644
--- a/karma-ng.conf.js
+++ b/karma-ng.conf.js
@@ -7,14 +7,11 @@
const path = require('path');
-const uuid = require('uuid');
const {flatten} = require('lodash');
const makeBrowsers = require('./browsers-ng');
/* eslint-disable global-require */
-const SAUCE = process.env.SC_TUNNEL_IDENTIFIER || process.env.SAUCE;
-
module.exports = function configureKarma(config) {
config.set(makeConfig(process.env.PACKAGE));
};
@@ -36,7 +33,6 @@ function makeConfig(packageName, argv) {
argv.os.map((os) => (os.includes(',') ? os.toLowerCase().split(',') : os.toLowerCase()))
);
- const pkg = require(`./packages/${packageName}/package`);
/* eslint complexity: [0] */
const launchers = makeBrowsers(packageName, argv);
const integrationTestPath = path.join(
@@ -157,7 +153,7 @@ function makeConfig(packageName, argv) {
recordScreenshots: true,
};
- if (process.env.COVERAGE || process.env.CIRCLECI || process.env.CI) {
+ if (process.env.COVERAGE || process.env.CI) {
cfg.junitReporter = {
outputFile: `${packageName}.xml`,
outputDir: 'reports/junit/karma',
@@ -170,34 +166,6 @@ function makeConfig(packageName, argv) {
cfg.reporters.push('junit');
}
- if (SAUCE) {
- cfg.transports = ['websocket', 'polling'];
-
- cfg.sauceLabs = {
- build: process.env.BUILD_NUMBER || `local-${process.env.USER}-${packageName}-${Date.now()}`,
- testName: `${pkg.name || packageName} (karma)`,
- tunnelIdentifier: process.env.SC_TUNNEL_IDENTIFIER || uuid.v4(),
- recordScreenshots: true,
- recordVideo: true,
- public: 'team',
- startConnect: true,
- connectOptions: {
- logfile: './sauce.log',
- noSslBumpDomains: [
- 'idbroker.webex.com',
- 'idbrokerbts.webex.com',
- '127.0.0.1',
- 'localhost',
- '*.wbx2.com',
- '*.ciscospark.com',
- ],
- tunnelDomains: ['127.0.0.1', 'localhost'],
- },
- };
-
- cfg.reporters.push('saucelabs');
- }
-
try {
cfg = require(`./packages/${packageName}/karma.conf.js`)(cfg);
} catch (error) {
diff --git a/package.json b/package.json
index 1aa66ec2244..b11e9554fb7 100644
--- a/package.json
+++ b/package.json
@@ -40,7 +40,6 @@
"check-karma-output": "./scripts/analyze-output.sh",
"build:package": "node ./tooling/index.js build",
"changelog:generate": "npx standard-changelog",
- "circleci:local": "circleci local execute -c .circleci/github.config.yml",
"lint": "yarn && yarn ws:tools build && yarn run --silent eslint .",
"lint:commitmsg": "commitlint -e $GIT_PARAMS",
"lint:staged": "lint-staged",
diff --git a/packages/@webex/media-helpers/package.json b/packages/@webex/media-helpers/package.json
index 406db47ddaf..b892b32383f 100644
--- a/packages/@webex/media-helpers/package.json
+++ b/packages/@webex/media-helpers/package.json
@@ -22,9 +22,9 @@
"deploy:npm": "yarn npm publish"
},
"dependencies": {
- "@webex/internal-media-core": "^2.0.0",
+ "@webex/internal-media-core": "^2.2.2",
"@webex/ts-events": "^1.1.0",
- "@webex/web-media-effects": "^2.13.3"
+ "@webex/web-media-effects": "^2.15.6"
},
"browserify": {
"transform": [
diff --git a/packages/@webex/plugin-meetings/src/meeting-info/meeting-info-v2.ts b/packages/@webex/plugin-meetings/src/meeting-info/meeting-info-v2.ts
index 69d0c238ad1..f6a4eb09482 100644
--- a/packages/@webex/plugin-meetings/src/meeting-info/meeting-info-v2.ts
+++ b/packages/@webex/plugin-meetings/src/meeting-info/meeting-info-v2.ts
@@ -151,7 +151,7 @@ export default class MeetingInfoV2 {
};
return this.webex
- .request(conversationUrl)
+ .request({uri: conversationUrl, qs: {includeParticipants: true}, disableTransform: true})
.then(({body: conversation}) => {
const body = {
title: conversation.displayName,
diff --git a/packages/@webex/plugin-meetings/src/meeting/index.ts b/packages/@webex/plugin-meetings/src/meeting/index.ts
index 6acf0f4871d..048ad1478d9 100644
--- a/packages/@webex/plugin-meetings/src/meeting/index.ts
+++ b/packages/@webex/plugin-meetings/src/meeting/index.ts
@@ -462,6 +462,7 @@ export default class Meeting extends StatelessWebexPlugin {
shareStatus: string;
statsAnalyzer: StatsAnalyzer;
transcription: Transcription;
+ receiveTranscription: boolean;
updateMediaConnections: (mediaConnections: any[]) => void;
endCallInitiateJoinReq: any;
endJoinReqResp: any;
@@ -1761,8 +1762,8 @@ export default class Meeting extends StatelessWebexPlugin {
LOCUSINFO.EVENTS.CONTROLS_MEETING_TRANSCRIBE_UPDATED,
({caption, transcribing}) => {
// @ts-ignore - config coming from registerPlugin
- if (transcribing && this.transcription && this.config.receiveTranscription) {
- this.receiveTranscription();
+ if (transcribing && !this.transcription && this.config.receiveTranscription) {
+ this.startTranscription();
} else if (!transcribing && this.transcription) {
Trigger.trigger(
this,
@@ -2261,8 +2262,17 @@ export default class Meeting extends StatelessWebexPlugin {
});
}
});
- this.locusInfo.on(LOCUSINFO.EVENTS.SELF_ADMITTED_GUEST, (payload) => {
+ this.locusInfo.on(LOCUSINFO.EVENTS.SELF_ADMITTED_GUEST, async (payload) => {
this.stopKeepAlive();
+ // @ts-ignore
+ if (!this.transcription && (this.config.receiveTranscription || this.receiveTranscription)) {
+ if (this.isTranscriptionSupported()) {
+ await this.startTranscription();
+ LoggerProxy.logger.info(
+ 'Meeting:index#setUpLocusInfoSelfListener --> enabled to receive transcription for guest user!'
+ );
+ }
+ }
if (payload) {
Trigger.trigger(
@@ -3725,9 +3735,9 @@ export default class Meeting extends StatelessWebexPlugin {
* @private
* @returns {Promise} a promise to open the WebSocket connection
*/
- private async receiveTranscription() {
+ private async startTranscription() {
LoggerProxy.logger.info(
- `Meeting:index#receiveTranscription -->
+ `Meeting:index#startTranscription -->
Attempting to generate a web socket url.`
);
@@ -3744,7 +3754,7 @@ export default class Meeting extends StatelessWebexPlugin {
});
LoggerProxy.logger.info(
- `Meeting:index#receiveTranscription -->
+ `Meeting:index#startTranscription -->
Generated web socket url succesfully.`
);
@@ -3756,7 +3766,7 @@ export default class Meeting extends StatelessWebexPlugin {
);
LoggerProxy.logger.info(
- `Meeting:index#receiveTranscription -->
+ `Meeting:index#startTranscription -->
opened LLM web socket connection successfully.`
);
@@ -3777,7 +3787,7 @@ export default class Meeting extends StatelessWebexPlugin {
// @ts-ignore - fix type
this.transcription.connect(this.webex.credentials.supertoken.access_token);
} catch (error) {
- LoggerProxy.logger.error(`Meeting:index#receiveTranscription --> ${error}`);
+ LoggerProxy.logger.error(`Meeting:index#startTranscription --> ${error}`);
Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.RECEIVE_TRANSCRIPTION_FAILURE, {
correlation_id: this.correlationId,
reason: error.message,
@@ -3950,6 +3960,7 @@ export default class Meeting extends StatelessWebexPlugin {
.then((join) => {
joinSuccess(join);
this.deferJoin = undefined;
+ this.receiveTranscription = !!options.receiveTranscription;
Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.JOIN_SUCCESS, {
correlation_id: this.correlationId,
});
@@ -3959,10 +3970,10 @@ export default class Meeting extends StatelessWebexPlugin {
.then(async (join) => {
if (isBrowser) {
// @ts-ignore - config coming from registerPlugin
- if (this.config.receiveTranscription || options.receiveTranscription) {
+ if (this.config.receiveTranscription || this.receiveTranscription) {
if (this.isTranscriptionSupported()) {
- await this.receiveTranscription();
- LoggerProxy.logger.info('Meeting:index#join --> enabled to recieve transcription!');
+ await this.startTranscription();
+ LoggerProxy.logger.info('Meeting:index#join --> enabled to receive transcription!');
}
}
} else {
@@ -5698,7 +5709,7 @@ export default class Meeting extends StatelessWebexPlugin {
if (layoutType) {
if (!LAYOUT_TYPES.includes(layoutType)) {
return this.rejectWithErrorLog(
- 'Meeting:index#changeVideoLayout --> cannot change video layout, invalid layoutType recieved.'
+ 'Meeting:index#changeVideoLayout --> cannot change video layout, invalid layoutType received.'
);
}
diff --git a/packages/@webex/plugin-meetings/src/roap/index.ts b/packages/@webex/plugin-meetings/src/roap/index.ts
index f258572751d..b9e211acf13 100644
--- a/packages/@webex/plugin-meetings/src/roap/index.ts
+++ b/packages/@webex/plugin-meetings/src/roap/index.ts
@@ -287,17 +287,20 @@ export default class Roap extends StatelessWebexPlugin {
// When reconnecting, it's important that the first roap message being sent out has empty media id.
// Normally this is the roap offer, but when TURN discovery is enabled,
// then this is the TURN discovery request message
- const sendEmptyMediaId = reconnect && !meeting.config.experimental.enableTurnDiscovery;
+ return this.turnDiscovery
+ .isSkipped(meeting)
+ .then((isTurnDiscoverySkipped) => {
+ const sendEmptyMediaId = reconnect && isTurnDiscoverySkipped;
- return this.roapRequest
- .sendRoap({
- roapMessage,
- correlationId: meeting.correlationId,
- locusSelfUrl: meeting.selfUrl,
- mediaId: sendEmptyMediaId ? '' : meeting.mediaId,
- audioMuted: meeting.audio?.isLocallyMuted(),
- videoMuted: meeting.video?.isLocallyMuted(),
- meetingId: meeting.id,
+ return this.roapRequest.sendRoap({
+ roapMessage,
+ correlationId: meeting.correlationId,
+ locusSelfUrl: meeting.selfUrl,
+ mediaId: sendEmptyMediaId ? '' : meeting.mediaId,
+ audioMuted: meeting.audio?.isLocallyMuted(),
+ videoMuted: meeting.video?.isLocallyMuted(),
+ meetingId: meeting.id,
+ });
})
.then(({locus, mediaConnections}) => {
this.roapHandler.submit({
diff --git a/packages/@webex/plugin-meetings/src/roap/turnDiscovery.ts b/packages/@webex/plugin-meetings/src/roap/turnDiscovery.ts
index 19be416d1c5..2e3cef26afb 100644
--- a/packages/@webex/plugin-meetings/src/roap/turnDiscovery.ts
+++ b/packages/@webex/plugin-meetings/src/roap/turnDiscovery.ts
@@ -230,28 +230,14 @@ export default class TurnDiscovery {
* media connection just after a reconnection
* @returns {Promise}
*/
- doTurnDiscovery(meeting: Meeting, isReconnecting?: boolean) {
- // @ts-ignore - fix type
- const isAnyClusterReachable = meeting.webex.meetings.reachability.isAnyClusterReachable();
-
- if (isAnyClusterReachable) {
- LoggerProxy.logger.info(
- 'Roap:turnDiscovery#doTurnDiscovery --> reachability has not failed, skipping TURN discovery'
- );
+ async doTurnDiscovery(meeting: Meeting, isReconnecting?: boolean) {
+ const turnDiscoverySkippedReason = await this.getSkipReason(meeting);
- return Promise.resolve({
+ if (turnDiscoverySkippedReason) {
+ return {
turnServerInfo: undefined,
- turnDiscoverySkippedReason: 'reachability',
- });
- }
-
- // @ts-ignore - fix type
- if (!meeting.config.experimental.enableTurnDiscovery) {
- LoggerProxy.logger.info(
- 'Roap:turnDiscovery#doTurnDiscovery --> TURN discovery disabled in config, skipping it'
- );
-
- return Promise.resolve({turnServerInfo: undefined, turnDiscoverySkippedReason: 'config'});
+ turnDiscoverySkippedReason,
+ };
}
return this.sendRoapTurnDiscoveryRequest(meeting, isReconnecting)
@@ -280,4 +266,46 @@ export default class TurnDiscovery {
return Promise.resolve({turnServerInfo: undefined, turnDiscoverySkippedReason: undefined});
});
}
+
+ /**
+ * Gets the reason why reachability is skipped.
+ *
+ * @param {Meeting} meeting
+ * @returns {Promise} Promise with empty string if reachability is not skipped or a reason if it is skipped
+ */
+ private async getSkipReason(meeting: Meeting): Promise {
+ // @ts-ignore - fix type
+ const isAnyClusterReachable = await meeting.webex.meetings.reachability.isAnyClusterReachable();
+
+ if (isAnyClusterReachable) {
+ LoggerProxy.logger.info(
+ 'Roap:turnDiscovery#getSkipReason --> reachability has not failed, skipping TURN discovery'
+ );
+
+ return 'reachability';
+ }
+
+ // @ts-ignore - fix type
+ if (!meeting.config.experimental.enableTurnDiscovery) {
+ LoggerProxy.logger.info(
+ 'Roap:turnDiscovery#getSkipReason --> TURN discovery disabled in config, skipping it'
+ );
+
+ return 'config';
+ }
+
+ return '';
+ }
+
+ /**
+ * Checks if TURN discovery is skipped.
+ *
+ * @param {Meeting} meeting
+ * @returns {Boolean} true if TURN discovery is being skipped, false if it is being done
+ */
+ async isSkipped(meeting) {
+ const skipReason = await this.getSkipReason(meeting);
+
+ return !!skipReason;
+ }
}
diff --git a/packages/@webex/plugin-meetings/test/unit/spec/meeting-info/meetinginfov2.js b/packages/@webex/plugin-meetings/test/unit/spec/meeting-info/meetinginfov2.js
index f773af634ff..9a1f685ee86 100644
--- a/packages/@webex/plugin-meetings/test/unit/spec/meeting-info/meetinginfov2.js
+++ b/packages/@webex/plugin-meetings/test/unit/spec/meeting-info/meetinginfov2.js
@@ -354,7 +354,7 @@ describe('plugin-meetings', () => {
assert.calledWith(
webex.request,
- conversationUrl,
+ {uri:conversationUrl, qs: {includeParticipants: true}, disableTransform: true}
)
assert.calledWith(webex.request, {
diff --git a/packages/@webex/plugin-meetings/test/unit/spec/meeting/index.js b/packages/@webex/plugin-meetings/test/unit/spec/meeting/index.js
index 6ac9ea4aa83..d5ea784e031 100644
--- a/packages/@webex/plugin-meetings/test/unit/spec/meeting/index.js
+++ b/packages/@webex/plugin-meetings/test/unit/spec/meeting/index.js
@@ -770,12 +770,12 @@ describe('plugin-meetings', () => {
assert.equal(meeting.isTranscriptionSupported(), true);
});
});
- describe('#receiveTranscription', () => {
+ describe('#startTranscription', () => {
it('should invoke subscribe method to invoke the callback', () => {
meeting.monitorTranscriptionSocketConnection = sinon.stub();
meeting.initializeTranscription = sinon.stub();
- meeting.receiveTranscription().then(() => {
+ meeting.startTranscription().then(() => {
assert.equal(true, false);
assert.calledOnce(meeting.initializeTranscription);
assert.calledOnce(meeting.monitorTranscriptionSocketConnection);
@@ -786,7 +786,7 @@ describe('plugin-meetings', () => {
meeting.request = sinon.stub().returns(Promise.reject());
try {
- await meeting.receiveTranscription();
+ await meeting.startTranscription();
} catch (err) {
assert(err, {});
}
@@ -840,12 +840,12 @@ describe('plugin-meetings', () => {
assert.calledOnce(MeetingUtil.joinMeeting);
assert.calledOnce(meeting.setLocus);
});
- it('should invoke `receiveTranscription()` if receiveTranscription is set to true', async () => {
+ it('should invoke `startTranscription()` if receiveTranscription is set to true', async () => {
meeting.isTranscriptionSupported = sinon.stub().returns(true);
- meeting.receiveTranscription = sinon.stub().returns(Promise.resolve());
+ meeting.startTranscription = sinon.stub().returns(Promise.resolve());
await meeting.join({receiveTranscription: true});
- assert.calledOnce(meeting.receiveTranscription);
+ assert.calledOnce(meeting.startTranscription);
});
it('should not create new correlation ID on join immediately after create', async () => {
@@ -3578,8 +3578,49 @@ describe('plugin-meetings', () => {
);
done();
});
+ it('transcription should start when configured when guest admitted', (done) => {
+ meeting.isTranscriptionSupported = sinon.stub().returns(true);
+ meeting.receiveTranscription = sinon.stub().returns(true);
+ meeting.startTranscription = sinon.stub();
+
+ meeting.locusInfo.emit({function: 'test', file: 'test'}, 'SELF_ADMITTED_GUEST', test1);
+ assert.calledOnce(meeting.startTranscription);
+ done();
+ });
});
+ describe('#setupLocusControlsListener', () => {
+ it('transcription should start when meeting transcribe state is updated with active transcribing', (done) => {
+ const payload = {caption: true, transcribing: true};
+ meeting.startTranscription = sinon.stub();
+ meeting.config.receiveTranscription = true;
+ meeting.transcription = null;
+
+ meeting.locusInfo.emit({function: 'meeting/index', file: 'setupLocusControlsListener'}, 'CONTROLS_MEETING_TRANSCRIBE_UPDATED', payload);
+ assert.calledOnce(meeting.startTranscription);
+ done();
+ })
+
+ it('transcription should stop when meeting transcribe state is updated with inactive transcribing', (done) => {
+ const payload = {caption: false, transcribing: false};
+ meeting.startTranscription = sinon.stub();
+ meeting.config.receiveTranscription = true;
+ meeting.transcription = {};
+
+ meeting.locusInfo.emit({function: 'meeting/index', file: 'setupLocusControlsListener'}, 'CONTROLS_MEETING_TRANSCRIBE_UPDATED', payload);
+ assert.notCalled(meeting.startTranscription);
+ assert.calledTwice(TriggerProxy.trigger);
+ assert.calledWith(
+ TriggerProxy.trigger,
+ sinon.match.instanceOf(Meeting),
+ {file: 'meeting/index', function: 'setupLocusControlsListener'},
+ 'meeting:receiveTranscription:stopped',
+ payload
+ );
+ done();
+ })
+ })
+
describe('#setUpLocusUrlListener', () => {
it('listens to the locus url update event', (done) => {
const newLocusUrl = 'newLocusUrl/12345';
diff --git a/packages/@webex/plugin-meetings/test/unit/spec/roap/index.ts b/packages/@webex/plugin-meetings/test/unit/spec/roap/index.ts
index 671a7d42fb0..c1676c04d94 100644
--- a/packages/@webex/plugin-meetings/test/unit/spec/roap/index.ts
+++ b/packages/@webex/plugin-meetings/test/unit/spec/roap/index.ts
@@ -42,87 +42,92 @@ describe('Roap', () => {
let sendRoapStub;
let roapHandlerSubmitStub;
- const meeting = {
- id: 'some meeting id',
- correlationId: 'correlation id',
- selfUrl: 'self url',
- mediaId: 'media id',
- audio:{
- isLocallyMuted: () => true,
- },
- video:{
- isLocallyMuted: () => false,
- },
- setRoapSeq: sinon.stub(),
- config: {experimental: {enableTurnDiscovery: false}},
- };
+ let meeting;
beforeEach(() => {
- sendRoapStub = sinon.stub(RoapRequest.prototype, 'sendRoap').resolves({});
- roapHandlerSubmitStub = sinon.stub(RoapHandler.prototype, 'submit');
- meeting.setRoapSeq.resetHistory();
+ meeting = {
+ id: 'some meeting id',
+ correlationId: 'correlation id',
+ selfUrl: 'self url',
+ mediaId: 'media id',
+ audio: {
+ isLocallyMuted: () => true,
+ },
+ video: {
+ isLocallyMuted: () => false,
+ },
+ setRoapSeq: sinon.stub(),
+ config: {experimental: {enableTurnDiscovery: false}},
+ webex: {meetings: {reachability: {isAnyClusterReachable: () => true}}},
+ };
+
+ beforeEach(() => {
+ sendRoapStub = sinon.stub(RoapRequest.prototype, 'sendRoap').resolves({});
+ roapHandlerSubmitStub = sinon.stub(RoapHandler.prototype, 'submit');
+ meeting.setRoapSeq.resetHistory();
+ });
+
+ afterEach(() => {
+ sinon.restore();
+ });
+
+ [
+ {reconnect: true, turnDiscoverySkipped: false, expectEmptyMediaId: false},
+ {reconnect: true, turnDiscoverySkipped: true, expectEmptyMediaId: true},
+ {reconnect: false, turnDiscoverySkipped: false, expectEmptyMediaId: false},
+ {reconnect: false, turnDiscoverySkipped: true, expectEmptyMediaId: false},
+ ].forEach(({reconnect, turnDiscoverySkipped, expectEmptyMediaId}) =>
+ it(`sends roap OFFER with ${expectEmptyMediaId ? 'empty ' : ''}mediaId when ${
+ reconnect ? '' : 'not '
+ }reconnecting and TURN discovery is ${
+ turnDiscoverySkipped ? 'skipped' : 'not skipped'
+ }`, async () => {
+ const roap = new Roap({}, {parent: 'fake'});
+
+ sinon.stub(roap.turnDiscovery, 'isSkipped').resolves(turnDiscoverySkipped);
+
+ await roap.sendRoapMediaRequest({
+ meeting,
+ sdp: 'sdp',
+ reconnect,
+ roapSeq: 1,
+ });
+
+ const expectedRoapMessage = {
+ messageType: 'OFFER',
+ sdps: ['sdp'],
+ version: '2',
+ seq: 2,
+ tieBreaker: 4294967294,
+ };
+
+ assert.calledOnce(sendRoapStub);
+ assert.calledWith(sendRoapStub, {
+ roapMessage: expectedRoapMessage,
+ correlationId: meeting.correlationId,
+ locusSelfUrl: meeting.selfUrl,
+ mediaId: expectEmptyMediaId ? '' : meeting.mediaId,
+ audioMuted: meeting.audio?.isLocallyMuted(),
+ videoMuted: meeting.video?.isLocallyMuted(),
+ meetingId: meeting.id,
+ });
+
+ assert.calledTwice(roapHandlerSubmitStub);
+ assert.calledWith(roapHandlerSubmitStub, {
+ type: ROAP.SEND_ROAP_MSG,
+ msg: expectedRoapMessage,
+ correlationId: meeting.correlationId,
+ });
+ assert.calledWith(roapHandlerSubmitStub, {
+ type: ROAP.SEND_ROAP_MSG_SUCCESS,
+ seq: 2,
+ correlationId: meeting.correlationId,
+ });
+
+ assert.calledOnce(meeting.setRoapSeq);
+ assert.calledWith(meeting.setRoapSeq, 2);
+ })
+ );
});
-
- afterEach(() => {
- sinon.restore();
- });
-
- [
- {reconnect: true, enableTurnDiscovery: true, expectEmptyMediaId: false},
- {reconnect: true, enableTurnDiscovery: false, expectEmptyMediaId: true},
- {reconnect: false, enableTurnDiscovery: true, expectEmptyMediaId: false},
- {reconnect: false, enableTurnDiscovery: false, expectEmptyMediaId: false},
- ].forEach(({reconnect, enableTurnDiscovery, expectEmptyMediaId}) =>
- it(`sends roap OFFER with ${expectEmptyMediaId ? 'empty ' : ''}mediaId when ${
- reconnect ? '' : 'not '
- }reconnecting and TURN discovery is ${
- enableTurnDiscovery ? 'enabled' : 'disabled'
- }`, async () => {
- meeting.config.experimental.enableTurnDiscovery = enableTurnDiscovery;
-
- const roap = new Roap({}, {parent: 'fake'});
-
- await roap.sendRoapMediaRequest({
- meeting,
- sdp: 'sdp',
- reconnect,
- roapSeq: 1,
- });
-
- const expectedRoapMessage = {
- messageType: 'OFFER',
- sdps: ['sdp'],
- version: '2',
- seq: 2,
- tieBreaker: 4294967294,
- };
-
- assert.calledOnce(sendRoapStub);
- assert.calledWith(sendRoapStub, {
- roapMessage: expectedRoapMessage,
- correlationId: meeting.correlationId,
- locusSelfUrl: meeting.selfUrl,
- mediaId: expectEmptyMediaId ? '' : meeting.mediaId,
- audioMuted: meeting.audio?.isLocallyMuted(),
- videoMuted: meeting.video?.isLocallyMuted(),
- meetingId: meeting.id,
- });
-
- assert.calledTwice(roapHandlerSubmitStub);
- assert.calledWith(roapHandlerSubmitStub, {
- type: ROAP.SEND_ROAP_MSG,
- msg: expectedRoapMessage,
- correlationId: meeting.correlationId,
- });
- assert.calledWith(roapHandlerSubmitStub, {
- type: ROAP.SEND_ROAP_MSG_SUCCESS,
- seq: 2,
- correlationId: meeting.correlationId,
- });
-
- assert.calledOnce(meeting.setRoapSeq);
- assert.calledWith(meeting.setRoapSeq, 2);
- })
- );
});
});
diff --git a/packages/@webex/plugin-meetings/test/unit/spec/roap/turnDiscovery.ts b/packages/@webex/plugin-meetings/test/unit/spec/roap/turnDiscovery.ts
index fb237dd9578..59051cfed51 100644
--- a/packages/@webex/plugin-meetings/test/unit/spec/roap/turnDiscovery.ts
+++ b/packages/@webex/plugin-meetings/test/unit/spec/roap/turnDiscovery.ts
@@ -352,6 +352,27 @@ describe('TurnDiscovery', () => {
});
});
+ describe('isSkipped', () => {
+ [
+ {enabledInConfig: true, isAnyClusterReachable: true, expectedIsSkipped: true},
+ {enabledInConfig: true, isAnyClusterReachable: false, expectedIsSkipped: false},
+ {enabledInConfig: false, isAnyClusterReachable: true, expectedIsSkipped: true},
+ {enabledInConfig: false, isAnyClusterReachable: false, expectedIsSkipped: true},
+ ].forEach(({enabledInConfig, isAnyClusterReachable, expectedIsSkipped}) => {
+ it(`returns ${expectedIsSkipped} when TURN discovery is ${enabledInConfig ? '' : 'not '} enabled in config and isAnyClusterReachable() returns ${isAnyClusterReachable ? 'true' : 'false'}`, async () => {
+ testMeeting.config.experimental.enableTurnDiscovery = enabledInConfig;
+
+ sinon.stub(testMeeting.webex.meetings.reachability, 'isAnyClusterReachable').resolves(isAnyClusterReachable);
+
+ const td = new TurnDiscovery(mockRoapRequest);
+
+ const isSkipped = await td.isSkipped(testMeeting);
+
+ assert.equal(isSkipped, expectedIsSkipped);
+ })
+ })
+ })
+
describe('handleTurnDiscoveryResponse', () => {
it("doesn't do anything if turn discovery was not started", () => {
const td = new TurnDiscovery(mockRoapRequest);
diff --git a/packages/@webex/webex-core/src/lib/services/services.js b/packages/@webex/webex-core/src/lib/services/services.js
index 3f66d749512..a5583709dac 100644
--- a/packages/@webex/webex-core/src/lib/services/services.js
+++ b/packages/@webex/webex-core/src/lib/services/services.js
@@ -58,6 +58,8 @@ const Services = WebexPlugin.extend({
_serviceUrls: null,
+ _hostCatalog: null,
+
/**
* Get the registry associated with this webex instance.
*
@@ -166,6 +168,15 @@ const Services = WebexPlugin.extend({
this._serviceUrls = {...this._serviceUrls, ...serviceUrls};
},
+ /**
+ * saves the host catalog
+ * @param {Object} hostCatalog
+ * @returns {void}
+ */
+ _updateHostCatalog(hostCatalog) {
+ this._hostCatalog = {...this._hostCatalog, ...hostCatalog};
+ },
+
/**
* Update a list of `serviceUrls` to the most current
* catalog via the defined `discoveryUrl` then returns the current
@@ -671,6 +682,7 @@ const Services = WebexPlugin.extend({
* @returns {object}
*/
_formatReceivedHostmap(serviceHostmap) {
+ this._updateHostCatalog(serviceHostmap.hostCatalog);
// map the host catalog items to a formatted hostmap
const formattedHostmap = Object.keys(serviceHostmap.hostCatalog).reduce((accumulator, key) => {
if (serviceHostmap.hostCatalog[key].length === 0) {
diff --git a/packages/@webex/webex-core/test/unit/spec/services/services.js b/packages/@webex/webex-core/test/unit/spec/services/services.js
index c1080544dac..65aba3ee9ea 100644
--- a/packages/@webex/webex-core/test/unit/spec/services/services.js
+++ b/packages/@webex/webex-core/test/unit/spec/services/services.js
@@ -298,6 +298,12 @@ describe('webex-core', () => {
formattedHM.map((item) => item.name)
);
});
+
+ it('has hostCatalog updated', () => {
+ services._formatReceivedHostmap(serviceHostmap);
+
+ assert.deepStrictEqual(services._hostCatalog, serviceHostmap.hostCatalog);
+ });
});
describe('#updateCredentialsConfig()', () => {
diff --git a/packages/calling/cspell.json b/packages/calling/cspell.json
index 78c39df10ae..54bc6058355 100644
--- a/packages/calling/cspell.json
+++ b/packages/calling/cspell.json
@@ -30,7 +30,6 @@
"callprogress",
"causecode",
"cimg",
- "circleci",
"codecov",
"commitlint",
"dependabot",
diff --git a/packages/calling/package.json b/packages/calling/package.json
index fc9c3d23394..a4206cbf8b7 100644
--- a/packages/calling/package.json
+++ b/packages/calling/package.json
@@ -5,6 +5,7 @@
],
"contributors": [
"Bhargav Chinta (bchinta@cisco.com)",
+ "Karthik Raji (karaji@cisco.com)",
"Priya Kesari (pkesari@cisco.com)",
"Rajesh Kumar (rarajes2@cisco.com)",
"Shreyas Sharma (shreysh2@cisco.com)",
@@ -37,7 +38,7 @@
},
"dependencies": {
"@types/platform": "1.3.4",
- "@webex/internal-media-core": "2.0.0",
+ "@webex/internal-media-core": "2.2.2",
"@webex/media-helpers": "workspace:^",
"async-mutex": "0.4.0",
"buffer": "6.0.3",
diff --git a/packages/calling/src/CallHistory/callHistoryFixtures.ts b/packages/calling/src/CallHistory/callHistoryFixtures.ts
index a61d44cf186..13755c4f176 100644
--- a/packages/calling/src/CallHistory/callHistoryFixtures.ts
+++ b/packages/calling/src/CallHistory/callHistoryFixtures.ts
@@ -311,7 +311,15 @@ const WEBEX_CALL_SESSION = {
'https://conv-a.wbx2.com/conversation/api/v1/conversations/c9252ff0-9de2-11ec-a582-59d00c02cca9',
callbackAddress: '123-456-7890',
},
-
+ callingSpecifics: {
+ redirectionDetails: {
+ phoneNumber: '+18308508011',
+ name: 'Test QA Call Center',
+ reason: 'CALLQUEUE',
+ userId: '604a966d-7518-4b74-8d78-6c05caf98239',
+ isPrivate: false,
+ },
+ },
isDeleted: false,
isPMR: false,
correlationIds: ['58ea6cd9-852b-4a77-957f-e704c8b0e63e'],
diff --git a/packages/calling/src/CallingClient/CallingClient.test.ts b/packages/calling/src/CallingClient/CallingClient.test.ts
index ad3e507ea7d..ae9f0d6bd28 100644
--- a/packages/calling/src/CallingClient/CallingClient.test.ts
+++ b/packages/calling/src/CallingClient/CallingClient.test.ts
@@ -6,7 +6,7 @@ import {
getMockDeviceInfo,
getMobiusDiscoveryResponse,
} from '../common/testUtil';
-import {CallType, MobiusStatus, ServiceIndicator, WebexRequestPayload} from '../common/types';
+import {CallType, RegistrationStatus, ServiceIndicator, WebexRequestPayload} from '../common/types';
/* eslint-disable dot-notation */
import {CALLING_CLIENT_EVENT_KEYS, CallSessionEvent, MOBIUS_EVENT_KEYS} from '../Events/types';
import log from '../Logger';
@@ -17,13 +17,15 @@ import {getCallManager} from './calling/callManager';
import {
CALLING_CLIENT_FILE,
DISCOVERY_URL,
+ IP_ENDPOINT,
NETWORK_CHANGE_DETECTION_UTIL,
NETWORK_FLAP_TIMEOUT,
REGISTRATION_FILE,
SPARK_USER_AGENT,
+ URL_ENDPOINT,
} from './constants';
import {MOCK_MULTIPLE_SESSIONS_EVENT, MOCK_SESSION_EVENT} from './callRecordFixtures';
-import {ILine, LineStatus} from './line/types';
+import {ILine} from './line/types';
import {
ipPayload,
regionBody,
@@ -31,19 +33,27 @@ import {
primaryUrl,
discoveryPayload,
registrationPayload,
- uri,
myIP,
+ mockEUServiceHosts,
+ mockIntServiceHosts,
+ mockEUIntServiceHosts,
+ mockCatalogEU,
+ mockCatalogUSInt,
+ mockCatalogUS,
+ mockCatalogEUInt,
} from './callingClientFixtures';
import Line from './line';
import {filterMobiusUris} from '../common/Utils';
import {URL} from './registration/registerFixtures';
import {ICall} from './calling/types';
+import {ServiceHost} from '../SDKConnector/types';
describe('CallingClient Tests', () => {
// Common initializers
const handleErrorSpy = jest.spyOn(utils, 'handleCallingClientErrors');
const webex = getTestUtilsWebex();
+ webex.internal.services['_hostCatalog'] = mockCatalogUS;
const defaultServiceIndicator = ServiceIndicator.CALLING;
const callManager = getCallManager(webex, defaultServiceIndicator);
@@ -226,7 +236,7 @@ describe('CallingClient Tests', () => {
expect(webex.request).nthCalledWith(1, {
method: 'GET',
...getMockRequestTemplate(),
- uri: `${uri}myip`,
+ uri: `${callingClient['mobiusHost']}${URL_ENDPOINT}${IP_ENDPOINT}`,
});
expect(webex.request).nthCalledWith(2, {
@@ -241,7 +251,7 @@ describe('CallingClient Tests', () => {
expect(webex.request).nthCalledWith(3, {
method: 'GET',
...getMockRequestTemplate(),
- uri: `${uri}?regionCode=${regionBody.clientRegion}&countryCode=${regionBody.countryCode}`,
+ uri: `${callingClient['mobiusHost']}${URL_ENDPOINT}?regionCode=${regionBody.clientRegion}&countryCode=${regionBody.countryCode}`,
});
});
@@ -254,27 +264,41 @@ describe('CallingClient Tests', () => {
callingClient = await createClient(webex, {logger: {level: LOGGER.INFO}});
- expect(handleErrorSpy).toBeCalledOnceWith(failurePayload, expect.anything(), {
- file: CALLING_CLIENT_FILE,
- method: 'getMobiusServers',
+ expect(webex.request).nthCalledWith(1, {
+ ...getMockRequestTemplate(),
+ uri: 'https://mobius-us-east-1.prod.infra.webex.com/api/v1/calling/web/myip',
+ method: 'GET',
});
- expect(webex.request).toBeCalledOnceWith({
+ expect(webex.request).nthCalledWith(2, {
...getMockRequestTemplate(),
- uri: `${uri}myip`,
+ uri: 'https://mobius-ca-central-1.prod.infra.webex.com/api/v1/calling/web/myip',
method: 'GET',
});
- expect(callingClient.primaryMobiusUris).toEqual([uri]);
-
- expect(webex.request).nthCalledWith(1, {
+ expect(webex.request).nthCalledWith(3, {
+ ...getMockRequestTemplate(),
+ uri: 'https://mobius-eu-central-1.prod.infra.webex.com/api/v1/calling/web/myip',
method: 'GET',
+ });
+
+ expect(webex.request).nthCalledWith(4, {
...getMockRequestTemplate(),
- uri: `${uri}myip`,
+ uri: 'https://mobius-ap-southeast-2.prod.infra.webex.com/api/v1/calling/web/myip',
+ method: 'GET',
+ });
+
+ expect(handleErrorSpy).toBeCalledWith(failurePayload, expect.anything(), {
+ file: CALLING_CLIENT_FILE,
+ method: 'getMobiusServers',
});
+ expect(callingClient.primaryMobiusUris).toEqual([
+ `${callingClient['mobiusHost']}${URL_ENDPOINT}`,
+ ]);
+
expect(warnSpy).toBeCalledWith(
- 'Error in finding Mobius Servers. Will use the default URL.',
+ `Couldn't resolve the region and country code. Defaulting to the catalog entries to discover mobius servers`,
''
);
});
@@ -297,12 +321,14 @@ describe('CallingClient Tests', () => {
});
expect(webex.request).toBeCalledTimes(3);
- expect(callingClient.primaryMobiusUris).toEqual([uri]);
+ expect(callingClient.primaryMobiusUris).toEqual([
+ `${callingClient['mobiusHost']}${URL_ENDPOINT}`,
+ ]);
expect(webex.request).nthCalledWith(1, {
method: 'GET',
...getMockRequestTemplate(),
- uri: `${uri}myip`,
+ uri: `${callingClient['mobiusHost']}${URL_ENDPOINT}${IP_ENDPOINT}`,
});
expect(webex.request).nthCalledWith(2, {
@@ -315,7 +341,7 @@ describe('CallingClient Tests', () => {
});
expect(warnSpy).toBeCalledWith(
- 'Error in finding Mobius Servers. Will use the default URL.',
+ `Couldn't resolve the region and country code. Defaulting to the catalog entries to discover mobius servers`,
''
);
});
@@ -342,13 +368,47 @@ describe('CallingClient Tests', () => {
});
expect(webex.request).toBeCalledOnceWith({
...getMockRequestTemplate(),
- uri: `${uri}?regionCode=${regionBody.clientRegion}&countryCode=${regionBody.countryCode}`,
+ uri: `${callingClient['mobiusHost']}${URL_ENDPOINT}?regionCode=${regionBody.clientRegion}&countryCode=${regionBody.countryCode}`,
method: 'GET',
});
expect(handleErrorSpy).not.toBeCalled();
});
});
+ describe('Testing each cluster present withing host catalog', () => {
+ const mobiusCluster = [
+ 'mobius-eu-central-1.prod.infra.webex.com',
+ 'mobius-us-east-1.int.infra.webex.com',
+ 'mobius-eu-central-1.int.infra.webex.com',
+ ];
+
+ const checkCluster = async (
+ mockServiceHosts: ServiceHost[],
+ mockCatalog: Record
+ ) => {
+ webex.internal.services._hostCatalog = mockCatalog;
+ const callingClient = await createClient(webex, {logger: {level: LOGGER.INFO}});
+
+ expect(callingClient['mobiusClusters']).toStrictEqual(mockServiceHosts);
+ };
+
+ it.each(mobiusCluster)('%s', async (clusterName) => {
+ switch (clusterName) {
+ case 'mobius-eu-central-1.prod.infra.webex.com':
+ checkCluster(mockEUServiceHosts, mockCatalogEU);
+ break;
+ case 'mobius-us-east-1.int.infra.webex.com':
+ checkCluster(mockIntServiceHosts, mockCatalogUSInt);
+ break;
+ case 'mobius-eu-central-1.int.infra.webex.com':
+ checkCluster(mockEUIntServiceHosts, mockCatalogEUInt);
+ break;
+ default:
+ break;
+ }
+ });
+ });
+
describe('Network activity detection tests', () => {
let callingClient;
let line;
@@ -370,8 +430,6 @@ describe('CallingClient Tests', () => {
callingClient = await createClient(webex, {logger: {level: LOGGER.INFO}});
line = Object.values(callingClient.lineDict)[0] as ILine;
reg = line.registration;
-
- expect(line.getRegistrationStatus()).toEqual(MobiusStatus.DEFAULT);
await line.register();
deRegSpy = jest.spyOn(line.registration, 'deregister');
@@ -390,7 +448,7 @@ describe('CallingClient Tests', () => {
});
it('detect a network flap in mercury connection', async () => {
- expect(line.getRegistrationStatus()).toEqual(MobiusStatus.ACTIVE);
+ expect(line.getStatus()).toEqual(RegistrationStatus.ACTIVE);
/* Set mercury connection to be down and execute a delay of 2.5 seconds */
webex.internal.mercury.connected = false;
@@ -398,7 +456,7 @@ describe('CallingClient Tests', () => {
jest.advanceTimersByTime(NETWORK_FLAP_TIMEOUT + 500);
/* We should be detecting the network flap */
- expect(warnSpy).toBeCalledWith(
+ expect(warnSpy).toBeCalledOnceWith(
'Network has flapped, waiting for mercury connection to be up',
{file: CALLING_CLIENT_FILE, method: NETWORK_CHANGE_DETECTION_UTIL}
);
@@ -411,13 +469,14 @@ describe('CallingClient Tests', () => {
await flushPromises();
/* We should be detecting the network recovery */
- expect(logSpy).nthCalledWith(
- 7,
- 'Mercury connection is up again, Re-registering with Mobius',
- {file: REGISTRATION_FILE, method: 'handleConnectionRestoration'}
+ expect(logSpy).toBeCalledWith(
+ 'Mercury connection is up again, re-registering with Webex Calling if needed',
+ {
+ file: REGISTRATION_FILE,
+ method: 'handleConnectionRestoration',
+ }
);
- expect(deRegSpy).toBeCalledWith();
expect(restoreSpy).toBeCalledWith('handleConnectionRestoration');
expect(restartRegisterSpy).toBeCalledWith('handleConnectionRestoration');
expect(webex.request).toBeCalledTimes(6);
@@ -426,7 +485,7 @@ describe('CallingClient Tests', () => {
});
it('Simulate a network flap with no active calls and re-verify registration: Restore Failure', async () => {
- expect(line.getRegistrationStatus()).toEqual(MobiusStatus.ACTIVE);
+ expect(line.getStatus()).toEqual(RegistrationStatus.ACTIVE);
const failurePayload = ({
statusCode: 500,
@@ -453,37 +512,37 @@ describe('CallingClient Tests', () => {
/* Set mercury connection to be up and execute a delay of 2.5 seconds */
webex.internal.mercury.connected = true;
+
jest.advanceTimersByTime(NETWORK_FLAP_TIMEOUT + 500);
await flushPromises();
+
/* We should be detecting the network recovery */
- expect(logSpy).toBeCalledWith('Mercury connection is up again, Re-registering with Mobius', {
- file: REGISTRATION_FILE,
- method: 'handleConnectionRestoration',
- });
+ expect(logSpy).toBeCalledWith(
+ 'Mercury connection is up again, re-registering with Webex Calling if needed',
+ {
+ file: REGISTRATION_FILE,
+ method: 'handleConnectionRestoration',
+ }
+ );
- expect(deRegSpy).toBeCalledWith();
- expect(restoreSpy).toBeCalledWith('handleConnectionRestoration');
- expect(restartRegisterSpy).toBeCalledWith('handleConnectionRestoration');
+ expect(restoreSpy).toBeCalledOnceWith('handleConnectionRestoration');
+ expect(restartRegisterSpy).toBeCalledOnceWith('handleConnectionRestoration');
expect(webex.request).toBeCalledTimes(6);
expect(registerSpy).toBeCalledWith('handleConnectionRestoration', [reg.getActiveMobiusUrl()]);
expect(registerSpy).lastCalledWith('handleConnectionRestoration', [primaryUrl]);
});
it('Simulate a network flap before initial registration is done', async () => {
- expect(line.getRegistrationStatus()).toEqual(MobiusStatus.ACTIVE);
-
- reg.deregister();
- reg.setActiveMobiusUrl(undefined);
-
- jest.clearAllMocks();
+ const handleConnectionRestoreSpy = jest.spyOn(reg, 'handleConnectionRestoration');
+ reg.setStatus(RegistrationStatus.IDLE);
/* Set mercury connection to be down and execute a delay of 2.5 seconds */
webex.internal.mercury.connected = false;
jest.advanceTimersByTime(NETWORK_FLAP_TIMEOUT + 500);
/* We should be detecting the network flap */
- expect(warnSpy).toBeCalledWith(
+ expect(warnSpy).toBeCalledOnceWith(
'Network has flapped, waiting for mercury connection to be up',
{file: CALLING_CLIENT_FILE, method: NETWORK_CHANGE_DETECTION_UTIL}
);
@@ -495,22 +554,23 @@ describe('CallingClient Tests', () => {
await flushPromises();
/* We should be detecting the network recovery */
- expect(logSpy).toBeCalledWith('Mercury connection is up again, Re-registering with Mobius', {
- file: REGISTRATION_FILE,
- method: 'handleConnectionRestoration',
- });
+ expect(logSpy).not.toBeCalledWith(
+ 'Mercury connection is up again, re-registering with Webex Calling if needed',
+ {
+ file: REGISTRATION_FILE,
+ method: 'handleConnectionRestoration',
+ }
+ );
/*
* When initial registration is not done, network flap
* will not trigger de-registration/registration
*/
- expect(webex.request).not.toBeCalled();
- expect(restoreSpy).not.toBeCalled();
- expect(registerSpy).not.toBeCalled();
+ expect(handleConnectionRestoreSpy).not.toBeCalledOnceWith();
});
it('Simulate a network flap with 1 active call', async () => {
- expect(line.getRegistrationStatus()).toEqual(MobiusStatus.ACTIVE);
+ expect(line.getStatus()).toEqual(RegistrationStatus.ACTIVE);
/** create a new call */
reg.callManager.createCall();
@@ -522,7 +582,7 @@ describe('CallingClient Tests', () => {
await flushPromises();
/* We should be detecting the network flap */
- expect(warnSpy).not.toBeCalledWith(
+ expect(warnSpy).not.toBeCalledOnceWith(
'Network has flapped, waiting for mercury connection to be up',
{file: CALLING_CLIENT_FILE, method: 'handleConnectionRestoration'}
);
@@ -534,8 +594,8 @@ describe('CallingClient Tests', () => {
await flushPromises();
/* We should be detecting the network recovery */
- expect(logSpy).not.toBeCalledWith(
- 'Mercury connection is up again, Re-registering with Mobius',
+ expect(logSpy).not.toBeCalledOnceWith(
+ 'Mercury connection is up again, re-registering with Webex Calling if needed',
{file: REGISTRATION_FILE, method: 'handleConnectionRestoration'}
);
@@ -590,7 +650,6 @@ describe('CallingClient Tests', () => {
line = new Line(
userId,
clientDeviceUri,
- LineStatus.ACTIVE,
mutex,
primaryMobiusUris(),
backupMobiusUris(),
diff --git a/packages/calling/src/CallingClient/CallingClient.ts b/packages/calling/src/CallingClient/CallingClient.ts
index eb9d04078f8..938ef3ecf92 100644
--- a/packages/calling/src/CallingClient/CallingClient.ts
+++ b/packages/calling/src/CallingClient/CallingClient.ts
@@ -6,7 +6,7 @@ import {Mutex} from 'async-mutex';
import {filterMobiusUris, handleCallingClientErrors, validateServiceData} from '../common/Utils';
import {LOGGER, LogContext} from '../Logger/types';
import SDKConnector from '../SDKConnector';
-import {ClientRegionInfo, ISDKConnector, WebexSDK} from '../SDKConnector/types';
+import {ClientRegionInfo, ISDKConnector, ServiceHost, WebexSDK} from '../SDKConnector/types';
import {Eventing} from '../Events/impl';
import {
CallingClientEventTypes,
@@ -23,6 +23,7 @@ import {
IpInfo,
MobiusServers,
WebexRequestPayload,
+ RegistrationStatus,
} from '../common/types';
import {ICallingClient, CallingClientConfig} from './types';
import {ICall, ICallManager} from './calling/types';
@@ -39,9 +40,14 @@ import {
SPARK_USER_AGENT,
URL_ENDPOINT,
NETWORK_FLAP_TIMEOUT,
+ API_V1,
+ MOBIUS_US_PROD,
+ MOBIUS_EU_PROD,
+ MOBIUS_US_INT,
+ MOBIUS_EU_INT,
} from './constants';
import Line from './line';
-import {ILine, LINE_EVENTS, LineStatus} from './line/types';
+import {ILine, LINE_EVENTS} from './line/types';
import {METRIC_EVENT, REG_ACTION, METRIC_TYPE, IMetricManager} from '../Metrics/types';
import {getMetricManager} from '../Metrics';
@@ -73,6 +79,10 @@ export class CallingClient extends Eventing implements
private backupMobiusUris: string[];
+ private mobiusClusters: ServiceHost[];
+
+ private mobiusHost: string;
+
public mediaEngine: typeof Media;
private lineDict: Record = {};
@@ -105,6 +115,12 @@ export class CallingClient extends Eventing implements
this.primaryMobiusUris = [];
this.backupMobiusUris = [];
+ this.mobiusClusters =
+ this.webex.internal.services._hostCatalog[MOBIUS_US_PROD] ||
+ this.webex.internal.services._hostCatalog[MOBIUS_EU_PROD] ||
+ this.webex.internal.services._hostCatalog[MOBIUS_US_INT] ||
+ this.webex.internal.services._hostCatalog[MOBIUS_EU_INT];
+ this.mobiusHost = '';
this.registerSessionsListener();
@@ -156,14 +172,17 @@ export class CallingClient extends Eventing implements
method: this.detectNetworkChange.name,
});
- line.lineEmitter(LINE_EVENTS.UNREGISTERED);
line.registration.clearKeepaliveTimer();
retry = true;
}
if (retry && this.webex.internal.mercury.connected) {
- retry = await line.registration.handleConnectionRestoration(retry);
+ if (line.getStatus() !== RegistrationStatus.IDLE) {
+ retry = await line.registration.handleConnectionRestoration(retry);
+ } else {
+ retry = false;
+ }
}
}, NETWORK_FLAP_TIMEOUT);
}
@@ -174,48 +193,57 @@ export class CallingClient extends Eventing implements
private async getClientRegionInfo(): Promise {
const regionInfo = {} as RegionInfo;
- try {
- const temp = await this.webex.request({
- uri: `${this.webex.internal.services._serviceUrls.mobius}${URL_ENDPOINT}${IP_ENDPOINT}`,
- method: HTTP_METHODS.GET,
- headers: {
- [CISCO_DEVICE_URL]: this.webex.internal.device.url,
- [SPARK_USER_AGENT]: CALLING_USER_AGENT,
- },
- service: ALLOWED_SERVICES.MOBIUS,
- });
+ for (const mobius of this.mobiusClusters) {
+ this.mobiusHost = `https://${mobius.host}${API_V1}`;
- const myIP = (temp.body as IpInfo).ipv4;
- const response = await this.webex.request({
- uri: `${DISCOVERY_URL}/${myIP}`,
- method: HTTP_METHODS.GET,
- addAuthHeader: false,
- headers: {
- [SPARK_USER_AGENT]: null,
- },
- });
+ try {
+ // eslint-disable-next-line no-await-in-loop
+ const temp = await this.webex.request({
+ uri: `${this.mobiusHost}${URL_ENDPOINT}${IP_ENDPOINT}`,
+ method: HTTP_METHODS.GET,
+ headers: {
+ [CISCO_DEVICE_URL]: this.webex.internal.device.url,
+ [SPARK_USER_AGENT]: CALLING_USER_AGENT,
+ },
+ service: ALLOWED_SERVICES.MOBIUS,
+ });
- const clientRegionInfo = response.body as ClientRegionInfo;
-
- regionInfo.clientRegion = clientRegionInfo?.clientRegion ? clientRegionInfo.clientRegion : '';
-
- regionInfo.countryCode = clientRegionInfo?.countryCode ? clientRegionInfo.countryCode : '';
- } catch (err: unknown) {
- handleCallingClientErrors(
- err as WebexRequestPayload,
- (clientError) => {
- this.metricManager.submitRegistrationMetric(
- METRIC_EVENT.REGISTRATION_ERROR,
- REG_ACTION.REGISTER,
- METRIC_TYPE.BEHAVIORAL,
- clientError
- );
- this.emit(CALLING_CLIENT_EVENT_KEYS.ERROR, clientError);
- },
- {method: GET_MOBIUS_SERVERS_UTIL, file: CALLING_CLIENT_FILE}
- );
- regionInfo.clientRegion = '';
- regionInfo.countryCode = '';
+ const myIP = (temp.body as IpInfo).ipv4;
+ // eslint-disable-next-line no-await-in-loop
+ const response = await this.webex.request({
+ uri: `${DISCOVERY_URL}/${myIP}`,
+ method: HTTP_METHODS.GET,
+ addAuthHeader: false,
+ headers: {
+ [SPARK_USER_AGENT]: null,
+ },
+ });
+
+ const clientRegionInfo = response.body as ClientRegionInfo;
+
+ regionInfo.clientRegion = clientRegionInfo?.clientRegion
+ ? clientRegionInfo.clientRegion
+ : '';
+
+ regionInfo.countryCode = clientRegionInfo?.countryCode ? clientRegionInfo.countryCode : '';
+ break;
+ } catch (err: unknown) {
+ handleCallingClientErrors(
+ err as WebexRequestPayload,
+ (clientError) => {
+ this.metricManager.submitRegistrationMetric(
+ METRIC_EVENT.REGISTRATION_ERROR,
+ REG_ACTION.REGISTER,
+ METRIC_TYPE.BEHAVIORAL,
+ clientError
+ );
+ this.emit(CALLING_CLIENT_EVENT_KEYS.ERROR, clientError);
+ },
+ {method: GET_MOBIUS_SERVERS_UTIL, file: CALLING_CLIENT_FILE}
+ );
+ regionInfo.clientRegion = '';
+ regionInfo.countryCode = '';
+ }
}
return regionInfo;
@@ -246,6 +274,7 @@ export class CallingClient extends Eventing implements
});
clientRegion = this.sdkConfig?.discovery?.region;
countryCode = this.sdkConfig?.discovery?.country;
+ this.mobiusHost = this.webex.internal.services._serviceUrls.mobius;
} else {
log.info('Updating region and country through Region discovery', {
file: CALLING_CLIENT_FILE,
@@ -265,8 +294,9 @@ export class CallingClient extends Eventing implements
);
try {
+ // eslint-disable-next-line no-await-in-loop
const temp = await this.webex.request({
- uri: `${this.webex.internal.services._serviceUrls.mobius}${URL_ENDPOINT}?regionCode=${clientRegion}&countryCode=${countryCode}`,
+ uri: `${this.mobiusHost}${URL_ENDPOINT}?regionCode=${clientRegion}&countryCode=${countryCode}`,
method: HTTP_METHODS.GET,
headers: {
[CISCO_DEVICE_URL]: this.webex.internal.device.url,
@@ -279,10 +309,7 @@ export class CallingClient extends Eventing implements
const mobiusServers = temp.body as MobiusServers;
/* update arrays of Mobius Uris. */
- const mobiusUris = filterMobiusUris(
- mobiusServers,
- this.webex.internal.services._serviceUrls.mobius
- );
+ const mobiusUris = filterMobiusUris(mobiusServers, this.mobiusHost);
this.primaryMobiusUris = mobiusUris.primary;
this.backupMobiusUris = mobiusUris.backup;
log.info(
@@ -316,10 +343,12 @@ export class CallingClient extends Eventing implements
*/
if (useDefault) {
- log.warn('Error in finding Mobius Servers. Will use the default URL.', '' as LogContext);
- this.primaryMobiusUris = [
- `${this.webex.internal.services._serviceUrls.mobius}${URL_ENDPOINT}`,
- ];
+ log.warn(
+ `Couldn't resolve the region and country code. Defaulting to the catalog entries to discover mobius servers`,
+ '' as LogContext
+ );
+ this.mobiusHost = `https://${this.mobiusClusters[0].host}${API_V1}`;
+ this.primaryMobiusUris = [`${this.mobiusHost}${URL_ENDPOINT}`];
}
}
@@ -411,7 +440,6 @@ export class CallingClient extends Eventing implements
const line = new Line(
this.webex.internal.device.userId,
this.webex.internal.device.url,
- LineStatus.INACTIVE,
this.mutex,
this.primaryMobiusUris,
this.backupMobiusUris,
diff --git a/packages/calling/src/CallingClient/calling/CallerId/index.ts b/packages/calling/src/CallingClient/calling/CallerId/index.ts
index 88b7b385997..e78e5470bbd 100644
--- a/packages/calling/src/CallingClient/calling/CallerId/index.ts
+++ b/packages/calling/src/CallingClient/calling/CallerId/index.ts
@@ -138,10 +138,6 @@ export class CallerId implements ICallerId {
if (nameMatch) {
result.name = nameMatch[0].trimEnd();
- log.info(`Parsed Name: ${result.name}`, {
- file: CALLER_ID_FILE,
- method: 'parseSipUri',
- });
} else {
log.warn(`Name field not found!`, {
file: CALLER_ID_FILE,
@@ -153,10 +149,6 @@ export class CallerId implements ICallerId {
if (phoneMatch && phoneMatch[0].length === num.length) {
result.num = num;
- log.info(`Parsed Number: ${result.num}`, {
- file: CALLER_ID_FILE,
- method: 'parseSipUri',
- });
} else {
log.warn(`Number field not found!`, {
file: CALLER_ID_FILE,
@@ -183,7 +175,7 @@ export class CallerId implements ICallerId {
this.callerInfo.num = undefined;
if ('p-asserted-identity' in callerId) {
- log.info(`Parsing p-asserted-identity:- ${callerId['p-asserted-identity']}`, {
+ log.info('Parsing p-asserted-identity within remote party information', {
file: CALLER_ID_FILE,
method: 'fetchCallerDetails',
});
@@ -192,29 +184,16 @@ export class CallerId implements ICallerId {
/* For P-Asserted-Identity, we update the callerInfo blindly, as it is of highest preference */
this.callerInfo.name = result.name;
this.callerInfo.num = result.num;
-
- log.info(
- `CallerId retrieved from p-asserted-identity: name: ${this.callerInfo.name} , num: ${this.callerInfo.num}`,
- {
- file: CALLER_ID_FILE,
- method: 'fetchCallerDetails',
- }
- );
}
if (callerId.from) {
- log.info(`Parsing from header:- ${callerId.from}`, {
+ log.info('Parsing from header within the remote party information', {
file: CALLER_ID_FILE,
method: 'fetchCallerDetails',
});
const result = this.parseSipUri(callerId.from);
- log.info(`CallerId retrieved from FROM: name: ${result.name} , num: ${result.num}`, {
- file: CALLER_ID_FILE,
- method: 'fetchCallerDetails',
- });
-
/* For From header , we should only update if not filled already by P-Asserted-Identity */
if (!this.callerInfo.name && result.name) {
log.info('Updating name field from From header', {
@@ -241,25 +220,14 @@ export class CallerId implements ICallerId {
/* We need to parse x-broadworks-remote-party-info if present asynchronously */
if ('x-broadworks-remote-party-info' in callerId) {
- log.info(
- `Parsing x-broadworks-remote-party-info:- ${callerId['x-broadworks-remote-party-info']}`,
- {
- file: CALLER_ID_FILE,
- method: 'fetchCallerDetails',
- }
- );
+ log.info('Parsing x-broadworks-remote-party-info within remote party information', {
+ file: CALLER_ID_FILE,
+ method: 'fetchCallerDetails',
+ });
this.parseRemotePartyInfo(callerId['x-broadworks-remote-party-info'] as string);
}
- log.log(
- `Intermediate callerId :- name: ${this.callerInfo.name} , num: ${this.callerInfo.num}`,
- {
- file: CALLER_ID_FILE,
- method: 'fetchCallerDetails',
- }
- );
-
return this.callerInfo;
}
}
diff --git a/packages/calling/src/CallingClient/calling/call.test.ts b/packages/calling/src/CallingClient/calling/call.test.ts
index 90c92dee6f6..723964aa6b1 100644
--- a/packages/calling/src/CallingClient/calling/call.test.ts
+++ b/packages/calling/src/CallingClient/calling/call.test.ts
@@ -168,6 +168,7 @@ describe('Call Tests', () => {
outputStream: {
getAudioTracks: jest.fn().mockReturnValue([mockTrack]),
},
+ on: jest.fn(),
};
const localAudioStream = mockStream as unknown as MediaSDK.LocalMicrophoneStream;
@@ -452,6 +453,163 @@ describe('Call Tests', () => {
call.getCorrelationId()
);
});
+
+ it('answer fails if localAudioTrack is empty', async () => {
+ const mockStream = {
+ outputStream: {
+ getAudioTracks: jest.fn().mockReturnValue([]),
+ },
+ on: jest.fn(),
+ };
+
+ const localAudioStream = mockStream as unknown as MediaSDK.LocalMicrophoneStream;
+ webex.request.mockReturnValue({
+ statusCode: 200,
+ body: {
+ device: {
+ deviceId: '8a67806f-fc4d-446b-a131-31e71ea5b010',
+ correlationId: '8a67806f-fc4d-446b-a131-31e71ea5b011',
+ },
+ callId: '8a67806f-fc4d-446b-a131-31e71ea5b020',
+ },
+ });
+
+ const warnSpy = jest.spyOn(log, 'warn');
+ const call = createCall(
+ activeUrl,
+ webex,
+ dest,
+ CallDirection.OUTBOUND,
+ deviceId,
+ mockLineId,
+ deleteCallFromCollection,
+ defaultServiceIndicator
+ );
+
+ call.answer(localAudioStream);
+
+ await waitForMsecs(50);
+ expect(warnSpy).toBeCalledTimes(2);
+ expect(warnSpy).toBeCalledWith(
+ `Did not find a local track while answering the call ${call.getCorrelationId()}`,
+ {file: 'call', method: 'answer'}
+ );
+ expect(call['callStateMachine'].state.value).toBe('S_CALL_CLEARED');
+ expect(call['mediaStateMachine'].state.value).toBe('S_ROAP_IDLE');
+
+ expect(call.getDisconnectReason().code).toBe(DisconnectCode.MEDIA_INACTIVITY);
+ expect(call.getDisconnectReason().cause).toBe(DisconnectCause.MEDIA_INACTIVITY);
+
+ expect(webex.request.mock.calls[0][0].body.metrics).toStrictEqual(disconnectStats);
+ });
+
+ it('dial fails if localAudioTrack is empty', async () => {
+ const mockStream = {
+ outputStream: {
+ getAudioTracks: jest.fn().mockReturnValue([]),
+ },
+ on: jest.fn(),
+ };
+
+ const localAudioStream = mockStream as unknown as MediaSDK.LocalMicrophoneStream;
+
+ const warnSpy = jest.spyOn(log, 'warn');
+ const call = createCall(
+ activeUrl,
+ webex,
+ dest,
+ CallDirection.OUTBOUND,
+ deviceId,
+ mockLineId,
+ deleteCallFromCollection,
+ defaultServiceIndicator
+ );
+
+ call.dial(localAudioStream);
+
+ await waitForMsecs(50);
+ expect(warnSpy).toBeCalledTimes(1);
+ expect(warnSpy).toBeCalledWith(
+ `Did not find a local track while dialing the call ${call.getCorrelationId()}`,
+ {file: 'call', method: 'dial'}
+ );
+ expect(call['callStateMachine'].state.value).toBe('S_IDLE');
+ expect(call['mediaStateMachine'].state.value).toBe('S_ROAP_IDLE');
+
+ expect(webex.request).not.toBeCalledOnceWith();
+ });
+
+ it('update media after call creation with valid stream', () => {
+ const callManager = getCallManager(webex, defaultServiceIndicator);
+
+ const mockStream = {
+ outputStream: {
+ getAudioTracks: jest.fn().mockReturnValue([mockTrack]),
+ },
+ on: jest.fn(),
+ };
+
+ const localAudioStream = mockStream as unknown as MediaSDK.LocalMicrophoneStream;
+
+ const call = callManager.createCall(dest, CallDirection.OUTBOUND, deviceId, mockLineId);
+
+ call.dial(localAudioStream);
+
+ expect(mockTrack.enabled).toEqual(true);
+
+ const mockTrack2 = {
+ enabled: true,
+ };
+
+ const mockStream2 = {
+ outputStream: {
+ getAudioTracks: jest.fn().mockReturnValue([mockTrack2]),
+ },
+ on: jest.fn(),
+ };
+
+ const localAudioStream2 = mockStream2 as unknown as MediaSDK.LocalMicrophoneStream;
+
+ call.updateMedia(localAudioStream2);
+
+ expect(call['mediaConnection'].updateLocalTracks).toBeCalledOnceWith({audio: mockTrack2});
+ });
+
+ it('update media with invalid stream', () => {
+ const callManager = getCallManager(webex, defaultServiceIndicator);
+ const warnSpy = jest.spyOn(log, 'warn');
+
+ const mockStream = {
+ outputStream: {
+ getAudioTracks: jest.fn().mockReturnValue([mockTrack]),
+ },
+ on: jest.fn(),
+ };
+
+ const localAudioStream = mockStream as unknown as MediaSDK.LocalMicrophoneStream;
+
+ const call = callManager.createCall(dest, CallDirection.OUTBOUND, deviceId, mockLineId);
+
+ call.dial(localAudioStream);
+
+ expect(mockTrack.enabled).toEqual(true);
+
+ const errorStream = {
+ outputStream: {
+ getAudioTracks: jest.fn().mockReturnValue([]),
+ },
+ };
+
+ const localAudioStream2 = errorStream as unknown as MediaSDK.LocalMicrophoneStream;
+
+ call.updateMedia(localAudioStream2);
+
+ expect(call['mediaConnection'].updateLocalTracks).not.toBeCalled();
+ expect(warnSpy).toBeCalledOnceWith(
+ `Did not find a local track while updating media for call ${call.getCorrelationId()}. Will not update media`,
+ {file: 'call', method: 'updateMedia'}
+ );
+ });
});
describe('State Machine handler tests', () => {
@@ -1914,7 +2072,7 @@ describe('Supplementary Services tests', () => {
/* We should return back to call established state */
expect(call['callStateMachine'].state.value).toStrictEqual('S_CALL_ESTABLISHED');
- expect(warnSpy).toHaveBeenCalledWith('MediaOk failed with Mobius', {
+ expect(warnSpy).toHaveBeenCalledWith('Failed to process MediaOk request', {
file: 'call',
method: 'handleRoapEstablished',
});
@@ -1958,7 +2116,7 @@ describe('Supplementary Services tests', () => {
expect(call.isHeld()).toStrictEqual(true);
/* We should return back to call established state */
expect(call['callStateMachine'].state.value).toStrictEqual('S_CALL_ESTABLISHED');
- expect(warnSpy).toHaveBeenCalledWith('MediaOk failed with Mobius', {
+ expect(warnSpy).toHaveBeenCalledWith('Failed to process MediaOk request', {
file: 'call',
method: 'handleRoapEstablished',
});
diff --git a/packages/calling/src/CallingClient/calling/call.ts b/packages/calling/src/CallingClient/calling/call.ts
index eb853f443be..027775eb06e 100644
--- a/packages/calling/src/CallingClient/calling/call.ts
+++ b/packages/calling/src/CallingClient/calling/call.ts
@@ -6,6 +6,7 @@ import {
} from '@webex/internal-media-core';
import {createMachine, interpret} from 'xstate';
import {v4 as uuid} from 'uuid';
+import {EffectEvent, TrackEffect} from '@webex/web-media-effects';
import {ERROR_LAYER, ERROR_TYPE, ErrorContext} from '../../Errors/types';
import {handleCallErrors, parseMediaQualityStatistics} from '../../common/Utils';
import {
@@ -23,7 +24,6 @@ import {CallError, createCallError} from '../../Errors/catalog/CallError';
/* eslint-disable tsdoc/syntax */
/* eslint-disable no-param-reassign */
import {
- BACKGROUND_NOISE_REMOVAL,
CALL_ENDPOINT_RESOURCE,
CALL_FILE,
CALL_HOLD_SERVICE,
@@ -38,6 +38,7 @@ import {
HOLD_ENDPOINT,
INITIAL_SEQ_NUMBER,
MEDIA_ENDPOINT_RESOURCE,
+ NOISE_REDUCTION_EFFECT,
RESUME_ENDPOINT,
SPARK_USER_AGENT,
SUPPLEMENTARY_SERVICES_TIMEOUT,
@@ -127,6 +128,8 @@ export class Call extends Eventing implements ICall {
private connected: boolean;
+ private mediaInactivity: boolean;
+
private callerInfo: DisplayInformation;
private localRoapMessage: RoapMessage; // Use it for new offer
@@ -216,6 +219,7 @@ export class Call extends Eventing implements ICall {
this.correlationId = uuid();
this.deleteCb = deleteCb;
this.connected = false;
+ this.mediaInactivity = false;
this.held = false;
this.earlyMedia = false;
this.callerInfo = {} as DisplayInformation;
@@ -225,7 +229,7 @@ export class Call extends Eventing implements ICall {
this.receivedRoapOKSeq = 0;
this.mediaNegotiationCompleted = false;
- log.info(`Mobius Url:- ${this.mobiusUrl}`, {
+ log.info(`Webex Calling Url:- ${this.mobiusUrl}`, {
file: CALL_FILE,
method: 'constructor',
});
@@ -919,7 +923,7 @@ export class Call extends Eventing implements ICall {
});
this.setCallId(response.body.callId);
} catch (e) {
- log.warn('Call setup failed with Mobius', {
+ log.warn('Failed to setup the call', {
file: CALL_FILE,
method: this.handleOutgoingCallSetup.name,
});
@@ -988,7 +992,7 @@ export class Call extends Eventing implements ICall {
}, SUPPLEMENTARY_SERVICES_TIMEOUT);
}
} catch (e) {
- log.warn('Call Hold failed with Mobius', {
+ log.warn('Failed to put the call on hold', {
file: CALL_FILE,
method: this.handleCallHold.name,
});
@@ -1057,7 +1061,7 @@ export class Call extends Eventing implements ICall {
}, SUPPLEMENTARY_SERVICES_TIMEOUT);
}
} catch (e) {
- log.warn('Call Resume failed with Mobius', {
+ log.warn('Failed to resume the call', {
file: CALL_FILE,
method: this.handleCallResume.name,
});
@@ -1175,7 +1179,7 @@ export class Call extends Eventing implements ICall {
method: this.handleOutgoingCallAlerting.name,
});
} catch (err) {
- log.warn('Call Progress failed with Mobius', {
+ log.warn('Failed to signal call progression', {
file: CALL_FILE,
method: this.handleOutgoingCallAlerting.name,
});
@@ -1242,18 +1246,19 @@ export class Call extends Eventing implements ICall {
return;
}
- /* send call_connect PATCH */
try {
+ /* Start Offer/Answer as we might have buffered the offer by now */
+ this.mediaConnection.roapMessageReceived(this.remoteRoapMessage);
+
+ /* send call_connect PATCH */
const res = await this.patch(MobiusCallState.CONNECTED);
log.log(`PATCH response: ${res.statusCode}`, {
file: CALL_FILE,
method: this.handleOutgoingCallConnect.name,
});
- /* Start Offer/Answer as we might have buffered the offer by now */
- this.mediaConnection.roapMessageReceived(this.remoteRoapMessage);
} catch (err) {
- log.warn('Call Connect failed with Mobius', {
+ log.warn('Failed to connect the call', {
file: CALL_FILE,
method: this.handleOutgoingCallConnect.name,
});
@@ -1298,7 +1303,7 @@ export class Call extends Eventing implements ICall {
method: this.handleIncomingCallDisconnect.name,
});
} catch (e) {
- log.warn('Delete Call failed with Mobius', {
+ log.warn('Failed to delete the call', {
file: CALL_FILE,
method: this.handleIncomingCallDisconnect.name,
});
@@ -1340,7 +1345,7 @@ export class Call extends Eventing implements ICall {
method: this.handleOutgoingCallDisconnect.name,
});
} catch (e) {
- log.warn('Delete Call failed with Mobius', {
+ log.warn('Failed to delete the call', {
file: CALL_FILE,
method: this.handleOutgoingCallDisconnect.name,
});
@@ -1474,7 +1479,7 @@ export class Call extends Eventing implements ICall {
method: this.handleUnknownState.name,
});
} catch (e) {
- log.warn('Delete Call failed with Mobius', {
+ log.warn('Failed to delete the call', {
file: CALL_FILE,
method: this.handleUnknownState.name,
});
@@ -1586,7 +1591,7 @@ export class Call extends Eventing implements ICall {
this.sendCallStateMachineEvt({type: 'E_CALL_ESTABLISHED'});
}
} catch (err) {
- log.warn('MediaOk failed with Mobius', {
+ log.warn('Failed to process MediaOk request', {
file: CALL_FILE,
method: 'handleRoapEstablished',
});
@@ -1665,7 +1670,7 @@ export class Call extends Eventing implements ICall {
method: this.handleRoapError.name,
});
} catch (err) {
- log.warn('Failed to communicate ROAP error with Mobius', {
+ log.warn('Failed to communicate ROAP error to Webex Calling', {
file: CALL_FILE,
method: this.handleRoapError.name,
});
@@ -1733,7 +1738,7 @@ export class Call extends Eventing implements ICall {
method: this.handleOutgoingRoapOffer.name,
});
} catch (err) {
- log.warn('MediaOk failed with Mobius', {
+ log.warn('Failed to process MediaOk request', {
file: CALL_FILE,
method: this.handleOutgoingRoapOffer.name,
});
@@ -1781,7 +1786,7 @@ export class Call extends Eventing implements ICall {
method: this.handleOutgoingRoapAnswer.name,
});
} catch (err) {
- log.warn('MediaAnswer failed with Mobius', {
+ log.warn('Failed to send MediaAnswer request', {
file: CALL_FILE,
method: this.handleOutgoingRoapAnswer.name,
});
@@ -1953,7 +1958,10 @@ export class Call extends Eventing implements ICall {
*
*/
private setDisconnectReason() {
- if (this.connected || this.direction === CallDirection.OUTBOUND) {
+ if (this.mediaInactivity) {
+ this.disconnectReason.code = DisconnectCode.MEDIA_INACTIVITY;
+ this.disconnectReason.cause = DisconnectCause.MEDIA_INACTIVITY;
+ } else if (this.connected || this.direction === CallDirection.OUTBOUND) {
this.disconnectReason.code = DisconnectCode.NORMAL;
this.disconnectReason.cause = DisconnectCause.NORMAL;
} else {
@@ -1978,6 +1986,18 @@ export class Call extends Eventing implements ICall {
*/
public async answer(localAudioStream: LocalMicrophoneStream) {
const localAudioTrack = localAudioStream.outputStream.getAudioTracks()[0];
+
+ if (!localAudioTrack) {
+ log.warn(`Did not find a local track while answering the call ${this.getCorrelationId()}`, {
+ file: CALL_FILE,
+ method: 'answer',
+ });
+ this.mediaInactivity = true;
+ this.sendCallStateMachineEvt({type: 'E_SEND_CALL_DISCONNECT'});
+
+ return;
+ }
+
localAudioTrack.enabled = true;
if (!this.mediaConnection) {
@@ -1988,7 +2008,7 @@ export class Call extends Eventing implements ICall {
}
if (this.callStateMachine.state.value === 'S_SEND_CALL_PROGRESS') {
- const effect = localAudioStream.getEffect(BACKGROUND_NOISE_REMOVAL);
+ const effect = localAudioStream.getEffectByKind(NOISE_REDUCTION_EFFECT);
if (effect && effect.isEnabled) {
this.metricManager.submitBNRMetric(
METRIC_EVENT.MEDIA,
@@ -2014,6 +2034,17 @@ export class Call extends Eventing implements ICall {
*/
public async dial(localAudioStream: LocalMicrophoneStream) {
const localAudioTrack = localAudioStream.outputStream.getAudioTracks()[0];
+ if (!localAudioTrack) {
+ log.warn(`Did not find a local track while dialing the call ${this.getCorrelationId()}`, {
+ file: CALL_FILE,
+ method: 'dial',
+ });
+
+ this.deleteCb(this.getCorrelationId());
+ this.emit(CALL_EVENT_KEYS.DISCONNECT, this.getCorrelationId());
+
+ return;
+ }
localAudioTrack.enabled = true;
if (!this.mediaConnection) {
@@ -2024,7 +2055,7 @@ export class Call extends Eventing implements ICall {
}
if (this.mediaStateMachine.state.value === 'S_ROAP_IDLE') {
- const effect = localAudioStream.getEffect(BACKGROUND_NOISE_REMOVAL);
+ const effect = localAudioStream.getEffectByKind(NOISE_REDUCTION_EFFECT);
if (effect && effect.isEnabled) {
this.metricManager.submitBNRMetric(
METRIC_EVENT.MEDIA,
@@ -2081,7 +2112,7 @@ export class Call extends Eventing implements ICall {
* @param state -.
*/
private async patch(state: MobiusCallState): Promise {
- log.info(`Send a PATCH for ${state} to mobius`, {
+ log.info(`Send a PATCH for ${state} to Webex Calling`, {
file: CALL_FILE,
method: this.patch.name,
});
@@ -2325,7 +2356,7 @@ export class Call extends Eventing implements ICall {
* @param roapMessage -.
*/
private async postMedia(roapMessage: RoapMessage): Promise {
- log.log('Posting message to mobius', {
+ log.log('Posting message to Webex Calling', {
file: CALL_FILE,
method: this.postMedia.name,
});
@@ -2429,26 +2460,30 @@ export class Call extends Eventing implements ICall {
}
private outputTrackUpdateListener(localAudioStream: LocalMicrophoneStream) {
- let effect;
- localAudioStream.on(LocalStreamEventNames.OutputTrackChange, (track: MediaStreamTrack) => {
- this.mediaConnection.updateLocalTracks({audio: track});
- effect = localAudioStream.getEffect(BACKGROUND_NOISE_REMOVAL);
- if (effect && effect.isEnabled) {
- this.metricManager.submitBNRMetric(
- METRIC_EVENT.MEDIA,
- MEDIA_EFFECT_ACTION.BNR_ENABLED,
- METRIC_TYPE.BEHAVIORAL,
- this.callId,
- this.correlationId
- );
- } else if (effect && !effect.isEnabled) {
- this.metricManager.submitBNRMetric(
- METRIC_EVENT.MEDIA,
- MEDIA_EFFECT_ACTION.BNR_DISABLED,
- METRIC_TYPE.BEHAVIORAL,
- this.callId,
- this.correlationId
- );
+ let effect: TrackEffect | undefined;
+ localAudioStream.on(LocalStreamEventNames.EffectAdded, (addedEffect: TrackEffect) => {
+ // this.mediaConnection.updateLocalTracks({audio: track});
+ effect = localAudioStream.getEffectByKind(NOISE_REDUCTION_EFFECT);
+ if (effect === addedEffect) {
+ effect.on(EffectEvent.Enabled, () => {
+ this.metricManager.submitBNRMetric(
+ METRIC_EVENT.MEDIA,
+ MEDIA_EFFECT_ACTION.BNR_ENABLED,
+ METRIC_TYPE.BEHAVIORAL,
+ this.callId,
+ this.correlationId
+ );
+ });
+
+ effect.on(EffectEvent.Disabled, () => {
+ this.metricManager.submitBNRMetric(
+ METRIC_EVENT.MEDIA,
+ MEDIA_EFFECT_ACTION.BNR_DISABLED,
+ METRIC_TYPE.BEHAVIORAL,
+ this.callId,
+ this.correlationId
+ );
+ });
}
});
}
@@ -2658,7 +2693,7 @@ export class Call extends Eventing implements ICall {
}
/**
- * .
+ * Mutes/Unmutes the call.
*
* @param localAudioTrack -.
*/
@@ -2673,6 +2708,32 @@ export class Call extends Eventing implements ICall {
}
};
+ /**
+ * Change the audio stream of the call.
+ *
+ * @param newAudioStream - The new audio stream to be used in the call.
+ */
+
+ public updateMedia = (newAudioStream: LocalMicrophoneStream): void => {
+ const localAudioTrack = newAudioStream.outputStream.getAudioTracks()[0];
+
+ if (!localAudioTrack) {
+ log.warn(
+ `Did not find a local track while updating media for call ${this.getCorrelationId()}. Will not update media`,
+ {
+ file: CALL_FILE,
+ method: 'updateMedia',
+ }
+ );
+
+ return;
+ }
+
+ this.mediaConnection.updateLocalTracks({
+ audio: localAudioTrack,
+ });
+ };
+
/**
* @param broadworksCorrelationInfo
*/
diff --git a/packages/calling/src/CallingClient/calling/callManager.test.ts b/packages/calling/src/CallingClient/calling/callManager.test.ts
index 2744772a61e..6065de11d1e 100644
--- a/packages/calling/src/CallingClient/calling/callManager.test.ts
+++ b/packages/calling/src/CallingClient/calling/callManager.test.ts
@@ -275,7 +275,7 @@ describe('Call Manager Tests with respect to calls', () => {
await waitForMsecs(50);
expect(patchMock).toHaveBeenCalledWith(MobiusCallState.ALERTING);
- expect(warnSpy).toHaveBeenCalledWith('Call Progress failed with Mobius', {
+ expect(warnSpy).toHaveBeenCalledWith('Failed to signal call progression', {
file: 'call',
method: 'handleOutgoingCallAlerting',
});
diff --git a/packages/calling/src/CallingClient/calling/types.ts b/packages/calling/src/CallingClient/calling/types.ts
index 7632364bc35..9d5264ccfe0 100644
--- a/packages/calling/src/CallingClient/calling/types.ts
+++ b/packages/calling/src/CallingClient/calling/types.ts
@@ -369,6 +369,13 @@ export interface ICall extends Eventing {
transferTarget?: string
): void;
+ /**
+ * Change the audio stream of the call.
+ *
+ * @param newAudioStream - The new audio stream to be used in the call.
+ */
+ updateMedia(newAudioStream: LocalMicrophoneStream): void;
+
/**
* Fetches the information related to the call's Broadworks correlationId.
*
diff --git a/packages/calling/src/CallingClient/callingClientFixtures.ts b/packages/calling/src/CallingClient/callingClientFixtures.ts
index db3cd15d893..ec9c69cee43 100644
--- a/packages/calling/src/CallingClient/callingClientFixtures.ts
+++ b/packages/calling/src/CallingClient/callingClientFixtures.ts
@@ -47,6 +47,131 @@ const registrationPayload = ({
const uri = `${webex.internal.services._serviceUrls.mobius}${URL_ENDPOINT}`;
const myIP = mockIPReturnBody.ipv4;
+const mockUSServiceHosts = [
+ {
+ host: 'mobius-us-east-1.prod.infra.webex.com',
+ ttl: -1,
+ priority: 5,
+ id: 'urn:TEAM:us-east-2_a:mobius',
+ },
+ {
+ host: 'mobius-ca-central-1.prod.infra.webex.com',
+ ttl: -1,
+ priority: 10,
+ id: 'urn:TEAM:us-east-2_a:mobius',
+ },
+ {
+ host: 'mobius-eu-central-1.prod.infra.webex.com',
+ ttl: -1,
+ priority: 15,
+ id: 'urn:TEAM:us-east-2_a:mobius',
+ },
+ {
+ host: 'mobius-ap-southeast-2.prod.infra.webex.com',
+ ttl: -1,
+ priority: 20,
+ id: 'urn:TEAM:us-east-2_a:mobius',
+ },
+];
+
+const mockEUServiceHosts = [
+ {
+ host: 'mobius-eu-central-1.prod.infra.webex.com',
+ ttl: -1,
+ priority: 5,
+ id: 'urn:TEAM:eu-central-1_k:mobius',
+ },
+ {
+ host: 'mobius-us-east-1.prod.infra.webex.com',
+ ttl: -1,
+ priority: 15,
+ id: 'urn:TEAM:eu-central-1_k:mobius',
+ },
+ {
+ host: 'mobius-ca-central-1.prod.infra.webex.com',
+ ttl: -1,
+ priority: 10,
+ id: 'urn:TEAM:eu-central-1_k:mobius',
+ },
+ {
+ host: 'mobius-ap-southeast-2.prod.infra.webex.com',
+ ttl: -1,
+ priority: 20,
+ id: 'urn:TEAM:eu-central-1_k:mobius',
+ },
+];
+
+const mockEUIntServiceHosts = [
+ {
+ host: 'mobius-eu-central-1.int.infra.webex.com',
+ ttl: -1,
+ priority: 15,
+ id: 'urn:TEAM:us-east-2_a:mobius',
+ },
+ {
+ host: 'mobius-us-east-1.int.infra.webex.com',
+ ttl: -1,
+ priority: 5,
+ id: 'urn:TEAM:us-east-2_a:mobius',
+ },
+ {
+ host: 'mobius-ca-central-1.int.infra.webex.com',
+ ttl: -1,
+ priority: 10,
+ id: 'urn:TEAM:us-east-2_a:mobius',
+ },
+ {
+ host: 'mobius-ap-southeast-2.int.infra.webex.com',
+ ttl: -1,
+ priority: 20,
+ id: 'urn:TEAM:us-east-2_a:mobius',
+ },
+];
+
+const mockIntServiceHosts = [
+ {
+ host: 'mobius-us-east-1.int.infra.webex.com',
+ ttl: -1,
+ priority: 5,
+ id: 'urn:TEAM:us-east-2_a:mobius',
+ },
+ {
+ host: 'mobius-ca-central-1.int.infra.webex.com',
+ ttl: -1,
+ priority: 10,
+ id: 'urn:TEAM:us-east-2_a:mobius',
+ },
+ {
+ host: 'mobius-eu-central-1.int.infra.webex.com',
+ ttl: -1,
+ priority: 15,
+ id: 'urn:TEAM:us-east-2_a:mobius',
+ },
+ {
+ host: 'mobius-ap-southeast-2.int.infra.webex.com',
+ ttl: -1,
+ priority: 20,
+ id: 'urn:TEAM:us-east-2_a:mobius',
+ },
+];
+
+const mockCatalogEU = {
+ 'mobius-eu-central-1.prod.infra.webex.com': mockEUServiceHosts,
+};
+const mockCatalogEUInt = {
+ 'mobius-eu-central-1.int.infra.webex.com': mockEUIntServiceHosts,
+};
+
+const mockCatalogUS = {
+ 'mobius-us-east-1.prod.infra.webex.com': mockUSServiceHosts,
+ 'mobius-eu-central-1.prod.infra.webex.com': mockEUServiceHosts,
+};
+
+const mockCatalogUSInt = {
+ 'mobius-us-east-1.int.infra.webex.com': mockIntServiceHosts,
+ 'mobius-eu-central-1.int.infra.webex.com': mockEUIntServiceHosts,
+};
+
export {
ipPayload,
regionBody,
@@ -56,4 +181,12 @@ export {
registrationPayload,
uri,
myIP,
+ mockEUServiceHosts,
+ mockEUIntServiceHosts,
+ mockIntServiceHosts,
+ mockUSServiceHosts,
+ mockCatalogEU,
+ mockCatalogEUInt,
+ mockCatalogUS,
+ mockCatalogUSInt,
};
diff --git a/packages/calling/src/CallingClient/constants.ts b/packages/calling/src/CallingClient/constants.ts
index da7e7b060ac..25587d8a235 100644
--- a/packages/calling/src/CallingClient/constants.ts
+++ b/packages/calling/src/CallingClient/constants.ts
@@ -58,6 +58,7 @@ export const SCIM_USER_FILTER = 'v1/Users?filter=';
export const SPARK_USER_AGENT = 'spark-user-agent';
export const REGISTER_RETRY_TIMEOUT = 10000;
export const SUPPLEMENTARY_SERVICES_TIMEOUT = 10000;
+export const API_V1 = '/api/v1';
export const URL_ENDPOINT = '/calling/web/';
export const VALID_PHONE = /[\d\s()*#+.-]+/;
export const WEB_AGENT = '(web)';
@@ -119,4 +120,8 @@ export const FAILOVER_UTIL = 'startFailoverTimer';
export const NETWORK_CHANGE_DETECTION_UTIL = 'detectNetworkChange';
export const CALLS_CLEARED_HANDLER_UTIL = 'callsClearedHandler';
export const RECONNECT_UTIL = 'reconnectOnFailure';
-export const BACKGROUND_NOISE_REMOVAL = 'background-noise-removal';
+export const NOISE_REDUCTION_EFFECT = 'noise-reduction-effect';
+export const MOBIUS_US_PROD = 'mobius-us-east-1.prod.infra.webex.com';
+export const MOBIUS_EU_PROD = 'mobius-eu-central-1.prod.infra.webex.com';
+export const MOBIUS_US_INT = 'mobius-us-east-1.int.infra.webex.com';
+export const MOBIUS_EU_INT = 'mobius-eu-central-1.int.infra.webex.com';
diff --git a/packages/calling/src/CallingClient/line/index.ts b/packages/calling/src/CallingClient/line/index.ts
index 34de294e2d5..41adad4de6e 100644
--- a/packages/calling/src/CallingClient/line/index.ts
+++ b/packages/calling/src/CallingClient/line/index.ts
@@ -6,10 +6,10 @@ import {
CorrelationId,
IDeviceInfo,
MobiusDeviceId,
- MobiusStatus,
+ RegistrationStatus,
ServiceIndicator,
} from '../../common/types';
-import {ILine, LINE_EVENTS, LineEventTypes, LineStatus} from './types';
+import {ILine, LINE_EVENTS} from './types';
import {LINE_FILE, VALID_PHONE} from '../constants';
import log from '../../Logger';
import {IRegistration} from '../registration/types';
@@ -21,7 +21,7 @@ import {LineError} from '../../Errors/catalog/LineError';
import {LOGGER} from '../../Logger/types';
import {validateServiceData} from '../../common';
import SDKConnector from '../../SDKConnector';
-import {LINE_EVENT_KEYS} from '../../Events/types';
+import {LINE_EVENT_KEYS, LineEventTypes} from '../../Events/types';
import {ICall, ICallManager} from '../calling/types';
import {getCallManager} from '../calling/callManager';
import {ERROR_TYPE} from '../../Errors/types';
@@ -49,9 +49,7 @@ export default class Line extends Eventing implements ILine {
public extension?: string;
- public status: LineStatus;
-
- public sipAddresses?: string[];
+ public sipAddresses: string[] = [];
public voicemail?: string;
@@ -78,7 +76,6 @@ export default class Line extends Eventing implements ILine {
constructor(
userId: string,
clientDeviceUri: string,
- status: LineStatus,
mutex: Mutex,
primaryMobiusUris: string[],
backupMobiusUris: string[],
@@ -92,7 +89,6 @@ export default class Line extends Eventing implements ILine {
this.lineId = uuid();
this.userId = userId;
this.clientDeviceUri = clientDeviceUri;
- this.status = status;
this.phoneNumber = phoneNumber;
this.extension = extension;
this.voicemail = voicemail;
@@ -118,7 +114,6 @@ export default class Line extends Eventing implements ILine {
logLevel
);
- this.registration.setStatus(MobiusStatus.DEFAULT);
log.setLogger(logLevel, LINE_FILE);
this.callManager = getCallManager(this.#webex, serviceData.indicator);
@@ -131,7 +126,6 @@ export default class Line extends Eventing implements ILine {
*/
public async register() {
await this.#mutex.runExclusive(async () => {
- this.registration.setStatus(MobiusStatus.DEFAULT);
this.emit(LINE_EVENTS.CONNECTING);
this.registration.setMobiusServers(this.#primaryMobiusUris, this.#backupMobiusUris);
@@ -146,7 +140,8 @@ export default class Line extends Eventing implements ILine {
* Wrapper to for device deregister.
*/
public async deregister() {
- this.registration.deregister();
+ await this.registration.deregister();
+ this.registration.setStatus(RegistrationStatus.IDLE);
}
/**
@@ -166,7 +161,7 @@ export default class Line extends Eventing implements ILine {
this.mobiusDeviceId = device?.deviceId;
this.mobiusUri = device?.uri;
this.lastSeen = device?.lastSeen;
- this.sipAddresses = device?.addresses;
+ this.sipAddresses = device?.addresses ?? [];
this.keepaliveInterval = keepaliveInterval;
this.callKeepaliveInterval = callKeepaliveInterval;
this.rehomingIntervalMin = rehomingIntervalMin;
@@ -218,7 +213,7 @@ export default class Line extends Eventing implements ILine {
/**
* Gets registration status
*/
- public getRegistrationStatus = (): MobiusStatus => this.registration.getStatus();
+ public getStatus = (): RegistrationStatus => this.registration.getStatus();
/**
* Gets device id
@@ -260,7 +255,7 @@ export default class Line extends Eventing implements ILine {
'An invalid phone number was detected. Check the number and try again.',
{},
ERROR_TYPE.CALL_ERROR,
- LineStatus.ACTIVE
+ RegistrationStatus.ACTIVE
);
this.emit(LINE_EVENTS.ERROR, err);
diff --git a/packages/calling/src/CallingClient/line/line.test.ts b/packages/calling/src/CallingClient/line/line.test.ts
index e450feeffa5..b49aee75411 100644
--- a/packages/calling/src/CallingClient/line/line.test.ts
+++ b/packages/calling/src/CallingClient/line/line.test.ts
@@ -11,11 +11,11 @@ import {
CallDirection,
CallType,
MobiusServers,
- MobiusStatus,
+ RegistrationStatus,
ServiceIndicator,
WebexRequestPayload,
} from '../../common/types';
-import {LINE_EVENTS, LineStatus} from './types';
+import {LINE_EVENTS} from './types';
import Line from '.';
import * as utils from '../../common/Utils';
import SDKConnector from '../../SDKConnector';
@@ -57,7 +57,6 @@ describe('Line Tests', () => {
line = new Line(
userId,
clientDeviceUri,
- LineStatus.ACTIVE,
mutex,
primaryMobiusUris(),
backupMobiusUris(),
@@ -83,7 +82,7 @@ describe('Line Tests', () => {
expect.anything(),
LOGGER.INFO
);
- expect(line.getRegistrationStatus()).toEqual(MobiusStatus.DEFAULT);
+ expect(line.getStatus()).toEqual(RegistrationStatus.IDLE);
await line.register();
expect(webex.request).toBeCalledOnceWith({
@@ -98,7 +97,7 @@ describe('Line Tests', () => {
});
expect(handleErrorSpy).not.toBeCalled();
- expect(line.getRegistrationStatus()).toEqual(MobiusStatus.ACTIVE);
+ expect(line.getStatus()).toEqual(RegistrationStatus.ACTIVE);
expect(line.getActiveMobiusUrl()).toEqual(primaryUrl);
expect(line.getLoggingLevel()).toEqual(LOGGER.INFO);
expect(line.getDeviceId()).toEqual(mockRegistrationBody.device.deviceId);
@@ -129,11 +128,11 @@ describe('Line Tests', () => {
);
});
- expect(line.getRegistrationStatus()).toBe(MobiusStatus.DEFAULT);
+ expect(line.getStatus()).toBe(RegistrationStatus.IDLE);
line.register();
await utils.waitForMsecs(20);
- expect(line.getRegistrationStatus()).toBe(MobiusStatus.DEFAULT);
+ expect(line.getStatus()).toBe(RegistrationStatus.INACTIVE);
expect(handleErrorSpy).toBeCalledOnceWith(
expect.anything(),
expect.anything(),
@@ -148,14 +147,15 @@ describe('Line Tests', () => {
it('verify successful de-registration cases', async () => {
webex.request.mockReturnValueOnce(registrationPayload);
- expect(line.getRegistrationStatus()).toEqual(MobiusStatus.DEFAULT);
+ expect(line.getStatus()).toEqual(RegistrationStatus.IDLE);
await line.register();
- expect(line.getRegistrationStatus()).toEqual(MobiusStatus.ACTIVE);
+ expect(line.getStatus()).toEqual(RegistrationStatus.ACTIVE);
await line.deregister();
- expect(line.getRegistrationStatus()).toEqual(MobiusStatus.DEFAULT);
+ expect(line.getStatus()).toEqual(RegistrationStatus.IDLE);
});
});
+
describe('Line calling tests', () => {
let line;
@@ -163,7 +163,6 @@ describe('Line Tests', () => {
line = new Line(
userId,
clientDeviceUri,
- LineStatus.ACTIVE,
mutex,
primaryMobiusUris(),
backupMobiusUris(),
diff --git a/packages/calling/src/CallingClient/line/types.ts b/packages/calling/src/CallingClient/line/types.ts
index 283085b3dca..f5463c76027 100644
--- a/packages/calling/src/CallingClient/line/types.ts
+++ b/packages/calling/src/CallingClient/line/types.ts
@@ -1,3 +1,5 @@
+import {LineEventTypes} from '../../Events/types';
+import {Eventing} from '../../Events/impl';
import {IRegistration} from '../registration/types';
import {LineError} from '../../Errors/catalog/LineError';
import {
@@ -5,15 +7,10 @@ import {
CorrelationId,
IDeviceInfo,
MobiusDeviceId,
- MobiusStatus,
+ RegistrationStatus,
} from '../../common/types';
import {ICall} from '../calling/types';
-export enum LineStatus {
- INACTIVE = 'inactive',
- ACTIVE = 'active',
-}
-
export enum LINE_EVENTS {
CONNECTING = 'connecting',
ERROR = 'error',
@@ -27,7 +24,7 @@ export enum LINE_EVENTS {
/**
* Represents an interface for managing a telephony line.
*/
-export interface ILine {
+export interface ILine extends Eventing {
/**
* The unique identifier of the user associated with the line.
*/
@@ -43,11 +40,6 @@ export interface ILine {
*/
lineId: string;
- /**
- * The current status of the line as {@link LineStatus}.
- */
- status: LineStatus;
-
/**
* The optional Mobius device identifier associated with the line.
*/
@@ -133,7 +125,7 @@ export interface ILine {
* Retrieves the registration status of the line as {@link MobiusStatus}.
*
*/
- getRegistrationStatus(): MobiusStatus;
+ getStatus(): RegistrationStatus;
/**
* Retrieves the device identifier associated with the line as {@link MobiusDeviceId},
@@ -182,16 +174,6 @@ export interface ILine {
getCall(correlationId: CorrelationId): ICall;
}
-export type LineEventTypes = {
- [LINE_EVENTS.CONNECTING]: () => void;
- [LINE_EVENTS.ERROR]: (error: LineError) => void;
- [LINE_EVENTS.RECONNECTED]: () => void;
- [LINE_EVENTS.RECONNECTING]: () => void;
- [LINE_EVENTS.REGISTERED]: (lineInfo: ILine) => void;
- [LINE_EVENTS.UNREGISTERED]: () => void;
- [LINE_EVENTS.INCOMING_CALL]: (callObj: ICall) => void;
-};
-
export type LineEmitterCallback = (
event: LINE_EVENTS,
deviceInfo?: IDeviceInfo,
diff --git a/packages/calling/src/CallingClient/registration/register.test.ts b/packages/calling/src/CallingClient/registration/register.test.ts
index bc459eccc4f..dcaa1eea862 100644
--- a/packages/calling/src/CallingClient/registration/register.test.ts
+++ b/packages/calling/src/CallingClient/registration/register.test.ts
@@ -6,7 +6,7 @@ import {
getMockRequestTemplate,
getTestUtilsWebex,
} from '../../common/testUtil';
-import {MobiusStatus, ServiceIndicator, WebexRequestPayload} from '../../common/types';
+import {RegistrationStatus, ServiceIndicator, WebexRequestPayload} from '../../common/types';
import * as utils from '../../common/Utils';
import log from '../../Logger';
import {LOGGER} from '../../Logger/types';
@@ -26,7 +26,7 @@ import {
SEC_TO_MSEC_MFACTOR,
} from '../constants';
import {ICall} from '../calling/types';
-import {LINE_EVENTS, LineStatus} from '../line/types';
+import {LINE_EVENTS} from '../line/types';
import {createLineError} from '../../Errors/catalog/LineError';
import {IRegistration} from './types';
@@ -115,7 +115,7 @@ describe('Registration Tests', () => {
method: 'POST',
});
- expect(reg.getStatus()).toEqual(MobiusStatus.ACTIVE);
+ expect(reg.getStatus()).toEqual(RegistrationStatus.ACTIVE);
expect(lineEmitter).toBeCalledTimes(2);
expect(lineEmitter).toBeCalledWith(LINE_EVENTS.CONNECTING);
expect(lineEmitter).toBeCalledWith(LINE_EVENTS.REGISTERED, mockPostResponse);
@@ -138,10 +138,10 @@ describe('Registration Tests', () => {
'User is unauthorized due to an expired token. Sign out, then sign back in.',
{},
ERROR_TYPE.TOKEN_ERROR,
- LineStatus.INACTIVE
+ RegistrationStatus.INACTIVE
);
- expect(reg.getStatus()).toEqual(MobiusStatus.DEFAULT);
+ expect(reg.getStatus()).toEqual(RegistrationStatus.INACTIVE);
expect(lineEmitter).toBeCalledTimes(2);
expect(lineEmitter).nthCalledWith(1, LINE_EVENTS.CONNECTING);
expect(lineEmitter).nthCalledWith(2, LINE_EVENTS.ERROR, undefined, error);
@@ -164,7 +164,7 @@ describe('Registration Tests', () => {
global.fetch = jest.fn(() => Promise.resolve({json: () => mockDeleteResponse})) as jest.Mock;
- expect(reg.getStatus()).toEqual(MobiusStatus.DEFAULT);
+ expect(reg.getStatus()).toEqual(RegistrationStatus.IDLE);
await reg.triggerRegistration();
expect(webex.request).toBeCalledTimes(2);
expect(webex.request).toBeCalledWith({
@@ -180,7 +180,7 @@ describe('Registration Tests', () => {
expect(logSpy).toBeCalledWith('Registration restoration in progress.', expect.anything());
expect(logSpy).toBeCalledWith('Registration restored successfully.', expect.anything());
- expect(reg.getStatus()).toEqual(MobiusStatus.ACTIVE);
+ expect(reg.getStatus()).toEqual(RegistrationStatus.ACTIVE);
expect(lineEmitter).toBeCalledTimes(4);
expect(lineEmitter).nthCalledWith(1, LINE_EVENTS.CONNECTING);
expect(lineEmitter).nthCalledWith(2, LINE_EVENTS.UNREGISTERED);
@@ -197,7 +197,7 @@ describe('Registration Tests', () => {
.mockRejectedValueOnce(failurePayload)
.mockResolvedValueOnce(successPayload);
- expect(reg.getStatus()).toEqual(MobiusStatus.DEFAULT);
+ expect(reg.getStatus()).toEqual(RegistrationStatus.IDLE);
await reg.triggerRegistration();
jest.advanceTimersByTime(REG_TRY_BACKUP_TIMER_VAL_IN_SEC * SEC_TO_MSEC_MFACTOR);
await flushPromises();
@@ -213,7 +213,7 @@ describe('Registration Tests', () => {
method: 'POST',
uri: `${mobiusUris.backup[0]}device`,
});
- expect(reg.getStatus()).toEqual(MobiusStatus.ACTIVE);
+ expect(reg.getStatus()).toEqual(RegistrationStatus.ACTIVE);
/* Active Url must match with the backup url as per the test */
expect(reg.getActiveMobiusUrl()).toEqual(mobiusUris.backup[0]);
});
@@ -223,7 +223,7 @@ describe('Registration Tests', () => {
// try the primary twice and register successfully with backup servers
webex.request.mockRejectedValue(failurePayload);
- expect(reg.getStatus()).toEqual(MobiusStatus.DEFAULT);
+ expect(reg.getStatus()).toEqual(RegistrationStatus.IDLE);
await reg.triggerRegistration();
jest.advanceTimersByTime(REG_TRY_BACKUP_TIMER_VAL_IN_SEC * SEC_TO_MSEC_MFACTOR);
await flushPromises();
@@ -252,7 +252,7 @@ describe('Registration Tests', () => {
method: 'POST',
uri: `${mobiusUris.backup[1]}device`,
});
- expect(reg.getStatus()).toEqual(MobiusStatus.DEFAULT);
+ expect(reg.getStatus()).toEqual(RegistrationStatus.INACTIVE);
});
});
@@ -278,7 +278,7 @@ describe('Registration Tests', () => {
/* Active Url must match with the backup url as per the test */
expect(reg.getActiveMobiusUrl()).toStrictEqual(mobiusUris.backup[0]);
- expect(reg.getStatus()).toEqual(MobiusStatus.ACTIVE);
+ expect(reg.getStatus()).toEqual(RegistrationStatus.ACTIVE);
});
afterEach(() => {
@@ -305,7 +305,7 @@ describe('Registration Tests', () => {
expect(failbackRetry429Spy).toBeCalledOnceWith();
expect(reg.failback429RetryAttempts).toBe(0);
- expect(reg.getStatus()).toBe(MobiusStatus.DEFAULT);
+ expect(reg.getStatus()).toBe(RegistrationStatus.INACTIVE);
expect(restoreSpy).toBeCalledOnceWith(FAILBACK_429_RETRY_UTIL);
expect(restartSpy).toBeCalledOnceWith(FAILBACK_429_RETRY_UTIL);
expect(reg.failbackTimer).toBe(undefined);
@@ -326,7 +326,7 @@ describe('Registration Tests', () => {
method: 'executeFailback',
file: REGISTRATION_FILE,
});
- expect(reg.getStatus()).toBe(MobiusStatus.DEFAULT);
+ expect(reg.getStatus()).toBe(RegistrationStatus.INACTIVE);
expect(restoreSpy).toBeCalledOnceWith(FAILBACK_UTIL);
expect(restartSpy).toBeCalledOnceWith(FAILBACK_UTIL);
expect(reg.rehomingIntervalMin).toBe(DEFAULT_REHOMING_INTERVAL_MIN);
@@ -352,7 +352,7 @@ describe('Registration Tests', () => {
method: 'executeFailback',
file: REGISTRATION_FILE,
});
- expect(reg.getStatus()).toBe(MobiusStatus.DEFAULT);
+ expect(reg.getStatus()).toBe(RegistrationStatus.INACTIVE);
expect(restoreSpy).toBeCalledOnceWith(FAILBACK_UTIL);
expect(restartSpy).not.toBeCalled();
expect(reg.failbackTimer).toBe(undefined);
@@ -375,7 +375,7 @@ describe('Registration Tests', () => {
});
/* Active Url should still match backup url */
expect(reg.getActiveMobiusUrl()).toStrictEqual(mobiusUris.backup[0]);
- expect(reg.getStatus()).toBe(MobiusStatus.ACTIVE);
+ expect(reg.getStatus()).toBe(RegistrationStatus.ACTIVE);
expect(restoreSpy).toBeCalledOnceWith(FAILBACK_UTIL);
expect(restartSpy).not.toBeCalled();
expect(reg.rehomingIntervalMin).toBe(DEFAULT_REHOMING_INTERVAL_MIN);
@@ -398,7 +398,7 @@ describe('Registration Tests', () => {
/* Active Url must now match with the primary url */
expect(reg.getActiveMobiusUrl()).toStrictEqual(mobiusUris.primary[0]);
- expect(reg.getStatus()).toBe(MobiusStatus.ACTIVE);
+ expect(reg.getStatus()).toBe(RegistrationStatus.ACTIVE);
expect(reg.failbackTimer).toBe(undefined);
expect(restoreSpy).not.toBeCalled();
expect(reg.rehomingIntervalMin).toBe(mockPostResponse.rehomingIntervalMin);
@@ -425,7 +425,7 @@ describe('Registration Tests', () => {
/* Active Url should still match backup url */
expect(reg.getActiveMobiusUrl()).toStrictEqual(mobiusUris.backup[0]);
- expect(reg.getStatus()).toBe(MobiusStatus.ACTIVE);
+ expect(reg.getStatus()).toBe(RegistrationStatus.ACTIVE);
expect(restoreSpy).not.toBeCalled();
expect(restartSpy).not.toBeCalled();
@@ -451,7 +451,7 @@ describe('Registration Tests', () => {
postRegistrationSpy.mockResolvedValueOnce(successPayload);
jest.useFakeTimers();
await reg.triggerRegistration();
- expect(reg.getStatus()).toBe(MobiusStatus.ACTIVE);
+ expect(reg.getStatus()).toBe(RegistrationStatus.ACTIVE);
});
afterEach(() => {
@@ -509,7 +509,7 @@ describe('Registration Tests', () => {
file: REGISTRATION_FILE,
});
- expect(reg.getStatus()).toBe(MobiusStatus.ACTIVE);
+ expect(reg.getStatus()).toBe(RegistrationStatus.ACTIVE);
expect(reg.keepaliveTimer).toBe(timer);
expect(lineEmitter).nthCalledWith(1, LINE_EVENTS.RECONNECTING);
expect(lineEmitter).nthCalledWith(2, LINE_EVENTS.RECONNECTED);
@@ -532,7 +532,7 @@ describe('Registration Tests', () => {
webex.request.mockRejectedValue(failurePayload);
- expect(reg.getStatus()).toEqual(MobiusStatus.ACTIVE);
+ expect(reg.getStatus()).toEqual(RegistrationStatus.ACTIVE);
const timer = reg.keepaliveTimer;
@@ -544,7 +544,7 @@ describe('Registration Tests', () => {
// sendKeepAlive tries to retry 5 times before accepting failure
// later 2 attempts to register with primary server
expect(handleErrorSpy).toBeCalledTimes(7);
- expect(reg.getStatus()).toEqual(MobiusStatus.DEFAULT);
+ expect(reg.getStatus()).toEqual(RegistrationStatus.INACTIVE);
expect(reg.reconnectPending).toStrictEqual(false);
expect(reconnectSpy).toBeCalledOnceWith(KEEPALIVE_UTIL);
expect(restoreSpy).toBeCalledOnceWith(KEEPALIVE_UTIL);
@@ -591,7 +591,7 @@ describe('Registration Tests', () => {
/* successful registration */
// webex.request.mockResolvedValue(successPayload);
- expect(reg.getStatus()).toEqual(MobiusStatus.ACTIVE);
+ expect(reg.getStatus()).toEqual(RegistrationStatus.ACTIVE);
const url = 'https://mobius.asydm-m-1.prod.infra.webex.com/api/v1';
@@ -605,7 +605,7 @@ describe('Registration Tests', () => {
expect(clearIntervalSpy).toBeCalledOnceWith(timer);
expect(handleErrorSpy).toBeCalledTimes(5);
- expect(reg.getStatus()).toEqual(MobiusStatus.ACTIVE);
+ expect(reg.getStatus()).toEqual(RegistrationStatus.ACTIVE);
expect(reconnectSpy).toBeCalledOnceWith(KEEPALIVE_UTIL);
expect(restoreSpy).toBeCalledOnceWith(KEEPALIVE_UTIL);
expect(restartRegSpy).not.toBeCalled();
@@ -632,7 +632,7 @@ describe('Registration Tests', () => {
.mockRejectedValueOnce(failurePayload)
.mockResolvedValue(successPayload);
- expect(reg.getStatus()).toBe(MobiusStatus.ACTIVE);
+ expect(reg.getStatus()).toBe(RegistrationStatus.ACTIVE);
const timer = reg.keepaliveTimer;
@@ -641,7 +641,7 @@ describe('Registration Tests', () => {
await flushPromises();
expect(webex.request).toBeCalledTimes(3);
- expect(reg.getStatus()).toBe(MobiusStatus.ACTIVE);
+ expect(reg.getStatus()).toBe(RegistrationStatus.ACTIVE);
expect(handleErrorSpy).toBeCalledTimes(2);
expect(clearIntervalSpy).not.toBeCalled();
expect(reg.keepaliveTimer).toBe(timer);
@@ -660,14 +660,14 @@ describe('Registration Tests', () => {
webex.request.mockRejectedValue(failurePayload);
- expect(reg.getStatus()).toBe(MobiusStatus.ACTIVE);
+ expect(reg.getStatus()).toBe(RegistrationStatus.ACTIVE);
/* send one keepalive */
jest.advanceTimersByTime(mockPostResponse.keepaliveInterval * SEC_TO_MSEC_MFACTOR);
await flushPromises();
expect(clearIntervalSpy).toBeCalledTimes(1);
- expect(reg.getStatus()).toBe(MobiusStatus.DEFAULT);
+ expect(reg.getStatus()).toBe(RegistrationStatus.INACTIVE);
expect(reconnectSpy).not.toBeCalled();
expect(restoreSpy).not.toBeCalled();
expect(restartRegSpy).not.toBeCalled();
@@ -731,7 +731,7 @@ describe('Registration Tests', () => {
expect(handleErrorSpy).toBeCalledTimes(5);
expect(reg.keepaliveTimer).toStrictEqual(undefined);
expect(reg.failbackTimer).toStrictEqual(undefined);
- expect(reg.getStatus()).toBe(MobiusStatus.DEFAULT);
+ expect(reg.getStatus()).toBe(RegistrationStatus.INACTIVE);
expect(lineEmitter).lastCalledWith(LINE_EVENTS.UNREGISTERED);
expect(reconnectSpy).toBeCalledOnceWith(KEEPALIVE_UTIL);
expect(restoreSpy).not.toBeCalled();
@@ -749,7 +749,7 @@ describe('Registration Tests', () => {
await reg.reconnectOnFailure(CALLS_CLEARED_HANDLER_UTIL);
expect(Object.keys(reg.callManager.getActiveCalls()).length).toBe(0);
- expect(reg.getStatus()).toBe(MobiusStatus.ACTIVE);
+ expect(reg.getStatus()).toBe(RegistrationStatus.ACTIVE);
expect(reconnectSpy).toBeCalledOnceWith(CALLS_CLEARED_HANDLER_UTIL);
expect(restoreSpy).toBeCalledOnceWith(CALLS_CLEARED_HANDLER_UTIL);
expect(restartRegSpy).not.toBeCalled();
diff --git a/packages/calling/src/CallingClient/registration/register.ts b/packages/calling/src/CallingClient/registration/register.ts
index 6c43b610b5c..1121a49407d 100644
--- a/packages/calling/src/CallingClient/registration/register.ts
+++ b/packages/calling/src/CallingClient/registration/register.ts
@@ -1,4 +1,3 @@
-/* eslint-disable valid-jsdoc */
import {v4 as uuid} from 'uuid';
import {Mutex} from 'async-mutex';
import {ERROR_CODE} from '../../Errors/types';
@@ -16,7 +15,7 @@ import {
ALLOWED_SERVICES,
HTTP_METHODS,
IDeviceInfo,
- MobiusStatus,
+ RegistrationStatus,
ServiceData,
WebexRequestPayload,
} from '../../common/types';
@@ -57,7 +56,7 @@ export class Registration implements IRegistration {
private serviceData: ServiceData;
private failback429RetryAttempts: number;
- private registrationStatus: MobiusStatus;
+ private registrationStatus: RegistrationStatus;
private failbackTimer?: NodeJS.Timer;
private activeMobiusUrl!: string;
@@ -91,7 +90,7 @@ export class Registration implements IRegistration {
}
this.webex = this.sdkConnector.getWebex();
this.userId = this.webex.internal.device.userId;
- this.registrationStatus = MobiusStatus.DEFAULT;
+ this.registrationStatus = RegistrationStatus.IDLE;
this.failback429RetryAttempts = 0;
log.setLogger(logLevel, REGISTRATION_FILE);
this.rehomingIntervalMin = DEFAULT_REHOMING_INTERVAL_MIN;
@@ -141,19 +140,25 @@ export class Registration implements IRegistration {
*
*/
private async deleteRegistration(url: string, deviceId: string, deviceUrl: string) {
- const response = await fetch(`${url}${DEVICES_ENDPOINT_RESOURCE}/${deviceId}`, {
- method: HTTP_METHODS.DELETE,
- headers: {
- [CISCO_DEVICE_URL]: deviceUrl,
- Authorization: await this.webex.credentials.getUserToken(),
- trackingId: `${WEBEX_WEB_CLIENT}_${uuid()}`,
- [SPARK_USER_AGENT]: CALLING_USER_AGENT,
- },
- });
+ let response;
+ try {
+ response = await fetch(`${url}${DEVICES_ENDPOINT_RESOURCE}/${deviceId}`, {
+ method: HTTP_METHODS.DELETE,
+ headers: {
+ [CISCO_DEVICE_URL]: deviceUrl,
+ Authorization: await this.webex.credentials.getUserToken(),
+ trackingId: `${WEBEX_WEB_CLIENT}_${uuid()}`,
+ [SPARK_USER_AGENT]: CALLING_USER_AGENT,
+ },
+ });
+ } catch (error) {
+ log.warn(`Delete failed with Mobius`, {});
+ }
+ this.setStatus(RegistrationStatus.INACTIVE);
this.lineEmitter(LINE_EVENTS.UNREGISTERED);
- return response.json();
+ return response?.json();
}
/**
@@ -442,14 +447,14 @@ export class Registration implements IRegistration {
* ACTIVE, else false.
*/
public isDeviceRegistered(): boolean {
- return this.registrationStatus === MobiusStatus.ACTIVE;
+ return this.registrationStatus === RegistrationStatus.ACTIVE;
}
- public getStatus(): MobiusStatus {
+ public getStatus(): RegistrationStatus {
return this.registrationStatus;
}
- public setStatus(value: MobiusStatus) {
+ public setStatus(value: RegistrationStatus) {
this.registrationStatus = value;
}
@@ -481,7 +486,7 @@ export class Registration implements IRegistration {
await this.mutex.runExclusive(async () => {
/* Check retry once again to see if another timer thread has not finished the job already. */
if (retry) {
- log.info('Mercury connection is up again, Re-registering with Mobius', {
+ log.info('Mercury connection is up again, re-registering with Webex Calling if needed', {
file: REGISTRATION_FILE,
method: this.handleConnectionRestoration.name,
});
@@ -592,7 +597,7 @@ export class Registration implements IRegistration {
for (const url of servers) {
try {
abort = false;
- this.registrationStatus = MobiusStatus.DEFAULT;
+ this.registrationStatus = RegistrationStatus.INACTIVE;
this.lineEmitter(LINE_EVENTS.CONNECTING);
log.log(`[${caller}] : Mobius url to contact: ${url}`, {
file: REGISTRATION_FILE,
@@ -600,10 +605,9 @@ export class Registration implements IRegistration {
});
// eslint-disable-next-line no-await-in-loop
const resp = await this.postRegistration(url);
-
this.deviceInfo = resp.body as IDeviceInfo;
this.lineEmitter(LINE_EVENTS.REGISTERED, resp.body as IDeviceInfo);
- this.registrationStatus = MobiusStatus.ACTIVE;
+ this.registrationStatus = RegistrationStatus.ACTIVE;
this.setActiveMobiusUrl(url);
this.setIntervalValues(this.deviceInfo);
this.metricManager.setDeviceInfo(this.deviceInfo);
@@ -641,7 +645,7 @@ export class Registration implements IRegistration {
{method: this.attemptRegistrationWithServers.name, file: REGISTRATION_FILE},
this.restoreRegistrationCallBack()
);
- if (this.registrationStatus === MobiusStatus.ACTIVE) {
+ if (this.registrationStatus === RegistrationStatus.ACTIVE) {
log.info(
`[${caller}] : Device is already restored, active mobius url: ${this.activeMobiusUrl}`,
{
@@ -652,6 +656,7 @@ export class Registration implements IRegistration {
break;
}
if (abort) {
+ this.setStatus(RegistrationStatus.INACTIVE);
break;
} else if (caller === this.executeFailback.name) {
const error = body.statusCode;
@@ -716,7 +721,7 @@ export class Registration implements IRegistration {
);
if (abort || keepAliveRetryCount >= 5) {
- this.setStatus(MobiusStatus.DEFAULT);
+ this.setStatus(RegistrationStatus.INACTIVE);
this.clearKeepaliveTimer();
this.clearFailbackTimer();
this.lineEmitter(LINE_EVENTS.UNREGISTERED);
@@ -760,7 +765,7 @@ export class Registration implements IRegistration {
}
this.clearKeepaliveTimer();
- this.setStatus(MobiusStatus.DEFAULT);
+ this.setStatus(RegistrationStatus.INACTIVE);
}
/**
@@ -798,7 +803,7 @@ export class Registration implements IRegistration {
const uri = restoreData.devices[0].uri.replace(stringToReplace, '');
this.setActiveMobiusUrl(uri);
- this.registrationStatus = MobiusStatus.ACTIVE;
+ this.registrationStatus = RegistrationStatus.ACTIVE;
return true;
}
diff --git a/packages/calling/src/CallingClient/registration/types.ts b/packages/calling/src/CallingClient/registration/types.ts
index bd11a26183b..5791ec33631 100644
--- a/packages/calling/src/CallingClient/registration/types.ts
+++ b/packages/calling/src/CallingClient/registration/types.ts
@@ -1,4 +1,4 @@
-import {IDeviceInfo, MobiusStatus} from '../../common/types';
+import {IDeviceInfo, RegistrationStatus} from '../../common/types';
export type Header = {
[key: string]: string;
@@ -38,13 +38,13 @@ export interface IRegistration {
*
* @param value - The registration status to set.
*/
- setStatus(value: MobiusStatus): void;
+ setStatus(value: RegistrationStatus): void;
/**
* Retrieves the current registration status.
*
*/
- getStatus(): MobiusStatus;
+ getStatus(): RegistrationStatus;
/**
* Retrieves information about the device as {@link IDeviceInfo}.
diff --git a/packages/calling/src/Errors/catalog/CallingDeviceError.ts b/packages/calling/src/Errors/catalog/CallingDeviceError.ts
index c6a7e0b8b21..9eb92e85ee1 100644
--- a/packages/calling/src/Errors/catalog/CallingDeviceError.ts
+++ b/packages/calling/src/Errors/catalog/CallingDeviceError.ts
@@ -1,5 +1,5 @@
/* eslint-disable valid-jsdoc */
-import {MobiusStatus} from '../../common/types';
+import {RegistrationStatus} from '../../common/types';
import {ErrorContext, ErrorMessage, ErrorObject, ERROR_TYPE} from '../types';
import ExtendedError from './ExtendedError';
@@ -8,7 +8,7 @@ import ExtendedError from './ExtendedError';
* Any error reported from Calling client should be stored here.
*/
export class CallingClientError extends ExtendedError {
- public status: MobiusStatus = MobiusStatus.DEFAULT;
+ public status: RegistrationStatus = RegistrationStatus.INACTIVE;
/**
* Instantiate the Error class with these parameters.
@@ -18,7 +18,12 @@ export class CallingClientError extends ExtendedError {
* @param type - Error Type.
* @param status - Mobius Status, should be default.
*/
- constructor(msg: ErrorMessage, context: ErrorContext, type: ERROR_TYPE, status: MobiusStatus) {
+ constructor(
+ msg: ErrorMessage,
+ context: ErrorContext,
+ type: ERROR_TYPE,
+ status: RegistrationStatus
+ ) {
super(msg, context, type);
this.status = status;
}
@@ -57,5 +62,5 @@ export const createClientError = (
msg: ErrorMessage,
context: ErrorContext,
type: ERROR_TYPE,
- status: MobiusStatus
+ status: RegistrationStatus
) => new CallingClientError(msg, context, type, status);
diff --git a/packages/calling/src/Errors/catalog/LineError.ts b/packages/calling/src/Errors/catalog/LineError.ts
index 2e309e88999..19d9c5bdda6 100644
--- a/packages/calling/src/Errors/catalog/LineError.ts
+++ b/packages/calling/src/Errors/catalog/LineError.ts
@@ -1,5 +1,5 @@
/* eslint-disable valid-jsdoc */
-import {LineStatus} from '../../CallingClient/line/types';
+import {RegistrationStatus} from '../../common/types';
import {ErrorMessage, ERROR_TYPE, LineErrorObject, ErrorContext} from '../types';
import ExtendedError from './ExtendedError';
@@ -7,7 +7,7 @@ import ExtendedError from './ExtendedError';
* Any error reported from Line class should be stored here.
*/
export class LineError extends ExtendedError {
- public status: LineStatus = LineStatus.INACTIVE;
+ public status: RegistrationStatus = RegistrationStatus.INACTIVE;
/**
* Instantiate the Error class with these parameters.
@@ -17,7 +17,12 @@ export class LineError extends ExtendedError {
* @param type - Error Type.
* @param status - Line Status, should be inactive.
*/
- constructor(msg: ErrorMessage, context: ErrorContext, type: ERROR_TYPE, status: LineStatus) {
+ constructor(
+ msg: ErrorMessage,
+ context: ErrorContext,
+ type: ERROR_TYPE,
+ status: RegistrationStatus
+ ) {
super(msg, context, type);
this.status = status;
}
@@ -62,5 +67,5 @@ export const createLineError = (
msg: ErrorMessage,
context: ErrorContext,
type: ERROR_TYPE,
- status: LineStatus
+ status: RegistrationStatus
) => new LineError(msg, context, type, status);
diff --git a/packages/calling/src/Errors/index.ts b/packages/calling/src/Errors/index.ts
index 13cccf83989..27aadeeba92 100644
--- a/packages/calling/src/Errors/index.ts
+++ b/packages/calling/src/Errors/index.ts
@@ -1,2 +1,3 @@
export {CallingClientError} from './catalog/CallingDeviceError';
export {CallError} from './catalog/CallError';
+export {LineError} from './catalog/LineError';
diff --git a/packages/calling/src/Errors/types.ts b/packages/calling/src/Errors/types.ts
index fbdf7a517cd..c7c8fb3a7b4 100644
--- a/packages/calling/src/Errors/types.ts
+++ b/packages/calling/src/Errors/types.ts
@@ -1,6 +1,5 @@
/* eslint-disable @typescript-eslint/no-empty-interface */
-import {LineStatus} from '../CallingClient/line/types';
-import {CorrelationId, IMetaContext} from '../common/types';
+import {CorrelationId, IMetaContext, RegistrationStatus} from '../common/types';
export type ErrorMessage = string;
@@ -61,7 +60,7 @@ export type ErrorObject = {
};
export interface LineErrorObject extends ErrorObject {
- status: LineStatus;
+ status: RegistrationStatus;
}
export interface CallErrorObject extends ErrorObject {
diff --git a/packages/calling/src/Events/types.ts b/packages/calling/src/Events/types.ts
index 6c0580369f2..8624b85a488 100644
--- a/packages/calling/src/Events/types.ts
+++ b/packages/calling/src/Events/types.ts
@@ -1,7 +1,9 @@
/* eslint-disable @typescript-eslint/no-unused-vars */ // TODO: remove once we define the payloads
+import {ILine} from '../api';
+import {LINE_EVENTS} from '../CallingClient/line/types';
import type {ICall} from '../CallingClient/calling/types';
import {CallId, DisplayInformation} from '../common/types';
-import {CallError, CallingClientError} from '../Errors';
+import {CallError, CallingClientError, LineError} from '../Errors';
/** External Eventing Start */
export enum COMMON_EVENT_KEYS {
@@ -92,6 +94,15 @@ export type CallRecordListOther = {
email?: string;
};
+export type RedirectionDetails = {
+ phoneNumber?: string;
+ sipUrl?: string;
+ name?: string;
+ reason: string;
+ userId?: string;
+ isPrivate: boolean;
+};
+
export enum SessionType {
SPARK = 'SPARK',
WEBEX_CALLING = 'WEBEXCALLING',
@@ -116,6 +127,9 @@ export type UserSession = {
other: CallRecordListOther;
sessionType: SessionType;
direction: string;
+ callingSpecifics?: {
+ redirectionDetails: RedirectionDetails;
+ };
};
export type CallingParty = {
@@ -168,6 +182,16 @@ export type CallerIdDisplay = {
callerId: DisplayInformation;
};
+export type LineEventTypes = {
+ [LINE_EVENTS.CONNECTING]: () => void;
+ [LINE_EVENTS.ERROR]: (error: LineError) => void;
+ [LINE_EVENTS.RECONNECTED]: () => void;
+ [LINE_EVENTS.RECONNECTING]: () => void;
+ [LINE_EVENTS.REGISTERED]: (lineInfo: ILine) => void;
+ [LINE_EVENTS.UNREGISTERED]: () => void;
+ [LINE_EVENTS.INCOMING_CALL]: (callObj: ICall) => void;
+};
+
export type CallEventTypes = {
[CALL_EVENT_KEYS.ALERTING]: (callId: CallId) => void;
[CALL_EVENT_KEYS.CALL_ERROR]: (error: CallError) => void;
@@ -207,8 +231,6 @@ export type CallHistoryEventTypes = {
/* External Eventing End */
/** Internal Eventing Start */
-// https://sqbu-github.cisco.com/pages/webrtc-calling/mobius/mobius-api-spec/docs/async.html#operation-publish-calls
-
enum CALL_STATE {
HELD = 'held',
REMOTE_HELD = 'remoteheld',
diff --git a/packages/calling/src/Metrics/index.test.ts b/packages/calling/src/Metrics/index.test.ts
index 733859d703d..a251d90f429 100644
--- a/packages/calling/src/Metrics/index.test.ts
+++ b/packages/calling/src/Metrics/index.test.ts
@@ -5,7 +5,7 @@ import {METRIC_TYPE, METRIC_EVENT, REG_ACTION, VOICEMAIL_ACTION} from './types';
import {VERSION} from '../CallingClient/constants';
import {createClientError} from '../Errors/catalog/CallingDeviceError';
import {CallErrorObject, ErrorObject, ERROR_LAYER, ERROR_TYPE} from '../Errors/types';
-import {MobiusStatus, ServiceIndicator} from '../common/types';
+import {RegistrationStatus, ServiceIndicator} from '../common/types';
import log from '../Logger';
import {createCallError} from '../Errors/catalog/CallError';
@@ -67,7 +67,12 @@ describe('CALLING: Metric tests', () => {
it('submit registration failure metric', () => {
metricManager.setDeviceInfo(mockDeviceInfo);
- const clientError = createClientError('', {}, ERROR_TYPE.DEFAULT, MobiusStatus.DEFAULT);
+ const clientError = createClientError(
+ '',
+ {},
+ ERROR_TYPE.DEFAULT,
+ RegistrationStatus.INACTIVE
+ );
const err = {};
err.context = {};
diff --git a/packages/calling/src/SDKConnector/types.ts b/packages/calling/src/SDKConnector/types.ts
index d12f68abd97..6df1dfb67e5 100644
--- a/packages/calling/src/SDKConnector/types.ts
+++ b/packages/calling/src/SDKConnector/types.ts
@@ -16,7 +16,7 @@ export type ServiceHost = {
ttl: number;
priority: number;
id: string;
- homeCluster: boolean;
+ homeCluster?: boolean;
};
export type Model = {
@@ -97,6 +97,7 @@ export interface WebexSDK {
presence: unknown;
support: unknown;
services: {
+ _hostCatalog: Record;
_serviceUrls: {
mobius: string;
identity: string;
diff --git a/packages/calling/src/common/Utils.test.ts b/packages/calling/src/common/Utils.test.ts
index 78d990d9225..e480b3497b9 100644
--- a/packages/calling/src/common/Utils.test.ts
+++ b/packages/calling/src/common/Utils.test.ts
@@ -13,11 +13,11 @@ import {
CallDirection,
CallType,
DecodeType,
- MobiusStatus,
ServiceIndicator,
SORT,
WebexRequestPayload,
CALLING_BACKEND,
+ RegistrationStatus,
} from './types';
import log from '../Logger';
import {
@@ -300,7 +300,7 @@ describe('Registration Tests', () => {
mockErrorEvent.message,
mockErrorEvent.context,
mockErrorEvent.type,
- MobiusStatus.ACTIVE
+ RegistrationStatus.ACTIVE
);
handleRegistrationErrors(webexPayload, mockEmitterCb, logObj, mockRestoreCb);
diff --git a/packages/calling/src/common/Utils.ts b/packages/calling/src/common/Utils.ts
index e8973656a8f..0d3fcf45d64 100644
--- a/packages/calling/src/common/Utils.ts
+++ b/packages/calling/src/common/Utils.ts
@@ -1,6 +1,5 @@
/* eslint-disable no-fallthrough */
/* eslint-disable no-underscore-dangle */
-/* eslint-disable valid-jsdoc */
/* eslint-disable @typescript-eslint/no-shadow */
import * as platform from 'platform';
import {restoreRegistrationCallBack} from '../CallingClient/registration/types';
@@ -36,7 +35,7 @@ import {
HTTP_METHODS,
IDeviceInfo,
MobiusServers,
- MobiusStatus,
+ RegistrationStatus,
SORT,
ServiceData,
ServiceIndicator,
@@ -120,7 +119,7 @@ import {scimResponseBody} from '../CallingClient/calling/CallerId/types';
import SDKConnector from '../SDKConnector';
import {CallSettingResponse} from '../CallSettings/types';
import {ContactResponse} from '../Contacts/types';
-import {LineErrorEmitterCallback, LineStatus} from '../CallingClient/line/types';
+import {LineErrorEmitterCallback} from '../CallingClient/line/types';
import {LineError, createLineError} from '../Errors/catalog/LineError';
export function filterMobiusUris(mobiusServers: MobiusServers, defaultMobiusUrl: string) {
@@ -215,7 +214,7 @@ function updateLineErrorContext(
errContext: ErrorContext,
type: ERROR_TYPE,
message: string,
- status: LineStatus,
+ status: RegistrationStatus,
lineError: LineError
) {
const errObj = {};
@@ -258,13 +257,13 @@ function updateErrorContext(
* @param file - File name from where error got reported.
*/
export function emitFinalFailure(emitterCb: LineErrorEmitterCallback, loggerContext: LogContext) {
- const clientError = createLineError('', {}, ERROR_TYPE.DEFAULT, LineStatus.INACTIVE);
+ const clientError = createLineError('', {}, ERROR_TYPE.DEFAULT, RegistrationStatus.INACTIVE);
updateLineErrorContext(
loggerContext,
ERROR_TYPE.SERVICE_UNAVAILABLE,
'An unknown error occurred. Wait a moment and try again. Please contact the administrator if the problem persists.',
- LineStatus.INACTIVE,
+ RegistrationStatus.INACTIVE,
clientError
);
emitterCb(clientError);
@@ -292,7 +291,7 @@ export async function handleRegistrationErrors(
loggerContext: LogContext,
restoreRegCb?: restoreRegistrationCallBack
): Promise {
- const lineError = createLineError('', {}, ERROR_TYPE.DEFAULT, LineStatus.INACTIVE);
+ const lineError = createLineError('', {}, ERROR_TYPE.DEFAULT, RegistrationStatus.INACTIVE);
const errorCode = Number(err.statusCode);
let finalError = false;
@@ -307,7 +306,7 @@ export async function handleRegistrationErrors(
loggerContext,
ERROR_TYPE.TOKEN_ERROR,
'User is unauthorized due to an expired token. Sign out, then sign back in.',
- LineStatus.INACTIVE,
+ RegistrationStatus.INACTIVE,
lineError
);
@@ -321,7 +320,7 @@ export async function handleRegistrationErrors(
loggerContext,
ERROR_TYPE.SERVER_ERROR,
'An unknown error occurred while placing the request. Wait a moment and try again.',
- LineStatus.INACTIVE,
+ RegistrationStatus.INACTIVE,
lineError
);
@@ -335,7 +334,7 @@ export async function handleRegistrationErrors(
loggerContext,
ERROR_TYPE.SERVICE_UNAVAILABLE,
'An error occurred on the server while processing the request. Wait a moment and try again.',
- LineStatus.INACTIVE,
+ RegistrationStatus.INACTIVE,
lineError
);
@@ -352,7 +351,7 @@ export async function handleRegistrationErrors(
loggerContext,
ERROR_TYPE.FORBIDDEN_ERROR,
'An unauthorized action has been received. This action has been blocked. Please contact the administrator if this persists.',
- LineStatus.INACTIVE,
+ RegistrationStatus.INACTIVE,
lineError
);
@@ -381,7 +380,7 @@ export async function handleRegistrationErrors(
loggerContext,
ERROR_TYPE.FORBIDDEN_ERROR,
errorMessage,
- LineStatus.INACTIVE,
+ RegistrationStatus.INACTIVE,
lineError
);
log.warn(errorMessage, loggerContext);
@@ -395,7 +394,7 @@ export async function handleRegistrationErrors(
loggerContext,
ERROR_TYPE.FORBIDDEN_ERROR,
errorMessage,
- LineStatus.INACTIVE,
+ RegistrationStatus.INACTIVE,
lineError
);
log.warn(errorMessage, loggerContext);
@@ -409,7 +408,7 @@ export async function handleRegistrationErrors(
loggerContext,
ERROR_TYPE.FORBIDDEN_ERROR,
errorMessage,
- LineStatus.INACTIVE,
+ RegistrationStatus.INACTIVE,
lineError
);
log.warn(errorMessage, loggerContext);
@@ -426,7 +425,7 @@ export async function handleRegistrationErrors(
loggerContext,
ERROR_TYPE.NOT_FOUND,
'The client has unregistered. Please wait for the client to register before attempting the call. If error persists, sign out, sign back in and attempt the call.',
- LineStatus.INACTIVE,
+ RegistrationStatus.INACTIVE,
lineError
);
emitterCb(lineError, finalError);
@@ -438,7 +437,7 @@ export async function handleRegistrationErrors(
loggerContext,
ERROR_TYPE.DEFAULT,
'Unknown error',
- LineStatus.INACTIVE,
+ RegistrationStatus.INACTIVE,
lineError
);
log.warn(`Unknown Error`, loggerContext);
@@ -461,7 +460,7 @@ export async function handleCallingClientErrors(
emitterCb: CallingClientErrorEmitterCallback,
loggerContext: LogContext
): Promise {
- const clientError = createClientError('', {}, ERROR_TYPE.DEFAULT, MobiusStatus.DEFAULT);
+ const clientError = createClientError('', {}, ERROR_TYPE.DEFAULT, RegistrationStatus.INACTIVE);
const errorCode = Number(err.statusCode);
const finalError = false;
@@ -1251,14 +1250,6 @@ export async function resolveCallerIdDisplay(filter: string) {
displayResult.avatarSrc = photo ? photo.value : 'unknown';
displayResult.id = scimResource.id;
-
- log.info(
- `Extracted details:- name: ${displayResult.name} , number: ${displayResult.num}, photo: ${displayResult.avatarSrc}, id: ${displayResult.id}`,
- {
- file: UTILS_FILE,
- method: 'resolveCallerIdDisplay',
- }
- );
}
return displayResult;
diff --git a/packages/calling/src/common/testUtil.ts b/packages/calling/src/common/testUtil.ts
index 3a0691f5a8d..a3ef45bb5f1 100644
--- a/packages/calling/src/common/testUtil.ts
+++ b/packages/calling/src/common/testUtil.ts
@@ -66,6 +66,7 @@ export function getTestUtilsWebex() {
presence: jest.fn(),
support: jest.fn(),
services: {
+ _hostCatalog: {},
_serviceUrls: {
mobius: 'https://mobius.aintgen-a-1.int.infra.webex.com/api/v1',
identity: 'https://identity-b-us.webex.com',
diff --git a/packages/calling/src/common/types.ts b/packages/calling/src/common/types.ts
index bf13432cd38..a5ef4d22b84 100644
--- a/packages/calling/src/common/types.ts
+++ b/packages/calling/src/common/types.ts
@@ -14,9 +14,10 @@ export enum HTTP_METHODS {
DELETE = 'DELETE',
}
-export enum MobiusStatus {
+export enum RegistrationStatus {
+ IDLE = 'IDLE',
ACTIVE = 'active',
- DEFAULT = 'default',
+ INACTIVE = 'inactive',
}
export enum CALLING_BACKEND {
diff --git a/packages/calling/src/index.ts b/packages/calling/src/index.ts
index 85b3c14592b..cdb92097f7e 100644
--- a/packages/calling/src/index.ts
+++ b/packages/calling/src/index.ts
@@ -16,3 +16,39 @@ export {
Logger,
NoiseReductionEffect,
};
+
+export {ERROR_LAYER, ERROR_TYPE} from './Errors/types';
+export {ICallingClient} from './CallingClient/types';
+export {ICallHistory, JanusResponseEvent} from './CallHistory/types';
+export {
+ CallForwardSetting,
+ CallForwardAlwaysSetting,
+ CallSettingResponse,
+ ICallSettings,
+ ToggleSetting,
+ VoicemailSetting,
+} from './CallSettings/types';
+export {Contact, ContactResponse, GroupType, IContacts} from './Contacts/types';
+export {IVoicemail, SummaryInfo, VoicemailResponseEvent} from './Voicemail/types';
+export {ILine, LINE_EVENTS} from './CallingClient/line/types';
+export {
+ CALLING_CLIENT_EVENT_KEYS,
+ CALL_EVENT_KEYS,
+ CallerIdDisplay,
+ Disposition,
+ LINE_EVENT_KEYS,
+ COMMON_EVENT_KEYS,
+ UserSession,
+} from './Events/types';
+export {
+ CallDetails,
+ CallDirection,
+ CallType,
+ DisplayInformation,
+ SORT,
+ SORT_BY,
+} from './common/types';
+export {CallError, LineError} from './Errors';
+export {ICall, TransferType} from './CallingClient/calling/types';
+export {LOGGER} from './Logger/types';
+export {LocalMicrophoneStream} from '@webex/media-helpers';
diff --git a/packages/webex/package.json b/packages/webex/package.json
index fe7c1ec63e2..3cd9d1254d6 100644
--- a/packages/webex/package.json
+++ b/packages/webex/package.json
@@ -9,6 +9,7 @@
"Kesava Krishnan Madavan ",
"Priya Kesari ",
"Rajesh Kumar ",
+ "Shreyas Sharma ",
"Sreekanth Narayanan "
],
"main": "dist/index.js",
diff --git a/tooling/babel-plugin-inject-package-version.js b/tooling/babel-plugin-inject-package-version.js
index 69515e739b1..750da6a8dca 100644
--- a/tooling/babel-plugin-inject-package-version.js
+++ b/tooling/babel-plugin-inject-package-version.js
@@ -4,7 +4,7 @@
const t = require('@babel/types');
-const {version} = require('../package.json');
+const {version} = require('../packages/webex/package.json');
/**
* Simple babel transform for ensuring that every WebexPlugin (and WebexCore)
diff --git a/tooling/lib/test/mocha.js b/tooling/lib/test/mocha.js
index 08f50437018..6d01b072510 100644
--- a/tooling/lib/test/mocha.js
+++ b/tooling/lib/test/mocha.js
@@ -32,12 +32,12 @@ async function run(options, files) {
const cfg = {
diff: true,
bail: options.bail,
- retries: process.env.JENKINS || process.env.CIRCLECI || process.env.CI ? 1 : 0,
+ retries: process.env.JENKINS || process.env.CI ? 1 : 0,
timeout: 30000,
grep: new RegExp(options.grep.join('|')),
};
- if (options.xunit || process.env.COVERAGE || process.env.CIRCLECI || process.env.CI) {
+ if (options.xunit || process.env.COVERAGE || process.env.CI) {
cfg.reporter = 'mocha-junit-reporter';
cfg.reporterOptions = {
mochaFile: options.output,
diff --git a/wdio.conf.js b/wdio.conf.js
index 0d87f003e43..ef112a76eaf 100644
--- a/wdio.conf.js
+++ b/wdio.conf.js
@@ -41,7 +41,7 @@ require('@babel/register')({
const webpackConfig = require('./webpack.config')();
const PORT = process.env.PORT || 8000;
-const CI = !!(process.env.JENKINS || process.env.CIRCLECI || process.env.CI || process.env.SAUCE);
+const CI = !!(process.env.JENKINS || process.env.CI || process.env.SAUCE);
exports.config = {
//
diff --git a/wdio.conf.mobile.js b/wdio.conf.mobile.js
index 2964f8fe7b9..4cd1f721c0c 100644
--- a/wdio.conf.mobile.js
+++ b/wdio.conf.mobile.js
@@ -39,7 +39,7 @@ require('@babel/register')({
const webpackConfig = require('./webpack.config')();
const PORT = process.env.PORT || 8000;
-const CI = !!(process.env.JENKINS || process.env.CIRCLECI || process.env.CI || process.env.SAUCE);
+const CI = !!(process.env.JENKINS || process.env.CI || process.env.SAUCE);
const LOCALHOST_ALIAS = CI
? process.env.LOCALHOST_ALIAS || 'local.localhost'
: os.networkInterfaces().en0.find((elm) => elm.family === 'IPv4').address;
diff --git a/yarn.lock b/yarn.lock
index c16f80cd7c8..a58da0cf61a 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -6989,7 +6989,7 @@ __metadata:
"@typescript-eslint/eslint-plugin": 5.38.1
"@typescript-eslint/parser": 5.38.1
"@web/dev-server": 0.1.30
- "@webex/internal-media-core": 2.0.0
+ "@webex/internal-media-core": 2.2.2
"@webex/media-helpers": "workspace:^"
async-mutex: 0.4.0
buffer: 6.0.3
@@ -7285,20 +7285,20 @@ __metadata:
languageName: node
linkType: hard
-"@webex/internal-media-core@npm:2.0.0, @webex/internal-media-core@npm:^2.0.0":
- version: 2.0.0
- resolution: "@webex/internal-media-core@npm:2.0.0"
+"@webex/internal-media-core@npm:2.2.2, @webex/internal-media-core@npm:^2.2.2":
+ version: 2.2.2
+ resolution: "@webex/internal-media-core@npm:2.2.2"
dependencies:
"@babel/runtime": ^7.18.9
- "@webex/ts-sdp": 1.4.1
- "@webex/web-client-media-engine": ^3.3.1
+ "@webex/ts-sdp": 1.6.0
+ "@webex/web-client-media-engine": 3.11.1
detectrtc: ^1.4.1
events: ^3.3.0
typed-emitter: ^2.1.0
uuid: ^8.3.2
webrtc-adapter: ^8.1.2
xstate: ^4.30.6
- checksum: 5f4b66f50a57f710dc12d74d29f0f97a7a948bcda8479cc540baf356d8369442d474164bec419ab81b51f0f0a632bdea6a79e31bdb77c071768d50c9aab06740
+ checksum: c5ca3ff1e186feac627564f27469e019a87de4466a2f98212a7e475fff8dd12a6857023ecf99b2463ee88b7521613d6a2702f5bd1b3d33652c0d3dfba2fa8e35
languageName: node
linkType: hard
@@ -7957,19 +7957,10 @@ __metadata:
languageName: unknown
linkType: soft
-"@webex/json-multistream@npm:^2.0.1":
- version: 2.1.0
- resolution: "@webex/json-multistream@npm:2.1.0"
- checksum: 7d2ab123ed121d7f6cb1a0b3b9a8b2e97115eb1364ff0f5f2074a2fb976faf7844e6a3d4e1cdec8f3cc517caf8e26ba812bf0068bcaa005f5c1bb6792bc840ac
- languageName: node
- linkType: hard
-
-"@webex/ladon-ts@npm:^4.2.3":
- version: 4.2.3
- resolution: "@webex/ladon-ts@npm:4.2.3"
- dependencies:
- onnxruntime-web: ^1.15.1
- checksum: 2c4f7754a2957cb03ecc8bc9f0a27052b4eb4b4babda59840b31fc44dd01022e581b0d83bd104d61fcd89d423420fbc23e44f89169beb608f78c4f2984145c9d
+"@webex/json-multistream@npm:^2.1.1":
+ version: 2.1.1
+ resolution: "@webex/json-multistream@npm:2.1.1"
+ checksum: 6808b8fb1b6a8c2a01dc397c4490d73fbb2ce73ad5f15c3030c904ee2ddc1947f40a0b6aa1c51e2a5a9b5dd68c92945acbb8916918e80c99e24cc6359c7498b5
languageName: node
linkType: hard
@@ -8056,13 +8047,13 @@ __metadata:
"@babel/preset-typescript": 7.22.11
"@webex/babel-config-legacy": "workspace:^"
"@webex/eslint-config-legacy": "workspace:^"
- "@webex/internal-media-core": ^2.0.0
+ "@webex/internal-media-core": ^2.2.2
"@webex/jest-config-legacy": "workspace:^"
"@webex/legacy-tools": "workspace:^"
"@webex/test-helper-chai": "workspace:^"
"@webex/test-helper-mock-webex": "workspace:^"
"@webex/ts-events": ^1.1.0
- "@webex/web-media-effects": ^2.13.3
+ "@webex/web-media-effects": ^2.15.6
eslint: ^8.24.0
sinon: ^9.2.4
languageName: unknown
@@ -8555,13 +8546,13 @@ __metadata:
languageName: unknown
linkType: soft
-"@webex/rtcstats@npm:^1.0.2":
- version: 1.0.2
- resolution: "@webex/rtcstats@npm:1.0.2"
+"@webex/rtcstats@npm:^1.1.1":
+ version: 1.1.1
+ resolution: "@webex/rtcstats@npm:1.1.1"
dependencies:
"@types/node": ^18.7.6
uuid: ^8.3.2
- checksum: 1015597ba3c8b05c84b356f4cf7507cb1a3f668c4acc61924e0524b4119fff9d5ad808fe41a40965b6aa9dd36e8fdd4652e3af63dcd40b8668b5e26a7ede6f31
+ checksum: e357651ffbcece7c8eef9aaa784192ca762fa4b77e1609061b26c51df0d10306bfb4c0ea2fb3490bdf080a552b5fa105fbe0cd40e5bf01f05e2bc0cf573ed080
languageName: node
linkType: hard
@@ -8951,17 +8942,10 @@ __metadata:
languageName: node
linkType: hard
-"@webex/ts-sdp@npm:1.4.1":
- version: 1.4.1
- resolution: "@webex/ts-sdp@npm:1.4.1"
- checksum: 457b92ac4b5fd3d66a9fc8487a657bd1c4edf3fd4ac4868661f2ccf12b158f66ddee6cc06e1aaf39f7c453cd1518d0289ea31ca6bfe4537f6b2577743caa47a5
- languageName: node
- linkType: hard
-
-"@webex/ts-sdp@npm:1.5.0":
- version: 1.5.0
- resolution: "@webex/ts-sdp@npm:1.5.0"
- checksum: 6e8df92efc8660fec0376a65a214bfa75437d3473829f73b461f9e96d2c2eb0725ea35589b6947737b13b2736c38c5b1f66379651d203cd1ccde6f33aa4632c2
+"@webex/ts-sdp@npm:1.6.0":
+ version: 1.6.0
+ resolution: "@webex/ts-sdp@npm:1.6.0"
+ checksum: 37d826c7226e3ba3f7231d8d06e23645a6d9910d714c36a7c5e86c7690f857bfea20f4d9f2064edb0c367db0f899a23db5af304ba10b4cd963130a21c155c852
languageName: node
linkType: hard
@@ -8978,45 +8962,43 @@ __metadata:
languageName: unknown
linkType: soft
-"@webex/web-client-media-engine@npm:^3.3.1":
- version: 3.5.0
- resolution: "@webex/web-client-media-engine@npm:3.5.0"
+"@webex/web-capabilities@npm:^1.1.0, @webex/web-capabilities@npm:^1.1.1":
+ version: 1.2.0
+ resolution: "@webex/web-capabilities@npm:1.2.0"
dependencies:
- "@webex/json-multistream": ^2.0.1
- "@webex/rtcstats": ^1.0.2
- "@webex/ts-events": ^1.0.1
- "@webex/ts-sdp": 1.5.0
- "@webex/webrtc-core": 2.1.0
- async: ^3.2.4
bowser: ^2.11.0
- js-logger: ^1.6.1
- typed-emitter: ^2.1.0
- uuid: ^8.3.2
- checksum: 44b452a03106a200fca7a73ff9e4acd22895cda5e087646d8aae19254793b188952c9aca20c387ce2f6f234cff081e2bc8246e3ae88c81e0b4a86a582d7f38ad
+ checksum: 69bf1521485c0a29f10edc85c06fee33a983f1363639e6662bd65389602f4e2ded8e37be6d3cf845bd6efef6712680fce7592e175d5e1e33291dc2769ac66c4c
languageName: node
linkType: hard
-"@webex/web-media-effects@npm:^2.13.3":
- version: 2.13.4
- resolution: "@webex/web-media-effects@npm:2.13.4"
+"@webex/web-client-media-engine@npm:3.11.1":
+ version: 3.11.1
+ resolution: "@webex/web-client-media-engine@npm:3.11.1"
dependencies:
- "@webex/ladon-ts": ^4.2.4
- events: ^3.3.0
+ "@webex/json-multistream": ^2.1.1
+ "@webex/rtcstats": ^1.1.1
+ "@webex/ts-events": ^1.0.1
+ "@webex/ts-sdp": 1.6.0
+ "@webex/web-capabilities": ^1.1.1
+ "@webex/webrtc-core": 2.3.0
+ async: ^3.2.4
js-logger: ^1.6.1
- typed-emitter: ^1.4.0
- checksum: 494c96404a82eeebc07fb634cffed8180ce44cd9b93b066a5b16490a83e01f19ae6622a3314cc9d8b44967d6a0dfdf8761354432a26f8316a28ef7f13a19f82b
+ typed-emitter: ^2.1.0
+ uuid: ^8.3.2
+ checksum: 7103c9793030b039664e29cbbaef3d9a74814e3724b518db40fd6124e41f58b59d9af91f7ff83572318df0f13a1f07600f0d6424f2f273910b4b2ed9cc953da2
languageName: node
linkType: hard
-"@webex/web-media-effects@npm:^2.7.0":
- version: 2.11.3
- resolution: "@webex/web-media-effects@npm:2.11.3"
+"@webex/web-media-effects@npm:^2.15.6":
+ version: 2.15.6
+ resolution: "@webex/web-media-effects@npm:2.15.6"
dependencies:
- "@webex/ladon-ts": ^4.2.3
+ "@webex/ladon-ts": ^4.2.4
events: ^3.3.0
js-logger: ^1.6.1
typed-emitter: ^1.4.0
- checksum: 8fbbd94dbedaf5f24c89e67268f0ee0ba85f68673166d79e6e50f69cf3bfa216c1f27ba7e7ea4480514647771904d535eb34ec6ec039cfe0afbc8e2c02d7ea76
+ uuid: ^9.0.1
+ checksum: cd37e0c7b37a7a6611ae14ca1926453cd536c3259bfffc6b1ca2d3a804caab97c44101c31cccdb8b91a7d03cc4e0fc60d0b3785e4c6fcde0f937ceb055fcf977
languageName: node
linkType: hard
@@ -9110,17 +9092,18 @@ __metadata:
languageName: unknown
linkType: soft
-"@webex/webrtc-core@npm:2.1.0":
- version: 2.1.0
- resolution: "@webex/webrtc-core@npm:2.1.0"
+"@webex/webrtc-core@npm:2.3.0":
+ version: 2.3.0
+ resolution: "@webex/webrtc-core@npm:2.3.0"
dependencies:
"@webex/ts-events": ^1.1.0
- "@webex/web-media-effects": ^2.7.0
+ "@webex/web-capabilities": ^1.1.0
+ "@webex/web-media-effects": ^2.15.6
events: ^3.3.0
js-logger: ^1.6.1
typed-emitter: ^2.1.0
webrtc-adapter: ^8.1.2
- checksum: e715155031ff85c8c0799910a4f78a3c1683f069e0c1419e09683b1065783f4a40735bd2f60c3725da7e1609995ba76183d62f62da75234cbca11ae52c471d71
+ checksum: ecbdce95478f3db34ddeb1a7308fba039aeb4b7e9a0111e8efa804e8f8b1aca5d7a7720020ea0557aa107bbc7c55fe11443e308b5b926fca55364abc3c5ede7d
languageName: node
linkType: hard
@@ -30045,6 +30028,15 @@ __metadata:
languageName: node
linkType: hard
+"uuid@npm:^9.0.1":
+ version: 9.0.1
+ resolution: "uuid@npm:9.0.1"
+ bin:
+ uuid: dist/bin/uuid
+ checksum: 39931f6da74e307f51c0fb463dc2462807531dc80760a9bff1e35af4316131b4fc3203d16da60ae33f07fdca5b56f3f1dd662da0c99fea9aaeab2004780cc5f4
+ languageName: node
+ linkType: hard
+
"uvu@npm:^0.5.0":
version: 0.5.6
resolution: "uvu@npm:0.5.6"