how to add creational of third party CRM contacts search into embeddable widget

  • 1
  • Idea
  • Updated 2 weeks ago
I want to include the contact search and display contact name via a search through the embeddable widget.
There is a way like following, but how I pass creds and domain details to the request
https://github.com/ringcentral/ringcentral-embeddable/blob/master/docs/third-party-service-in-widget...
Photo of sharmilan A

sharmilan A

  • 538 Points 500 badge 2x thumb

Posted 3 months ago

  • 1
Photo of Embbnux Ji

Embbnux Ji, Employee

  • 1,198 Points 1k badge 2x thumb
Hi, Sharmilan This is a demo about how to integrate third party contacts https://github.com/embbnux/ringcentral-embeddable-voice-with-third-party/blob/master/index.html 

https://medium.com/ringcentral-developers/custom-extensions-for-the-ringcentral-embeddable-voice-web...

Firstly, you need to register the service into the widget when it is :

  function registerService() {
    document.querySelector("#rc-widget-adapter-frame").contentWindow.postMessage({
      type: 'rc-adapter-register-third-party-service',
      service: {
        name: 'TestService',
        contactsPath: '/contacts',
        contactSearchPath: '/contacts/search',
        contactMatchPath: '/contacts/match',
      }
    }, '*');
  } // To register the widget when it is ready. var registered = false; window.addEventListener('message', function (e) { const data = e.data; if (data && data.type === 'rc-adapter-pushAdapterState' && registered === false) { registered = true; registerService(); } })
And add message event to response to the widget:

  window.addEventListener('message', function (e) {
    var data = e.data;
    if (data && data.type === 'rc-post-message-request') {
      if (data.path === '/contacts') {
        getContacts(data);
      }
      if (data.path === '/contacts/search') {
        searchContacts(data);
      }
      if (data.path === '/contacts/match') {
        matchContacts(data);
      }
    }
  });
function responseMessage(request, response) {
    console.log(request);
    document.querySelector("#rc-widget-adapter-frame").contentWindow.postMessage({
      type: 'rc-post-message-response',
      responseId: request.requestId,
      response,
    }, '*');
  }
  function getContacts(request) {
    responseMessage(request, {
      data: [{
        id: '123456',
        name: 'TestService Name',
        type: 'TestService',
        phoneNumbers: [{
          phoneNumber: '+16579991394',
          phoneType: 'directPhone',
        }]
      }],
      nextPage: null,
    });
  }
  function searchContacts(request) {
    responseMessage(request, {
      data: [{
        id: '123456',
        name: 'TestService Name',
        type: 'TestService Name',
        phoneNumbers: [{
          phoneNumber: '+16579991394',
          phoneType: 'directPhone',
        }]
      }]
    });
  }
  function matchContacts(request) {
    responseMessage(request, {
      data: {
        '+12165325078': [
          {
            entityType: 'TestService',
            name: 'TestService 1',
            phoneNumbers: [{
              phoneNumber: '+12165325078',
              phoneType: 'directPhone',
            }]
          }
        ]
      }
    });
  }
Photo of Embbnux Ji

Embbnux Ji, Employee

  • 1,198 Points 1k badge 2x thumb
You don't need to pass creds and domain to it. But you need to implement message event listener to response the data by `postMessage` out of widget.
Photo of sharmilan A

sharmilan A

  • 538 Points 500 badge 2x thumb
Thank you very much. works fine, I am currently working with the nextPage. If we have a good doc for each component would be great 
(Edited)
Photo of Embbnux Ji

Embbnux Ji, Employee

  • 1,198 Points 1k badge 2x thumb
Yes. Document is very important. We are working on building better tutorials and documents.
Photo of sharmilan A

sharmilan A

  • 538 Points 500 badge 2x thumb
Hi Embbnux Ji,
I have used Recururion for getContacts function with next page number, until the last page, that works fine. but this scenario repeating infinity.
I have added some of my code here:

private getContacts(request: any) {
    const getContactsFromCRM = (request: any, page = 1) => {
        return getData('/contacts', false, {itemCount: 50, page}).then((res: any) => {
            const _links = res.data._links;
            let response = {
                data: res,
                nextPage: false
            };

            if (_links.next) {
                page++;
                response.nextPage = getContactsFromCRM(request, page);
            }

            return this.responseMessage(request, response);
        });
    };

    return getContactsFromCRM(request);
}

is there any way to use lazy loding?
Also is it possible to keep 5M contacts inside the widget? how can I handle?
Also I have to reload the contacts, if any updates have been made.
(Edited)
Photo of Embbnux Ji

Embbnux Ji, Employee

  • 1,198 Points 1k badge 2x thumb
Hi, Sharmilan You should just set response.nextPage = page + 1 if has next page data
```
private getContacts(request: any) {
    return getData('/contacts', false, {itemCount: 50, page: request.body.page}).then((res: any) => {
        const _links = res.data._links;
        let response = {
            data: res
        };

        if (_links.next) {
            response.nextPage = page + 1;
        }

        return this.responseMessage(request, response);
    });
}
```
the widget will repeat contacts request to your message event listener with page = 2.
You don't need to implement recururion. Just return correct paging data to widget.

Now it hasn't support lazy loading. We save contacts data in memory. So now it only fresh data when user refreshes page. I think 5M data is ok for it. I have created a issue to follow this problem https://github.com/ringcentral/ringcentral-embeddable/issues/148
Photo of sharmilan A

sharmilan A

  • 538 Points 500 badge 2x thumb
what is the purpose of have /contacts/search? Because if that will work for filtering contacts and also getting the name when incoming calls for displaying. Then I can get like 1k contacts in the widget. without loading the memory.
Photo of Embbnux Ji

Embbnux Ji, Employee

  • 1,198 Points 1k badge 2x thumb
Hi,Sharmilan. When user searches in dial callee input area, widget will call `/contacts/search`. You need to implement the search logics in `/contacts/search` response. For `/contacts/match` is used to match phone number with contacts to show in call history and messages list. We can get detail document in here https://github.com/ringcentral/ringcentral-embeddable/blob/master/docs/third-party-service-in-widget...
Photo of sharmilan A

sharmilan A

  • 538 Points 500 badge 2x thumb
Hi Embbnux Ji,
I am having still confusing bit when we are searching through the dial pad trigger the `contacts/search` and I have added the logic but not populate a list in the dial pad.

Also when searching through the contacts filter, only works for the contacts which are in the RingCentral account. So not working for the third party service.

Ideally, I need to load the dropdown list from both search places.
Thanks
Photo of Embbnux Ji

Embbnux Ji, Employee

  • 1,198 Points 1k badge 2x thumb
Hi, @sharmilan Just check with it. There are bugs in contacts list filter. We will fix it soon.  https://github.com/ringcentral/ringcentral-embeddable/issues/159 
And for dial pad search, it will only show 50 search results. and there are some problem on result sorting. we are working on it. https://github.com/ringcentral/ringcentral-embeddable/issues/111

Thanks very much for feedback.
Photo of sharmilan A

sharmilan A

  • 538 Points 500 badge 2x thumb
Thank you very much, FYI contacts list filter by telephone number works fine with the 3rd party list as well, the name search is the issue.
Photo of Embbnux Ji

Embbnux Ji, Employee

  • 1,198 Points 1k badge 2x thumb
Hi , @sharmilan We have fixed contacts list filter issue. Do you still have name search issue?
Photo of sharmilan A

sharmilan A

  • 538 Points 500 badge 2x thumb
Hi @Embbnux Ji, ya contacts list filter works fine in the contacts list tab.
But working in dial pad, using the name or telephone number.
Also, for incoming calls, most of the time getting as 'Unknown number'.
All these requests for the CRM databases.

Can you have a look Please?
(Edited)
Photo of Embbnux Ji

Embbnux Ji, Employee

  • 1,198 Points 1k badge 2x thumb
hi,Sharmilan Which version of widget are you using?  Do you register `contactMatchPath` into widget?  When widget shows incoming call page, it will request `/contact/match` path as '/contacts' to get user name. https://github.com/ringcentral/ringcentral-embeddable/blob/master/docs/third-party-service-in-widget...
Photo of sharmilan A

sharmilan A

  • 538 Points 500 badge 2x thumb
That is working, The issue if the `phoneType` inside the contacts list, those contacts do not populate in the dial pad dropdown list.
I have used the RC widget without version.