WebHooks

Some AppXchange partners want to be notified over HTTP when events occur, such as . A WebHook is a useful feature to achieve this.

Each time an event occurs Kolibri POSTS a message using HTTP(S) to your server, using a pre-configured URI. The AppXchange partner must provide the URI so it can be configured in our platform.

Message envelope

Message envelopeMessages send by Kolibri are JSON objects wrapped inside an envelope. To process messages you need to process all items (“batches”) inside the “items” array, take each message inside the “data.messages” array and process the string in the “data” property of the message as a JSON object.

{
   "items": [
	  {
		 "webhookId": "d28HJw",
		 "source": "channel.message",
		 "serial": "e91URQe6QA0gwm05496618:2",
		 "timestamp": 1479301189860,
		 "name": "channel.message",
		 "data": {
			"channelId": "foob",
			"site": "eu-central-1-A",
			"messages": [
			   {
				  "id": "9qaOH1C4tO:2:0",
				  "name": "foo1",
				  "connectionId": "9qaOH1C4tO",
				  "timestamp": 1479301189856,
				  "data": "<json message 1>"
			   },
			   {
				  "id": "8q5aOH3C44O:5:5",
				  "name": "foo2",
				  "connectionId": "9qaOH1C4tO",
				  "timestamp": 1479301189859,
				  "data": "<json message 2>"
			   }
			]
		 }
	  },
	  {
		 "webhookId": "d28HJx",
		 "source": "channel.message",
		 "serial": "e91URQe6QA0gwm05496618:4",
		 "timestamp": 1479301189866,
		 "name": "channel.message",
		 "data": {
			"channelId": "foob",
			"site": "eu-central-1-A",
			"messages": [
			   {
				  "id": "9qaOH1C4t9:2:0",
				  "name": "foo3",
				  "connectionId": "9qaOH1C4tO",
				  "timestamp": 1479301189877,
				  "data": "<json message 3>"
			   }
			]
		 }
	  }
   ]
}

For your reference a description of each property in the message container is given in the table below. We advise you to not use any of these properties, except from the JSON array “messages”, since in the near future properties might be added or removed from the container, except “items.data.messages”.

Name Description
webhookId An internal unique ID for the configured WebHook.
source The source for the WebHook, namely “channel.message”.
timestamp A timestamp represented as milliseconds since epoch for the published message.
data An object containing the attributes defined below in JSONPath format data.*.
data.channelId Name of the channel that the presence event belongs to.
data.site An internal site identifier indicating the datacenter from which the message was published.
data.messages An array of messages with fields for each message described below.
data.messages.id Unique ID assigned by Kolibri to this message
data.messages.name A string representing the event name for the published message, see the publish method
data.messages.connectionId The public unique identifier for the publisher’s connection. Find out more about connectionId
data.messages.timestamp The time in milliseconds since the epoch when this message was received by Kolibri.
data.messages.data An utf-8 encoded string representing a JSON object containing the message to process by the AppXchange partner.

 

Message format

The data inside the data.messages.data has the following format:

id string
timeStamp string
realEstateAgencyId string
personId string
mailAccountId string
appClientKey string
category* AnnouncementCategorystring
x-enumNames: List [ “Entity”, “Notification”, “EmailAccountChange”, “EmailPersonalChange”, “EventCenterChange”, “Voip”, “Authorization” ]
Enum:
Array [ 7 ]
entityDetails EntityDetails{

entityType* RootEntityTypestring
x-enumNames: List [ “Unknown”, “AccountSettings”, “Agendaitem”, “AgendaItemCategory”, “AppClient”, “AppClientConsent”, “AssignmentRequest”, “BusinessPartner”, “Cadastre”, “CommunicationLog”, “CommunicationLogBlob”, “CompanyListing”, “CompanySettings”, “ContactCompany”, “ContactPerson”, “DocumentSession”, “DocumentTemplate”, “DossierItem”, “Employee”, “FinancialAdministration”, “Invoice”, “MediaContract”, “MediaPartner”, “MemoTextItem”, “Message”, “ObjectAssignment”, “ObjectTypeAssignment”, “Office”, “ProjectAssignment”, “Publication”, “RealEstateAgency”, “RelationGroup”, “SearchAssignment”, “Task”, “Testimonial”, “AcquisitionAssignment”, “AcquisitionObjectAssignment”, “Bid” ]
Enum:
Array [ 38 ]
entityId string
event* RootEntityEventstring
x-enumNames: List [ “Unknown”, “Add”, “Update”, “Delete” ]
Enum:
Array [ 4 ]
dateTimeCreated string
createdBy string
dateTimeModified string
modifiedBy string
parenEntityId string
parentEntityType RootEntityTypestring
x-enumNames: List [ “Unknown”, “AccountSettings”, “Agendaitem”, “AgendaItemCategory”, “AppClient”, “AppClientConsent”, “AssignmentRequest”, “BusinessPartner”, “Cadastre”, “CommunicationLog”, “CommunicationLogBlob”, “CompanyListing”, “CompanySettings”, “ContactCompany”, “ContactPerson”, “DocumentSession”, “DocumentTemplate”, “DossierItem”, “Employee”, “FinancialAdministration”, “Invoice”, “MediaContract”, “MediaPartner”, “MemoTextItem”, “Message”, “ObjectAssignment”, “ObjectTypeAssignment”, “Office”, “ProjectAssignment”, “Publication”, “RealEstateAgency”, “RelationGroup”, “SearchAssignment”, “Task”, “Testimonial”, “AcquisitionAssignment”, “AcquisitionObjectAssignment”, “Bid” ]
Enum:
Array [ 38 ]

}

notificationDetails NotificationDetails{

dateTimeCreated string
personId string
entityType* RootEntityTypestring
x-enumNames: List [ “Unknown”, “AccountSettings”, “Agendaitem”, “AgendaItemCategory”, “AppClient”, “AppClientConsent”, “AssignmentRequest”, “BusinessPartner”, “Cadastre”, “CommunicationLog”, “CommunicationLogBlob”, “CompanyListing”, “CompanySettings”, “ContactCompany”, “ContactPerson”, “DocumentSession”, “DocumentTemplate”, “DossierItem”, “Employee”, “FinancialAdministration”, “Invoice”, “MediaContract”, “MediaPartner”, “MemoTextItem”, “Message”, “ObjectAssignment”, “ObjectTypeAssignment”, “Office”, “ProjectAssignment”, “Publication”, “RealEstateAgency”, “RelationGroup”, “SearchAssignment”, “Task”, “Testimonial”, “AcquisitionAssignment”, “AcquisitionObjectAssignment”, “Bid” ]
Enum:
Array [ 38 ]
entityId string
message string
event* NotificationEventstring
x-enumNames: List [ “Unknown”, “AccountCreated”, “AccountDeleted”, “BankwarrantyExpired”, “Birthday”, “BrochureDownloaded”, “ContactMeRequest”, “NvmOauthTokenExpired”, “OfferListing”, “PublicationFailed”, “PublicationSucceeded”, “RentedFromExpired”, “RentedUntilExpired”, “ReservationExpired”, “Searchprofile”, “SoldExpired”, “SystemMessage”, “TransferExpired”, “Valuation”, “Viewing”, “ViewingRequest”, “SendMailFailed”, “SendMailSuccess”, “TaskReminder”, “AgendaItemReminder”, “PersonalMessage”, “RentedExpired”, “RentReservationExpired”, “IncomingBidExpired”, “OutgoingBidExpired”, “SentEmailOpened” ]
Enum:
Array [ 31 ]

}

emailChangeDetails EmailChangeDetails{

category* EmailChangeCategorystring
x-enumNames: List [ “Message”, “Folder”, “Draft”, “Account”, “MessageOpened”, “MessageForwarded”, “MessageReplied”, “MessageLinkClicked”, “AccountConnected”, “AccountRunning”, “AccountStopped”, “AccountInvalidCredentials”, “AccountError”, “FolderUnreadCount”, “SendingMessageFailure”, “SendingMessageSuccess”, “Unknown” ]
Enum:
Array [ 17 ]
actionType* EmailChangeActionTypestring
x-enumNames: List [ “Create”, “Modify”, “Delete”, “Unknown” ]
Enum:
[ Create, Modify, Delete, Unknown ]
emailMessage EmailChangeEmailMessage{

id string
subject string
emailAddresses [EmailChangeEmailAddress{

name string
email string
type* EmailChangeEmailAddressTypestring
x-enumNames: List [ “From”, “To”, “Bcc”, “Cc”, “Unknown” ]
Enum:
[ From, To, Bcc, Cc, Unknown ]

}]

folder EmailChangeFolder{

id string
displayName string
type* EmailChangeFolderTypestring
x-enumNames: List [ “Inbox”, “All”, “Trash”, “Archive”, “Drafts”, “Sent”, “Spam”, “Important”, “UserCreated”, “Unknown” ]
Enum:
[ Inbox, All, Trash, Archive, Drafts, Sent, Spam, Important, UserCreated, Unknown ]

}

}

emailDraft EmailChangeEmailMessage{

id string
subject string
emailAddresses [EmailChangeEmailAddress{

name string
email string
type* EmailChangeEmailAddressTypestring
x-enumNames: List [ “From”, “To”, “Bcc”, “Cc”, “Unknown” ]
Enum:
Array [ 5 ]

}]

folder EmailChangeFolder{

id string
displayName string
type* EmailChangeFolderTypestring
x-enumNames: List [ “Inbox”, “All”, “Trash”, “Archive”, “Drafts”, “Sent”, “Spam”, “Important”, “UserCreated”, “Unknown” ]
Enum:
Array [ 10 ]

}

}

emailFolder EmailChangeEmailFolder{

id string
displayName string
type* EmailChangeFolderTypestring
x-enumNames: List [ “Inbox”, “All”, “Trash”, “Archive”, “Drafts”, “Sent”, “Spam”, “Important”, “UserCreated”, “Unknown” ]
Enum:
Array [ 10 ]
unreadCount integer($int32)

}

objectId string
messageType* EmailChangeMessageTypestring
x-enumNames: List [ “MailPersonalChange”, “MailAccountChange” ]
Enum:
Array [ 2 ]

}

eventCenterChangeDetails EventCenterChangeDetails{

entityAction* RootEntityEventstring
x-enumNames: List [ “Unknown”, “Add”, “Update”, “Delete” ]
Enum:
Array [ 4 ]
entityType* EventCenterEntityTypestring
x-enumNames: List [ “Unknown”, “Event”, “EventNotification” ]
Enum:
Array [ 3 ]
entityIds [string($guid)]

}

voipDetails VoipDetails{

phoneNumber string
conversationId* string($guid)
direction* VoipConversationDirectionstring
x-enumNames: List [ “Outgoing”, “Incoming”, “Unknown” ]
Enum:
Array [ 3 ]
status* VoipConversationStatusstring
x-enumNames: List [ “Ringing”, “Answered”, “Disconnected”, “Transferred”, “Unknown” ]
Enum:
Array [ 5 ]
conversationEmployeeId string($guid)

}

authorizationDetails AuthorizationDetails{

companyId* string($guid)
employeeId string($guid)
entity* AuthorizationEntitystring
x-enumNames: List [ “Consent”, “EmployeeSettings”, “CompanySettings”, “Unknown” ]
Enum:
Array [ 4 ]
action* AuthorizationActionstring
x-enumNames: List [ “Added”, “Deleted”, “Updated”, “Unknown” ]
Enum:
Array [ 4 ]
appClientKey string

}

Request authenticity

WebHook messages send by Kolibri are signed allowing the AppXchange partner to verify the authenticity of each request. Kolibri signs the data with a private pre-shared key (PSK) and include an HTTP header with the signature in every HTTP post request issued to your server.
Customers who receive WebHooks can then use the private pre-shared key (PSK) to verify the authenticity of the WebHook data.

In order to verify the signature, you need to do the following:
• start with the webhook request body. This will be a JSON string encoded with content-encoding utf-8;
• calculate the HMAC of that request body with algorithm SHA-256 and the private pre-shared key (PSK);
• encode the resulting HMAC using RFC 3548 base 64;
• compare that result with the signature value indicated in the Signature header.

Validating the authenticity of messages coming from Kolibri is an optional feature and is not required. But we do encourage you to do validate the message signature.
We also encourage customers to use a secure HTTPS URL for their WebHooks endpoint. This will ensure that requests cannot be intercepted and all communication with your servers is secured with TLS.

In order to prevent overloading your servers with requests, Kolibri batches WebHook data and issues one POST request with JSON data in the body of the request to your servers. WebHook requests are typically published at most once per second per configured WebHook. Webhook requests are made with a default timeout of 15s. If the request fails or times out, Kolibri retries the request with exponential backoff (base delay 1s, backoff factor sqrt(2), up to a max of 60s).