Skip to content

Messaging Module

Overview

The Alexa Auto SDK Messaging module enables your Alexa Auto SDK client application to use the Short Message Service (SMS) capabilities of Alexa, independent of the messaging device's connection mechanism. The SMS features of this module include reading messages, sending messages, and replying to messages as they are read.

The user must connect their device and consent to allow Alexa to read and send SMS messages through the messaging device. The Messaging feature can use phone numbers directly or use phone contacts uploaded via the Address Book module.

Managing Messaging Sessions

The application is responsible for managing the life cycle of the messaging session, including enhancing the end user experience by:

  • Uploading unread SMS messages when the messaging device is connected, so they are ready for readout.
  • Uploading new SMS messages when they are received on the messaging device.
  • Updating the status of messages when notified to do so.
  • Responding to messaging requests with appropriate successful or failure responses.

Alexa will not notify the user when new SMS messages are available, your implementation is responsible for providing new message notifications.

Configuring the Messaging Module

The Messaging module does not require Engine configuration.

Using the Messaging Module AASB Messages

Sending Messages

When Alexa sends a request to the Engine to deliver a message, the Engine publishes the SendMessage message including the text and URL for the audio from which the message was created. Publish either the SendMessageSucceeded message or SendMessageFailed message indicating either the success or failure of the request.

Click to expand or collapse sequence diagram: Sending Messages

Sending Messages


Reading Messages

When a user requests for Alexa to read messages, your application's Messaging module integration must upload a conversation report containing all unread messages. Once Alexa requests a conversation report upload, the Engine publishes the UploadConversations message. Publish the ConversationsReport message to notify the Engine to upload a conversation report to the cloud.

Note: Messages are grouped by conversation, each given a unique identifier. Conversations also have unique identifiers and contain the list of recipient phone numbers included in the conversation, but not the phone number of the messaging device.

After Alexa reads a message, it notifies the application that the message was read and should exclude the read message in subsequent conversation report uploads. The Engine publishes the UpdateMessagesStatus message to update the status of the SMS messages. Publish either the UpdateMessagesStatusSucceeded message or UpdateMessageStatusFailed message indicating the success of the message status update. After Alexa reads all messages, or if message readout is interrupted, Alexa requests the upload of a new conversation report. In this way, Alexa stays in sync with unread messages on the messaging device.

Note: Unread messages are stored in the cloud for 12 hours before being deleted. By design Alexa will read a limited number of unread messages with a 'read messages' utterance. Therefore, it may be necessary to issue additional read messages requests to head all messages.

Click to expand or collapse sequence diagram: Reading Messages and Replying

Reading messages


Replying to Message

The user can request to reply to a message after Alexa reads the message or as it is being read. Replying is always done within the context of the currently read message.

Click to expand or collapse sequence diagram: Replying to Message

Reply to message


Updating Messaging Endpoint State

When connection to a calling device is established or broken and/or the user grants or denies permissions to read and send messages, publish the UpdateMessagingEndpointState message to update Alexa with the state of the messaging device.

Click to expand or collapse sequence diagram: Connecting/Disconnecting Calling Device

Updating Messaging Endpoint State

Click to expand or collapse sequence diagram: Granting/Denying Permissions to Read and Send Messages

Updating Messaging Endpoint State


Integrating the Messaging Module Into Your Application

C++ MessageBroker Integration

Use the Engine's MessageBroker to subscribe to and publish "Messaging" AASB messages.

Click to expand or collapse C++ sample code

#include <AACE/Core/MessageBroker.h>

#include <AASB/Message/Messaging/Messaging/ConnectionState.h>
#include <AASB/Message/Messaging/Messaging/ErrorCode.h>
#include <AASB/Message/Messaging/Messaging/PermissionState.h>

#include <AASB/Message/Messaging/Messaging/ConversationsReportMessage.h>
#include <AASB/Message/Messaging/Messaging/SendMessageMessage.h>
#include <AASB/Message/Messaging/Messaging/SendMessageFailedMessage.h>
#include <AASB/Message/Messaging/Messaging/SendMessageSucceededMessage.h>
#include <AASB/Message/Messaging/Messaging/UpdateMessagesStatusMessage.h>
#include <AASB/Message/Messaging/Messaging/UpdateMessagesStatusFailedMessage.h>
#include <AASB/Message/Messaging/Messaging/UpdateMessagesStatusSucceededMessage.h>
#include <AASB/Message/Messaging/Messaging/UpdateMessagingEndpointStateMessage.h>
#include <AASB/Message/Messaging/Messaging/UploadConversationsMessage.h>

#include <nlohmann/json.hpp>
using json = nlohmann::json;

class MyMessagingHandler {

  // Subscribe to messages from the Engine
  void MyMessagingHandler::subscribeToAASBMessages() {
    m_messageBroker->subscribe(
        [=](const std::string& message) { handleSendMessageMessage(message); },
        SendMessageMessage::topic(),
        SendMessageMessage::action());
    m_messageBroker->subscribe(
        [=](const std::string& message) { handleUpdateMessagesStatusMessage(message); },
        UpdateMessagesStatusMessage::topic(),
        UpdateMessagesStatusMessage::action());
    m_messageBroker->subscribe(
        [=](const std::string& message) { handleUploadConversationsMessage(message); },
        UploadConversationsMessage::topic(),
        UploadConversationsMessage::action());
  }

  // Handle the SendMessage message from the Engine
  void MyMessagingHandler::handleSendMessageMessage(const std::string& message) {
    SendMessageMessage msg = json::parse(message);
    sendMessage(msg.payload.token, msg.payload.message, msg.payload.recipients);
}

  // Handle the UpdateMessagesStatus message from the Engine
  void MyMessagingHandler::handleUpdateMessagesStatusMessage(const std::string& message) {
    UpdateMessagesStatusMessage msg = json::parse(message);
    updateMessagesStatus(msg.payload.token, msg.payload.conversationId, msg.payload.status);
  }

  // Handle the UploadConversations message from the Engine
  void MyMessagingHandler::handleUploadConversationsMessage(const std::string& message) {
    UploadConversationsMessage msg = json::parse(message);
    uploadConversations(msg.payload.token);
  }

  // To upload a conversations report to Alexa, publish a ConversationsReport message to the Engine
  void MyMessagingHandler::conversationsReport(
    const std::string& token,
    const std::string& conversations) {
    ConversationsReportMessage msg;
    msg.payload.token = token;
    msg.payload.conversations = conversations;
    m_messageBroker->publish(msg.toString());
  }

  // When the message fails to send, publish a SendMessageFailed message to the Engine
  void MyMessagingHandler::sendMessageFailed(
    const std::string& token,
    ErrorCode code,
    const std::string& message) {
    SendMessageFailedMessage msg;
    msg.payload.token = token;
    msg.payload.code = code;
    msg.payload.message = message;
    m_messageBroker->publish(msg.toString());
  }

  // When the message is successfully sent, publish a SendMessageSucceeded message to the Engine
  void MyMessagingHandler::sendMessageSucceeded(const std::string& token) {
    SendMessageSucceededMessage msg;
    msg.payload.token = token;
    m_messageBroker->publish(msg.toString());
  }

  // When the message status update fails, publish a UpdateMessagesStatusFailed message to the Engine
  void MyMessagingHandler::updateMessagesStatusFailed(
    const std::string& token,
    ErrorCode code,
    const std::string& message) {
    UpdateMessagesStatusFailedMessage msg;
    msg.payload.token = token;
    msg.payload.code = code;
    msg.payload.message = message;
    m_messageBroker->publish(msg.toString());
  }

  // When the message status update succeeds, publish an UpdateMessagesStatusSucceeded message to the Engine
  void MyMessagingHandler::updateMessagesStatusSucceeded(const std::string& token) {
    UpdateMessagesStatusSucceededMessage msg;
    msg.payload.token = token;
    m_messageBroker->publish(msg.toString());
  }

  // To update the messaging endpoint state, publish an UpdateMessagingEndpointState message to the Engine
  void MyMessagingHandler::updateMessagingEndpointState(
    ConnectionState connectionState,
    PermissionState sendPermission,
    PermissionState readPermission) {
    UpdateMessagingEndpointStateMessage msg;
    msg.payload.connectionState = connectionState;
    msg.payload.sendPermission = sendPermission;
    msg.payload.readPermission = readPermission;
    m_messageBroker->publish(msg.toString());
  }

  void MyMessagingHandler::sendMessage(
    const std::string& token,
    const std::string& message,
    const std::string& recipients) {
    // Parse list of recipients to extract the phone number(s)
    // Send message using the connected messaging device
    // Send response of the result using the received token

    // If message was sent successfully then call
    sendMessageSucceeded(token);
    // Otherwise, notify of error using code from @c ErrorCode enum and corresponding error message
    sendMessageFailed(token, ErrorCode::GENERIC_FAILURE, "Unable to send message");

  }

  void MyMessagingHandler::updateMessagesStatus(
    const std::string& token,
    const std::string& conversationId,
    const std::string& status) {
    // Remove unread messages specified in 'status' from the conversation that matches the 'conversationId'
    // Send response of the result using the received token

    // If messages status was updated successfully then call
    updateMessagesStatusSucceeded(token);
    // Otherwise, notify of error using code from @c ErrorCode enum and corresponding error message
    updateMessagesStatusFailed(token, ErrorCode::GENERIC_FAILURE, "Unable to update message status");
  }

  // Alexa is requesting that a conversation report is uploaded so it can sync up the
  // status of messages on the cloud
  void MyMessagingHandler::uploadConversations(const std::string& token) {
    conversationsReport(token, storedConversations);
  }

};