Skip to content

Conversation

@KevLehman
Copy link
Member

@KevLehman KevLehman commented Sep 2, 2021

Proposed changes (including videos or screenshots)

  • Created VoipService to manage VoIP connections and PBX connection
  • Created LivechatVoipService that will handle custom cases for livechat (creating rooms, assigning chats to queue, actions when call is finished, etc)
  • Created Basic interfaces to support new services and new model
  • Created Endpoints for management interfaces
  • Implemented asterisk connector on VoIP service
  • Created UI components to show calls incoming and to allow answering/rejecting calls
  • Added new settings to control call server/management server connection values
  • Added endpoints to associate Omnichannel Agents with PBX Extensions
  • Added support for event listening on server side, to get metadata about calls being received/ongoing
  • Created new pages to update settings & to see user-extension association
  • Created new page to see ongoing calls (and past calls)
  • Added support for remote hangup/hold on calls
  • Implemented call metrics calculation (hold time, waiting time, talk time)
  • Show a notificaiton when call is received

Issue(s)

Steps to test or reproduce

Further comments

This PR (and a new Fuselage release) are needed to avoid having to pass a random className to TopBar.ToolBox RocketChat/fuselage#603

How it looks:

  • Omnichannel Header component
    image
  • Call received component
    image
  • Call room when call's ongoing
    image
  • Call information panel (from call room)
    image
  • Call events attached to room
    image
  • Wrapup when call is finished
    image
  • Omnichannel contact center (with calls support)
    image
  • Call information panel (from contact center)
    image

@KevLehman KevLehman marked this pull request as draft September 2, 2021 21:08
@KevLehman KevLehman changed the title [NEW] VoIP Support for livechat [NEW] VoIP Support for Omnichannel Sep 9, 2021
KevLehman and others added 3 commits September 13, 2021 14:29
* Initial commit for SIP code

* Adding SIP library framework for doing VoIP.

* Clickup Tasks : https://app.clickup.com/t/7qdnh4
Description : Adding sip.js node dependency. Hence committing package.json and package-lock.json

* Clicup Task : https://app.clickup.com/t/7qdnh4
Description :
1. Added level based logging class.
2. Added necessary logs in different files.
3. Added comments on important functions.

* Update client/components/voip/RegisterHandlerDelegate.ts

Co-authored-by: Kevin Aleman <kevin.aleman@rocket.chat>

* Clickup Tasks : https://app.clickup.com/t/7qdnh4
Description:
Handling code-review comments.
1. Renamed delegate interface classes and files. Prefixed I before the name.
2. Removed unused files.
3. Renamed User.ts to VoIPUser.ts to avoid confusion.
4. Added interface for voip configuration.
5. Side effect changes in VoIPLayout.ts because of the above changes.

* Clickup Tasks : https://app.clickup.com/t/7qdnh4
Description : Converting javascript files to typescript files.

* Clickup Tasks : https://app.clickup.com/t/7qdnh4
Description : Added missing return type for a function.

Co-authored-by: Kevin Aleman <kevin.aleman@rocket.chat>
@lgtm-com
Copy link

lgtm-com bot commented Sep 14, 2021

This pull request introduces 1 alert when merging eba5721 into ae2a5ac - view on LGTM.com

new alerts:

  • 1 for Unused or undefined state property

@lgtm-com
Copy link

lgtm-com bot commented Sep 16, 2021

This pull request introduces 1 alert when merging 4401b73 into 8b66ed5 - view on LGTM.com

new alerts:

  • 1 for Unused or undefined state property

* Create new set of livechat permissions for voip

* Update app/authorization/server/startup.js

Co-authored-by: Renato Becker <renato.augusto.becker@gmail.com>

* Move EE permissions to EE

* Apply suggestions from CR

Co-authored-by: Renato Becker <renato.augusto.becker@gmail.com>
@lgtm-com
Copy link

lgtm-com bot commented Sep 17, 2021

This pull request introduces 1 alert when merging 4c0c2c9 into 7388867 - view on LGTM.com

new alerts:

  • 1 for Unused or undefined state property

tiagoevanp and others added 5 commits September 20, 2021 08:50
* create voip call icon in omnichannel section

* upgrade fuselage version

* remove success prop

* phone-disabled icon
* create voip server config collection in DB + modify interfaces

* Add new endpoints to fetch management and server-config info

* Add new endpoints to add or update voip server configs

* Add translations + move serverName property to IVoipServerConfig interface

* Remove VoipServerConfiguration DB model and rely on DB Raw module to create collection

* archive server configs instead of completely deleting them upon update/insert

* Add comment for future scope

* Apply suggestions from code review

Co-authored-by: Kevin Aleman <kevin.aleman@rocket.chat>

* Apply suggestions from code review

* remove deactive logic from endpoint

Co-authored-by: Kevin Aleman <kevin.aleman@rocket.chat>
* Clickup task : https://app.clickup.com/t/7qerzq
Description:
1. Adding connector framework
2. interface for connecting to asterisk manager interface.
3. Added Endpoint handling command which can query list of endpoints and details of a single endpoint.
4. Added REST APIs to access the connecter.
6. Moved logger to ./lib and changed the corresponding paths

* Clickup task : https://app.clickup.com/t/7qerzq
Description:
1. Fixed lint error in Logger.
2. Commented hardcoded server path for timebeing as this code will not be used directly.

* Clickup task : https://app.clickup.com/t/7qerzq
Description:
1. Added new API in asterisk-connector to get the registration information.
2. Used this API for registering the demo endpoint.
3. Added a new interface for the return types of the connector.
4. Modified Command and PJSIPEndpoint to add a declaration for the multiple return types as a result of executeCommand
5. Modified CommandHandler to to add a declaration for the multiple return types as a result of executeCommand

* Clickup task : https://app.clickup.com/t/7qerzq
Description:
Deleting unnecessary code.

* Clickup task: https://app.clickup.com/t/7qerzq
Description:
1. Handled code review comments.
2. Modified client side logging classname and file name. Imported new classname and filename
in the client code.
3. Moved server side logging to Pino based logging. Earlier it was using the same logger
that was used in the client.
4. Removed optional methods from the interfaces and removed unnecessary |undefined| checks from
the method calls.

* Clickup task: https://app.clickup.com/t/7qerzq
Description:
Fixed some old style logging statements. They were missed to be replaced in the previous commit.
@lgtm-com
Copy link

lgtm-com bot commented Oct 5, 2021

This pull request introduces 2 alerts when merging 8bc0d8c into 6074512 - view on LGTM.com

new alerts:

  • 1 for Useless assignment to local variable
  • 1 for Unused or undefined state property

@lgtm-com
Copy link

lgtm-com bot commented Oct 22, 2021

This pull request introduces 2 alerts when merging 6880fb3 into 45a5d1f - view on LGTM.com

new alerts:

  • 1 for Useless assignment to local variable
  • 1 for Unused or undefined state property

…eue details and calls waiting in the queue (#23371)

* Clickup task : https://app.clickup.com/t/7qex83
Description:
1. This commit, at its base, adds a functionality to fetch the calls waiting in the queue for a given extension.
For this, it adds a new command object in server/services/voip/connector/asterisk/ami called |ACDQueue|.
ACD queue is capable of fetching various queue parameters such as queue summary, details of a particular queue (Members of a given queue)
It also provides a set of new APIs for fetching queue summary |queues.getSummary| and fetching the calls waiting in the queue
|queues.getCallWaitingInQueuesForThisExtension|.

2. Beyond this it also modifies the connector architecture a bit.
The reason for this change is that, it was observed that the AMI library does not have a way to turn off event handling.
Event handling gets turned off only when the connection to Asterisk AMI socket is disconnected. That may not be desirable.
So to avoid this, the architecture is changed as follows :
a. Connection registers for all management events.
b. Each command object registers the callback context for each manager event that it is interested in.
c. Connection (AMIConnection) goes thru the list of registered callbacks for a particular event. If it finds an array
of registered Callback contexts, it goes on calling each callback in the array.
d. Once the expected data is received, the command object unregisters the callback context. It is removed from the handler list for a particular
event.As a result of this design change existing command objects |PJSIPEndpoint| have been changed too to adapt to this arch change.

3. Removed hardcoding from extensions.ts. Now it reads the callserver information from the database, which was
hardcoded earlier.

* Clickup task : https://app.clickup.com/t/7qex83
Description:
1. Fixed review comments.
2. Simplified some nested ifs suggested in review comments.
3. Added new consolidated type IVoipConnectorResult to contain either of the result to avoid
growing function signature as suggested in the comment.
4. Made necessary changes in REST API files which were necessary as above changes
created some side-effects.

* Clickup task : https://app.clickup.com/t/7qex83
Description:
1. Fixed code-review comments.

* Update app/api/server/v1/voip/extensions.ts

Fixed.

Co-authored-by: Kevin Aleman <kevin.aleman@rocket.chat>

* Update app/api/server/v1/voip/extensions.ts

Fixed

Co-authored-by: Kevin Aleman <kevin.aleman@rocket.chat>

Co-authored-by: Kevin Aleman <kevin.aleman@rocket.chat>
@lgtm-com
Copy link

lgtm-com bot commented Oct 25, 2021

This pull request introduces 2 alerts when merging a009e38 into 45a5d1f - view on LGTM.com

new alerts:

  • 1 for Useless assignment to local variable
  • 1 for Unused or undefined state property

amolghode1981 and others added 4 commits November 8, 2021 13:45
…hardcoding for management server (#23571)

* Clickup Task : https://app.clickup.com/t/7qeq76
Description :
Some background :
Issue#1 : CommandHandler class is an entry point to a connector to Asterisk. This command handler had hardcoded values till the APIs and database for the management API was getting ready.
Once it got ready there was a need to change it and use the database values. This design change is triggered by this need.
The aim for the re-design was that all the API access should happen via voip service. It was realised that |CommandHandler| gets created (Because it is declared globally in REST APIs) before the Voip service gets initialised. And because of this fact, CommandHandler does not get to read the values as the service has not yet started and initialised |VoipServerConfiguration|.

To fix this issue, |CommandHandler| has to be created after service and should be accessible only via service. So it has been moved to Voip service. Few more points to consider here is that
CommandHandler::initConnection may not work always. When Voip is getting used for the first time, the server values (management and callserver) will be empty. One has to add those values using the admin interface. So CommandHandler::initConnection failure should not cause server to crash. So errors from CommandHandler::initConnection should be written in logs and the code should move ahead.

Issue#2 : Some design refinements have been done. The intelligence in the REST APIs have been reduced. While building the code connector was exposed outside. Now connector is contained within the
service. Service contains all necessary implementation. The necessary changes have been done to support this architectural change.

Considering these points, following changes have been done.
1. Voip rest APIs which use CommandHandler (Queue and extension APIs) now query for the CommandHandler instead of creating it.
2. server-config.ts REST API for adding management interface reinitialises the connection after adding a management interface.
3. On the server side, Voip Service interface has been changed, to have new methods. Voip service and CommandHandler is changed to adapt to the design mentioned above.
4. Log level change in AMIConnection file.
5. Modified the IVoipService interface to contain all the necessary methods and changed service.ts to have the implementation.

* Update server/services/voip/service.ts

Co-authored-by: Kevin Aleman <kevin.aleman@rocket.chat>

* Clickup Task : https://app.clickup.com/t/7qeq76
Description :
Fixing review comments.

* Clickup task : https://app.clickup.com/t/7qeq76
Description:
Fixing review comments.

Co-authored-by: Kevin Aleman <kevin.aleman@rocket.chat>
… on sidebar (#23550)

* Clickup task : https://app.clickup.com/t/du0e8p
Description :
This code manages the registering of SIP endpoint on a button click on the side bar. To achieve this, following things needs to be considered.
1. Voip User Object will be used by multiple UI components. e.g Register and Incoming call component need to use this component.
2. Once initialised, it will remain in the context till the Agent UI is active.
3. Voip user object uses callback mechanism to notify about different events such as incoming call, call establishment and call termination.

Design alternatives and decisions:
1. Placement of Voip User Object : It was earlier thought that it might make sense to add this object in its own Context and be managed by its own context provider. Voip object makes REST API calls. The requirement is also that, it must get initialised before sidebar/sections/Omnichannel.tsx comes to life. Hence (Considering my current knowledge of code), it must have got created before Omnichannel provider. Which means that OmnichannelProvider must be a child for Voip, which is not true as Omnichannel provider is not dependent on the creation of VoIP. So for timebeing, the Voip user object has been placed in |OmnichannelContext| and initialised in |OmnichannelProvider|.
2. Callbacks vs waiting on Promise: Most of the code in the repository is written without use of any callbacks. So there was a thought on if we could write this code without using callback. But considering the nature of voip calls and the way of using sip.js, it was more natural to write it using emitters and callbacks. There are multiple events happen when the call is received or dialed out. e.g Call getting established (This is must to handle becuase the call may fail because of some codec mismatch), call getting terminated. etc. Waiting for each of such promise and managing the state on UI client would have been a tricky job.

Current Design :
1. A simple wrapper |SimpleVoipUser| is written on top of more feature rich class |VoIPUser|. This class should be able to provide what we need in our omnichannel voip.
2. This |SimpleVoipUser| class is a part of |OmnichannelContext| and gets initialised in |OmnichannelProvider|. |OmnichannelContext| also contains |extensionConfig|, which is the necessary information needed for registering the extension.
3. In |OmnichannelProvider|, function initVoipLib is used for fetching necessary values using the REST API. |extensionConfig| and |SimpleVoipUser| objects get initialised there and they are ready to be used when |OmnichannelProvider| is loaded.
4. Media elements for rendering local and remote streams have been pulled out from |VoIPUserConfiguration|. They are converted in to a type |IMediaStreamRenderer|. The reason is that the configuration is passed when the component gets initialised. But because the calling component is going to be different, media elements will not be available during the creation of |SimpleVoipUser| (Which in turns needs these media elements for creating |VoIPUser|). So instead of passing it as a part of |VoIPUserConfiguration|, it can be passed as an argument to the constructor of |VoIPUser| if that information is available during the creation time, or can be passed in acceptCall function. Newly passed |IMediaStreamRenderer| replaces the old value if the old one is passed in the constructor.
5. |VoIPLayout| uses this new way of creating the Voip user objects and demonstrates how it will be used.

* Update client/components/voip/SimpleVoipUser.ts

Co-authored-by: Kevin Aleman <kevin.aleman@rocket.chat>

* Update client/components/voip/SimpleVoipUser.ts

Fixed.

Co-authored-by: Kevin Aleman <kevin.aleman@rocket.chat>

* Clickup task : https://app.clickup.com/t/du0e8p
Description : Fixing code review comments.

* Clickup task : https://app.clickup.com/t/du0e8p
Description: Fixing review comments.

* Clickup task: https://app.clickup.com/t/du0e8p
Description: Remove the hardcoding for ICE servers. Now we pull it from the admin
settings. The setting Id is 'WebRTC_Servers'.

* Clickup task: https://app.clickup.com/t/du0e8p
Description:
Fixing LGTM issue.

* Clickup task : https://app.clickup.com/t/du0e8p
Description : Fixing the issues post merging. Few thing were changed in the parent repo.
This workspace is for taking those changes in account.

* Clickup task : https://app.clickup.com/t/du0e8p
Description :
Fixing review comments.
1. Toggled the logic for the register icon.
when it is registered, icon should be green. i.e success and grayed out when not registered.
2. When it is registered, the icon should be of a phone. On clicking this, it would unregister, which will change the icon to striked out phone.

Co-authored-by: Kevin Aleman <kevin.aleman@rocket.chat>
Co-authored-by: Kevin Aleman <kevin.aleman@rocket.chat>
@lgtm-com
Copy link

lgtm-com bot commented Dec 7, 2021

This pull request introduces 1 alert when merging f411d8f into 5d0bdf1 - view on LGTM.com

new alerts:

  • 1 for Useless assignment to local variable

tiagoevanp and others added 19 commits February 15, 2022 09:56
* voip room

* visitor logic

* fix noo js

* end

* fix build errors

* fix

* room start header

* \n
* Draft workspace for call server monitor.

* Draft workspace for call server monitor. Using Event notification mechanism to notify the clients.
Implements strategy for notifying source queue (While the agent is riniging) and Calls in queue

* Fix issue with duplicated notifications on client

* Started adding support for 3 more events, QueueMemeberAdded, QueueMemberRemoved and QueueCallerAbandon

* Fixing errors.

* Use user extension to fetch queue details

* Clickup Task : https://app.clickup.com/t/21fekdx
Description: This PR implements continuous monitor in the asterisk connector.
Asterisk continuously generates a stream of events on various activities. Management
server user defined in asterisk's manager.conf determines the events to be sent on this user.

This PR's main focus is to find out calls in the queue and source queue of a call.
To do this, it monitors following events

queuecallerjoin (For finding out the source queue of a call)
agentcalled (for calls in the queue)
agentconnect (for calls in the queue)
queuememberadded (for calls in the queue)
queuememberremoved (for calls in the queue)
queuecallerabandon (for calls in the queue)

The client is going to create an aggregator which will be responsible for the events which cause change in |calls waiting in the queue|
The aggregator will always have the latest 'calls waiting in the queue'

* Clickup Task : https://app.clickup.com/t/21fekdx
Description : Fixing build issues.

* Clickup Task : https://app.clickup.com/t/21fekdx
Description : Adding agentconnect event. Refactored some duplicated code.

* QoL changes

* Remove endpoints for call server management

* remove import to old server mgmnt endpoints

* Clickup Task : https://app.clickup.com/t/21fekdx
Description : Handling review comments.
1. Added database object as compulsory field to Command's constructor.
2. Resetting handlers for new events.

* https://app.clickup.com/t/21fekdx
Description:
1. Added queue wait time to the agentconnect event.
2. Fixed the socket disconnection issue happening after 30 seconds. Asterisk closes the socket after 30 seconds
if it does not receive any message. Added some code in client/lib/voip/VoIPUser.ts which will send
SIP OPTIONS message. After sending this message, there is no disconnection.

* Listen to asterisk events and store them on DB for validation

* Fix type error on storepbxevent

Co-authored-by: Kevin Aleman <kevin.aleman@rocket.chat>
Co-authored-by: amolghode <amol.ghode@gmail.com>
… to close the room (#24563)

* Clickup Task : https://app.clickup.com/t/22c968v
Description :
When the agent disconnects abruptly, the room should be closed. But because the agent is sitting on browser, agent will not be
able to do these things gracefully. The reason is that the browser may just crash or the agent just forces the tab close or refresh (Even though we prevent
it on client side)

So the solution is to detect this scenario on server and close the associated room. When such forceful tab close happens, Asterisk sends AMI event
'ContactStatus' where the field contactstatus = 'Removed'

We will handle the ContactStatus event and if the contactstatus is removed, we will gracefully close the room on server.

Changes
1. Added new Event definition for ContactStatus event.
2. Added event handling function for this event in ContinuousMonitor.ts

* Handle agent unexpected disconnection events

Co-authored-by: Kevin Aleman <kevin.aleman@rocket.chat>
Co-authored-by: Kevin Aleman <kevin.aleman@rocket.chat>
Co-authored-by: Kevin Aleman <kevin.aleman@rocket.chat>
Co-authored-by: amolghode <amol.ghode@gmail.com>
Co-authored-by: amolghode1981 <86001342+amolghode1981@users.noreply.github.com>
Co-authored-by: Tiago Evangelista Pinto <tiago.evangelista@rocket.chat>
* Prep work: Type files needed for the feature

* Auto stash before merge of "new/livechat-voip-contact-center" and "origin/new/livechat-voip"

* Wip

* Wrapping up

* No console logs

* Fix ts

* fix types

* remove unnecessary commented code

* Fix conflicts with v.phone prop

* Fix ts signature

* Update client/views/omnichannel/directory/calls/Call.tsx

Co-authored-by: Kevin Aleman <kevin.aleman@rocket.chat>

* Fix issues with rooms endpoints

* Fix reviews

* Fix storing and calculation of some timers

* Its late toniight

Co-authored-by: Kevin Aleman <kevin.aleman@rocket.chat>
* calls in queue

* Fix lint && ts

Co-authored-by: Martin Schoeler <martin.schoeler@rocket.chat>
* wip

* voip room

* visitor logic

* fix noo js

* end

* fix build errors

* fix en

* fix

* wip

* events

* Update app/livechat/server/api/v1/visitor.ts

Co-authored-by: Martin Schoeler <martin.schoeler@rocket.chat>

* fixes

* add moment

* fix duplicate type

* almost there

* fix

* Fix events relation to call

* Create VoipRoomType server file

* Remove logs and stale code

Co-authored-by: Martin Schoeler <martin.schoeler@rocket.chat>
Co-authored-by: Kevin Aleman <kevin.aleman@rocket.chat>
@KevLehman KevLehman marked this pull request as ready for review February 22, 2022 17:37
pierre-lehnen-rc and others added 4 commits February 22, 2022 12:43
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: dougfabris <devfabris@gmail.com>
Co-authored-by: Tasso Evangelista <tasso.evangelista@rocket.chat>
Co-authored-by: Robot LingoHub <robot@lingohub.com>
Co-authored-by: Diego Sampaio <chinello@gmail.com>
Co-authored-by: Júlia Jaeger Foresti <60678893+juliajforesti@users.noreply.github.com>
Co-authored-by: Douglas Gubert <douglas.gubert@gmail.com>
Co-authored-by: lingohub[bot] <69908207+lingohub[bot]@users.noreply.github.com>
Co-authored-by: Murtaza Patrawala <34130764+murtaza98@users.noreply.github.com>
Copy link
Contributor

@casalsgh casalsgh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM - All conflicts resolved; all PRs properly reviewed and approved.

@casalsgh casalsgh merged commit 550bfb0 into develop Feb 22, 2022
@casalsgh casalsgh deleted the new/livechat-voip branch February 22, 2022 21:24
@pierre-lehnen-rc pierre-lehnen-rc mentioned this pull request Mar 1, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.