Chat conversation store

The chat interface delegates responsibility of storing chat-related data to a conversation store which is implemented by the integrator. We supply some reference implementations.

When new messages arrive, new conversations are created, or messages are marked as read, the SDK updates the conversation store through the following interface:

/**
 * 
 */
export interface IConversationStore {

    getConversations(): Promise<IChatConversation[]>;

    getConversation(conversationId: string): Promise<IChatConversation>;
    createConversation(conversation: IChatConversation): Promise<boolean>;
    updateConversation(conversation: IChatConversation): Promise<boolean>;
    deleteConversation(conversationId: string): Promise<boolean>;
    deleteConversationMessages(conversationId: string): Promise<boolean>;

    reset(): Promise<boolean>;
    // sdk calls this to see whether it needs to update / add the new message 
    getMessage(conversationId: string, messageId: string): Promise<IChatMessage>;
    // read / delivered info has been added, hand back to client to store ...
    updateMessageStatus(conversationId: string, messageId: string, profileId: string, status: string, timestamp: string): Promise<boolean>;
    // getMessageStatus(conversationId: string, messageId: string): Promise<boolean>;

    // new message added 
    createMessage(message: IChatMessage): Promise<boolean>;

    getMessages(conversationId: string): Promise<IChatMessage[]>;
}

We have implementations for in-memory and indexedDb stores that can be used. You can use these directly or use the source as a starting point to implement your own. The conversation stores are passed to the chat SDK during initialisation.


ES6 syntax

Note the imports:

import { ComapiChatClient, ComapiChatConfig, MemoryConversationStore } from '@comapi/sdk-js-chat';

let store = new MemoryConversationStore()

let comapiConfig = new ComapiChatConfig()    
    .withStore(store)
    .withApiSpace(">>> Your API SPACE ID <<<")
    .withAuthChallenge(this.authChallenge.bind(this));

let chatClient = new ComapiChatClient();

chatClient.initialise(comapiConfig)
    .then(succeeded => {
        console.log("initialised!");
    });

Traditional syntax

Note the use of the global COMAPI_CHAT object:.

var store = new COMAPI_CHAT.MemoryConversationStore();

var comapiConfig = new COMAPI_CHAT.ComapiChatConfig()    
    .withStore(store)
    .withApiSpace(">>> Your API SPACE ID <<<")
    .withAuthChallenge(authChallenge);

var chatClient = new COMAPI_CHAT.ComapiChatClient()

chatClient.initialise(comapiConfig)
    .then(function(succeeded){
        console.log("initialised!");
    });

Custom implementation

You might want to implement your own interface if you need to perform any custom action when new messages are delivered, and so on. The Angular 1.x based sample app implements its own store. The reason being that it uses $q instead of native Promises is so that Angular's change detection seamlessly works. The Angular4 sample just uses the stock interface, as Angular4 internally uses zone.js to monkey patch all async operations.

Both of these two Angular samples rely on Angular's binding mechanism to keep the views up to date. If you’re not using a framework that supports this kind of binding, you must hook into some of these store methods. You could publish an event that your view code could consume and subsequently redraw the view or append the new data.


Asynchronous methods

All of the store interface methods are asynchronous and return promises. This is because all of the native persistence interfaces supported by the browser are asynchronous.

🚧

Be aware

If you implement your own interface, you run the risk of breaking the SDK if your code throws an exception or fails to resolve a promise.

Reference implementations

There are 2 reference implementations of stores available. You can use these as a starting point to a custom implementation:

MemoryConversationStore
IndexedDBConversationStore