LSEG Messenger - User Feed

About Message Feed

The Message Feed application is designed to receive all messages sent by a user, by using a service account in read-only mode. The service account is nothing but a passive listener to all the conversations the use does. Users can use their own Messenger account to send messages and can create their own plugin jar file to record or handle every message received.

The Message Feed app monitors all messages sent by individual users. This is done by specifying a service account and the user account to track (trackUUID). That is, the core functionality of the application is to allow a feed to subscribe to the 1-1 conversation and chatrooms both BLC and MCRs, of which users are members. This effectively enables the application to shadow user communications within the system.

 

Intended readership

This document is intended for developers within a financial organisation, who are responsible for the automation of message feeds for the following business areas:

· Sales

· Commodities

· FX

· Broker

 

Running Message Feed

Currently, message feed plugin jar files must be compiled using Java 11 or 17.

 Plugin jar files that are compiled using Java 17 allow the Message Feed app to run on Java 17. However, if the files are compiled using Java 17, the app must be run using Java 17.

To run Message Feed, do the following:

1. Using the Platform Administration Application (PAA), set up your service account and track user account (TrackUUID) to ensure that they:

· belong to the same company (same A number / same A location)

· are licensed for MESSENGER_USER_FEED

· are licensed for LSEG Messenger

2. Under the message-feed folder, create the plugins folder.

3. Copy message-feed-app.jar to the plugins folder on your machine.

4. Run the message feed start up command.

java "-Djava.system.class.loader=com.refinitiv.collab.platform.msgfeed.keep.DecryptClassLoader" -jar message-feed-0.0.4.0.jar "-Dserviceaccount=GE-XXXXXXXXX" "-Dpwd=XXXX-XXXX-XXXX" "-DtrackUUID=uuid-of-the-user-to-track"

There is an additional parameter -Denv=dev which can be used for connecting to different environments. The possible values are dev | qa | beta | trd | prod

Messages are now received by the Message Feed app and are sent to your plugins.

For security, active Message Feed sessions are maintained by the system, where only one session is supported for each service and track user account pair. When you start Message Feed, a session is created for you.

File structure

/message-feed

message-feed-0.0.4.0.jar

/plugins

CustomerPlugin.jar

Where:

· message-feed-app.jar is the main Message Feed app file.

· CustomerPlugin.jar is the plugin which is defined and implemented by the customer. This jar file is used to import the common library for the plugin and implement the ChatroomMessageHandler interface (found in the common library).

Key files

The following resources can be downloaded from the Developer Portal:

Main message feed application file: message-feed-0.0.4.0.jar

Plugin source example (source for CustomerPlugin.jar): message-feed-plugin-example.zip

Common library for plugin: message-feed-handler-x.x.x.jar

Preparing accounts

To run the Message Feed app, at least one service account and one or more ‘track user’ accounts are required.

The service account is the company level account, which is used to authenticate through AAA and access backend services. You can run multiple Message Feed apps concurrently, under one service account.

The track user account must belong to the same company and location as the service account, and they must be defined in the Platform Administration Application as under the same legal entity or location account under the legal entity (the A-number attribute). The track user account is used to find and subscribe to chatrooms for message feeding.

Creating and maintaining accounts

Service and track user accounts are created and maintained using the Platform Administration Application. Access to the Application is dependent on the environment:

Environment Link

Pre-production environment (PPE) https://platformadmin.ppe.refinitiv.com/Apps/platform-administration

Production environment https://platformadmin.refinitiv.com/Apps/platform-administration/

Requesting Platform Administration Application access

Access to the Platform Administration Application can only be requested internally. As such, customers requiring access to this application must contact LSEG Support. · Requesting access to PAA in PPE/PROD for Internal Users - RDP UI. · Requesting access to PAA in PPE/PROD for External Users - RDP UI - Enterprise Confluence (refinitiv.com)

When logging in to the Platform Administration Application for the first time, you are prompted for a user account id, which you will have received in a registration email, and password:

1. Type the assigned user account ID.

2. Click the Forgotten your password? link to reset your password.

Once you have reset your password, return to the same Platform Administration Application URL. You can then login using your assigned user account ID and your new password.

Creating and managing your service account

To create a service account, you need the legal entity number (the A-number attribute) for your company, which will be provided by LSEG. You can then use the Platform Administration Application to do the following:

1. Add the MESSENGER USER FEED and LSEG MESSENGER license to the service account.

2. Create a new account under the same A-number, add the MESSENGER USER FEED license to the account.

3. Select the ACCOUNTS tab ❶

4. In the search box ❷, enter your A-number to find your Account name and enter or click search icon, then click the Account name link ❸. For example:

5. Select the APPLICATION MANAGEMENT tab ❹, then click the CREATE APPLICATION button ❺:The Create application panel is displayed.

6. Enter the application name ❻ and owner ❼, then click the ADD APPLICATION button ❽.

7. In the newly created application page, in the Service accounts section, click the CREATE SERVICE ACCOUNT button ❾. 8. In the Service account details panel, click the newly created Service account name:

9. In the Application Management panel, assign the MESSENGER USER FEED license by doing the following:

i. Search for Messenger

ii. Select the checkbox that is adjacent to MESSENGER USER FEED

iii. Click the Save button

Important: For this step, a license for MESSENGER USER FEED is required. This can be obtained through the OMS. The license needs to be added to PAA before it can be added to a Service account.

Customer-defined plugins

The CustomerPlugin.jar files are used to handle messages and are developed by the customer. At least one of the customer-developed jar files must be put under plugins directory.

The plugin jar file must be created as a fat jar. That is, all libraries should be included in this jar. For more information about creating a fat jar, refer to the following site: https://www.baeldung.com/gradle-fat-jar

Each plugin jar file must implement at least one ChatroomMessageHandler1 interface. This interface is maintained by the Messenger Platform Team and can be found in the common library, message-feed-handler-x.x.x.jar.

Plugin processing overview

When the Message Feed app receives a user message, the message is forwarded to the ChatroomMessageHandler interfaces that are implemented in the customer-defined plugin jar files and stored in the plugins directory. For example, if a customer creates two plugin jar files, and the interface is implemented once in each file, the received messages are handled twice, once for each file.

You can update or add new plugin jar files even when the Message Feed app is running. However, to delete one or more plugin jar files, you must do the following:

1. Shutdown the Message Feed app

2. Delete the plugin jar file(s)

3. Restart the Message Feed app

Implementing the interface

In the Message Feed app, the CustomerPlugin.jar file is initialized by calling LoggingMessageHandler(). If your plugin needs to initialize resources, you should do so in the constructor of LoggingMessageHandler.

Interface implementation example:

package com.refinitiv.myplugin;

import org.json.JSONObject;

import com.refinitiv.collab.platform.msgfeed.handler.ChatroomMessageHandler;

public class LoggingMessageHandler implements ChatroomMessageHandler {

public LoggingMessageHandler() {

// Resource initialize

}

@Override

// when receiving message will call this method, for message structure please refer to section 2.3 Message Structure

public void handleChatroomMessage(String message) {

System.out.println("Handling message2: " + message);

JSONObject jo = new JSONObject(message);

System.out.println("Message id: " + jo.getJSONObject("eventData").optString("messageId"));

}

}

Message structure

Messages are passed into the handler as JSON strings. The structure of a JSON string can be found in the common library, message-feed-handler-x.x.x.jar, under com.refinitiv.collab.platform.msgfeed.Data.ChatMessageEvent.

Message structure example:

@Data

@ToString(callSuper = true)

@JsonInclude(JsonInclude.Include.NON_NULL)

public class ChatMessageEvent {

protected String eventType;

private String traceId;

private EventData eventData;

@Data

@JsonInclude(JsonInclude.Include.NON_NULL)

public static class EventData {

private String clientRequestId;

private String clientRequestDate;

private String chatRoomId;

private String complianceWarningApprove;

private String messengerUuid;

private String userUuid;

private String messageId;

private String createAt;

private String messageType;

private String message;

private List<Attachment> attachments;

private Boolean blastMessage;

private String blastId;

private JsonNode command;

@Getter(AccessLevel.NONE)

@Setter(AccessLevel.NONE)

private boolean isBot;

private JsonNode messageExtension;

private String replyTargetMessageId;

private JsonNode replyTarget;

private JsonNode urlDetails;

public boolean getIsBot() {

return this.isBot;

}

public void setIsBot(boolean isBot) {

this.isBot = isBot;

}

}

@Data

@ToString

@JsonInclude(JsonInclude.Include.NON_NULL)

public static class Attachment {

private String attachmentReference;

private String attachmentType;

private String attachmentName;

}

}

Starting Message Feed

The message-feed-app.jar file is used to start Message Feed app, as shown in the following command line:

java "-Djava.system.class.loader=com.refinitiv.collab.platform.msgfeed.keep.DecryptClassLoader" -jar message-feed-app.jar "-Dseriveaccount=<service account uuid>" "-Dpwd=<service account password>" "-DtrackUUID=<user uuid to track>"

Mandatory parameters:

· -Djava.system.class.loader=com.refinitiv.collab.platform.msgfeed.keep.DecryptClassLoader must be set before -jar message-feed-app.jar

· -Dserviceaccount=<service account uuid> is used to define the service account. For example, service account: GE-AAAAAA

· -Dpwd=<service account password> is used to specify the service account password. For example, password: abcXYZ123

· -DtrackUUID=<user uuid to track> is used to specify the user email address to monitor · When testing, for the messenger app please use the url https://messenger.ppe.refinitiv.com/messenger/?api-name=clp-beta

Network Requirements for Messenger User Feed

To ensure seamless connectivity and functionality of the User Message Feed, the following domains must be accessible from the customer’s infrastructure:

Required Domains

· api.refinitiv.com

· cdn.refinitiv.com

· messenger.collaboration.refinitiv.com

· a-fallback.collaboration.refinitiv.com

· b-fallback.collaboration.refinitiv.com

· c-fallback.collaboration.refinitiv.com

· d-fallback.collaboration.refinitiv.com

· e-fallback.collaboration.refinitiv.com

Required Ports

No custom ports are required. The application operates over standard HTTPS using:

· TCP Port 443

Please ensure that outbound access to the above domains over port 443 is permitted through your firewall or proxy settings.

Troubleshooting

Session already exists

A Message Feed application session cannot start if another session is active that uses the same service account / track user

account pair. In this event, the Session already exists! error is shown.

To rectify this issue:

Request that the person running a Message Feed app session with the same pair stops the app. Please use Ctrl + C to stop the session

Plugins folder does not exist

The plugins folder has not been created under the default folder location or the wrong plugin directory (Dplugin.dir) is set. To rectify this issue:

· Create the plugins folder under the default folder structure or

· Set the correct value for Dplugin.dir.(this can be passed as a parameter when starting the jar)

Sample Command with Plugin Dir set

java "-Djava.system.class.loader=com.refinitiv.collab.platform.msgfeed.keep.DecryptClassLoader" -jar message-feed-0.0.4.0.jar "-Dserviceaccount=GE-XXXXXXXXX" "-Dpwd=XXXX-XXXX-XXXX" "-DtrackUUID=xxxx" "-Dplugin.dir=ABSOLUTE_PATH_TO_PLUGINS_FOLDER"

Connection Issues

If you encounter any such errors related to connections it should be probably a certificate issue

(ERROR): io.ably.lib.transport.WebSocketTransport: Connection error javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:131) at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:369) at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:312) at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:307) at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.checkServerCerts(CertificateMessage.java:1357) at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.onConsumeCertificate(CertificateMessage.java:1232) at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.consume(CertificateMessage.java:1175) at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:392) at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:478) at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:456) at java.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:199) at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:172) at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1383) at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1296) at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:416) at java.base/sun.security.ssl.SSLSocketImpl.ensureNegotiated(SSLSocketImpl.java:835) at java.base/sun.security.ssl.SSLSocketImpl$AppInputStream.read(SSLSocketImpl.java:924) at java.base/java.io.InputStream.read(InputStream.java:205) at org.java_websocket.client.WebSocketClient.run(WebSocketClient.java:515) at java.base/java.lang.Thread.run(Thread.java:834) Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at java.base/sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:439) at java.base/sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:306) at java.base/sun.security.validator.Validator.validate(Validator.java:264) at java.base/sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:313) at java.base/sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:222) at java.base/sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:129) at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.checkServerCerts(CertificateMessage.java:1341) ... 15 more Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at java.base/sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141) at java.base/sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126) at java.base/java.security.cert.CertPathBuilder.build(CertPathBuilder.java:297)

Solution

· If the machine which is used for testing contains any firewalls or network filtering apps (like Zscalar) the certificate needs to be added to java trusted list

Eg:

keytool -import -alias ZscalerRootCerttificate -keystore "C:/Program Files/Microsoft/jdk-17.0.2.8-hotspot/lib/security/cacerts" -file "C:/Users/pkollapa1/Downloads/ZscalerRootCerttificate.der" -storepass changeit

SUBSCRIBE TO THIS API UPDATES

By submitting this form, you agree to your personal data being shared within the London Stock Exchange Group of companies (LSEG) for the purpose of receiving communications via post, phone and electronic means from LSEG about event, resources, products, and/or services.

For more information on how LSEG uses your data, see our Privacy Statement. You can adjust your preferences at any time through the preference link in any electronic communication that you receive from us.

Request Free Trial

Help & Support

Already a customer?

Office locations

Contact LSEG near you