├── .gitignore ├── README.md ├── docs ├── assets │ ├── extra.css │ ├── fonts.js │ ├── rc-developers_logo.png │ ├── ringcentral-developers_embeddable-web-widget.png │ └── ringcentral-developers_embeddable-web-widget_2.png ├── favicon.ico ├── index.md ├── java_desktop_app │ └── tutorial │ │ ├── index.md │ │ └── java_desktop_app_screenshot.png ├── salesforce_lightning │ ├── code │ │ ├── SLIDES.md │ │ ├── app-gallery_salesforce.png │ │ ├── ringcentral-web-widget-stack-2.png │ │ ├── ringcentral-web-widget-stack.png │ │ ├── ringcentral-web-widget-stack.svg │ │ ├── ringcentral-web-widget.png │ │ ├── ringcentral-web-widget_2200x.png │ │ ├── ringcentral_connectcentral2017_logo.png │ │ ├── ringcentral_widget_instructions.png │ │ ├── ringcentral_widget_instructions_full.png │ │ ├── salesforce_CTI-Architecture-Overview.png │ │ ├── salesforce_demo-0.1.0_config_CallCenterDefinition.xml │ │ ├── salesforce_demo-0.1.1_config_RCPhone.vfp │ │ ├── salesforce_demo-0.2.0_click-to-dial_RCPhone.vfp │ │ ├── salesforce_demo-0.3.0_inbound-screen-pop_RCPhoneHelper.apxc │ │ ├── salesforce_demo-0.3.1_inbound-screen-pop_RCPhone.vfp │ │ ├── salesforce_demo-0.4.0_call-logging_RCPhoneHelper.apxc │ │ ├── salesforce_demo-0.4.1_call-logging_RCPhone.vfp │ │ ├── salesforce_demo-1.0.0_RCPhone.vfp │ │ ├── salesforce_demo-1.0.0_RCPhoneHelper.apxc │ │ ├── salesforce_demo-1.0.0_config_CallCenterDefinition.xml │ │ ├── test │ │ │ └── index.html │ │ └── theme │ │ │ └── ringcentral.css │ └── tutorial │ │ ├── index.md │ │ ├── salesforce_step-1.11_select-app.png │ │ ├── salesforce_step-1.12_sfdc-app_add-the-softphone.png │ │ ├── salesforce_step-1.13_sfdc-app_save-the-softphone.png │ │ ├── salesforce_step-1.1_setup.png │ │ ├── salesforce_step-1.4_call-center_import-xml-1.png │ │ ├── salesforce_step-1.5_call-center_manage-call-center-users.png │ │ ├── salesforce_step-1.6_call-center_find-and-add-users.png │ │ ├── salesforce_step-1.8_open-developer-console.png │ │ └── salesforce_step-1.9_new-visualforce-page.png ├── salesforce_lightning_more │ ├── code │ │ ├── CallCenterDefinition.xml │ │ ├── RCPhone.vfp │ │ └── RCPhoneHelper.apxc │ └── tutorial │ │ └── index.md ├── static_crm │ ├── code │ │ ├── assets │ │ │ ├── bootstrap-v4.0.0-beta-example-dashboard.css │ │ │ ├── bootstrap-v4.0.0-beta.min.css │ │ │ ├── bootstrap-v4.0.0-beta.min.js │ │ │ ├── font-awesome-v4.7.0.min.css │ │ │ ├── ie10-viewport-bug-workaround.js │ │ │ ├── jquery-3.2.1.slim.min.js │ │ │ ├── libphonenumber-v0.9.4 │ │ │ │ ├── libphonenumber.js │ │ │ │ ├── libphonenumber_001.js │ │ │ │ ├── libphonenumber_AC.js │ │ │ │ ├── libphonenumber_AD.js │ │ │ │ ├── libphonenumber_AE.js │ │ │ │ ├── libphonenumber_AF.js │ │ │ │ ├── libphonenumber_AG.js │ │ │ │ ├── libphonenumber_AI.js │ │ │ │ ├── libphonenumber_AL.js │ │ │ │ ├── libphonenumber_AM.js │ │ │ │ ├── libphonenumber_AO.js │ │ │ │ ├── libphonenumber_AR.js │ │ │ │ ├── libphonenumber_AS.js │ │ │ │ ├── libphonenumber_AT.js │ │ │ │ ├── libphonenumber_AU.js │ │ │ │ ├── libphonenumber_AW.js │ │ │ │ ├── libphonenumber_AX.js │ │ │ │ ├── libphonenumber_AZ.js │ │ │ │ ├── libphonenumber_BA.js │ │ │ │ ├── libphonenumber_BB.js │ │ │ │ ├── libphonenumber_BD.js │ │ │ │ ├── libphonenumber_BE.js │ │ │ │ ├── libphonenumber_BF.js │ │ │ │ ├── libphonenumber_BG.js │ │ │ │ ├── libphonenumber_BH.js │ │ │ │ ├── libphonenumber_BI.js │ │ │ │ ├── libphonenumber_BJ.js │ │ │ │ ├── libphonenumber_BL.js │ │ │ │ ├── libphonenumber_BM.js │ │ │ │ ├── libphonenumber_BN.js │ │ │ │ ├── libphonenumber_BO.js │ │ │ │ ├── libphonenumber_BQ.js │ │ │ │ ├── libphonenumber_BR.js │ │ │ │ ├── libphonenumber_BS.js │ │ │ │ ├── libphonenumber_BT.js │ │ │ │ ├── libphonenumber_BW.js │ │ │ │ ├── libphonenumber_BY.js │ │ │ │ ├── libphonenumber_BZ.js │ │ │ │ ├── libphonenumber_CA.js │ │ │ │ ├── libphonenumber_CC.js │ │ │ │ ├── libphonenumber_CD.js │ │ │ │ ├── libphonenumber_CF.js │ │ │ │ ├── libphonenumber_CG.js │ │ │ │ ├── libphonenumber_CH.js │ │ │ │ ├── libphonenumber_CI.js │ │ │ │ ├── libphonenumber_CK.js │ │ │ │ ├── libphonenumber_CL.js │ │ │ │ ├── libphonenumber_CM.js │ │ │ │ ├── libphonenumber_CN.js │ │ │ │ ├── libphonenumber_CO.js │ │ │ │ ├── libphonenumber_CR.js │ │ │ │ ├── libphonenumber_CU.js │ │ │ │ ├── libphonenumber_CV.js │ │ │ │ ├── libphonenumber_CW.js │ │ │ │ ├── libphonenumber_CX.js │ │ │ │ ├── libphonenumber_CY.js │ │ │ │ ├── libphonenumber_CZ.js │ │ │ │ ├── libphonenumber_DE.js │ │ │ │ ├── libphonenumber_DJ.js │ │ │ │ ├── libphonenumber_DK.js │ │ │ │ ├── libphonenumber_DM.js │ │ │ │ ├── libphonenumber_DO.js │ │ │ │ ├── libphonenumber_DZ.js │ │ │ │ ├── libphonenumber_EC.js │ │ │ │ ├── libphonenumber_EE.js │ │ │ │ ├── libphonenumber_EG.js │ │ │ │ ├── libphonenumber_EH.js │ │ │ │ ├── libphonenumber_ER.js │ │ │ │ ├── libphonenumber_ES.js │ │ │ │ ├── libphonenumber_ET.js │ │ │ │ ├── libphonenumber_FI.js │ │ │ │ ├── libphonenumber_FJ.js │ │ │ │ ├── libphonenumber_FK.js │ │ │ │ ├── libphonenumber_FM.js │ │ │ │ ├── libphonenumber_FO.js │ │ │ │ ├── libphonenumber_FR.js │ │ │ │ ├── libphonenumber_GA.js │ │ │ │ ├── libphonenumber_GB.js │ │ │ │ ├── libphonenumber_GD.js │ │ │ │ ├── libphonenumber_GE.js │ │ │ │ ├── libphonenumber_GF.js │ │ │ │ ├── libphonenumber_GG.js │ │ │ │ ├── libphonenumber_GH.js │ │ │ │ ├── libphonenumber_GI.js │ │ │ │ ├── libphonenumber_GL.js │ │ │ │ ├── libphonenumber_GM.js │ │ │ │ ├── libphonenumber_GN.js │ │ │ │ ├── libphonenumber_GP.js │ │ │ │ ├── libphonenumber_GQ.js │ │ │ │ ├── libphonenumber_GR.js │ │ │ │ ├── libphonenumber_GT.js │ │ │ │ ├── libphonenumber_GU.js │ │ │ │ ├── libphonenumber_GW.js │ │ │ │ ├── libphonenumber_GY.js │ │ │ │ ├── libphonenumber_HK.js │ │ │ │ ├── libphonenumber_HN.js │ │ │ │ ├── libphonenumber_HR.js │ │ │ │ ├── libphonenumber_HT.js │ │ │ │ ├── libphonenumber_HU.js │ │ │ │ ├── libphonenumber_ID.js │ │ │ │ ├── libphonenumber_IE.js │ │ │ │ ├── libphonenumber_IL.js │ │ │ │ ├── libphonenumber_IM.js │ │ │ │ ├── libphonenumber_IN.js │ │ │ │ ├── libphonenumber_IO.js │ │ │ │ ├── libphonenumber_IQ.js │ │ │ │ ├── libphonenumber_IR.js │ │ │ │ ├── libphonenumber_IS.js │ │ │ │ ├── libphonenumber_IT.js │ │ │ │ ├── libphonenumber_JE.js │ │ │ │ ├── libphonenumber_JM.js │ │ │ │ ├── libphonenumber_JO.js │ │ │ │ ├── libphonenumber_JP.js │ │ │ │ ├── libphonenumber_KE.js │ │ │ │ ├── libphonenumber_KG.js │ │ │ │ ├── libphonenumber_KH.js │ │ │ │ ├── libphonenumber_KI.js │ │ │ │ ├── libphonenumber_KM.js │ │ │ │ ├── libphonenumber_KN.js │ │ │ │ ├── libphonenumber_KP.js │ │ │ │ ├── libphonenumber_KR.js │ │ │ │ ├── libphonenumber_KW.js │ │ │ │ ├── libphonenumber_KY.js │ │ │ │ ├── libphonenumber_KZ.js │ │ │ │ ├── libphonenumber_LA.js │ │ │ │ ├── libphonenumber_LB.js │ │ │ │ ├── libphonenumber_LC.js │ │ │ │ ├── libphonenumber_LI.js │ │ │ │ ├── libphonenumber_LK.js │ │ │ │ ├── libphonenumber_LR.js │ │ │ │ ├── libphonenumber_LS.js │ │ │ │ ├── libphonenumber_LT.js │ │ │ │ ├── libphonenumber_LU.js │ │ │ │ ├── libphonenumber_LV.js │ │ │ │ ├── libphonenumber_LY.js │ │ │ │ ├── libphonenumber_MA.js │ │ │ │ ├── libphonenumber_MC.js │ │ │ │ ├── libphonenumber_MD.js │ │ │ │ ├── libphonenumber_ME.js │ │ │ │ ├── libphonenumber_MF.js │ │ │ │ ├── libphonenumber_MG.js │ │ │ │ ├── libphonenumber_MH.js │ │ │ │ ├── libphonenumber_MK.js │ │ │ │ ├── libphonenumber_ML.js │ │ │ │ ├── libphonenumber_MM.js │ │ │ │ ├── libphonenumber_MN.js │ │ │ │ ├── libphonenumber_MO.js │ │ │ │ ├── libphonenumber_MP.js │ │ │ │ ├── libphonenumber_MQ.js │ │ │ │ ├── libphonenumber_MR.js │ │ │ │ ├── libphonenumber_MS.js │ │ │ │ ├── libphonenumber_MT.js │ │ │ │ ├── libphonenumber_MU.js │ │ │ │ ├── libphonenumber_MV.js │ │ │ │ ├── libphonenumber_MW.js │ │ │ │ ├── libphonenumber_MX.js │ │ │ │ ├── libphonenumber_MY.js │ │ │ │ ├── libphonenumber_MZ.js │ │ │ │ ├── libphonenumber_NA.js │ │ │ │ ├── libphonenumber_NC.js │ │ │ │ ├── libphonenumber_NE.js │ │ │ │ ├── libphonenumber_NF.js │ │ │ │ ├── libphonenumber_NG.js │ │ │ │ ├── libphonenumber_NI.js │ │ │ │ ├── libphonenumber_NL.js │ │ │ │ ├── libphonenumber_NO.js │ │ │ │ ├── libphonenumber_NP.js │ │ │ │ ├── libphonenumber_NR.js │ │ │ │ ├── libphonenumber_NU.js │ │ │ │ ├── libphonenumber_NZ.js │ │ │ │ ├── libphonenumber_OM.js │ │ │ │ ├── libphonenumber_PA.js │ │ │ │ ├── libphonenumber_PE.js │ │ │ │ ├── libphonenumber_PF.js │ │ │ │ ├── libphonenumber_PG.js │ │ │ │ ├── libphonenumber_PH.js │ │ │ │ ├── libphonenumber_PK.js │ │ │ │ ├── libphonenumber_PL.js │ │ │ │ ├── libphonenumber_PM.js │ │ │ │ ├── libphonenumber_PR.js │ │ │ │ ├── libphonenumber_PS.js │ │ │ │ ├── libphonenumber_PT.js │ │ │ │ ├── libphonenumber_PW.js │ │ │ │ ├── libphonenumber_PY.js │ │ │ │ ├── libphonenumber_QA.js │ │ │ │ ├── libphonenumber_RE.js │ │ │ │ ├── libphonenumber_RO.js │ │ │ │ ├── libphonenumber_RS.js │ │ │ │ ├── libphonenumber_RU.js │ │ │ │ ├── libphonenumber_RW.js │ │ │ │ ├── libphonenumber_SA.js │ │ │ │ ├── libphonenumber_SB.js │ │ │ │ ├── libphonenumber_SC.js │ │ │ │ ├── libphonenumber_SD.js │ │ │ │ ├── libphonenumber_SE.js │ │ │ │ ├── libphonenumber_SG.js │ │ │ │ ├── libphonenumber_SH.js │ │ │ │ ├── libphonenumber_SI.js │ │ │ │ ├── libphonenumber_SJ.js │ │ │ │ ├── libphonenumber_SK.js │ │ │ │ ├── libphonenumber_SL.js │ │ │ │ ├── libphonenumber_SM.js │ │ │ │ ├── libphonenumber_SN.js │ │ │ │ ├── libphonenumber_SO.js │ │ │ │ ├── libphonenumber_SR.js │ │ │ │ ├── libphonenumber_SS.js │ │ │ │ ├── libphonenumber_ST.js │ │ │ │ ├── libphonenumber_SV.js │ │ │ │ ├── libphonenumber_SX.js │ │ │ │ ├── libphonenumber_SY.js │ │ │ │ ├── libphonenumber_SZ.js │ │ │ │ ├── libphonenumber_TA.js │ │ │ │ ├── libphonenumber_TC.js │ │ │ │ ├── libphonenumber_TD.js │ │ │ │ ├── libphonenumber_TG.js │ │ │ │ ├── libphonenumber_TH.js │ │ │ │ ├── libphonenumber_TJ.js │ │ │ │ ├── libphonenumber_TK.js │ │ │ │ ├── libphonenumber_TL.js │ │ │ │ ├── libphonenumber_TM.js │ │ │ │ ├── libphonenumber_TN.js │ │ │ │ ├── libphonenumber_TO.js │ │ │ │ ├── libphonenumber_TR.js │ │ │ │ ├── libphonenumber_TT.js │ │ │ │ ├── libphonenumber_TV.js │ │ │ │ ├── libphonenumber_TW.js │ │ │ │ ├── libphonenumber_TZ.js │ │ │ │ ├── libphonenumber_UA.js │ │ │ │ ├── libphonenumber_UG.js │ │ │ │ ├── libphonenumber_US.js │ │ │ │ ├── libphonenumber_UY.js │ │ │ │ ├── libphonenumber_UZ.js │ │ │ │ ├── libphonenumber_VA.js │ │ │ │ ├── libphonenumber_VC.js │ │ │ │ ├── libphonenumber_VE.js │ │ │ │ ├── libphonenumber_VG.js │ │ │ │ ├── libphonenumber_VI.js │ │ │ │ ├── libphonenumber_VN.js │ │ │ │ ├── libphonenumber_VU.js │ │ │ │ ├── libphonenumber_WF.js │ │ │ │ ├── libphonenumber_WS.js │ │ │ │ ├── libphonenumber_YE.js │ │ │ │ ├── libphonenumber_YT.js │ │ │ │ ├── libphonenumber_ZA.js │ │ │ │ ├── libphonenumber_ZM.js │ │ │ │ └── libphonenumber_ZW.js │ │ │ └── popper.min.js │ │ ├── data │ │ │ ├── characters_data.js │ │ │ └── characters_methods.js │ │ ├── index.html │ │ └── ringcentral.js │ └── tutorial │ │ ├── index.md │ │ └── static_crm_demo.png └── static_simple │ ├── code │ ├── index.html │ └── static_embed.html │ └── tutorial │ └── index.md └── mkdocs.yml /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | _* 3 | .env -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RingCentral Web Widget + Salesforce Open CTI Tutorial 2 | 3 | [![Docs][docs-readthedocs-img]][docs-readthedocs-url] 4 | [![Community][community-img]][community-url] 5 | [![Twitter][twitter-img]][twitter-url] 6 | 7 | [docs-readthedocs-img]: https://img.shields.io/badge/docs-readthedocs-blue.svg 8 | [docs-readthedocs-url]: http://ringcentral-web-widget-demos.readthedocs.org/ 9 | [community-img]: https://img.shields.io/badge/community-forums-blue 10 | [community-url]: https://devcommunity.ringcentral.com/ringcentraldev 11 | [twitter-img]: https://img.shields.io/twitter/follow/ringcentraldevs.svg?style=social&label=follow 12 | [twitter-url]: https://twitter.com/RingCentralDevs 13 | 14 | This is a set of demos to get started using the RingCentral Web Widget: 15 | 16 | * Embeddable Web Widget: https://github.com/ringcentral/ringcentral-embeddable-voice 17 | * React Component Library: https://github.com/ringcentral/ringcentral-js-widgets 18 | 19 | ## Demos 20 | 21 | The demo files are in the [`docs`](docs) folder so they can be automatically published on [ReadTheDocs.io](http://ringcentral-web-widget-demos.readthedocs.io/) 22 | 23 | | Demo | Description | Click-to-Dial | Click-to-Text | Screen-Pop | Call Log | Live Demo | 24 | |------|-------------|---------------|---------------|------------|----------|-----------| 25 | | [Static Simple](https://ringcentral.github.io/ringcentral-web-widget/) (external) | `tel` and `sms` URI schemes | y | y | n | n | [Live Demo](https://ringcentral.github.io/ringcentral-embeddable/) | 26 | | [Static CRM](http://ringcentral-web-widget-demos.readthedocs.io/en/latest/static_crm/tutorial/) | Static CRM example | y | y | y | n | [Live Demo](https://ringcentral-tutorials.github.io/ringcentral-embeddable-demos/static_crm/code) | 27 | | [Salesforce Lightning](http://ringcentral-web-widget-demos.readthedocs.io/en/latest/salesforce_lightning/tutorial/) | Core use cases | y | n | y | y | [Video](https://www.youtube.com/watch?v=uXZkYNVaGc0) | 28 | | [Salesforce Plus](http://ringcentral-web-widget-demos.readthedocs.io/en/latest/salesforce_lightning_more/tutorial/) | Additional screen pops for Google/LinkedIn Search | y | n | y | y | | 29 | | [Java desktop app using jxBrowser](https://github.com/tylerlong/jxbrowser-webrtc) (external) | Embedding Chromium in a Java app. | y | n | y | n | [Video](https://www.youtube.com/watch?v=SKpLd20b2OM) | 30 | 31 | ### Static CRM Demo 32 | 33 | This is a quick demo showing a CRM with Click-to-Dial, Click-to-Text and Inbound Screen-Pop. 34 | 35 | [![](docs/static_crm/tutorial/static_crm_demo.png)](https://ringcentral-tutorials.github.io/ringcentral-web-widget-demos/static_crm/code/) 36 | -------------------------------------------------------------------------------- /docs/assets/extra.css: -------------------------------------------------------------------------------- 1 | .wy-nav-top { 2 | background-color: #fff; 3 | color: #0073ae; 4 | font-size: 16px; 5 | } 6 | 7 | .wy-side-nav-search { 8 | background-color: #fff; 9 | } 10 | 11 | .wy-side-nav-search input[type=text] { 12 | background-image: url("./img/ico_search.png?1468643959"); 13 | background-position-x: 8px; 14 | background-position-y: 50%; 15 | background-size: initial; 16 | background-repeat: no-repeat; 17 | box-shadow: none; 18 | padding-left: 25px; 19 | } 20 | 21 | .wy-side-nav-search>a { 22 | color: #0073ae; 23 | font-size: 18px; 24 | font-weight: 200; 25 | } 26 | 27 | .wy-side-nav-search input[type=text] { 28 | border: 1px solid #e8e8e8; 29 | border-radius: 3px; 30 | font-size: 14px; 31 | color: #282828; 32 | } 33 | 34 | .wy-nav-side { 35 | background-color: #fff; 36 | 37 | } 38 | 39 | .wy-menu-vertical { 40 | border: 1px solid #e8e8e8; 41 | border-radius: 8px; 42 | } 43 | 44 | .wy-menu-vertical a { 45 | font-size: 14px; 46 | font-weight: 400; 47 | padding: 10px 0px; 48 | color: #585858; 49 | border-bottom: 1px solid #e8e8e8; 50 | } 51 | 52 | .wy-menu-vertical a:visited { 53 | color: #585858; 54 | } 55 | 56 | .wy-menu-vertical a:hover { 57 | background-color: #fff; 58 | } 59 | 60 | .wy-menu-vertical li.toctree-l1 { 61 | margin: 0 20px 0 30px; 62 | } 63 | 64 | .wy-menu-vertical li.toctree-l3 { 65 | margin-left: 20px; 66 | } 67 | 68 | .wy-menu-vertical li a.toctree-l4 { 69 | margin-left: 40px; 70 | } 71 | 72 | .wy-menu-vertical li.current { 73 | background-color: #fff; 74 | } 75 | 76 | .wy-menu-vertical li.current a { 77 | background-color: #fff; 78 | color: #585858; 79 | border: none; 80 | padding: 10px 0; 81 | font-size: 14px; 82 | border-bottom: 1px solid #e8e8e8; 83 | } 84 | 85 | .wy-menu-vertical li.current a:hover { 86 | background-color: #fff; 87 | } 88 | 89 | .wy-menu-vertical li.current>a { 90 | background-color: #fff; 91 | color: #0073ae; 92 | border-bottom: 1px solid #0073ae; 93 | font-weight: bold; 94 | } 95 | 96 | .wy-menu-vertical .subnav a { 97 | padding: 10px 0; 98 | color: #585858; 99 | } 100 | 101 | .wy-menu-vertical .subnav li.toctree-l1 { 102 | margin: 0 20px 0 50px; 103 | } 104 | 105 | .wy-menu-vertical span { 106 | line-height: 18px; 107 | padding: 10px 0; 108 | margin: 0 20px 0 30px; 109 | font-size: 14px; 110 | font-weight: 400; 111 | color: #585858; 112 | border-bottom: 1px solid #e8e8e8; 113 | } 114 | 115 | .wy-nav-content { 116 | background-color: #fff; 117 | } 118 | 119 | .wy-nav-content-wrap { 120 | background: #fff; 121 | } 122 | 123 | .btn { 124 | padding: 3px 16px 0 16px; 125 | border: 1px solid #e2e2e2; 126 | border-radius: 5px; 127 | box-shadow: none; 128 | font-size: 12px; 129 | color: #585858 !important; 130 | height: 44px; 131 | line-height: 35px; 132 | } 133 | 134 | .btn-neutral { 135 | background-color: #fff !important; 136 | } 137 | 138 | .btn-neutral:hover { 139 | background-color: #fff !important; 140 | } 141 | 142 | .rst-content table.docutils { 143 | border: none; 144 | } 145 | 146 | .rst-content table.docutils th { 147 | padding: 15px 10px; 148 | font-size: 14px; 149 | font-weight: bold; 150 | border-top: 1px solid #e8e8e8; 151 | border-bottom: 1px solid #e8e8e8; 152 | background: #fbfbfb; 153 | color: #585858; 154 | } 155 | 156 | .rst-content table.docutils td { 157 | padding: 15px 10px; 158 | font-size: 14px; 159 | border-top: 1px solid #e8e8e8; 160 | border-bottom: 1px solid #e8e8e8; 161 | border-left: none; 162 | border-right:none; 163 | background: #fff; 164 | } 165 | 166 | .rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td { 167 | background-color: #fff; 168 | } 169 | 170 | .rst-content table.docutils tbody>tr:last-child td { 171 | border-bottom-width: 1px; 172 | } 173 | 174 | .rst-versions { 175 | display: none; 176 | } 177 | 178 | body { 179 | font-size: 12px; 180 | font-family: "Lato",Helvetica,Arial,sans-serif; 181 | font-weight: 200; 182 | color: #585858; 183 | background-color: #fff; 184 | } 185 | 186 | h1 { 187 | margin-top:; 188 | margin-bottom: 38px; 189 | font-size: 32px; 190 | font-weight: 200; 191 | font-family: "Lato",Helvetica,Arial,sans-serif; 192 | } 193 | 194 | h2 { 195 | margin-bottom: 38px; 196 | font-size: 24px; 197 | font-weight: 200; 198 | font-family: "Lato",Helvetica,Arial,sans-serif; 199 | } 200 | 201 | h3 { 202 | color: #585858; 203 | font-size: 18px; 204 | font-weight: 200; 205 | font-family: "Lato",Helvetica,Arial,sans-serif; 206 | } 207 | 208 | code { 209 | margin: 10px 0; 210 | padding: 0; 211 | border: none; 212 | font-size: 15px; 213 | font-family: "courier new",courier,monospace; 214 | color: #585858; 215 | font-weight: 600; 216 | } 217 | 218 | code.hljs { 219 | margin: 10px 0; 220 | padding: 24px; 221 | overflow-x: auto; 222 | border: 1px solid #e8e8e8; 223 | border-radius: 4px; 224 | font-size: 15px; 225 | line-height: 24px; 226 | font-family: "courier new",courier,monospace; 227 | color: #585858; 228 | font-weight: 200; 229 | } 230 | 231 | ul { 232 | font-size: 16px; 233 | } 234 | 235 | ol { 236 | font-size: 16px; 237 | } 238 | 239 | a { 240 | color: #0073ae; 241 | } 242 | 243 | a:visited { 244 | color: #0073ae; 245 | } 246 | 247 | a.icon { 248 | font-weight: 200; 249 | } -------------------------------------------------------------------------------- /docs/assets/fonts.js: -------------------------------------------------------------------------------- 1 | WebFontConfig = { 2 | google: { families: [ 'Lato:300:latin' ] } 3 | }; 4 | (function() { 5 | var wf = document.createElement('script'); 6 | wf.src = 'https://ajax.googleapis.com/ajax/libs/webfont/1/webfont.js'; 7 | wf.type = 'text/javascript'; 8 | wf.async = 'true'; 9 | var s = document.getElementsByTagName('script')[0]; 10 | s.parentNode.insertBefore(wf, s); 11 | })(); -------------------------------------------------------------------------------- /docs/assets/rc-developers_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ringcentral-tutorials/ringcentral-embeddable-demos/a3bd6064af87e75d6b478ac20725a9f359561e5f/docs/assets/rc-developers_logo.png -------------------------------------------------------------------------------- /docs/assets/ringcentral-developers_embeddable-web-widget.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ringcentral-tutorials/ringcentral-embeddable-demos/a3bd6064af87e75d6b478ac20725a9f359561e5f/docs/assets/ringcentral-developers_embeddable-web-widget.png -------------------------------------------------------------------------------- /docs/assets/ringcentral-developers_embeddable-web-widget_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ringcentral-tutorials/ringcentral-embeddable-demos/a3bd6064af87e75d6b478ac20725a9f359561e5f/docs/assets/ringcentral-developers_embeddable-web-widget_2.png -------------------------------------------------------------------------------- /docs/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ringcentral-tutorials/ringcentral-embeddable-demos/a3bd6064af87e75d6b478ac20725a9f359561e5f/docs/favicon.ico -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | [![](assets/rc-developers_logo.png)](https://developer.ringcentral.com) 2 | 3 | **Embeddable Web Widget Demo Apps** 4 | 5 | **[http://ringcentral-web-widget-demos.readthedocs.io](http://ringcentral-web-widget-demos.readthedocs.io)** 6 | 7 | This repo provides a few quick demos showing embedding of the RingCentral Web Widget all-in-one, embeddable app. It also links to external demos as well. 8 | 9 | The following demos are tracked by this project: 10 | 11 | * **[Static Simple](static_simple/tutorial/index.md)** (external): click-to-dial, click-to-sms 12 | * **[Static CRM](static_crm/tutorial/index.md)**: click-to-dial, click-to-sms, inbound screen-pop 13 | * **[Salesforce Lightning](salesforce_lightning/tutorial/index.md)**: click-to-dial, inbound screen-pop, automaticall call logging 14 | * **[Salesforce Lightning Plus](salesforce_lightning_more/tutorial/index.md)**: additional inbound screen-pops with Google and LinkedIn Searches 15 | * **[Java Desktop App](java_desktop_app/tutorial/index.md)** (external): embedding RingCentral WebRTC in a Java desktop app 16 | 17 | These demos rely on the following projects: 18 | 19 | * **[RingCentral Embeddable Web Widget](https://github.com/ringcentral/ringcentral-web-widget)** - [https://github.com/ringcentral/ringcentral-web-widget](https://github.com/ringcentral/ringcentral-web-widget) 20 | * **[RingCentral React Component Library](https://github.com/ringcentral/ringcentral-js-widget)** - [https://github.com/ringcentral/ringcentral-js-widget](https://github.com/ringcentral/ringcentral-js-widget) 21 | -------------------------------------------------------------------------------- /docs/java_desktop_app/tutorial/index.md: -------------------------------------------------------------------------------- 1 | This simple demo provides an easy way to get started with both adding the Web Widget to a Java desktop app using jxBrowser: 2 | 3 | * Repo: [https://github.com/tylerlong/jxbrowser-webrtc](https://github.com/tylerlong/jxbrowser-webrtc) 4 | * jxBrowser: [https://www.teamdev.com/jxbrowser](https://www.teamdev.com/jxbrowser) 5 | 6 | [![](java_desktop_app_screenshot.png)](https://www.youtube.com/watch?v=SKpLd20b2OM) 7 | 8 | ![](https://raw.githubusercontent.com/tylerlong/jxbrowser-webrtc/master/screenshots/calling.png) -------------------------------------------------------------------------------- /docs/java_desktop_app/tutorial/java_desktop_app_screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ringcentral-tutorials/ringcentral-embeddable-demos/a3bd6064af87e75d6b478ac20725a9f359561e5f/docs/java_desktop_app/tutorial/java_desktop_app_screenshot.png -------------------------------------------------------------------------------- /docs/salesforce_lightning/code/SLIDES.md: -------------------------------------------------------------------------------- 1 | ## Add CTI in 15 Minutes with the RingCentral Web Widget 2 | 3 | John Wang 4 | 5 | ![](ringcentral_connectcentral2017_logo.png) 6 | 7 | Note: I'm John Wang, Sr. Director of Platform for RingCentral and we are going to talk about how to add CTI quickly to your apps in just 15 Minutes with the Web Widget and why this is important. 8 | 9 | --- 10 | 11 | # Why CTI? 12 | 13 | Note: 14 | 15 | * Problem - Organizational Drag 16 | * Context Switching 17 | * Inadequate Information 18 | * Slow Response Time 19 | 20 | * The Solution - CTI 21 | * Better Customer Experience 22 | * Improved Employee Productivity & Efficiency 23 | * Boosts ROI of CRM 24 | * Connects with many systems 25 | * Installs easy in a short timeframe 26 | 27 | Our top use case at RingCentral 28 | 29 | --- 30 | 31 | ## Our Most Popular Use Case 32 | 33 | ![](app-gallery_salesforce.png) 34 | 35 | Note: To get started, how many of you know what Computer-Telephony Integration is? ... It's actually our most popular use case for integrations and embeds a RingCentral web phone into your web app for receiving and making calls with rich integration like click-to-dial and inbound screen-pop, both of which we'll talk about today. 36 | 37 | --- 38 | 39 | ## Agenda 40 | 41 | * What is the Web Widget? 42 | * Lab #1 - Static HTML 43 | * Lab #2 - Salesforce Open CTI 44 | * Lab #3 - Salesforce + Google 45 | 46 | --- 47 | 48 | ## RingCentral and Salesforce Open CTI 49 | 50 | ![](ringcentral-web-widget_2200x.png) 51 | 52 | Note: 53 | 54 | What is the web widget? 55 | 56 | * Out of the box widget you can embed right aways 57 | * Set of UI Components 58 | 59 | Before you only had REST APIs and had to build the UI yourself. 60 | 61 | --- 62 | 63 | ## Web Widget Capabilities 64 | 65 | * WebRTC 66 | * SMS 67 | * Click-to-Dial 68 | * Inbound Screen Pop 69 | * Call Logging 70 | 71 | --- 72 | 73 | ## Web Widget Stack 74 | 75 | ![](ringcentral-web-widget-stack-2.png) 76 | 77 | Note: 78 | 79 | The widget you see is actually a number of open source libraries that work together. The entire web widget is an impleentation of the widget library. 80 | 81 | --- 82 | 83 | ## Web Widgets Library 84 | 85 | ![](ringcentral_widget_instructions_full.png) 86 | 87 | --- 88 | 89 | ## Web Widget Stack Libraries 90 | 91 | * Web Widget Demo: [github.com/ringcentral/ringcentral-widget-demo](https://github.com/ringcentral/ringcentral-widget-demo) 92 | * Widgets Library: [github.com/ringcentral/ringcentral-js-widget](https://github.com/ringcentral/ringcentral-js-widget) 93 | * JS Commons SDK: [github.com/ringcentral/ringcentral-js-integration-commons](https://github.com/ringcentral/ringcentral-js-integration-commons) 94 | * JS Client SDK: [github.com/ringcentral/ringcentral-js-client](https://github.com/ringcentral/ringcentral-js-client) 95 | * WebRTC SDK: [github.com/ringcentral/ringcentral-web-phone](https://github.com/ringcentral/ringcentral-web-phone) 96 | * JS SDK: [github.com/ringcentral/ringcentral-js](https://github.com/ringcentral/ringcentral-js) 97 | 98 | Note: Here's a list of the web widget and supporting libraries you can use. At RingCentral, we support open source and all of these are open source. 99 | 100 | --- 101 | 102 | ## Lab #1: Static HTML Demo 103 | 104 | * Install widget on static HTML webpage 105 | * Configure click-to-dial 106 | 107 | --- 108 | 109 | ## Static HTML App Configuration 110 | 111 | * Permissions: VoIP Calling, SMS, Read Accounts, Edit Messages, etc. 112 | * OAuth Grants: Authorization Code 113 | * App Type: Browser-based 114 | 115 | --- 116 | 117 | ## Add the Web Widget 118 | 119 | Add the RingCentral webphone simply by adding `adapter.js` to web page 120 | 121 | 122 | ```html 123 | (650) 555-0100 124 | (650) 555-0101 125 | 126 | 134 | ``` 135 | 136 | --- 137 | 138 | ## Lab #2: Salesforce Open CTI Demo 139 | 140 | * Create / Configure Salesforce 141 | * Make and Receive Calls 142 | * Enable Click-to-Dial 143 | * Enable Inbound Screen-Pop 144 | * Enable Call-Logging 145 | 146 | --- 147 | 148 | ## CTI Architecture Overview 149 | 150 | ![](salesforce_CTI-Architecture-Overview.png "") 151 | 152 | --- 153 | 154 | ### Lab Prerequisites 155 | 156 | * Accounts 157 | * RingCentral: Office or Developer 158 | * Salesforce: Dev Edition, Pro or above 159 | * App Configuration 160 | * Permissions: VoIP Calling, SMS, Read Accounts, Edit Messages, etc. 161 | * OAuth Grants: Authorization Code 162 | * App Type: Browser-based 163 | 164 | --- 165 | 166 | ### Integration Components 167 | 168 | * Salesforce Call Center 169 | * Visualforce Page 170 | * Apex Helper Class 171 | 172 | --- 173 | 174 | ### What is a Salesforce Call Center? 175 | 176 | * A Salesfore Call Center is used to connect a CTI (computer-telephony integration) 177 | * Users must be assigned to a call center to use a CTI such as RingCentral Web Widget 178 | 179 | --- 180 | 181 | ### Creating the Call Center 182 | 183 | * Create a Call Center by importing `salesforce_CallCenterDefinition.xml` 184 | * This uses the `/apex/RCPhone` CTI Adapter URL 185 | 186 | ```xml 187 | 188 |
189 | RingCentralAdapterOpenCTI 190 | RingCentral Call Center Adapter Open CTI 191 | /apex/RCPhone 192 | true 193 | 550 194 | 300 195 | Lightning 196 |
197 |
198 | ``` 199 | 200 | [salesforce_CallCenterDefinition.xml](https://github.com/grokify/ringcentral-web-widget-demo/blob/master/salesforce_CallCenterDefinition.xml) 201 | 202 | --- 203 | 204 | ## Create the Webphone Visualforce page 205 | 206 | Create an a VF page with iframe to the widget named `RCPhone` to make and receive calls. 207 | 208 | ```html 209 | 210 | 215 | 216 | 217 | ``` 218 | 219 | --- 220 | 221 | ## Creating a SF App 222 | 223 | * In Setup, search for "App Manager" 224 | * Create New Lightning App 225 | * Choose Standard Navigation 226 | * Add Utility Bar Item "Open CTI Softphone" 227 | * Select All Items 228 | * Assign to all User Profiles 229 | * Select Test App and open phone 230 | 231 | --- 232 | 233 | ### Click-to-Dial VF Page 234 | 235 | Add the following to the RCPhone VF page: 236 | 237 | ```html 238 | 239 | 255 | ``` 256 | 257 | Click a phone number to make a call! 258 | 259 | --- 260 | 261 | ### Inbound Screen Pop - Part 1 - Apex 262 | 263 | * Create an APEX class `RCPhoneHelper` 264 | 265 | ```cs 266 | global class RCPhoneHelper { 267 | 268 | // Inbound Screen Pop 269 | webService static Contact searchContact(String phone) { 270 | List < List < SObject >> l = [FIND: phone IN PHONE FIELDS RETURNING Contact(Id limit 1)]; 271 | if (l.size() > 0 && l[0].size() > 0) { 272 | return (Contact) l[0][0]; 273 | } 274 | return null; 275 | } 276 | } 277 | ``` 278 | 279 | --- 280 | 281 | ### Inbound Screen Pop - Part 2 - JS 282 | 283 | * Add the `searchContact(String phone)` method 284 | 285 | ```html 286 | function receiveMessage(event) { 287 | if (event.data.type === 'rc-call-ring-notify') { 288 | sforce.opencti.setSoftphonePanelVisibility({ 289 | visible: true 290 | }); 291 | var fromNumber = event.data.call.from; 292 | if (fromNumber[0] === '+') { 293 | fromNumber = fromNumber.substring(1); 294 | } 295 | 296 | sforce.opencti.runApex({ 297 | apexClass: 'RCPhoneHelper', 298 | methodName: 'searchContact', 299 | methodParams: 'phone=' + fromNumber, 300 | callback: function(response) { 301 | if (response.success == true) { 302 | var contactId = response.returnValue.runApex.Id; 303 | if (contactId !== null) { 304 | sforce.opencti.screenPop({ 305 | type: sforce.opencti.SCREENPOP_TYPE.SOBJECT, 306 | params: { 307 | recordId: contactId 308 | } 309 | }); 310 | } 311 | } 312 | } 313 | }); 314 | } 315 | } 316 | window.addEventListener("message", receiveMessage, false); 317 | ``` 318 | 319 | Call the user to receive an screen-pop! 320 | 321 | --- 322 | 323 | ### Call Logging - Part 1 - Apex 324 | 325 | ```cs 326 | // Call Logging 327 | webService static void logACall(string contactId, Integer duration, String fromNumber, String toNumber) { 328 | Task t = new Task( 329 | ActivityDate = date.today(), 330 | CallDurationInSeconds = duration, 331 | CallType = 'Inbound', 332 | Description = 'From: ' + fromNumber + '\nTo: ' + toNumber + '\nDuration: ' + duration + ' seconds', 333 | Status = 'Completed', 334 | Subject = 'Call log', 335 | TaskSubtype = 'Call', 336 | Type = 'Call', 337 | WhoId = contactId 338 | ); 339 | insert t; 340 | } 341 | ``` 342 | 343 | --- 344 | 345 | ### Call Logging - Part 2 - JS 346 | 347 | ```js 348 | else if (event.data.type === 'rc-call-end-notify') { 349 | if (event.data.call.startTime !== null) { 350 | var fromNumber = event.data.call.from; 351 | if (fromNumber[0] === '+') { 352 | fromNumber = fromNumber.substring(1); 353 | } 354 | sforce.opencti.runApex({ 355 | apexClass: 'RCPhoneHelper', 356 | methodName: 'searchContact', 357 | methodParams: 'phone=' + fromNumber, 358 | callback: function(response) { 359 | if (response.success == true) { 360 | var contactId = response.returnValue.runApex.Id; 361 | if (contactId !== null) { 362 | sforce.opencti.runApex({ 363 | apexClass: 'RCPhoneHelper', 364 | methodName: 'logACall', 365 | methodParams: 'contactId=' + contactId + 366 | '&duration=' + Math.round((event.data.call.endTime - event.data.call.startTime) / 1000) + 367 | '&fromNumber=' + event.data.call.from + 368 | '&toNumber=' + event.data.call.to, 369 | callback: function(rr) { 370 | console.log(rr); 371 | } 372 | }); 373 | } 374 | } 375 | } 376 | }); 377 | } 378 | } 379 | ``` 380 | 381 | Log a call! 382 | 383 | --- 384 | 385 | ## Continue the Journey 386 | 387 | RingCentral Developers 388 | * Dev Portal: https://developer.ringcentral.com 389 | * Community: https://devcommunity.ringcentral.com 390 | * Twitter: https://twitter/RingCentralDevs 391 | * Github: https://github.com/ringcentral 392 | 393 | John Wang 394 | * Twitter: https://twitter.com/grokify 395 | * Github: https://github.com/grokify -------------------------------------------------------------------------------- /docs/salesforce_lightning/code/app-gallery_salesforce.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ringcentral-tutorials/ringcentral-embeddable-demos/a3bd6064af87e75d6b478ac20725a9f359561e5f/docs/salesforce_lightning/code/app-gallery_salesforce.png -------------------------------------------------------------------------------- /docs/salesforce_lightning/code/ringcentral-web-widget-stack-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ringcentral-tutorials/ringcentral-embeddable-demos/a3bd6064af87e75d6b478ac20725a9f359561e5f/docs/salesforce_lightning/code/ringcentral-web-widget-stack-2.png -------------------------------------------------------------------------------- /docs/salesforce_lightning/code/ringcentral-web-widget-stack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ringcentral-tutorials/ringcentral-embeddable-demos/a3bd6064af87e75d6b478ac20725a9f359561e5f/docs/salesforce_lightning/code/ringcentral-web-widget-stack.png -------------------------------------------------------------------------------- /docs/salesforce_lightning/code/ringcentral-web-widget-stack.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | background 5 | 6 | 7 | 8 | 9 | 10 | 11 | Layer 1 12 | 13 | 14 | 15 | Embeddable Web Widget 16 | Widgets Library 17 | JS Commons SDK 18 | 19 | 20 | JS Client SDK 21 | JS SDK 22 | 23 | WebRTC 24 | SDK 25 | 26 | -------------------------------------------------------------------------------- /docs/salesforce_lightning/code/ringcentral-web-widget.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ringcentral-tutorials/ringcentral-embeddable-demos/a3bd6064af87e75d6b478ac20725a9f359561e5f/docs/salesforce_lightning/code/ringcentral-web-widget.png -------------------------------------------------------------------------------- /docs/salesforce_lightning/code/ringcentral-web-widget_2200x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ringcentral-tutorials/ringcentral-embeddable-demos/a3bd6064af87e75d6b478ac20725a9f359561e5f/docs/salesforce_lightning/code/ringcentral-web-widget_2200x.png -------------------------------------------------------------------------------- /docs/salesforce_lightning/code/ringcentral_connectcentral2017_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ringcentral-tutorials/ringcentral-embeddable-demos/a3bd6064af87e75d6b478ac20725a9f359561e5f/docs/salesforce_lightning/code/ringcentral_connectcentral2017_logo.png -------------------------------------------------------------------------------- /docs/salesforce_lightning/code/ringcentral_widget_instructions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ringcentral-tutorials/ringcentral-embeddable-demos/a3bd6064af87e75d6b478ac20725a9f359561e5f/docs/salesforce_lightning/code/ringcentral_widget_instructions.png -------------------------------------------------------------------------------- /docs/salesforce_lightning/code/ringcentral_widget_instructions_full.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ringcentral-tutorials/ringcentral-embeddable-demos/a3bd6064af87e75d6b478ac20725a9f359561e5f/docs/salesforce_lightning/code/ringcentral_widget_instructions_full.png -------------------------------------------------------------------------------- /docs/salesforce_lightning/code/salesforce_CTI-Architecture-Overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ringcentral-tutorials/ringcentral-embeddable-demos/a3bd6064af87e75d6b478ac20725a9f359561e5f/docs/salesforce_lightning/code/salesforce_CTI-Architecture-Overview.png -------------------------------------------------------------------------------- /docs/salesforce_lightning/code/salesforce_demo-0.1.0_config_CallCenterDefinition.xml: -------------------------------------------------------------------------------- 1 | 2 |
3 | RingCentralAdapterOpenCTI 4 | RingCentral Call Center Adapter Open CTI 5 | /apex/RCPhone 6 | true 7 | 550 8 | 300 9 | Lightning 10 |
11 |
-------------------------------------------------------------------------------- /docs/salesforce_lightning/code/salesforce_demo-0.1.1_config_RCPhone.vfp: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | -------------------------------------------------------------------------------- /docs/salesforce_lightning/code/salesforce_demo-0.2.0_click-to-dial_RCPhone.vfp: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /docs/salesforce_lightning/code/salesforce_demo-0.3.0_inbound-screen-pop_RCPhoneHelper.apxc: -------------------------------------------------------------------------------- 1 | global class RCPhoneHelper { 2 | 3 | // Inbound Screen Pop 4 | webService static Contact searchContact(String phone) { 5 | List < List < SObject >> l = [FIND: phone IN PHONE FIELDS RETURNING Contact(Id limit 1)]; 6 | if (l.size() > 0 && l[0].size() > 0) { 7 | return (Contact) l[0][0]; 8 | } 9 | return null; 10 | } 11 | } -------------------------------------------------------------------------------- /docs/salesforce_lightning/code/salesforce_demo-0.3.1_inbound-screen-pop_RCPhone.vfp: -------------------------------------------------------------------------------- 1 | function receiveMessage(event) { 2 | if (event.data.type === 'rc-call-ring-notify') { 3 | sforce.opencti.setSoftphonePanelVisibility({ 4 | visible: true 5 | }); 6 | var fromNumberE164 = event.data.call.from; 7 | var fromNumber = phoneUtils.formatNational(fromNumberE164, "us"); 8 | if (fromNumber[0] === '+') { 9 | fromNumber = fromNumber.substring(1); 10 | } 11 | 12 | sforce.opencti.runApex({ 13 | apexClass: 'RCPhoneHelper', 14 | methodName: 'searchContact', 15 | methodParams: 'phone=' + fromNumber, 16 | callback: function(response) { 17 | if (response.success == true) { 18 | var contactId = response.returnValue.runApex.Id; 19 | if (contactId !== null) { 20 | sforce.opencti.screenPop({ 21 | type: sforce.opencti.SCREENPOP_TYPE.SOBJECT, 22 | params: { 23 | recordId: contactId 24 | } 25 | }); 26 | } 27 | } 28 | } 29 | }); 30 | } 31 | } 32 | window.addEventListener("message", receiveMessage, false); -------------------------------------------------------------------------------- /docs/salesforce_lightning/code/salesforce_demo-0.4.0_call-logging_RCPhoneHelper.apxc: -------------------------------------------------------------------------------- 1 | // Call Logging 2 | webService static void logACall(string contactId, Integer duration, String fromNumber, String toNumber) { 3 | Task t = new Task( 4 | ActivityDate = date.today(), 5 | CallDurationInSeconds = duration, 6 | CallType = 'Inbound', 7 | Description = 'From: ' + fromNumber + '\nTo: ' + toNumber + '\nDuration: ' + duration + ' seconds', 8 | Status = 'Completed', 9 | Subject = 'Call log', 10 | TaskSubtype = 'Call', 11 | Type = 'Call', 12 | WhoId = contactId 13 | ); 14 | insert t; 15 | } -------------------------------------------------------------------------------- /docs/salesforce_lightning/code/salesforce_demo-0.4.1_call-logging_RCPhone.vfp: -------------------------------------------------------------------------------- 1 | else if (event.data.type === 'rc-call-end-notify') { 2 | if (event.data.call.startTime !== null) { 3 | var fromNumber = event.data.call.from; 4 | if (fromNumber[0] === '+') { 5 | fromNumber = fromNumber.substring(1); 6 | } 7 | sforce.opencti.runApex({ 8 | apexClass: 'RCPhoneHelper', 9 | methodName: 'searchContact', 10 | methodParams: 'phone=' + fromNumber, 11 | callback: function(response) { 12 | if (response.success == true) { 13 | var contactId = response.returnValue.runApex.Id; 14 | if (contactId !== null) { 15 | sforce.opencti.runApex({ 16 | apexClass: 'RCPhoneHelper', 17 | methodName: 'logACall', 18 | methodParams: 'contactId=' + contactId + 19 | '&duration=' + Math.round((event.data.call.endTime - event.data.call.startTime) / 1000) + 20 | '&fromNumber=' + event.data.call.from + 21 | '&toNumber=' + event.data.call.to, 22 | callback: function(rr) { 23 | console.log(rr); 24 | } 25 | }); 26 | } 27 | } 28 | } 29 | }); 30 | } 31 | } -------------------------------------------------------------------------------- /docs/salesforce_lightning/code/salesforce_demo-1.0.0_RCPhone.vfp: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 93 | 94 | -------------------------------------------------------------------------------- /docs/salesforce_lightning/code/salesforce_demo-1.0.0_RCPhoneHelper.apxc: -------------------------------------------------------------------------------- 1 | global class RCPhoneHelper { 2 | 3 | // Inbound Screen Pop 4 | webService static Contact searchContact(String phone) { 5 | List < List < SObject >> l = [FIND: phone IN PHONE FIELDS RETURNING Contact(Id limit 1)]; 6 | if (l.size() > 0 && l[0].size() > 0) { 7 | return (Contact) l[0][0]; 8 | } 9 | return null; 10 | } 11 | 12 | // Call Logging 13 | webService static void logACall(string contactId, Integer duration, String fromNumber, String toNumber) { 14 | Task t = new Task( 15 | ActivityDate = date.today(), 16 | CallDurationInSeconds = duration, 17 | CallType = 'Inbound', 18 | Description = 'From: ' + fromNumber + '\nTo: ' + toNumber + '\nDuration: ' + duration + ' seconds', 19 | Status = 'Completed', 20 | Subject = 'Call log', 21 | TaskSubtype = 'Call', 22 | Type = 'Call', 23 | WhoId = contactId 24 | ); 25 | insert t; 26 | } 27 | } -------------------------------------------------------------------------------- /docs/salesforce_lightning/code/salesforce_demo-1.0.0_config_CallCenterDefinition.xml: -------------------------------------------------------------------------------- 1 | 2 |
3 | RingCentralAdapterOpenCTI 4 | RingCentral Call Center Adapter Open CTI 5 | /apex/RCPhone 6 | true 7 | 550 8 | 300 9 | Lightning 10 |
11 |
-------------------------------------------------------------------------------- /docs/salesforce_lightning/code/test/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 12 | 13 | -------------------------------------------------------------------------------- /docs/salesforce_lightning/tutorial/index.md: -------------------------------------------------------------------------------- 1 | The RingCentral Web Widget demo for Salesforce Lightning is a simple demo that show cases the following use cases: 2 | 3 | * Click-to-Dial 4 | * Inbound Screen-Pop 5 | * Call Logging 6 | 7 | This demo is located in the [`salesforce_lightning`](github.com/ringcentral-tutorials/ringcentral-web-widget-demos/tree/master/salesforce_lightning) folder. 8 | 9 | Note: There is a follow-on demo that builds on this and will create additional screen-pops for Google Search and LinkedIn Search in the [`salesforce_lightning_plus`](github.com/ringcentral-tutorials/ringcentral-web-widget-demos/tree/master/salesforce_lightning_plus) folder. This consists of just one additional line of JavaScript for each serach. 10 | 11 | ## Contents 12 | 13 | * [Installation](#installation) 14 | * [Create a RingCentral App](#create-a-ringcentral-app) 15 | * [Clone the repo](#clone-the-repo) 16 | * [Add the Widget to Salesforce](#add-the-widget-to-salesforce) 17 | * [Create the Salesforce Call Center](#create-the-salesforce-call-center) 18 | * [Create the Widget Visualforce Page](#create-the-widget-visualforce-page) 19 | * [Add the Widget to Your Salesforce App](#add-the-widget-to-your-salesforce-app) 20 | * [Integrations](#integrations) 21 | * [Click-to-Dial](#click-to-dial) 22 | * [Inbound Screen-Pop](#inbound-screen-pop) 23 | * [Autoamtic Call Logging](#automatic-call-logging) 24 | * [Summary](#summary) 25 | 26 | ## Installation 27 | 28 | To install this demo, clone the repo and load the file in your browser: 29 | 30 | ### Create a RingCentral App 31 | 32 | Create an app with the following characteristics: 33 | 34 | | Property | Setting | 35 | |----------|---------| 36 | | Platform Type | Browser-based | 37 | | Grant Types | Authorization Code or Implicit Grant | 38 | | Permissions | see [ringcentral/ringcentral-web-widget](https://github.com/ringcentral/ringcentral-web-widget) | 39 | 40 | ### Clone the repo 41 | 42 | `git clone https://github.com/ringcentral-tutorials/ringcentral-web-widget-demos` 43 | 44 | ### Add the Web Widget to Salesforce 45 | 46 | To add the RingCentral Web Widget, we need to create a Salesforce Call Center with the Visualforce page and then add users that want to use the Web Widget to the Call Center. 47 | 48 | #### Create the Salesforce Call Center 49 | 50 | In Salesforce Lightning create a Salesforce Call Center using the following steps: 51 | 52 | 1. In Salesforce Lightning click `Setup` 53 | 54 | ![](salesforce_step-1.1_setup.png) 55 | 56 | 2. In the *Quick Find*, type `call centers` and then click **Call Centers**. 57 | 58 | 3. If you see a "Say Hello to Salesforce Call Center" introduction page, click **Continue**. 59 | 60 | 4. Then click the **Import** button and select the XML file. 61 | 62 | ![](salesforce_step-1.4_call-center_import-xml-1.png) 63 | 64 | You can create a file similar to the below or import the `salesforce_demo-1.0.0_config_CallCenterDefinition.xml` file. 65 | 66 | You can change the settings in the XML file. The following are of note: 67 | 68 | * The *Display Name* is set to "RingCentral Call Center Adapter Open CTI" 69 | * The *CTI Adapter URL* is set to `/apex/RCPhone` 70 | 71 | ```xml 72 | 73 |
74 | RingCentralAdapterOpenCTI 75 | RingCentral Call Center Adapter Open CTI 76 | /apex/RCPhone 77 | true 78 | 550 79 | 300 80 | Lightning 81 |
82 |
83 | ``` 84 | 85 | 5. After you have created the Call Center, click **Manage Call Center Users** and then click **Add More Users**. 86 | 87 | ![](salesforce_step-1.5_call-center_manage-call-center-users.png) 88 | 89 | 6. Use the **Find** button to select the users you wish to use the RingCentral Widget, select the users and then click **Add to Call Center** 90 | 91 | ![](salesforce_step-1.6_call-center_find-and-add-users.png) 92 | 93 | #### Create the Widget Visualforce Page 94 | 95 | 96 | 97 | 102 | 103 | 104 | 105 | #### Create the Widget Visualforce Page 106 | 107 | 8. Open the *Developer Console* by clicking the gear icon in the upper right corner. 108 | 109 | ![](salesforce_step-1.8_open-developer-console.png) 110 | 111 | 9. Create a new Visualforce page by clicking **File > New > Visualforce Page** 112 | 113 | ![](salesforce_step-1.9_new-visualforce-page.png) 114 | 115 | 10. Replace the content of the page with the following HTML. Save the page by clicking **File > Save** 116 | 117 | ```html 118 | 119 | 124 | 125 | 126 | ``` 127 | 128 | #### Add the Widget to Your Salesforce App 129 | 130 | 11. Go to the App Manager 131 | 132 | In the *Setup > Quick Find*, search for and click on **App Manager** 133 | 134 | Select the "Lighting" app you wish to add the Webphone too by clicking **Edit**. For example, you can select the "LightningSales" app as shown below, another Lightning app or click **New Lightning App**. 135 | 136 | ![](salesforce_step-1.11_select-app.png) 137 | 138 | 12. Add Open CTI Softphone 139 | 140 | Under the *Utility Bar*, click **Add** and then search for, and click, **Open CTI Softphone**. 141 | 142 | ![](salesforce_step-1.12_sfdc-app_add-the-softphone.png) 143 | 144 | 13. You do not need to change any options. Click **Save**. 145 | 146 | ![](salesforce_step-1.13_sfdc-app_save-the-softphone.png) 147 | 148 | 10. Go to your Salesforce app via the *App Launcher* and bring up the RingCentral Web Widget 149 | 150 | ## Integrations 151 | 152 | The following section covers three primary use cases. 153 | 154 | ### Click-to-Dial 155 | 156 | To add click-to-dial to your RingCentral Widget in Salesforce, we want to call the `sforce.opencti.enableClickToDial()` and `sforce.opencti.onClickToDial()` functions. We will register a fuction to the `onClickToDial()` function that uses the browser's `Window.postMessage()` function message to send a message which the Widget is listening for using the `rc-adapter-new-call` message type. 157 | 158 | Code for this is shown below. Open your `RCPhone` Visualforce page and paste the code below the `` tag. 159 | 160 | ```html 161 | 162 | 178 | ``` 179 | 180 | ### Inbound Screen-Pop 181 | 182 | **Apex class** 183 | 184 | Create the `RCPhoneHelper` Apex class if you don't already have one and add a `searchContact` method as shown below: 185 | 186 | ```java 187 | global class RCPhoneHelper { 188 | 189 | // Inbound Screen Pop 190 | webService static Contact searchContact(String phone) { 191 | List < List < SObject >> l = [FIND: phone IN PHONE FIELDS RETURNING Contact(Id limit 1)]; 192 | if (l.size() > 0 && l[0].size() > 0) { 193 | return (Contact) l[0][0]; 194 | } 195 | return null; 196 | } 197 | } 198 | ``` 199 | 200 | **Visualforce page** 201 | 202 | In your Visualforce page, create a `receiveMessage` function to respond to the `rc-call-ring-notify` event and register it using `window.addEventListener` as shown below. If you are listening to multiple RingCentral event types such as `rc-call-end-notify` as shown for the Call Log use case shown below, you can use an else if clause in the `receiveMessage` function. 203 | 204 | ```javascript 205 | function receiveMessage(event) { 206 | if (event.data.type === 'rc-call-ring-notify') { 207 | sforce.opencti.setSoftphonePanelVisibility({ 208 | visible: true 209 | }); 210 | var fromNumberE164 = event.data.call.from; 211 | var fromNumber = phoneUtils.formatNational(fromNumberE164, "us"); 212 | if (fromNumber[0] === '+') { 213 | fromNumber = fromNumber.substring(1); 214 | } 215 | 216 | sforce.opencti.runApex({ 217 | apexClass: 'RCPhoneHelper', 218 | methodName: 'searchContact', 219 | methodParams: 'phone=' + fromNumber, 220 | callback: function(response) { 221 | if (response.success == true) { 222 | var contactId = response.returnValue.runApex.Id; 223 | if (contactId !== null) { 224 | sforce.opencti.screenPop({ 225 | type: sforce.opencti.SCREENPOP_TYPE.SOBJECT, 226 | params: { 227 | recordId: contactId 228 | } 229 | }); 230 | } 231 | } 232 | } 233 | }); 234 | } 235 | } 236 | window.addEventListener("message", receiveMessage, false); 237 | ``` 238 | 239 | ### Automatic Call Logging 240 | 241 | #### Apex Class 242 | 243 | To enable automatical call logging, first create an Apex helper method. This method should be added to your `RCPhoneHelper` class added above. 244 | 245 | ```java 246 | // Call Logging 247 | webService static void logACall(string contactId, Integer duration, String fromNumber, String toNumber) { 248 | Task t = new Task( 249 | ActivityDate = date.today(), 250 | CallDurationInSeconds = duration, 251 | CallType = 'Inbound', 252 | Description = 'From: ' + fromNumber + '\nTo: ' + toNumber + '\nDuration: ' + duration + ' seconds', 253 | Status = 'Completed', 254 | Subject = 'Call log', 255 | TaskSubtype = 'Call', 256 | Type = 'Call', 257 | WhoId = contactId 258 | ); 259 | insert t; 260 | } 261 | ``` 262 | 263 | #### Visualforce Page 264 | 265 | Now add the Visualforce page JavaScript that will listen for the `rc-call-end-notify` event, look up the contact and, if found, create a Call Log Task. 266 | 267 | The code below can be added to the `receiveMessage()` function added above in the Inbound Screen-Pop section. 268 | 269 | ```javascript 270 | else if (event.data.type === 'rc-call-end-notify') { 271 | if (event.data.call.startTime !== null) { 272 | var fromNumber = event.data.call.from; 273 | if (fromNumber[0] === '+') { 274 | fromNumber = fromNumber.substring(1); 275 | } 276 | sforce.opencti.runApex({ 277 | apexClass: 'RCPhoneHelper', 278 | methodName: 'searchContact', 279 | methodParams: 'phone=' + fromNumber, 280 | callback: function(response) { 281 | if (response.success == true) { 282 | var contactId = response.returnValue.runApex.Id; 283 | if (contactId !== null) { 284 | sforce.opencti.runApex({ 285 | apexClass: 'RCPhoneHelper', 286 | methodName: 'logACall', 287 | methodParams: 'contactId=' + contactId + 288 | '&duration=' + Math.round((event.data.call.endTime - event.data.call.startTime) / 1000) + 289 | '&fromNumber=' + event.data.call.from + 290 | '&toNumber=' + event.data.call.to, 291 | callback: function(rr) { 292 | console.log(rr); 293 | } 294 | }); 295 | } 296 | } 297 | } 298 | }); 299 | } 300 | } 301 | ``` 302 | 303 | ## Summary 304 | 305 | The above completes this tutorial on basic Salesforce Lightning configuration using the RingCentral Web Widget. 306 | 307 | The next tutorial covers popular use cases where a user may want to extend the functionality of the Web Widget, such as opening additional Screen-Pops to look up the user's info in sites like Google Search and LinkedIn. 308 | 309 | Next: [Using the RingCentral Web Widget with Salesforce Lightning Google Search and LinkedIn](../salesforce_lightning_more) 310 | 311 | ## References 312 | 313 | * [Salesforce Open CTI Developer Guide](https://developer.salesforce.com/docs/atlas.en-us.api_cti.meta/api_cti/) 314 | * [CTI In the Cloud: the New World of Cloud-based Telephony](https://www.slideshare.net/Salesforce/cti-in-the-cloud-the-new-world-of-cloud-based-telephony) -------------------------------------------------------------------------------- /docs/salesforce_lightning/tutorial/salesforce_step-1.11_select-app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ringcentral-tutorials/ringcentral-embeddable-demos/a3bd6064af87e75d6b478ac20725a9f359561e5f/docs/salesforce_lightning/tutorial/salesforce_step-1.11_select-app.png -------------------------------------------------------------------------------- /docs/salesforce_lightning/tutorial/salesforce_step-1.12_sfdc-app_add-the-softphone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ringcentral-tutorials/ringcentral-embeddable-demos/a3bd6064af87e75d6b478ac20725a9f359561e5f/docs/salesforce_lightning/tutorial/salesforce_step-1.12_sfdc-app_add-the-softphone.png -------------------------------------------------------------------------------- /docs/salesforce_lightning/tutorial/salesforce_step-1.13_sfdc-app_save-the-softphone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ringcentral-tutorials/ringcentral-embeddable-demos/a3bd6064af87e75d6b478ac20725a9f359561e5f/docs/salesforce_lightning/tutorial/salesforce_step-1.13_sfdc-app_save-the-softphone.png -------------------------------------------------------------------------------- /docs/salesforce_lightning/tutorial/salesforce_step-1.1_setup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ringcentral-tutorials/ringcentral-embeddable-demos/a3bd6064af87e75d6b478ac20725a9f359561e5f/docs/salesforce_lightning/tutorial/salesforce_step-1.1_setup.png -------------------------------------------------------------------------------- /docs/salesforce_lightning/tutorial/salesforce_step-1.4_call-center_import-xml-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ringcentral-tutorials/ringcentral-embeddable-demos/a3bd6064af87e75d6b478ac20725a9f359561e5f/docs/salesforce_lightning/tutorial/salesforce_step-1.4_call-center_import-xml-1.png -------------------------------------------------------------------------------- /docs/salesforce_lightning/tutorial/salesforce_step-1.5_call-center_manage-call-center-users.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ringcentral-tutorials/ringcentral-embeddable-demos/a3bd6064af87e75d6b478ac20725a9f359561e5f/docs/salesforce_lightning/tutorial/salesforce_step-1.5_call-center_manage-call-center-users.png -------------------------------------------------------------------------------- /docs/salesforce_lightning/tutorial/salesforce_step-1.6_call-center_find-and-add-users.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ringcentral-tutorials/ringcentral-embeddable-demos/a3bd6064af87e75d6b478ac20725a9f359561e5f/docs/salesforce_lightning/tutorial/salesforce_step-1.6_call-center_find-and-add-users.png -------------------------------------------------------------------------------- /docs/salesforce_lightning/tutorial/salesforce_step-1.8_open-developer-console.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ringcentral-tutorials/ringcentral-embeddable-demos/a3bd6064af87e75d6b478ac20725a9f359561e5f/docs/salesforce_lightning/tutorial/salesforce_step-1.8_open-developer-console.png -------------------------------------------------------------------------------- /docs/salesforce_lightning/tutorial/salesforce_step-1.9_new-visualforce-page.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ringcentral-tutorials/ringcentral-embeddable-demos/a3bd6064af87e75d6b478ac20725a9f359561e5f/docs/salesforce_lightning/tutorial/salesforce_step-1.9_new-visualforce-page.png -------------------------------------------------------------------------------- /docs/salesforce_lightning_more/code/CallCenterDefinition.xml: -------------------------------------------------------------------------------- 1 | 2 |
3 | RingCentralAdapterOpenCTI 4 | RingCentral Call Center Adapter Open CTI 5 | /apex/RCPhone 6 | true 7 | 550 8 | 300 9 | Lightning 10 |
11 |
-------------------------------------------------------------------------------- /docs/salesforce_lightning_more/code/RCPhone.vfp: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 106 | 107 | -------------------------------------------------------------------------------- /docs/salesforce_lightning_more/code/RCPhoneHelper.apxc: -------------------------------------------------------------------------------- 1 | global class RCPhoneHelper { 2 | 3 | // Inbound Screen Pop 4 | webService static Contact searchContact(String phone) { 5 | List> l = [FIND :phone IN PHONE FIELDS RETURNING Contact(Id limit 1)]; 6 | if(l.size() > 0 && l[0].size() > 0) { 7 | String id = ((Contact)l[0][0]).Id; 8 | return [select Id, Name from Contact where Id=:id limit 1]; 9 | } 10 | return null; 11 | } 12 | 13 | // Call Logging 14 | webService static void logACall(string contactId, Integer duration, String fromNumber, String toNumber) { 15 | Task t = new Task( 16 | ActivityDate = date.today(), 17 | CallDurationInSeconds = duration, 18 | CallType = 'Inbound', 19 | Description = 'From: ' + fromNumber + '\nTo: ' + toNumber + '\nDuration: ' + duration + ' seconds', 20 | Status = 'Completed', 21 | Subject = 'Call log', 22 | TaskSubtype = 'Call', 23 | Type = 'Call', 24 | WhoId = contactId 25 | ); 26 | insert t; 27 | } 28 | } -------------------------------------------------------------------------------- /docs/salesforce_lightning_more/tutorial/index.md: -------------------------------------------------------------------------------- 1 | Extending the RingCentral Web Widget in Salesforce Lightning. 2 | 3 | Here is a step-by-step tutorial for you to create a simple RingCentral to Salesforce integration. So whenever there is an incoming call, the caller's contact page in SalesForce will be popped up. It would also pop up a Google or LinkedIn Search to provid additional information about the person calling. 4 | 5 | Believe it or not, you can do it in 10 minutes. Let's start! 6 | 7 | First of all you need an SalesForce developer account. Please get one if you don't have one already: https://developer.salesforce.com/signup 8 | 9 | ![image](https://user-images.githubusercontent.com/733544/30905579-dbdcbfca-a33a-11e7-8e13-15674cce6055.png) 10 | 11 | Create an `callcenter.xml` file on your desktop, and copy paste the following content into it: 12 | 13 | ```xml 14 | 15 |
16 | RingCentralAdapterOpenCTI 17 | RingCentral Call Center Adapter Open CTI 18 | /apex/RCPhone 19 | true 20 | 550 21 | 300 22 | Lightning 23 |
24 |
25 | ``` 26 | 27 | Login your SalesForce developer account. In the "Quick Find" search box search "call center", In "Call Centers", click the "Import" button. Import the `callcenter.xml` file we created above. 28 | 29 | ![image](https://user-images.githubusercontent.com/733544/30905545-b9f8ef0a-a33a-11e7-929f-54f81f9b083d.png) 30 | 31 | Click "Manage Call Center Users" button, add yourself to the call center. 32 | 33 | ![image](https://user-images.githubusercontent.com/733544/30945813-f742e826-a3c5-11e7-9e67-1c6edded2a1e.png) 34 | 35 | 36 | Create a VisualForce page named `RCPhone` with following content: 37 | 38 | ```html 39 | 40 | 45 | 46 | 47 | ``` 48 | 49 | Create new Salesforce app, add a Open CTI Softphone to its utility bar. Launch this app and verify that there is an embedded phone in the utility bar. 50 | 51 | ![image](https://user-images.githubusercontent.com/733544/30905684-2102da62-a33b-11e7-90c9-698f6a3f16b0.png) 52 | 53 | ![image](https://user-images.githubusercontent.com/733544/30905775-6dd71254-a33b-11e7-9876-26e55741c6d1.png) 54 | 55 | 56 | Create an Apex class named `RCPhoneHelper`: 57 | 58 | ```java 59 | global class RCPhoneHelper { 60 | webService static Contact searchContact(String phone) { 61 | List> l = [FIND :phone IN PHONE FIELDS RETURNING Contact(Id limit 1)]; 62 | if(l.size() > 0 && l[0].size() > 0) { 63 | String id = ((Contact)l[0][0]).Id; 64 | return [select Id, Name from Contact where Id=:id limit 1]; 65 | } 66 | return null; 67 | } 68 | } 69 | ``` 70 | 71 | 72 | Add the following code to `RCPhone` VisualForce page: 73 | 74 | ```javascript 75 | 76 | 103 | ``` 104 | 105 | Save all of the changes to code. Refresh your SalesForce page to make sure that latest changes are applied. 106 | 107 | If the incoming call number exists in the contact list in SalesForce, the contact page of that customer will also be opened. 108 | 109 | ![image](https://user-images.githubusercontent.com/733544/30905909-d1cc3730-a33b-11e7-845e-8d4e929b15d3.png) 110 | 111 | We will also Google search the contact's name in a new browser tab. Please allow your browser to show the popup by the way. 112 | 113 | ![image](https://user-images.githubusercontent.com/733544/30945908-79d63fa4-a3c6-11e7-8eff-7ffa8c8e47e2.png) 114 | 115 | To add a LinkedIn People Search, simply add the following: 116 | 117 | `window.open('https://www.linkedin.com/search/results/people/?keywords=' + contact.Name);` 118 | -------------------------------------------------------------------------------- /docs/static_crm/code/assets/bootstrap-v4.0.0-beta-example-dashboard.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Base structure 3 | */ 4 | 5 | /* Move down content because we have a fixed navbar that is 3.5rem tall */ 6 | body { 7 | padding-top: 3.5rem; 8 | } 9 | 10 | /* 11 | * Typography 12 | */ 13 | 14 | h1 { 15 | margin-bottom: 20px; 16 | padding-bottom: 9px; 17 | border-bottom: 1px solid #eee; 18 | } 19 | 20 | /* 21 | * Sidebar 22 | */ 23 | 24 | .sidebar { 25 | position: fixed; 26 | top: 51px; 27 | bottom: 0; 28 | left: 0; 29 | z-index: 1000; 30 | padding: 20px; 31 | overflow-x: hidden; 32 | overflow-y: auto; /* Scrollable contents if viewport is shorter than content. */ 33 | border-right: 1px solid #eee; 34 | } 35 | 36 | /* Sidebar navigation */ 37 | .sidebar { 38 | padding-left: 0; 39 | padding-right: 0; 40 | } 41 | 42 | .sidebar .nav { 43 | margin-bottom: 20px; 44 | } 45 | 46 | .sidebar .nav-item { 47 | width: 100%; 48 | } 49 | 50 | .sidebar .nav-item + .nav-item { 51 | margin-left: 0; 52 | } 53 | 54 | .sidebar .nav-link { 55 | border-radius: 0; 56 | } 57 | 58 | /* 59 | * Dashboard 60 | */ 61 | 62 | /* Placeholders */ 63 | .placeholders { 64 | padding-bottom: 3rem; 65 | } 66 | 67 | .placeholder img { 68 | padding-top: 1.5rem; 69 | padding-bottom: 1.5rem; 70 | } 71 | -------------------------------------------------------------------------------- /docs/static_crm/code/assets/ie10-viewport-bug-workaround.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * IE10 viewport hack for Surface/desktop Windows 8 bug 3 | * Copyright 2014-2017 The Bootstrap Authors 4 | * Copyright 2014-2017 Twitter, Inc. 5 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 6 | */ 7 | 8 | // See the Getting Started docs for more information: 9 | // https://getbootstrap.com/getting-started/#support-ie10-width 10 | 11 | (function () { 12 | 'use strict' 13 | 14 | if (navigator.userAgent.match(/IEMobile\/10\.0/)) { 15 | var msViewportStyle = document.createElement('style') 16 | msViewportStyle.appendChild( 17 | document.createTextNode( 18 | '@-ms-viewport{width:auto!important}' 19 | ) 20 | ) 21 | document.head.appendChild(msViewportStyle) 22 | } 23 | 24 | }()) 25 | -------------------------------------------------------------------------------- /docs/static_crm/code/assets/libphonenumber-v0.9.4/libphonenumber_FK.js: -------------------------------------------------------------------------------- 1 | (function(){var aa=this;function l(a){return"string"==typeof a}function m(a,b){var c=a.split("."),d=aa;c[0]in d||!d.execScript||d.execScript("var "+c[0]);for(var e;c.length&&(e=c.shift());)c.length||void 0===b?d[e]?d=d[e]:d=d[e]={}:d[e]=b}function n(a,b){function c(){}c.prototype=b.prototype;a.o=b.prototype;a.prototype=new c;a.prototype.constructor=a;a.$=function(a,c,f){for(var g=Array(arguments.length-2),h=2;hc?Math.max(0,a.length+c):c;if(l(a))return l(b)&&1==b.length?a.indexOf(b,c):-1;for(;cb?1:aa.length?!1:N(Ea,a)}function La(a){return N(Ca,a)?O(a,wa):O(a,K)}function Ma(a){var b=La(a.toString());a.c="";a.a(b)}function Na(){return ca(Object.keys(ua),function(a){return isNaN(a)})} 51 | function O(a,b){for(var c=new B,d,e=a.length,f=0;f=a.c.length)throw"Phone number too short after IDD"; 60 | a:{d=a.toString();if(0!=d.length&&"0"!=d.charAt(0))for(b=d.length,f=1;3>=f&&f<=b;++f)if(a=parseInt(d.substring(0,f),10),a in I){c.a(d.substring(f));c=a;break a}c=0}if(0!=c)return r(e,1,c),c;throw"Invalid country calling code";}if(null!=b&&(f=u(b,10),g=""+f,h=a.toString(),0==h.lastIndexOf(g,0))){var k=new B(h.substring(g.length)),h=t(b,1),g=new RegExp(u(h,2));$a(k,b,null);b=k.toString();h=u(h,3);if(!N(g,a.toString())&&N(g,b)||3==Xa(h,a.toString()))return c.a(b),d&&r(e,6,10),r(e,1,f),f}r(e,1,0);return 0} 61 | function $a(a,b,c){var d=a.toString(),e=d.length,f=t(b,15);if(0!=e&&null!=f&&0!=f.length&&(f=new RegExp("^(?:"+f+")"),e=f.exec(d))){var g=RegExp,h;h=t(b,1);h=u(h,2);g=new g(h);h=N(g,d);var k=e.length-1;b=t(b,16);if(null==b||0==b.length||null==e[k]||0==e[k].length){if(!h||N(g,d.substring(e[0].length)))null!=c&&0b.c.length)throw"The string supplied is too short to be a phone number";null!=g&&(a=new B,c=new B(b.toString()),$a(c,g,a),e=c.toString(),g=t(g,1),g=u(g,3),2!=Xa(g,e)&&(b=c,d&&r(f,7,a.toString())));d=b.toString();a=d.length;if(2>a)throw"The string supplied is too short to be a phone number";if(17=g?e=d:(f=f.substring(0,g),f=O(f,K),0==f.length?e=d:(k=k.clone(),w(k,4),f=[k],k=u(c,1),d=R(c),k in I?(e=T(e,k,U(k)),g="",g=W(f,d),null==g?g=d:(f=g.clone(),g=u(g,4),0c?Math.max(0,a.length+c):c;if(l(a))return l(b)&&1==b.length?a.indexOf(b,c):-1;for(;cb?1:aa.length?!1:N(Ea,a)}function La(a){return N(Ca,a)?O(a,wa):O(a,K)}function Ma(a){var b=La(a.toString());a.c="";a.a(b)}function Na(){return ca(Object.keys(ua),function(a){return isNaN(a)})} 51 | function O(a,b){for(var c=new B,d,e=a.length,f=0;f=a.c.length)throw"Phone number too short after IDD"; 60 | a:{d=a.toString();if(0!=d.length&&"0"!=d.charAt(0))for(b=d.length,f=1;3>=f&&f<=b;++f)if(a=parseInt(d.substring(0,f),10),a in I){c.a(d.substring(f));c=a;break a}c=0}if(0!=c)return r(e,1,c),c;throw"Invalid country calling code";}if(null!=b&&(f=u(b,10),g=""+f,h=a.toString(),0==h.lastIndexOf(g,0))){var k=new B(h.substring(g.length)),h=t(b,1),g=new RegExp(u(h,2));$a(k,b,null);b=k.toString();h=u(h,3);if(!N(g,a.toString())&&N(g,b)||3==Xa(h,a.toString()))return c.a(b),d&&r(e,6,10),r(e,1,f),f}r(e,1,0);return 0} 61 | function $a(a,b,c){var d=a.toString(),e=d.length,f=t(b,15);if(0!=e&&null!=f&&0!=f.length&&(f=new RegExp("^(?:"+f+")"),e=f.exec(d))){var g=RegExp,h;h=t(b,1);h=u(h,2);g=new g(h);h=N(g,d);var k=e.length-1;b=t(b,16);if(null==b||0==b.length||null==e[k]||0==e[k].length){if(!h||N(g,d.substring(e[0].length)))null!=c&&0b.c.length)throw"The string supplied is too short to be a phone number";null!=g&&(a=new B,c=new B(b.toString()),$a(c,g,a),e=c.toString(),g=t(g,1),g=u(g,3),2!=Xa(g,e)&&(b=c,d&&r(f,7,a.toString())));d=b.toString();a=d.length;if(2>a)throw"The string supplied is too short to be a phone number";if(17=g?e=d:(f=f.substring(0,g),f=O(f,K),0==f.length?e=d:(k=k.clone(),w(k,4),f=[k],k=u(c,1),d=R(c),k in I?(e=T(e,k,U(k)),g="",g=W(f,d),null==g?g=d:(f=g.clone(),g=u(g,4),0c?Math.max(0,a.length+c):c;if(l(a))return l(b)&&1==b.length?a.indexOf(b,c):-1;for(;cb?1:aa.length?!1:N(Ea,a)}function La(a){return N(Ca,a)?O(a,wa):O(a,K)}function Ma(a){var b=La(a.toString());a.c="";a.a(b)}function Na(){return ca(Object.keys(ua),function(a){return isNaN(a)})} 51 | function O(a,b){for(var c=new B,d,e=a.length,f=0;f=a.c.length)throw"Phone number too short after IDD"; 60 | a:{d=a.toString();if(0!=d.length&&"0"!=d.charAt(0))for(b=d.length,f=1;3>=f&&f<=b;++f)if(a=parseInt(d.substring(0,f),10),a in I){c.a(d.substring(f));c=a;break a}c=0}if(0!=c)return r(e,1,c),c;throw"Invalid country calling code";}if(null!=b&&(f=u(b,10),g=""+f,h=a.toString(),0==h.lastIndexOf(g,0))){var k=new B(h.substring(g.length)),h=t(b,1),g=new RegExp(u(h,2));$a(k,b,null);b=k.toString();h=u(h,3);if(!N(g,a.toString())&&N(g,b)||3==Xa(h,a.toString()))return c.a(b),d&&r(e,6,10),r(e,1,f),f}r(e,1,0);return 0} 61 | function $a(a,b,c){var d=a.toString(),e=d.length,f=t(b,15);if(0!=e&&null!=f&&0!=f.length&&(f=new RegExp("^(?:"+f+")"),e=f.exec(d))){var g=RegExp,h;h=t(b,1);h=u(h,2);g=new g(h);h=N(g,d);var k=e.length-1;b=t(b,16);if(null==b||0==b.length||null==e[k]||0==e[k].length){if(!h||N(g,d.substring(e[0].length)))null!=c&&0b.c.length)throw"The string supplied is too short to be a phone number";null!=g&&(a=new B,c=new B(b.toString()),$a(c,g,a),e=c.toString(),g=t(g,1),g=u(g,3),2!=Xa(g,e)&&(b=c,d&&r(f,7,a.toString())));d=b.toString();a=d.length;if(2>a)throw"The string supplied is too short to be a phone number";if(17=g?e=d:(f=f.substring(0,g),f=O(f,K),0==f.length?e=d:(k=k.clone(),w(k,4),f=[k],k=u(c,1),d=R(c),k in I?(e=T(e,k,U(k)),g="",g=W(f,d),null==g?g=d:(f=g.clone(),g=u(g,4),0c?Math.max(0,a.length+c):c;if(l(a))return l(b)&&1==b.length?a.indexOf(b,c):-1;for(;cb?1:aa.length?!1:N(Ea,a)}function La(a){return N(Ca,a)?O(a,wa):O(a,K)}function Ma(a){var b=La(a.toString());a.c="";a.a(b)}function Na(){return ca(Object.keys(ua),function(a){return isNaN(a)})} 51 | function O(a,b){for(var c=new B,d,e=a.length,f=0;f=a.c.length)throw"Phone number too short after IDD"; 60 | a:{d=a.toString();if(0!=d.length&&"0"!=d.charAt(0))for(b=d.length,f=1;3>=f&&f<=b;++f)if(a=parseInt(d.substring(0,f),10),a in I){c.a(d.substring(f));c=a;break a}c=0}if(0!=c)return r(e,1,c),c;throw"Invalid country calling code";}if(null!=b&&(f=u(b,10),g=""+f,h=a.toString(),0==h.lastIndexOf(g,0))){var k=new B(h.substring(g.length)),h=t(b,1),g=new RegExp(u(h,2));$a(k,b,null);b=k.toString();h=u(h,3);if(!N(g,a.toString())&&N(g,b)||3==Xa(h,a.toString()))return c.a(b),d&&r(e,6,10),r(e,1,f),f}r(e,1,0);return 0} 61 | function $a(a,b,c){var d=a.toString(),e=d.length,f=t(b,15);if(0!=e&&null!=f&&0!=f.length&&(f=new RegExp("^(?:"+f+")"),e=f.exec(d))){var g=RegExp,h;h=t(b,1);h=u(h,2);g=new g(h);h=N(g,d);var k=e.length-1;b=t(b,16);if(null==b||0==b.length||null==e[k]||0==e[k].length){if(!h||N(g,d.substring(e[0].length)))null!=c&&0b.c.length)throw"The string supplied is too short to be a phone number";null!=g&&(a=new B,c=new B(b.toString()),$a(c,g,a),e=c.toString(),g=t(g,1),g=u(g,3),2!=Xa(g,e)&&(b=c,d&&r(f,7,a.toString())));d=b.toString();a=d.length;if(2>a)throw"The string supplied is too short to be a phone number";if(17=g?e=d:(f=f.substring(0,g),f=O(f,K),0==f.length?e=d:(k=k.clone(),w(k,4),f=[k],k=u(c,1),d=R(c),k in I?(e=T(e,k,U(k)),g="",g=W(f,d),null==g?g=d:(f=g.clone(),g=u(g,4),0c?Math.max(0,a.length+c):c;if(l(a))return l(b)&&1==b.length?a.indexOf(b,c):-1;for(;cb?1:aa.length?!1:N(Ea,a)}function La(a){return N(Ca,a)?O(a,wa):O(a,K)}function Ma(a){var b=La(a.toString());a.c="";a.a(b)}function Na(){return ca(Object.keys(ua),function(a){return isNaN(a)})} 51 | function O(a,b){for(var c=new B,d,e=a.length,f=0;f=a.c.length)throw"Phone number too short after IDD"; 60 | a:{d=a.toString();if(0!=d.length&&"0"!=d.charAt(0))for(b=d.length,f=1;3>=f&&f<=b;++f)if(a=parseInt(d.substring(0,f),10),a in I){c.a(d.substring(f));c=a;break a}c=0}if(0!=c)return r(e,1,c),c;throw"Invalid country calling code";}if(null!=b&&(f=u(b,10),g=""+f,h=a.toString(),0==h.lastIndexOf(g,0))){var k=new B(h.substring(g.length)),h=t(b,1),g=new RegExp(u(h,2));$a(k,b,null);b=k.toString();h=u(h,3);if(!N(g,a.toString())&&N(g,b)||3==Xa(h,a.toString()))return c.a(b),d&&r(e,6,10),r(e,1,f),f}r(e,1,0);return 0} 61 | function $a(a,b,c){var d=a.toString(),e=d.length,f=t(b,15);if(0!=e&&null!=f&&0!=f.length&&(f=new RegExp("^(?:"+f+")"),e=f.exec(d))){var g=RegExp,h;h=t(b,1);h=u(h,2);g=new g(h);h=N(g,d);var k=e.length-1;b=t(b,16);if(null==b||0==b.length||null==e[k]||0==e[k].length){if(!h||N(g,d.substring(e[0].length)))null!=c&&0b.c.length)throw"The string supplied is too short to be a phone number";null!=g&&(a=new B,c=new B(b.toString()),$a(c,g,a),e=c.toString(),g=t(g,1),g=u(g,3),2!=Xa(g,e)&&(b=c,d&&r(f,7,a.toString())));d=b.toString();a=d.length;if(2>a)throw"The string supplied is too short to be a phone number";if(17=g?e=d:(f=f.substring(0,g),f=O(f,K),0==f.length?e=d:(k=k.clone(),w(k,4),f=[k],k=u(c,1),d=R(c),k in I?(e=T(e,k,U(k)),g="",g=W(f,d),null==g?g=d:(f=g.clone(),g=u(g,4),0=o.clientWidth&&i>=o.clientHeight}),f=0i[e]&&!t.escapeWithReference&&(n=z(p[o],i[e]-('right'===e?p.width:p.height))),pe({},o,n)}};return n.forEach(function(e){var t=-1===['left','top'].indexOf(e)?'secondary':'primary';p=se({},p,s[t](e))}),e.offsets.popper=p,e},priority:['left','right','top','bottom'],padding:5,boundariesElement:'scrollParent'},keepTogether:{order:400,enabled:!0,fn:function(e){var t=e.offsets,o=t.popper,i=t.reference,n=e.placement.split('-')[0],r=V,p=-1!==['top','bottom'].indexOf(n),s=p?'right':'bottom',d=p?'left':'top',a=p?'width':'height';return o[s]r(i[s])&&(e.offsets.popper[d]=r(i[s])),e}},arrow:{order:500,enabled:!0,fn:function(e,t){if(!F(e.instance.modifiers,'arrow','keepTogether'))return e;var o=t.element;if('string'==typeof o){if(o=e.instance.popper.querySelector(o),!o)return e;}else if(!e.instance.popper.contains(o))return console.warn('WARNING: `arrow.element` must be child of its popper element!'),e;var i=e.placement.split('-')[0],n=e.offsets,r=n.popper,p=n.reference,s=-1!==['left','right'].indexOf(i),d=s?'height':'width',a=s?'top':'left',f=s?'left':'top',l=s?'bottom':'right',m=O(o)[d];p[l]-mr[l]&&(e.offsets.popper[a]+=p[a]+m-r[l]);var h=p[a]+p[d]/2-m/2,g=h-c(e.offsets.popper)[a];return g=_(z(r[d]-m,g),0),e.arrowElement=o,e.offsets.arrow={},e.offsets.arrow[a]=Math.round(g),e.offsets.arrow[f]='',e},element:'[x-arrow]'},flip:{order:600,enabled:!0,fn:function(e,t){if(W(e.instance.modifiers,'inner'))return e;if(e.flipped&&e.placement===e.originalPlacement)return e;var o=w(e.instance.popper,e.instance.reference,t.padding,t.boundariesElement),i=e.placement.split('-')[0],n=L(i),r=e.placement.split('-')[1]||'',p=[];switch(t.behavior){case fe.FLIP:p=[i,n];break;case fe.CLOCKWISE:p=K(i);break;case fe.COUNTERCLOCKWISE:p=K(i,!0);break;default:p=t.behavior;}return p.forEach(function(s,d){if(i!==s||p.length===d+1)return e;i=e.placement.split('-')[0],n=L(i);var a=e.offsets.popper,f=e.offsets.reference,l=V,m='left'===i&&l(a.right)>l(f.left)||'right'===i&&l(a.left)l(f.top)||'bottom'===i&&l(a.top)l(o.right),g=l(a.top)l(o.bottom),b='left'===i&&h||'right'===i&&c||'top'===i&&g||'bottom'===i&&u,y=-1!==['top','bottom'].indexOf(i),w=!!t.flipVariations&&(y&&'start'===r&&h||y&&'end'===r&&c||!y&&'start'===r&&g||!y&&'end'===r&&u);(m||b||w)&&(e.flipped=!0,(m||b)&&(i=p[d+1]),w&&(r=j(r)),e.placement=i+(r?'-'+r:''),e.offsets.popper=se({},e.offsets.popper,S(e.instance.popper,e.offsets.reference,e.placement)),e=N(e.instance.modifiers,e,'flip'))}),e},behavior:'flip',padding:5,boundariesElement:'viewport'},inner:{order:700,enabled:!1,fn:function(e){var t=e.placement,o=t.split('-')[0],i=e.offsets,n=i.popper,r=i.reference,p=-1!==['left','right'].indexOf(o),s=-1===['top','left'].indexOf(o);return n[p?'left':'top']=r[t]-(s?n[p?'width':'height']:0),e.placement=L(t),e.offsets.popper=c(n),e}},hide:{order:800,enabled:!0,fn:function(e){if(!F(e.instance.modifiers,'hide','preventOverflow'))return e;var t=e.offsets.reference,o=T(e.instance.modifiers,function(e){return'preventOverflow'===e.name}).boundaries;if(t.bottomo.right||t.top>o.bottom||t.right 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Iron Bank CRM Demo 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 51 | 52 | 78 | 79 | 120 | 121 | 122 | 123 | 124 | 125 | 206 | 207 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | -------------------------------------------------------------------------------- /docs/static_crm/code/ringcentral.js: -------------------------------------------------------------------------------- 1 | // Add the RingCentral Web Widget 2 | (function() { 3 | var rcs = document.createElement("script"); 4 | rcs.src = "https://ringcentral.github.io/ringcentral-web-widget/adapter.js?stylesUri=https://embbnux.github.io/ringcentral-web-widget-styles/GameofThrones/styles.css"; 5 | //https://ringcentral.github.io/ringcentral-web-widget/app.html?stylesUri=https://embbnux.github.io/ringcentral-web-widget-styles/GameofThrones/styles.css 6 | var rcs0 = document.getElementsByTagName("script")[0]; 7 | rcs0.parentNode.insertBefore(rcs, rcs0); 8 | if (window.RCAdapter) { 9 | window.RCAdapter.setMinimized(false); 10 | } 11 | })(); 12 | 13 | // Inbound Screen Pop Based in Message Event 14 | (function () { 15 | window.addEventListener('message', function(e) { 16 | const data = e.data; 17 | if (data) { 18 | switch (data.type) { 19 | case 'rc-call-ring-notify': 20 | var id = number2id(data.call.from, number2user); 21 | if (id) { 22 | var contact = id2user[id]; 23 | window.title = contact.character.displayName; 24 | window.history.pushState("", contact.character.displayName, "?id="+id); 25 | loadSingleUser(id, id2user); 26 | } 27 | break; 28 | default: 29 | break; 30 | } 31 | } 32 | }) 33 | })(); -------------------------------------------------------------------------------- /docs/static_crm/tutorial/index.md: -------------------------------------------------------------------------------- 1 | The Static CRM Web Widget demo is a simple demo that show cases a generic CRM with the following use cases: 2 | 3 | * Click-to-Dial 4 | * Click-to-Text (SMS) 5 | * Inbound Screen-Pop 6 | 7 | This demo is located in the `static_crm` folder. 8 | 9 | ![](static_crm_demo.png) 10 | 11 | ## Installation and Customization 12 | 13 | To install this demo, clone the repo and load the file in your browser: 14 | 15 | 1. Clone the repo 16 | 17 | `git clone https://github.com/ringcentral-tutorials/ringcentral-web-widget-demos` 18 | 19 | 2. Create a RingCentral App 20 | 21 | Create an app with the following characteristics: 22 | 23 | | Property | Setting | 24 | |----------|---------| 25 | | Platform Type | Browser-based | 26 | | Grant Types | Authorization Code or Implicit Grant | 27 | | Permissions | see [ringcentral/ringcentral-web-widget](https://github.com/ringcentral/ringcentral-web-widget) | 28 | 29 | 2. Add your demo PSTN number 30 | 31 | Edit the `data/characters_data.js` file for Jon Snow with your PSTN number in E.164 format. 32 | 33 | 3. Add/remote the demo code 34 | 35 | At the bottom of the `./static_crm/index.html` file, either link or copy and paste in the file in `./static_crm/ringcentral.js`, e.g. 36 | 37 | `` 38 | 39 | ## Notes 40 | 41 | ### Click-to-Dial and Click-to-Text 42 | 43 | These to capabilities are added automatically to the pages since the links are already provided using the `tel` and `sms` URI schemes. 44 | 45 | For example: 46 | 47 | `Call Text` 48 | 49 | Here is the JavaScript code that loads the web widget and attaches it to the `tel` and `sms` URI schemes. 50 | 51 | ```js 52 | // Add the RingCentral Web Widget 53 | (function() { 54 | var rcs = document.createElement("script"); 55 | rcs.src = "https://ringcentral.github.io/ringcentral-web-widget/adapter.js?appKey=myAppKey&appServer=https://platform.devtest.ringcentral.com&redirectUri=https://ringcentral.github.io/ringcentral-web-widget/redirect.html"; 56 | var rcs0 = document.getElementsByTagName("script")[0]; 57 | rcs0.parentNode.insertBefore(rcs, rcs0); 58 | if (window.RCAdapter) { 59 | window.RCAdapter.setMinimized(false); 60 | } 61 | })(); 62 | ``` 63 | 64 | ### Inbound Screen-Pop 65 | 66 | This is performed with the following code in `./ringcentral.js`. The code retrieves the from phone number in E.164 format using `data.call.from`. It then uses the `number2id` function to retrieve a userId. If present, the window location is changed to that user and the content for that user is loaded. 67 | 68 | ```js 69 | (function () { 70 | window.addEventListener('message', function(e) { 71 | const data = e.data; 72 | if (data) { 73 | switch (data.type) { 74 | case 'rc-call-ring-notify': 75 | var id = number2id(data.call.from, number2user); 76 | if (id) { 77 | var contact = id2user[id]; 78 | window.title = contact.character.displayName; 79 | window.history.pushState("", contact.character.displayName, "?id="+id); 80 | loadSingleUser(id, id2user); 81 | } 82 | break; 83 | default: 84 | break; 85 | } 86 | } 87 | }) 88 | })(); 89 | ``` 90 | -------------------------------------------------------------------------------- /docs/static_crm/tutorial/static_crm_demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ringcentral-tutorials/ringcentral-embeddable-demos/a3bd6064af87e75d6b478ac20725a9f359561e5f/docs/static_crm/tutorial/static_crm_demo.png -------------------------------------------------------------------------------- /docs/static_simple/code/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |

Simple RingCentral Web Widget Demo

5 | 6 |

Instructions: https://ringcentral.github.io/ringcentral-web-widget/

7 | 8 |

Tel: (415) 997-0079

9 | 10 |

SMS: (415) 997-0079

11 | 12 | 20 | 21 | -------------------------------------------------------------------------------- /docs/static_simple/code/static_embed.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/static_simple/tutorial/index.md: -------------------------------------------------------------------------------- 1 | This simple demo provides an easy way to get started with both adding the Web Widget and linking it to the `tel` and `sms` URI Schemes: 2 | 3 | * Live Demo: [https://ringcentral.github.io/ringcentral-web-widget](https://ringcentral.github.io/ringcentral-web-widget) 4 | * Repo: [https://github.com/ringcentral/ringcentral-web-widget](https://github.com/ringcentral/ringcentral-web-widget) -------------------------------------------------------------------------------- /mkdocs.yml: -------------------------------------------------------------------------------- 1 | site_name: RingCentral Web Widget Demos 2 | site_url: https://github.com/ringcentral-tutorials/ringcentral-web-widget-demos 3 | site_favicon: favicon.ico 4 | repo_url: https://github.com/ringcentral-tutorials/ringcentral-web-widget-demos.git 5 | docs_dir: docs 6 | theme: readthedocs 7 | extra_css: [assets/extra.css] 8 | extra_javascript: [assets/fonts.js] 9 | pages: 10 | - 'Overview': 'index.md' 11 | - 'Static Simple Demo': 'static_simple/tutorial/index.md' 12 | - 'Static CRM Demo': 'static_crm/tutorial/index.md' 13 | - 'Salesforce Lightning Demo': 'salesforce_lightning/tutorial/index.md' 14 | - 'More Salesforce Lightning': 'salesforce_lightning_more/tutorial/index.md' 15 | - 'Java Desktop App Demo': 'java_desktop_app/tutorial/index.md' 16 | --------------------------------------------------------------------------------