Asynchronous Behavior in Your Logic

4 min read

During conversations participants do not have to always wait on each other. For example while agent is typing a message customer can provide additional context, ask more questions, encourage agent to respond faster, etc. The same may happen for Your Logic no matter how fast it is.

Salted CX tries to reduce complexity for Your Logic while giving you control over how you process individual events in the conversations.

Inbound Communication

Every action by the customer that is worth processing can be intercepted by Your Logic. Because Your Logic may perform a time consuming actions the customer may send more messages (or other content) before you manage to respond to the first message.

This asynchronous communication is very similar to people. When somebody texts you a question, your are composing a message to clarify the question but just as you send your message another texts arrive. This can make your reply irrelevant. These things happen and are natural. It is important that Your Logic is ready for it.

The flow above would produce 2 or 3 request to Your Logic depending on how you handle them. Notice that while Your Logic is busy responding to the first message, the customer sends two more messages. The example could be something like this:

Hello

I would like to rebook the trip to sometime next week

I was thinking about Thursday or Friday.

Request versus Current State

Salted CX sequences the incoming messages (and all other actions) in each conversations, so you receive all individual requests for each event that happens unless you tell Salted CX you do not want to get them.

PropertyDescription
Request TimeTime when the request is sent to Your Logic. Salted CX sends you complete state of the current conversation as of this time including turns and other changes following the trigger that caused this. Your Logic is free to process these “future” updates as a response to this request or wait for a request in the future.
Expiration TimeTime until when Your Logic has time to respond. After this time expires Salted CX behaves as if Your Logic was not available. It also unblocks a next request in the queue.
Trigger TimeTime when the trigger causing this request actually happened. This is either the same time as request time or typically a bit earlier due to delay caused by processing the original event and even waiting for processing of previous events and Your Logic. Trigger time is specifically the end of post processing.

Importantly Salted CX sends you the current state of the conversation even when it contains messages and other events that happen after this request. You can choose to process them or not.

Salted CX follows these simple rules:

  • Sends one request for every message or other event unless you tell us not to do that
  • Sends the state of the conversation at the time when the request is sent

Request 1

Request 1 is simple. It sends only one message and the conversation contains only one message.

{
	"request": "5a1bfe8d-c73f-4af7-80db-3f6400a10f2d",
	"time": "2025-04-13T08:00:01Z",
	"expires": "2025-04-13T08:00:16Z",
	
	"trigger": {
		"time": "2025-04-13T08:00:00Z",
		"type": "Message",
		"participantType": "Customer",
		"content": "Message 1 content"
	},
	
	"customer": {
		/* customer attributes */
	},
	
	"conversation": {
		/* convesation attributes */
	},
	
	"engagements": [
		/* list of engagements */
	],
	
	"turns": [
		{
			"pid": "88b4b430-7f0b-4e15-90a5-3d2e287dfa71"
			"time": "2025-04-13T08:00:00Z"
			"type": "Message",
			"participantType": "Customer"
			"content": "Message 1 content"
		}
	]
}
Request 1 sent by Salted CX to Your Logic

Response 1

We show an example empty response that tells Salted CX just to cary on and continue sending subsequent requests for that conversation.

{
	"request": "5a1bfe8d-c73f-4af7-80db-3f6400a10f2d"
}

Request 2

Request 2 is interesting because while processing Request 1 in Your Logic the customer sent two more messages. Notice in the subsequent code example that despite the trigger is the Message 2 from he customer the turns array contains also the Message 3.

{
	"request": "a3bb189e-8bf9-3888-9912-ace4e6543002",
	"time": "2025-04-13T08:00:16Z",
	"expires": "2025-04-13T08:00:31Z",
	
	"trigger": {
		"time": "2025-04-13T08:00:10Z",
		"type": "Message",
		"participantType": "Customer",
		"content": "Message 2 content"
	},
	
	"customer": {
		/* customer attributes */
	},
	
	"conversation": {
		/* convesation attributes */
	},
	
	"engagements": [
		/* list of engagements */
	],
	
	"turns": [
		{
			"pid": "88b4b430-7f0b-4e15-90a5-3d2e287dfa71"
			"time": "2025-04-13T08:00:00Z"
			"type": "Message",
			"participantType": "Customer"
			"content": "Message 1 content"
		},
		{
			"pid": "b8d4c4e0-8e3d-4ff6-a3e3-681b4b9d570e"
			"time": "2025-04-13T08:00:10Z"
			"type": "Message",
			"participantType": "Customer"
			"content": "Message 2 content"
		},
		{
			"pid": "2d4e36b2-0c4d-4d75-b25f-4b6c56e3c25e"
			"time": "2025-04-13T08:00:15Z"
			"type": "Message",
			"participantType": "Customer"
			"content": "Message 3 content"
		}
	]
}

Response 2

There are two ways how Your Logic can respond. The first option is the same as Response 1. Just returning the request PID. This would lead to Salted CX sending a third request with content of the message 3.

{
	"request": "a3bb189e-8bf9-3888-9912-ace4e6543002"
}

However Your Logic can also process all turns including the “future” turns and tell Salted CX not to send requests for those. When you respond with skipAfter property all events that happened up to that time will not produce any requests to Your Logic. Typically this would be the time of the last turn in the request.

{
	"request": "a3bb189e-8bf9-3888-9912-ace4e6543002",
	"skipAfter": "2025-04-13T08:00:15Z" 
}
Did this answer your question?