Skip to main content
Version: 10

Manage chats in Creatio

Level: intermediate

Customers contact companies through different messengers, and agents need to handle these chats without switching between apps. Creatio lets agents process chats from Facebook Messenger, Telegram, and custom messengers in one place. The pre-installed OmnichannelMessaging package contains the basic functionality that lets you manage chats. Before using the functionality, set up chat processing. Instructions: Set up chat processing (user documentation).

Manage chat functionality in Creatio​

View the list of primary classes that let you manage chat functionality in the table below.

Class

Description

MessageManager

Enables the messenger integration with Creatio instance.

FacebookOmnichannelMessagingService

Receives and registers messages from Facebook Messenger. The class is based on the OmnichannelMessagingService class that contains the set methods that are common for both Facebook Messenger and Telegram.

TelegramOmnichannelMessagingService

Receives messages from Telegram. The class is based on the OmnichannelMessagingService class that contains the set methods that are common for both Facebook Messenger and Telegram.

OmnichannelChatService

Receives messages, chats of a specific agent, etc.

OmnichannelOperatorService

Receives and changes the agent status.

Implement a custom channel provider​

Previously, Creatio supported only one custom channel. All custom channels shared the single ChannelType.ThirdParty value, and Creatio routed messages using this value. Since version 10.1, you can register multiple custom channels. Each custom channel has its own channel name that Creatio uses to route messages to the corresponding classes. Existing integrations that implement a single custom channel continue to work when updating to version 10.1.

1. Add a channel provider to Creatio​

  1. Create a package. Instructions: Create a user-made package using Configuration section.

  2. Change the current package. Instructions: Change the current package.

  3. Click btn_system_designer_8_shell.png in the top right → System setup → Lookups.

  4. Open the "Channel provider" lookup.

  5. Click New to add the lookup value.

  6. Fill out the properties of the lookup value.

    The following example adds the "SomeProvider" channel provider.

    Property

    Description

    Example

    Name

    Unique name of the channel provider.

    SomeProvider

    Code

    Unique code of the channel provider. Available for Creatio 10.1 and later. Creatio uses the Code field to distinguish custom channel providers from out-of-the-box channel providers. Out-of-the-box channel providers use the ChannelType ordinal as the Code field value. Custom channel providers use "1000" and higher. Creatio requires this value to send messages when an agent opens a chat from a contact. Do not use codes of out-of-the-box channel providers.

    1000

  7. Save the changes.

As a result, the custom channel provider will be added to Creatio.

2. Create a database table to store data of the custom channel provider​

Creatio uses one database table to store data of one channel provider. The structure of the database table depends on the provider and contains data to send and receive messages.

To create a database table, execute the SQL query.

IF OBJECT_ID('SomeProviderMsgSettings') IS NULL
BEGIN
CREATE TABLE SomeProviderMsgSettings(
Id uniqueidentifier NOT NULL DEFAULT (newid()),
Token nvarchar(250) NOT NULL DEFAULT (''),
UserName nvarchar(250) NOT NULL DEFAULT (''),
CONSTRAINT PK_SomeProviderMsgSettings_Id PRIMARY KEY CLUSTERED (Id)
)
END

Where SomeProviderMsgSettings is a template for the name of database table that will store data of the custom channel provider whose name is SomeProvider.

As a result, the database table that stores data of the custom channel provider will be created.

3. Register the custom channel provider in the database​

To register the custom channel provider in the database, add a record to the Channel database table that stores a list of all channel providers. View the primary columns of the Channel database table below.

Column

Description

Name

The channel name.

ProviderId

The custom provider ID.

MsgSettingsId

The record ID from the database table that stores data of custom channel provider.

Source

The channel ID from the messenger. For example, Facebook page ID, Telegram client ID. The property value lets you identify the recipient by a messenger message.

As a result, the custom channel provider will be registered in the database.

4. Implement a custom web service that receives messages​

  1. Create the "Source code" type schema. Instructions: Implement the source code.

  2. Create a service class.

    1. Add the Terrasoft.Configuration.Omnichannel.Messaging namespace.
    2. Add the namespaces the data types of which to utilize in the class using the using directive.
    3. Add a class name that matches the schema name (the Code property).
    4. Specify the OmnichannelMessagingService class as a parent class.
    5. Add the [ServiceContract] and [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)] attributes to the class.
  3. Implement a class method. Add the public void ReceiveMessage(SomeProviderIncomingMessage message) method that implements the endpoint of the custom web service. The messenger sends a message to the receive endpoint.

    SomeProviderOmnichannelMessagingService
    namespace Terrasoft.Configuration.Omnichannel.Messaging
    {
    using System;
    using System.ServiceModel;
    using System.ServiceModel.Activation;
    using System.ServiceModel.Web;
    using Terrasoft.Common;
    using Terrasoft.Core;
    using Terrasoft.Core.DB;
    using Terrasoft.Web.Common.ServiceRouting;

    #region Class: SomeProviderOmnichannelMessagingService

    [ServiceContract]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
    [DefaultServiceRoute]
    public class SomeProviderOmnichannelMessagingService : OmnichannelMessagingService
    {

    #region Constructors: Public

    public SomeProviderIncomingMessage() : base()
    { }

    /* Initialize a new "SomeProviderIncomingMessage" class instance. */
    public SomeProviderIncomingMessage(UserConnection userConnection) : base(userConnection)
    { }

    #endregion

    #region Methods: Private

    private void GetChannelAndQueueBySource(MessagingMessage message) {
    Select channelSelect = new Select(UserConnection)
    .Top(1).Column("Id")
    .Column("ChatQueueId")
    .From("Channel")
    .Where("Source").IsEqual(Column.Parameter(message.Recipient))
    .And("IsActive").IsEqual(Column.Parameter(true)) as Select;
    channelSelect.ExecuteReader(reader => {
    message.ChannelId = reader.GetColumnValue("Id").ToString();
    message.ChannelQueueId = reader.GetColumnValue("ChatQueueId");
    });
    }

    #endregion

    #region Methods: Public

    /* The method that receives messages from the integration API. */
    [OperationContract]
    [WebInvoke(UriTemplate = "receive", Method = "POST", RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Json)]

    public void ReceiveMessage(SomeProviderIncomingMessage message) {

    /* Convert the message. */
    MessagingMessage messagingMessage = new MessagingMessage(SomeProviderIncomingMessageConverter.Convert(message));

    /* Identify the channel using the "Source" database field. */
    GetChannelAndQueueBySource(messagingMessage);

    /* If an open chat with this user is not found, create a new chat. Otherwise, add a message to an existing chat. If the user contacts you for the first time, create a contact and fill out their credentials. Otherwise, bind the chat to an existing contact. */
    InternalReceive(messagingMessage);
    }

    #endregion

    }

    #endregion

    }
  4. Publish the schema.

As a result, a custom web service that receives messages will be implemented.

5. Handle an incoming message​

Since Creatio attempts to handle incoming messages in the unified format, implement conversion of incoming messages to unified format. To do this:

  1. Create the "Source code" type schema. Instructions: Implement the source code.

  2. Implement the business logic that handles incoming messages using the SomeProviderIncomingMessageConverter class. The class converts a message that has the SomeProviderIncomingMessage type to the message with the MessagingMessage type.

    SomeProviderIncomingMessageConverter
    namespace Terrasoft.Configuration.Omnichannel.Messaging
    {
    using OmnichannelProviders.Domain.Entities;
    using System;
    using System.Collections.Generic;

    public class SomeProviderIncomingMessage : UnifiedMessage
    { }

    public static class SomeProviderIncomingMessageConverter
    {

    #region Methods: Public

    public static MessagingMessage Convert(SomeProviderIncomingMessage message) {

    var messageType = MessageType.Text;
    var messageId = Guid.NewGuid();
    var result = new MessagingMessage {
    Id = messageId,
    Message = message.Message,

    /* The message recipient is the ID of the page or client added to "Source" column in the "Channel" database table. */
    Recipient = message.Recipient,

    /* The ID of the message sender in the messenger. The sender is bound to the contact via the "ContactIdentity" database table. */
    Sender = message.Sender,

    Timestamp = message.Timestamp,

    /* The channel ID in Creatio specified in the "MsgSettingsid" object field. */
    ChannelId = message.ChannelId,

    MessageDirection = MessageDirection.Incoming,
    MessageType = messageType,

    /* The channel source. */
    Source = ChannelType.ThirdParty,

    /* The channel name that Creatio uses as the routing
    key. Must match the "ClassFactory.Bind()" key and
    "ChannelProvider.Name". */
    ChannelName = "SomeProvider"
    };

    if (messageType != MessageType.Text) {

    /* The "Attachments" block is populated depending on the file access format provided by the messenger. In this case, it is a link to download. Fill out the "FileId" parameter value in the message to make the file available for download. */
    result.Attachments = new List<MessageAttachment>();
    foreach (var attachment in message.Attachments){
    result.Attachments.Add(new MessageAttachment {
    MessageId = messageId,
    UploadUrl = attachment.UploadUrl,
    FileType = attachment.FileType
    });
    }
    }
    return result;
    }

    #endregion

    }
    }

    Previously, Creatio routed the message using the Source property value, and ChannelName only served as the provider ID. Since version 10.1, Creatio routes the message using the ChannelName property value. Source is the fixed out-of-the-box ChannelType enumeration that you cannot extend, so a custom channel sets Source to ChannelType.ThirdParty and stores its actual identity in ChannelName. Route and branch the behavior using ChannelName, because code that reads only Source treats every custom channel as ThirdParty. The ChannelName property value must be identical to the Name property of the channel provider lookup value, the ProviderName property of the channel provider resolver, and the binding key of the ClassFactory.Bind() method.

  3. Publish the schema.

As a result, incoming messages will be converted to the unified format that Creatio attempts to handle.

6. Implement retrieval of sender data​

Messengers provide an API to retrieve sender data. To do this:

  1. Create the "Source code" type schema. Instructions: Implement the source code.

  2. Implement the business logic that retrieves sender data using the IProfileDataProvider interface.

    1. Send a request to the channel provider API, for example, https://somechannelprovider.api/, to retrieve data in the SomeProviderProfileData format. The SomeProviderProfileData format is a hypothetical messenger format.
    2. Convert the received response into the internal ProfileData format.
    3. Create a contact and add the retrieved data using the internal format. For example, first name, last name, and photo. If the request is unsuccessful or data is invalid, create a contact named "{New Contact}{Channel}-{MessengerClientID}."
    SomeProviderProfileData
    namespace Terrasoft.Configuration.Omnichannel.Messaging
    {
    using Newtonsoft.Json;
    using OmnichannelProviders.Domain.Entities;
    using OmnichannelProviders.Interfaces;
    using System.IO;
    using System.Net;
    using Terrasoft.Core;

    public class SomeProviderProfileData {
    public string first_name { get; set; }
    public string last_name { get; set; }
    }

    #region Class: SomeProviderProfileData

    /* Retrieve the profile data from the "SomeProvider" provider. */
    public class SomeProviderProfileData : IProfileDataProvider
    {
    #region Properties: Private

    private readonly string _someProviderUrl = "https://somechannelprovider.api/";

    #endregion

    #region Constructors: Public

    /* Initialize a new "FacebookProfileDataProvider" class instance. */
    public SomeProviderProfileData(UserConnection userConnection)
    { }

    #endregion

    #region Methods: Public

    /* Retrieve the profile data from Facebook.
    The "profileId" parameter is the Facebook profile ID.
    The "channelId" parameter is the channel from which the request was sent.
    Return the contact ID. */
    public ProfileData GetProfileDataByProfileId(string profileId, string channelId) {
    var requestUrl = string.Concat(_someChannelProviderNameProviderApiUrl, profileId);
    WebRequest request = WebRequest.Create(requestUrl);
    try {
    using (var response = request.GetResponse()) {
    using (Stream stream = response.GetResponseStream()) {
    using (StreamReader sr = new StreamReader(stream)) {
    var someChannelProviderNameProfile = JsonConvert.DeserializeObject<SomeChannelProviderNameProfileData>(sr.ReadToEnd());
    return new ProfileData {
    FirstName = someChannelProviderNameProfile.first_name,
    LastName = someChannelProviderNameProfile.last_name,
    };
    }
    }
    }
    }
    catch {
    return new ProfileData();
    }
    }

    #endregion

    }

    #endregion
    }
  3. Publish the schema.

As a result, Creatio will retrieve the sender data and create contact using this data.

7. Implement downloading of attachments​

  1. Create the "Source code" type schema. Instructions: Implement the source code.

  2. Implement the business logic that lets you download attachments using the IAttachmentsLoadWorker interface. The class downloads the attachment via a link and saves the attachment to the OmnichannelMessageFile database table.

    SomeProviderAttachmentLoadWorker
    namespace Terrasoft.Configuration.Omnichannel.Messaging
    {
    using OmnichannelProviders;
    using OmnichannelProviders.Domain.Entities;
    using OmnichannelProviders.MessageConverters;
    using Terrasoft.Core;

    #region Class: SomeProviderAttachmentLoadWorker

    /* Load attachments from the "SomeProvider" provider. */
    public class SomeProviderAttachmentLoadWorker : IAttachmentsLoadWorker
    {

    #region Properties: Protected

    protected UserConnection UserConnection;
    protected AttachmentsDownloader AttachmentsDownloader;

    #endregion

    #region Constructors: Public

    /* Initialize a new "SomeProviderAttachmentLoadWorker" class instance. */
    public SomeProviderAttachmentLoadWorker(UserConnection userConnection) {
    UserConnection = userConnection;
    AttachmentsDownloader = new AttachmentsDownloader(userConnection);
    }

    #endregion

    #region Methods: Public

    /* Load the attachments.
    The "incomeAttachment" parameter is the attachment from the messenger.
    The "message" parameter is the source message. */
    public void Load(MessageAttachment incomeAttachment, UnifiedMessage message) {
    incomeAttachment.FileName = FileUtilities.GetFileNameFromUrl(incomeAttachment.UploadUrl);
    incomeAttachment.FileId = AttachmentsDownloader.Load(incomeAttachment);
    }

    #endregion
    }

    #endregion
    }
  3. Publish the schema.

As a result, users will be able to download attachments.

8. Implement sending of messages​

  1. Create the "Source code" type schema. Instructions: Implement the source code.

  2. Implement the business logic that sends messages using the IOutcomeMessageWorker interface.

    1. Convert the message to messenger format and send it using the messenger API.
    2. Send the message using a token. Store the token in the SomeChannelProviderNameMsgSettings database table. UserConnection sent in the constructor provides access to the database table.
    3. Send a message to the channel provider API, for example, https://somechannelprovider.api/, using the HttpRequestSender class.
    SomeProviderOutcomeMessageWorker
    namespace Terrasoft.Configuration.Omnichannel.Messaging
    {
    using Newtonsoft.Json;
    using Newtonsoft.Json.Serialization;
    using OmnichannelProviders.Application.Http;
    using OmnichannelProviders.Domain.Entities;
    using OmnichannelProviders.MessageWorkers;
    using Terrasoft.Core;

    #region Class: SomeProviderOutcomeMessageWorker

    /* Send messages to the "SomeProvider" provider. */
    public class SomeProviderOutcomeMessageWorker : IOutcomeMessageWorker
    {

    #region Properties: Protected

    protected UserConnection UserConnection;
    private readonly string _someChannelProviderNameProviderApiUrl = "https://somechannelprovider.api";

    #endregion

    #region Constructors: Public

    /* Initialize a new "SomeProviderOutcomeMessageWorker" class instance. */
    public SomeProviderOutcomeMessageWorker(UserConnection userConnection) {
    UserConnection = userConnection;
    }

    #endregion

    #region Methods: Public

    /* Send the message to the "SomeProvider" provider.
    The "message" parameter is the unified message. */
    public string SendMessage(UnifiedMessage unifiedMessage, out bool success) {
    var serializerSettings = new JsonSerializerSettings();
    serializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
    var json = JsonConvert.SerializeObject(unifiedMessage, serializerSettings);
    var requestUrl = string.Concat(_someChannelProviderNameProviderApiUrl, json);
    var result = new HttpRequestSender().PostAsync(requestUrl, json).Result;
    success = true;
    return result;
    }

    public string PassControlToPrimaryReceiver(UnifiedMessage message) {
    return string.Empty;
    }

    #endregion
    }

    #endregion
    }
  3. Publish the schema.

As a result, users will be able to send messages.

9. Implement a channel provider resolver (for Creatio 10.1 and later)​

Creatio uses the channel provider resolver to identify the custom channel provider, as well as to activate, deactivate, and remove the channel. To implement the resolver:

  1. Create the "Source code" type schema. Instructions: Implement the source code.

  2. Implement the business logic of the resolver.

    1. Specify the ChannelProviderResolver or IntegrationChannelProviderResolver class as a parent class.
    2. Add the [DefaultBinding] attribute to the class. Specify the channel name in the Name parameter.
    3. Specify the channel name in the ProviderName property.
    4. Specify the ID of the channel provider lookup value in the ProviderId property. Each custom channel must have a unique provider ID.
    SomeProviderResolver
    [DefaultBinding(typeof(ChannelProviderResolver), Name = "SomeProvider")]
    public class SomeProviderResolver : ChannelProviderResolver
    {
    public SomeProviderResolver(UserConnection uc) : base(uc) { }

    /* Must equal "MessagingMessage.ChannelName" and the
    "ClassFactory.Bind()" key. */
    protected override string ProviderName => "SomeProvider";

    /* Same ID as the ID of the channel provider lookup value. */
    public override Guid ProviderId =>
    new Guid("00000000-0000-0000-0000-0000000010A0");
    }
  3. Publish the schema.

As a result, Creatio will resolve the custom channel provider by its channel name.

10. Link the interfaces​

  1. Create the "Source code" type schema. Instructions: Implement the source code.

  2. Implement the business logic that links interfaces.

    1. Specify the AppEventListenerBase class as a parent class.

    2. Link the created classes using the binding key. Creatio uses the binding key to identify the classes required to retrieve profile data, upload attachments, and send messages.

      Previously, the ChannelType.ThirdParty.ToString() value was used as a binding key. Since version 10.1, use the SomeProvider channel name that is specified in the ChannelName property of the business logic handling incoming messages. Each custom channel must have its own channel name, which lets you register multiple custom channels. Creatio does not find classes bound using ChannelType.ThirdParty if the message has a channel name. Existing integrations that bind classes using ChannelType.ThirdParty and do not set ChannelName continue to work, but they support only one custom channel.

    For Creatio version 10.1 and later:

    SomeProviderAppEventListener
    namespace Terrasoft.Configuration.Omnichannel.Messaging
    {
    using Common;
    using Core;
    using OmnichannelProviders;
    using OmnichannelProviders.Interfaces;
    using OmnichannelProviders.MessageWorkers;
    using Terrasoft.Core.Factories;
    using Web.Common;

    #region Class : SomeProviderAppEventListener

    /* Run prerequisites for "OmnichannelMessaging" on app start. */
    public class SomeProviderAppEventListener : AppEventListenerBase
    {

    #region Fields : Protected

    protected UserConnection UserConnection {
    get;
    private set;
    }

    #endregion

    #region Methods : Protected

    /* Retrieve the user connection from the app event scope.
    The "context" parameter is the app event scope.
    Return user connection. */
    protected UserConnection GetUserConnection(
    AppEventContext context) {
    var appConnection =
    context.Application["AppConnection"] as AppConnection;
    if (appConnection == null) {
    throw new ArgumentNullOrEmptyException("AppConnection");
    }
    return appConnection.SystemUserConnection;
    }

    protected void BindInterfaces() {

    /* The binding key is the channel name: the same value as
    "MessagingMessage.ChannelName" set during conversion and
    "ChannelProvider.Name". The value must be identical in all
    places. */
    const string channelName = "SomeProvider";
    ClassFactory.Bind<IAttachmentsLoadWorker,
    SomeChannelProviderNameAttachmentLoadWorker>(channelName);
    ClassFactory.Bind<IProfileDataProvider,
    SomeChannelProviderNameProfileDataProvider>(channelName);
    ClassFactory.Bind<IOutcomeMessageWorker,
    SomeChannelProviderNameOutcomeMessageWorker>(channelName);
    }

    #endregion

    #region Methods : Public

    /* Handle the app start.
    The "context" parameter is the app event scope. */
    public override void OnAppStart(AppEventContext context) {
    base.OnAppStart(context);
    UserConnection = GetUserConnection(context);
    BindInterfaces();
    }

    #endregion

    }

    #endregion

    }
    For Creatio version 10X and earlier
    SomeProviderAppEventListener
    namespace Terrasoft.Configuration.Omnichannel.Messaging
    {
    using Common;
    using Core;
    using OmnichannelProviders;
    using OmnichannelProviders.Interfaces;
    using OmnichannelProviders.MessageWorkers;
    using Terrasoft.Core.Factories;
    using Web.Common;

    #region Class : SomeProviderAppEventListener

    /* Run prerequisites for "OmnichannelMessaging" on app start. */
    public class SomeProviderAppEventListener : AppEventListenerBase
    {

    #region Fields : Protected

    protected UserConnection UserConnection {
    get;
    private set;
    }

    #endregion

    #region Methods : Protected

    /* Retrieve the user connection from the app event scope.
    The "context" parameter is the app event scope.
    Return user connection. */
    protected UserConnection GetUserConnection(AppEventContext context) {
    var appConnection = context.Application["AppConnection"] as AppConnection;
    if (appConnection == null) {
    throw new ArgumentNullOrEmptyException("AppConnection");
    }
    return appConnection.SystemUserConnection;
    }

    protected void BindInterfaces() {
    ClassFactory.Bind<IAttachmentsLoadWorker, SomeChannelProviderNameAttachmentLoadWorker>(ChannelType.ThirdParty.ToString());
    ClassFactory.Bind<IProfileDataProvider, SomeChannelProviderNameProfileDataProvider>(ChannelType.ThirdParty.ToString());
    ClassFactory.Bind<IOutcomeMessageWorker, SomeChannelProviderNameOutcomeMessageWorker>(ChannelType.ThirdParty.ToString());
    }

    #endregion

    #region Methods : Public

    /* Handle the app start.
    The "context" parameter is the app event scope. */
    public override void OnAppStart(AppEventContext context) {
    base.OnAppStart(context);
    UserConnection = GetUserConnection(context);
    BindInterfaces();
    }

    #endregion

    }

    #endregion

    }
  3. Publish the schema.

As a result, the custom channel provider will be implemented.

Implement a custom chat routing rule​

1. Add a chat routing rule to Creatio​

  1. Create a package. Instructions: Create a user-made package using Configuration section.

  2. Change the current package. Instructions: Change the current package.

  3. Click btn_system_designer_8_shell.png in the top right → System setup → Lookups.

  4. Open the "Rules for routing chat queue operators" lookup.

  5. Click New to add the lookup value.

  6. Fill out the properties of the lookup value.

    The following example adds the "Some custom chat routing rule" chat routing rule.

    Property

    Value

    Name

    Some custom chat routing rule

    Code

    SomeCustomChatRoutingRule

  7. Save the changes.

As a result, the custom chat routing rule will be added to Creatio.

2. Implement routing of chats​

  1. Create the "Source code" type schema. Instructions: Implement the source code.

  2. Create a service class.

    1. Add the Terrasoft.Configuration.Omnichannel.Messaging namespace.
    2. Add the namespaces the data types of which to utilize in the class using the using directive.
    3. Add a class name that matches the schema name (the Code property).
    4. Specify the BaseOperatorRoutingRule class as a parent class.
  3. Implement class methods.

    1. Add the public CustomChatRoutingRule(UserConnection userConnection) method that routes the chat.
    2. Add the protected override List<Guid> PickUpFreeQueueOperators(Guid chatId, Guid queueId) method that matches agent IDs to chat IDs. If the chat is already assigned to an agent (the [OperatorId] column includes the user ID), select the agent. Otherwise, retrieve the agent or agents as List<Guid>, where Guid stores a list of agent IDs in the SysAdminUnit database table. The agents that have the corresponding IDs receive new chat notifications and can access the chat using the communication panel. ID of the Supervisor system user is specified in the btn_system_designer.png → Users and administration → Users section → Id column. For this example, the ID is "7f3b869f-34f3-4f20-ab4d-7480a5fdf647."
    3. Add the protected override Guid GetChatOperator(Guid chatId) method that returns agent ID using chat ID.

    The following example routes the chat to the Supervisor system user whose ID is "7f3b869f-34f3-4f20-ab4d-7480a5fdf647."

    SomeChatRouting
    namespace Terrasoft.Configuration.Omnichannel.Messaging {

    using System;
    using System.Collections.Generic;
    using Terrasoft.Core;
    using Terrasoft.Core.DB;

    #region Class: SomeChatRouting

    public class SomeChatRouting: BaseOperatorRoutingRule {

    #region Constructors: Public

    /* Route the chat to the Supervisor system user. */
    public CustomChatRoutingRule(UserConnection userConnection) : base(userConnection) {}

    #endregion

    #region Methods: Protected

    /* Match agent IDs to chat IDs. */
    protected override List<Guid> PickUpFreeQueueOperators(Guid chatId, Guid queueId) {
    return new List<Guid> {

    /* ID of Supervisor system user. */
    Guid.Parse("7f3b869f-34f3-4f20-ab4d-7480a5fdf647")
    };
    }

    /* Return agent ID using chat ID. */
    protected override Guid GetChatOperator(Guid chatId) {
    Guid operatorId = (new Select(UserConnection).Column("OperatorId").From("OmniChat", "oc").Where("oc", "Id").IsEqual(Column.Parameter(chatId))
    as Select).ExecuteScalar<Guid>();
    return operatorId;
    }

    #endregion

    }

    #endregion

    }
  4. Publish the schema.

As a result, Creatio will route chats to the dedicated user.

3. Link the interfaces​

  1. Create the "Source code" type schema. Instructions: Implement the source code.

  2. Implement the business logic that links interfaces.

    1. Specify the AppEventListenerBase class as a parent class.
    2. Link the created class using the SomeCustomChatRoutingRule chat routing rule that is specified in the Rules for routing chat queue operators lookup.
    SomeAppEventListener
    namespace Terrasoft.Configuration.Omnichannel.Messaging {
    using Common;
    using Core;
    using Terrasoft.Core.Factories;
    using Web.Common;

    #region Class: SomeAppEventListener

    /* Run prerequisites for "OmnichannelMessaging" on app start. */
    public class SomeAppEventListener: AppEventListenerBase {

    #region Fields: Protected

    protected UserConnection UserConnection {
    get;
    private set;
    }

    #endregion

    #region Methods: Protected

    /* Retrieve the user connection from the app event scope.
    The "context" parameter is the app event scope.
    Return user connection. */
    protected UserConnection GetUserConnection(AppEventContext context) {
    var appConnection = context.Application["AppConnection"] as AppConnection;
    if (appConnection == null) {
    throw new ArgumentNullOrEmptyException("AppConnection");
    }
    return appConnection.SystemUserConnection;
    }

    protected void BindInterfaces() {
    ClassFactory.Bind<IOperatorRoutingRule,
    TestOperatorRoutingRule> ("SomeCustomChatRoutingRule");
    }

    #endregion

    #region Methods: Public

    /* Handle the app start.
    The "context" parameter is the app event scope. */
    public override void OnAppStart(AppEventContext context) {
    base.OnAppStart(context);
    UserConnection = GetUserConnection(context);
    BindInterfaces();
    }

    #endregion

    }

    #endregion

    }
  3. Publish the schema.

As a result, the custom chat routing rule will be implemented.

4. Restart Creatio in IIS​

Restart Creatio in IIS to apply the changes.

5. Include the custom chat routing rule in the chat distribution mechanism​

  1. Click btn_system_designer.png in the top right → Import and integration → Chat settings.

  2. Go to the "Chat queues" expanded list.

  3. Click btn_add.png.

  4. Fill out the properties of the custom chat routing rule.

    Property

    Description

    Name*

    An arbitrary name of a custom chat routing rule. For example, "Some custom chat distribution mechanism."

    Routing rule*

    The way chats will be distributed to agents. For example, "Some custom chat routing rule."

    Queue agents*

    1. Click btn_add.png. This opens the Select user or role window.
    2. Open the Organizational roles, Functional roles or Users tab based on your business goals.
    3. Select roles and/or users.
    4. Click Select.

As a result, the custom chat routing rule will be implemented and Creatio will route new chats to selected roles and/or users using custom chat routing rule.


See also​

"Source code" type schema

Best practices for optimizing data fetching in Freedom UI page logic

Handle sensitive data shared by customers during chat sessions

Integrating custom translation providers for chats

Chat setup (user documentation)