@avaya/infinity-agent-sdk - v1.0.0
    Preparing search index...

    Message Types and subtypes

    This guide covers the message stream on an active interaction - consuming real-time voice transcriptions, and sending, receiving, and paging through private text messages. Both arrive as typed messages discriminated by their type and subtype.

    Personas: Agent - sends and receives private messages and consumes live transcriptions on their own call; Supervisor - reads transcriptions and sends private coaching messages while monitoring an interaction.

    Messages are delivered over the InteractionEventType.INTERACTION_MESSAGE_RECEIVED event and discriminated by type and subType:

    • Voice transcriptions - ChatMessages with subType === ChatMessageSubType.TRANSCRIPTION. No additional subscription or API setup is required beyond listening for incoming messages on a voice interaction.
    • Private messages - text exchanged with the customer on a live interaction. The SDK surfaces them through events and provides a cursor-based iterator for loading history via InteractionTrait.sendMessage, InteractionTrait.getMessages, MessagesIterator, and the INTERACTION_MESSAGE_RECEIVED / INTERACTION_MESSAGE_SENT events.
    • SDK initialized and agent on an active interaction - see Integration and Lifecycle and Handling interactions.
    • For transcriptions: the interaction is a voice call and transcription is enabled for its queue in the Avaya Infinity Admin Console.
    • For private messaging: the interaction channel must support messaging. Use interaction.canSendMessage() and interaction.canGetMessages() to guard at runtime.

    Filter incoming messages by type then subType. Narrowing to MessageType.CHAT is required before accessing subType, which is only present on ChatMessage:

    interaction.subscribe(InteractionEventType.INTERACTION_MESSAGE_RECEIVED, (event) => {
    const { message } = event.payload;
    if (message.type !== MessageType.CHAT) return;
    if (message.subType !== ChatMessageSubType.TRANSCRIPTION) return;

    const isCustomer = message.author.type === MessageAuthorType.CUSTOMER;
    console.log(isCustomer ? "Customer:" : "Agent:", message.body.text.content, message.createdAt);
    });

    Each transcription carries an author whose type identifies who spoke:

    author.type direction Who spoke
    MessageAuthorType.CUSTOMER MessageDirection.IN The customer
    MessageAuthorType.AGENT MessageDirection.OUT The agent or supervisor

    When author.type is MessageAuthorType.CUSTOMER, the author is a CustomerAuthor. Its details property holds a snapshot of Interaction.customer captured at transcription time - prefer author.details over reading interaction.customer directly, since the snapshot is scoped to that specific utterance:

    interaction.subscribe(InteractionEventType.INTERACTION_MESSAGE_RECEIVED, (event) => {
    const { message } = event.payload;
    if (message.type !== MessageType.CHAT) return;
    if (message.subType !== ChatMessageSubType.TRANSCRIPTION) return;
    if (message.author.type !== MessageAuthorType.CUSTOMER) return;

    const { name, phone } = message.author.details;
    console.log(`${name} (${phone}): ${message.body.text.content}`);
    });

    Subscribe to INTERACTION_MESSAGE_RECEIVED on the interaction to handle incoming messages in real time. The handler receives an event object; the message is under event.payload.message. Store the returned handler ID so you can clean up later:

    const handlerId = interaction.subscribe(InteractionEventType.INTERACTION_MESSAGE_RECEIVED, (event) => {
    const { message } = event.payload;
    if (!message.isPrivate) return;
    console.log(message.author.type, message.body.text.content, message.createdAt);
    });

    // unsubscribe when the component unmounts or the interaction completes
    interaction.unsubscribe(InteractionEventType.INTERACTION_MESSAGE_RECEIVED, handlerId);

    INTERACTION_MESSAGE_SENT fires with the same event shape when the server acknowledges a message you sent.

    Guard with canSendMessage() before calling InteractionTrait.sendMessage. Build the request with ChatMessageRequest - messages are always sent with ChatMessageVisibility.PRIVATE visibility (PUBLIC is reserved):

    if (interaction.canSendMessage()) {
    const request = new ChatMessageRequest().setText("How can I help you today?");
    const identifier = await interaction.sendMessage(request);
    console.log("sent:", identifier.messageId);
    }

    InteractionTrait.getMessages returns a MessagesIterator. Call hasNext() before next() and hasPrevious() before previous() - calling either iterator method without checking its guard throws immediately:

    if (interaction.canGetMessages()) {
    const iter = interaction.getMessages({ order: MessageOrder.DESC, pageSize: 20 });

    while (iter.hasPrevious()) {
    const page = await iter.previous();
    for (const message of page) {
    if (message.isPrivate) {
    console.log(message.author.type, message.body.text.content, message.createdAt);
    }
    }
    }
    }

    With MessageOrder.DESC (the default), each page arrives newest-first and previous() pages backward toward older history. next() moves forward toward newer messages from the current position.

    Failures surface as typed AvayaInfinityAgentSdkErrors with stable codes from AvayaInfinityAgentSdkErrorCodes. Errors that occur on the messaging path belong to the ASE_4xxx family - match error.code against AvayaInfinityAgentSdkErrorCodes to identify the specific failure. If no specific code applies, the SDK falls back to ASE_4000.

    Transcription messages are delivered via events and do not introduce error codes beyond those on the messaging path. There are no Promise-rejection paths specific to transcription.