Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

StartChat and SendChatMessage #574

Closed
Tracked by #596 ...
bertrand-s opened this issue Jan 31, 2022 · 8 comments · Fixed by #620 or #724
Closed
Tracked by #596 ...

StartChat and SendChatMessage #574

bertrand-s opened this issue Jan 31, 2022 · 8 comments · Fixed by #620 or #724
Labels
Context Data & Intents Contexts & Intents Discussion Group enhancement New feature or request
Milestone

Comments

@bertrand-s
Copy link
Contributor

Enhancement Request

Use Case:

This proposal covers two connected use cases:

  • extend the chat creation option parameters (today we only support a contact or a list of contacts)
  • support the possibility to send messages in existing chats

Intents

StartChat

The proposal is to support a new context type (ChatInit) to initialize a chat creation with new optional parameters:

  • a chat name
  • an initial pre-formatted message (that would be edited prior to sending in the chat application)
  • other application-specific configuration options (cf. below)

Example:

let chatInit: ChatInit = {
    type: "fdc3.chatInit",
    chatName: "Deal ABCD",
    members: {
        type: "fdc3.contactList",
        contacts: [
            {
                type: "fdc3.contact",
                name: "John Doe",
                id: {
                    "email": "john@sample.com"
                }
            }
        ]
    },
    chatRoomOptions: {
        "symphony": {
            visibility: "EXTERNAL-SINGLE",
            discoverable: true
        }
    },
    initMessage: "Hi John"
}

Which would translate into this type of interface:

// Intent<ParamType, ReturnType>
type StartChat = Intent<Contact | ContactList | ChatInit, ChatRoomRef>;

/**
 * ChatInit: new context to define the initialization parameters to create a new chat
 */
interface ChatInit {
    type: "fdc3.chat.init";
    chatName?: string;
    members: ContactList;
    chatRoomOptions?: { [appName: string]: ChatOptions };
    initMessage?: string | RichTextBlock;
}

type ChatOptions = Object;

/**
 * ChatOptions specific to Symphony
 */
interface SymphonyChatOptions extends ChatOptions {
    type: "symphony.chat.initOptions";
    visibility: "PUBLIC" | "PRIVATE" | "EXTERNAL-SINGLE" | "EXTERNAL-MULTI";
    discoverable?: boolean;
    memberPermissions?: {
        allowHistoryBrowsing?: boolean;
        allowMessageSend?: boolean;
        allowMessageCopy?: boolean;
        allowAddUser?: boolean;
    }
}

interface ChatRoomRef {
    type: "fdc3.chat.roomRef";
    appName: string; // name of the application that owns this chat - e.g. "symphony"
    id: {[idType:string]: string}; // id Object - similar structure 
    name?: string; // name of the chat at the time of its creation
}

Notes:

  • the purpose of the dictionary structure for chatRoomOptions is to allow supporting multiple chat applications. If multiple options are passed, the FDC3 agent should ask the end user to choose which application to pick (e.g. Symphony or Teams)
  • the optional init message could be either a plain string or a formatted structure (to be discussed in a separate proposal)
  • we also propose to have the StartChat intent return a ChatRoomRef object that could be used in the SendChatMessage to send further messages in the same chat room (cf. separate proposal)

SendChatMessage

This new intent would be used to send a message into an existing chat (that may have previously been created through StartChat).

// example
let chatMessage: ChatMessage = {
    type: "fdc3.chat.message",
    chatRoom: {
        type: "fdc3.chat.roomRef",
        appName: "symphony",
        id: "KTHwU5nxJJDgTKaIshGvjI3///o3"
    },
    message: "Hello World"
}

SendChatMessage would take a ChatMessage as input and would return

  • either null if the message was not sent (e.g. the end-user changed her mind)
  • or a ChatRoomRef context if the message was sucessfully sent. The reason for sending back a ChatRoomRef context is to give an application the opportunity to receive an updated version of the chat name (that may have been changed since its creation).
// Intent<ParamType, ReturnType>
type SendChatMessage = Intent<ChatMessage, ChatRoomRef | null>;

/**
 * ChatMessage: context passed to SendChatMessage
 * Send a message in an existing chat conversation
 */
interface ChatMessage {
    type: "fdc3.chat.message";
    chatRoom: ChatRoomRef;
    message: string | RichTextBlock;
}

/**
 * Context returned by StartChat and SendChatMessage
 */
interface ChatRoomRef {
    type: "fdc3.chat.roomRef";
    appName: string; // name of the application that owns this chat - e.g. "symphony"
    id: string;
    name?: string; // name of the chat
}

Note: the RichTextBlock type will be discussed in a separate thread

@bertrand-s bertrand-s added Context Data & Intents Contexts & Intents Discussion Group enhancement New feature or request labels Jan 31, 2022
@bertrand-s
Copy link
Contributor Author

Hi @rikoe - could this be put a next meeting agenda?

@openfin-johans
Copy link
Contributor

Hi @bertrand-s,

thanks for filing and including lots of details! Just adding my comments from the call last week.

My concern here is that it might complicate the intents flow a bit too much? While several apps might be able to handle eg "SendMessage" based on their app configs, this is introducing context that only the application itself can handle - eg does the user have access to the chatroom provided and are they able to send the message (considering all the various restrictions you can put on a room).

I do like the general idea of “chat init” where any custom options can be put in to improve the workflow but maybe “init” is a bit of a technical name?

Anyway, these are quite general concerns - if there's not a technical issue FDC3 should be "open" enough to allow for all of this to tested and proven amongst the community. We can then move to aiming to standardize based on what is actually being used?

That said - I think there might be a good argument for standardized "body" content or "message" so that a receiving application knows what to expect or how to handle the data. Please see my comment on #575

Best regards,

Johan

@kriswest
Copy link
Contributor

My concern here is that it might complicate the intents flow a bit too much? While several apps might be able to handle eg "SendMessage" based on their app configs, this is introducing context that only the application itself can handle - eg does the user have access to the chatroom provided and are they able to send the message (considering all the various restrictions you can put on a room).

I disagree that this complicates the intents flow, you would raise the intent (in this case SendChatMessage), if you don't have access to the room or it doesn't exist it would be up to the receiving app to display an error message. The DesktopAgent should not raise an error in this case (it has correctly delivered the intent and context), the receiving app just can't deal with it and should explain why. The same would apply to many other intent use cases, e.g. orders that don't exist, accounts you can't access etc.. We should consider a clarification on this in the spec/docs - it is already clear in the case of IntentResolution.getResult() (which can return an error in these cases).

if there's not a technical issue FDC3 should be "open" enough to allow for all of this to tested and proven amongst the community.

The group specifically addressed this comment already in its first meeting - intents already have a proven use case, the goal is now to propose specific intents for use cases that already exist and hence to try to both promote implementation and limit fragmentation. If we require every intent proposed to have already been in use then we risk: namespace conflicts (if they try to use a fdc3.XXX name), forcing all parties using them to reimplement their support later (after the name changes on standardisation) or failing to properly promote the use of intents for fdc3's intended purpose:

to develop specific protocols and taxonomies to advance the ability of desktop applications in financial workflows to interoperate in a plug-and-play fashion, without prior bi-lateral agreement
A key challenge in doing that without FDC3 first adopting a proposal like this is that it would require prior bi-lateral agreement between at least two parties to demonstrate use.

In this case, there already exist numerous examples of applications that can trigger sending a message or creating a chat in a different application. However, I think the point more valid on the type of the message field (but then I'm not as familiar with the specifics of chat applications as the proposer - @bertrand-s did point to a couple of examples of JSON already being used to encode messages rather than markdown or HTML). Would it make sense to add a string type field to the proposed contexts to allow labelling of different string and JSON encodings of the message to keep this proposal more 'open'?

@openfin-johans
Copy link
Contributor

Thanks @kriswest,

I guess my thought regarding complication was more from a user perspective where I would expect the intent resolver to show me "useful" apps - that could actually perform the functionality for me and not show an error once I raise it. You are right that the same thing exist for most if not all intent/context combinations but the more complex/unique the context - the more of this we'll see.

I stand corrected on the specific intent naming - of course we should standardize intents when there is enough interest without requiring them to be in use already.

Best regards,

Johan

@kriswest
Copy link
Contributor

I guess my thought regarding complication was more from a user perspective where I would expect the intent resolver to show me "useful" apps - that could actually perform the functionality for me and not show an error once I raise it.

Good point! Although for sendChatMessage I imagine most intents will be targeted at the app owning the chat as it requires the chat room reference... I've still got the action item on my TODO list to raise an issue enabling the ChatRoomRef to contain the AppMetadata for the app that created the room (or rather for the responding app to be able to retrieve its own AppMetadata so it can add it to it. That part of this flow does lack some elegance generate some redundancy (as IntentResolution will also contain that metadata). I don't see a better way to solve for that however.

@pauldyson
Copy link
Contributor

We're super-keen to see these Intents. IM integration, specifically with Symphony, is our customers' #1 request for our desktop integration!

Some thoughts on the proposed spec, none of which are strongly-held views:

initMessage on ChatInit is particularly important to us most of our use cases are one-shot hand-offs. E.g. starting a research discussion chat with a link to a research model or pack of research, starting a client review chat with recent interaction information, etc. We're unlikely to maintain a ChatRef and use this to continue to post although I can see there might be other systems that use this.

The use of SymphonyChatOptions kind of makes this specific to Symphony. As soon as you have to tie vendor-specific information into a call, you're effectively integrating 'directly' with the vendor. So my question is whether we can either make the Intent more Symphony-specific, and get advantage from that, or else make the options less Symphony-specific. Obviously the latter is preferable from an interop point of view as long as it doesn't limit the richness of Symphony integration.

From my reasonably broad knowledge of chat system, 'public' and 'private' are fairly standard concepts even if different systems have slightly different interpretations about what they mean. I don't exactly know what the Symphony interpretation of "EXTERNAL-SINGLE" and "EXTERNAL-MULTI" but these seem to be as much properties of the contacts (is there one of them, are they external to the organisation the user is from) as the chat room. Could they be removed without losing functionality?

Likewise the options for member permissions and discoverability. I don't think any CRM user would want to select these as part of initiating the chat ... they just want the system to do the right thing as quickly as possible. So can these just be defaulted in Symphony? This is how we integrate with Zoom ... you can one-click organise an online call from Singletrack and if you want to change the default perms, you get a URL to navigate to do that natively in Zoom rather than make these choices in our system. But I can see these are optional so maybe it doesn't matter, we just won't use them.

As mentioned, I don't think we have a use case for posting subsequent messages into the chat room but I can see value in having a quick way to navigate back to a running chat from the CRM. In that case, could we have an 'empty' version of ChatMessage that just opens the relevant chat channel without posting a message?

@bertrand-s
Copy link
Contributor Author

Many thanks for your feedback.
I propose to work a PR and amend the proposal as follows:

  • use AppMetaData instead of appName in the ChatRoomRef
  • integrate 'common' options like 'public' / 'private' in ChatOptions
  • make the initMessage type as string | Object - this would be temporary until we agree on what a structure message should be supported (I will also continue working on the separate RichTextBlock proposal)

Notes:

  • @pauldyson the proposal is to have chat options as a dictionary to allow the sender to provide multiple chat options in the intent request (i.e. an option object for each of the supported chat apps) - this is why I propose to have a SymphonyChatOptions (that won't be specified in the FINOS spec) as an independent context and maybe later a SlackChatOption, a TeamsChatOptions, etc.
  • @openfin-johans the options I propose are currently used in Symphony, so I am fairly confident on their 'battle-tested' side - but I agree this isn't true for RichTextBlock and I fully support the experimental flag approach

@kriswest
Copy link
Contributor

@bertrand-s when this issue auto-closes when the StartChat PR is merged you'll need to re-open or open a new one for SendChatMessage (which is not in the PR, right?)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Context Data & Intents Contexts & Intents Discussion Group enhancement New feature or request
Projects
None yet
4 participants