External Messaging System

Overview

This document outlines the integration process for Truvideo’s External Messaging System, enabling secure communication via embedded links and API interactions. The system supports:

  • Link embedding for customer conversations.

  • Message sending, searching, and event tracking via API.

  • Security measures including HMAC SHA256 signatures.


Requirements

Before integration, ensure you have:

  • API Key – Provided by Truvideo for authentication.

  • Secret Key – Used for cryptographic signatures.

  • Account ID – Unique identifier for your organization.

  • Subaccount ID – Assigned to each dealer/store for independent operations.


Integration Guide

1 Generating a Signature (HMAC SHA256)

Purpose: To securely generate a signature from a given string and an API key using HMAC SHA256, which can be used for authentication or integrity verification in API calls.

Steps:

  1. Prepare:

    • String (message): Properly formatted JSON payload.

    • API Key (Secret Key): Keep confidential (never expose client-side).

  2. Generate Signature:

    • Use HMAC SHA256 with the API key.

    • Example (Node.js):

    const crypto = require('crypto');
    const signature = crypto.createHmac('sha256', apiKey).update(message).digest('hex');

Security Considerations:

  • Always use HTTPS.

  • Never hardcode keys in client-side code.

  • Validate input to prevent injection attacks.


Purpose: Generate secure links to Truvideo’s messaging interface.

"payload": {
    "accountUID": "xxxxx",
    "subAccountUID": "xxxxx",
    "customerPhoneNumber": "+0123456789"
},
"uri": "/signature/validate",
"method": "POST"

Link Structure:

Once the signature is created, the link to our messaging platform follows this example:

<a href="https://messaging-ui-rc.truvideo.com/#/EX/channel?
  signature=[GENERATED_SIGNATURE]&
  phoneNumber=[E.164_FORMAT]&
  accountUID=[ACCOUNT_ID]&
  subAccountUID=[SUBACCOUNT_ID]&
  apikey=[API_KEY]&
  timestamp=[CURRENT_EPOCH_MS]">
  Show Conversation
</a>

Run HTML

Query Parameters:

Parameter

Description

accountUID

The provided Account ID

subAccountUID

The provided subAccount ID for the dealer that is using the link

apiKey

The provided apiKey

phoneNumber

Customer's phone number, format E.164

startDateTime and endDateTime

These are optional epoch timestamps used to filter the conversation messages. If these are not provided, the conversation will show every message ever sent and received to and from the customer's phone number. These parameters can work independently, for example, if a startDateTime is provided, messages will be filtered from the provided startDate until today, format for booth epoch. in milliseconds e.g. 1721824347804

signature

The generated signature

timestamp

current datetime in milliseconds e.g. 1721824347804 (this should be the same as the one used for creating the signature)

ownerId and ownerDisplayName

ID of the owner for notifications and the display name for the chat header and messages ownership.

displayName

the customer display name for channel creation.

tags

list of tags for messages, separated by a comma

messagesTags

list of tags separated by a comma to be added to new messages

primaryColor, secondaryColor, messageTextColor, messageBubbleColor, timestampColor, senderTimestampColor, placeholderTextColor, placeholderBackgroundColor, inputBackgroundColor, senderBubbleColor, senderTextColor, backgroundColor, headerBackgroundColor, headerTextColor and inputTextColor

These are parameters to customize the site theme, each one must be represented by a hexadecimal value without the '#'. Example: primaryColor=000000

readOnly

Boolean param to hide text input and interactive controls


Url generator examples : Messaging UI

3 Events Payload

JSON Structure for Inbound/Outbound Messages:

{
  "uid": "xxxx",
  "displayName": "Hi Customer!",
  "type": "TEXT",
  "source": "APPLICATION",
  "body": "Hi Customer!",
  "attachments": [],
  "createdAt": "2024-08-19T13:59:02.938Z",
  "createdBy": {
    "uid": "xxxx",
    "phone": {
      "number": "1111",
      "e164": "+1111",
      "isoCode": "US",
      "countryCode": "1"
    },
    "displayName": "Dealer Name",
    "subAccountUID": "xxxx",
    "accountUID": "xxxx",
    "businessReference": {
      "entityType": "dealer",
      "entityUID": "2906",
      "module": ""
    }
  },
  "channelUID": "xxxx",
  "channelTags": [
    "orderId:1111",
    "ownerId:1111"
  ],
  "to": {
    "e164": "+11111",
    "module": "SERVICE",
    "routing": "SMS"
  },
  "memberUID": "xxxx",
  "subAccount": {
    "createdAt": {
      "_seconds": 1691685765,
      "_nanoseconds": 871000000
    },
    "displayName": "Dealer Name",
    "accountUID": "xxxx",
    "updatedAt": {
      "_seconds": 1691685765,
      "_nanoseconds": 871000000
    },
    "businessReference": {
      "entityType": "dealer",
      "entityUID": "2906",
      "module": ""
    },
    "uid": "xxxx"
  },
  "eventName": "MESSAGE_DELIVERED", 
  "category": "OUTBOUND_MESSAGE", 
  "module": "SERVICE"
}

eventName could be:

MESSAGE_DELIVERED, MESSAGE_READ, MESSAGE_FAILED, MESSAGE_SENT

category could be:

OUTBOUND_MESSAGE, INBOUND_MESSAGE


4 Search Historical Messages

This is an endpoint that allows searching for messages for a particular account and subaccount. Using pagination and date range for searching.

Page and size (max size is 10000 per page) are optional as well as fromDate and toDate.

Endpoint: POST /message/search

Request Example:

{
  "accountUID": "xxxxx",
  "subAccountUID": "xxxxx",
  "fromDate": "2024-07-29T00:00:00.000Z",
  "toDate": "2024-07-29T23:59:59.999Z"
}

Headers:

  • x-authorization-signature: HMAC SHA256 signature.

  • x-authorization-timestamp: Epoch time in ms.

  • x-authorization-api-key: Your API key.

Response:

1{
1	"documents": [
3	{
4	"uid":  "dm-4hwHLUjuZt3QaJH3jPNj-UKlTc8TRQdont438UPTz-external-sms-1722265348658-hdf2c",
5	"accountUID": "xxxxx",
6	"subAccountUID": "xxxxx",
7	"createdAt": "2024-07-29T15:02:28.658Z",
8	"createdBy": {
9	"uid": "UKlTc8TRQdont438UPTz",
10	"displayName": "DEALER-1234",
11		"businessReference": {
12		"entityType": "dealer",
13		"entityUID": "DEALER-1234",
14		"module": ""
15		},
16		"accountUID": "xxxxx",
17		"subAccountUID": "xxxxx"
18		},
19		"updatedAt": "2024-07-29T15:02:38.673Z",
20		"updatedBy": {
21		"uid": "UKlTc8TRQdont438UPTz",
22		"displayName": "DEALER-1234",
23		"businessReference": {
24		"entityType": "dealer",
25		"entityUID": "DEALER-1234",
26		"module": ""
27		},
28		"accountUID": "xxxxx",
29		"subAccountUID": "xxxxx"
30		},
31		"attachments": [],
32		"body": "test",
33		"channel": {
34		"uid": "dm-4hwHLUjuZt3QaJH3jPNj-UKlTc8TRQdont438UPTz-external-sms",
35		"displayName": "customer",
36		"type": "DIRECT_MESSAGE",
37		"businessReference": {
38		"entityType": "",
39		"entityUID": "",
40		"module": "external"
41		},
42		"systemTags": [
43		"ownerDisplayName:customer",
44		"ownerId:123"
45		],
46		"routing": "SMS",
47		"consentStatus": "GRANTED"
48		},
49		"displayName": "test",
50		"source": "APPLICATION",
51		"status": "ACTIVE",
52		"type": "TEXT",
53		"isDeleted": false,
54		"category": "OUTBOUND_MESSAGE",
55		"systemTags": [
56		"ownerDisplayName:customer",
57		"ownerId:123",
58		"messageUID":"2024-07-29T15:02:27.375Z_dm-4hwHLUjuZt3QaJH3jPNj-UKlTc8TRQdont438UPTz-external-
	sms"	
59		],
60		"externalUID": "776c3566-e56d-4f7f-90c2-373fa121446e",
61		"deliveryStatus": {
62		"anyDelivered": false,
63		"anyRead": false,
64		"read": [],
65		"anyFailed": false,
66		"anySent": true,
67		"delivered": [],
68		"failed": [], 
69		"sent": [
70			{
71				"entity": {
72					"uid": "4hwHLUjuZt3QaJH3jPNj", 
73					"phone": {
74						"number": "99999",
75						"e164": "+5899999",
76						"isoCode": "VE", 
77						"countryCode": "58"
78					},
79					"displayName": "customer", 
80					"subAccountUID": "xxxxx", 
81					"accountUID": "xxxxx", 
82					"businessReference": {
83						"entityType": "customer", 
84						"entityUID": "",
85						"module": ""
86					}
87				}
88				}
89			]
90			},
91			"outcoming": true
92		}
93	],
94	"page": {
95		"page": 1,
96		"size": 1000,
97		"totalElementsInPage": 1,
98		"totalPages": 1,
99		"totalElements": 1, 
100		"hasNext": false, 
101		"hasPrevious": true
102	}
103}

Paginated list of messages with metadata (e.g., deliveryStatus, attachments).


5 Send Message

This is an endpoint that allows sending SMS messages

URL: https://us-central1-truvideo-messaging---stg.cloudfunctions.net:443/apiExternal/message

Endpoint: POST /message

Request Example:

{
  "accountUID": "xxxxx",
  "subAccountUID": "xxxxx",
  "to": "+11112222333",
  "body": "Hello!",
  "toDisplayName": "Customer Name"
}

Headers:

  • x-authorization-signature: HMAC SHA256 signature.

  • x-authorization-timestamp: Epoch time in ms.

  • x-authorization-api-key: Your API key.

Response:

{
    "uid": "dm-UKlTc8TRQdont438UPTz-ZGkFho8wrbTaWGW8S0QQ-external-sms-1743059714893-ubfu06",
    "accountUID": "xxxx",
    "subAccountUID": "xxxx",
    "createdAt": "2025-03-27T07:15:14.893Z",
    "createdBy": {
        "uid": "xxxx",
        "displayName": "DAIMLER-1234",
        "businessReference": {
            "entityType": "dealer",
            "entityUID": "DAIMLER-1234",
            "module": ""
        },
        "accountUID": "xxxx",
        "subAccountUID": "xxxx"
    },
    "updatedAt": "2025-03-27T07:15:14.893Z",
    "updatedBy": {
        "uid": "xxxx",
        "displayName": "DAIMLER-1234",
        "businessReference": {
            "entityType": "dealer",
            "entityUID": "DAIMLER-1234",
            "module": ""
        },
        "accountUID": "xxxx",
        "subAccountUID": "xxxx"
    },
    "attachments": [],
    "body": "test message",
    "channel": {
        "uid": "xxxx",
        "displayName": "TEST CUSTOMER",
        "type": "DIRECT_MESSAGE",
        "businessReference": {
            "module": "external",
            "entityType": "",
            "entityUID": ""
        },
        "routing": "SMS",
        "consentStatus": "NOT_APPLICABLE"
    },
    "displayName": "test message",
    "source": "APPLICATION",
    "status": "ACTIVE",
    "type": "TEXT",
    "isDeleted": false,
    "category": "OUTBOUND_MESSAGE",
    "origin": "SYSTEM"
}


6 Phone Number Update (UI)

In the UI, you can update the phone number as follows

Click on the edit icon that appears when you hover over the
Complete the form that appears in the modal to update the phone number

Associated function :

PATCH "/messageable-entity/customer-phone-number"
body:
{
    accountUID: string;
    subAccountUID: string;
    currentPhoneNumber: string;
    newPhoneNumber: string;
}

Overview :

This asynchronous function is responsible for updating the phone number associated with a customer entity within a specific sub- account. It ensures that the new phone number is not already assigned to another customer within the same sub-account before performing the update.

Key Functionality :

  1. Validates that the new phone number is not currently in use by another customer in the specified sub-account.

  2. Locates the customer entity using their current phone number and sub-account identifier.

  3. Updates the located customer entity with the new phone number

Function Signature

export async function updateCustomerPhoneNumber(
    requestDTO: UpdateCustomerPhoneNumberDTO
): Promise<void>;

Parameters

  • requestDTO (UpdateCustomerPhoneNumberDTO ): An object containing the necessary data for the update operation.

    • currentPhoneNumber (string ): The customer's current phone number in E.164 format (e.g., "+15551234567"). This is used to locate the customer record to be updated.

    • newPhoneNumber (string ): The desired new phone number for the customer, also in E.164 format.

    • subAccountUID (string ): The unique identifier for the sub-account to which the customer belongs. This scopes the search and update operations.

How it Works

  1. Provide Information: You need to supply the customer's current phone number, the new phone number they want to use, and the identifier of the sub-account they belong to.

  2. Check Availability: The system first checks if the new phone number is already being used by someone else in that same sub- account.

  3. Prevent Duplicates: If the new number is already taken, the system will stop and indicate that the number cannot be used. This prevents assigning the same number to multiple customers.

  4. Find the Customer: If the new number is available, the system uses the current phone number to find the correct customer record.

  5. Update: Once the customer is found, the system replaces their old phone number with the new one.

Last updated

Was this helpful?