After establishing a DIDComm connection with a peer, one of many supported interactions is the ability to exchange text messages back and forth along the E2EE channel. The Edge Agent supports Aries Basic Message Protocol (RFC 0095) to accomplish this.
The MessagingModule contains the methods to receive, send and manage these messages. It is accessed via the agent's fields: agent.connections.messaging.
Subscribe to Inbound Messages
As described in the section, subscription to new incoming Basic Messages is supported via the subscribeToAgentEvents API. The subscriber will be invoked once for each new message, and will include the inbound message data, such as the content, the receivedTime and the ID of the Connection who sent it.
classMessageSubscriber:AgentEventSubscriber {funcinboundBasicMessage(basicMessage: BasicMessage.Inbound) {// the following will be invoked whenever a new basic message is received.print("new message: \(basicMessage)") }funcconnectionExchangeStateChanged(connectionExchange: ConnectionExchange) {}funccredentialExchangeStateChanged(credentialExchange: CredentialExchange) {}funcproofExchangeStateChanged(proofExchange: ProofExchange) {}funcmessageProcessed(messageId: String) {}}let customSubscriber =MessageSubscriber()let subscriberId = agent.subscribeToAgentEvents(subscriber: customSubscriber)
val subscriber =object : AgentEventSubscriber {overridefuninboundBasicMessage(basicMessage: BasicMessage.Inbound) {// the following will be invoked whenever a new basic message is received.println("new message: $basicMessage") }}val subscriberId = agent.subscribeToAgentEvents(subscriber)
See for more subscription management details.
Send Messages
To send a basic message to a connection, the sendBasicMessage API can simply be used. On success, the outbound basic message that was sent to the peer will be returned.
let agent: SudoDIEdgeAgentlet connectionId: String// the identifier of the [Connection] to messagedo {let sentMessage =tryawait agent.connections.messaging.sendBasicMessage( connectionId: connectionId, content:"hello world")} catch {// handle error}
val agent: SudoDIEdgeAgentval connectionId: String// the identifier of the [Connection] to messagetry {val sentMessage = agent.connections.messaging.sendBasicMessage( connectionId = connectionId, content ="hello world" )} catch (e: MessagingModule.SendBasicMessageException) {// handle error}
Query Messages
The SDK features one API for listing basic messages in a variety of ways: listBasicMessages. The API is designed to support common peer to peer messaging use cases.
The method takes a ListBasicMessagesOptions object as input as a way to configure pagination, sorting and filtering. It has the following fields within it:
filters - A ListBasicMessagesFilter object with configurations for how results should be filtered
filters.connectionId - if provided, the resulting list of messages will only contain messages from the given connection
filters.limitMessagesPerConnection - if provided, the resulting list of messages will limit the number of messages from a single connection. Useful for "conversation list views": "list recent messages, limited to 1 per connection".
paging - A common Paging object, configuring the limit of items to fetch, and the current cursor position (if any)
sorting - A ListBasicMessagesSorting object specifying how the results should be sorted (pre filtering and paging). Currently chronological sorting (ascending and descending) is supported
The value returned is a PageResult<BasicMessage>, which contains a list of items and a string cursor, nextToken, if there is more items to fetch. This nextToken can be passed into the paging item when performing the next listBasicMessages operation to fetch the next page of items from where the cursor was up to.
List All Recent Messages
let agent: SudoDIEdgeAgentlet pageSize: UInt=10do {let page1 =tryawait agent.connections.messaging.listBasicMessages( options: .init( paging: .init(limit: pageSize)))let pageItems1 = page1.items// fetch next page if nextToken is not nillet page2 =tryawait agent.connections.messaging.listBasicMessages( options: .init( paging: .init(limit: pageSize, nextToken: page1.nextToken)))let pageItems2 = page2.items// continue..} catch {// handle error}
val agent: SudoDIEdgeAgentval pageSize =10utry {val page1 = agent.connections.messaging.listBasicMessages( options =ListBasicMessagesOptions( paging =Paging(pageSize) ) )val pageItems1 = page1.items// fetch next page if nextToken is not nullval page2 = agent.connections.messaging.listBasicMessages( options =ListBasicMessagesOptions( paging =Paging(pageSize, page1.nextToken) ) )val pageItems2 = page2.items// continue..} catch (e: MessagingModule.ListBasicMessagesException) {// handle error}
Some Edge Agent SDK consumers may wish to handle Basic Message storage themselves, for instance, to add their own indexes and data schema. Or even to just avoid message storage all together. If that is the case, the SDKs managed storage of Basic Messages can be opt out of with the AgentConfiguration's messagingConfiguration.storeBasicMessages field. By default this is true, setting the configuration field to false will disable storage of Basic Messages.
See Agent Management for details on managing the agent's configuration.
With storage disabled, Basic Messages will still be processed and will still invoke the subscription (see Subscribe to Inbound Messages), but nothing will be put into the agent's database. Meaning the above APIs (list, delete) will have limited functionality.