# 4. Messages flow

In the [Initialization document](3.Initialization.md) we described how to obtain your Cloud Agent.
Cloud Agent can be considered as a mailbox which able to receive and collect messages for your application.
In this document, we will describe how to deal with messages on the mobile application side.

## Message downloading

There are two strategies regarding receiving messages by the application from its Cloud Agent:

* Polling - Application once in a while calls Cloud Agent to download all received messages. 
    ![](/wiki-images/Polling.png)
    
* Push Notifications - Cloud Agent forwards messages to `Sponsor` which then notifies application.
  When the application receives notification it can download only one message related to the received push notification.
  ![](/wiki-images/PushNotifications.png)

After receiving messages from the Cloud Agent, Mobile application should process messages depending on its type and updated their status on the Cloud Agent as reviewed.

There are two general messages kinds that can be received:
* Messages which start a new protocol and require an interaction with User:
  * `Connection Invitation` - offer to establish a connection
  * `Credential Offer` - offer to issue a verifiable credential
  * `Proof Request` - request to share personal information
  * `Structured Message / Question` - select a predefined response from several options
* Messages continuing the protocol:
  * `Connection Response` - follows after accepting a connection invitation
  * `Credential` - follows after accepting a credential offer
  * `Ack` - follows after sharing a proof
  * `Connection Reuse Acceptance` - follows after connection reusing
  * `Problem Resport` - follows in case of some errors

## 1.1 Getting all pending messages

messageStatus - Using `MS-103` message status you can receive only pending messages.

### iOS
```objC
[sdkApi downloadMessages:@"MS-103"
        uid_s:nil
        pwdids:nil
        completion:^(NSError *error, NSString* messages) {
            // ...
        }];
```

### Android
    ```java
    String messages = UtilsApi.vcxGetMessages(MessageStatusType.PENDING, null, null).get();
    ```

## 1.1 Getting a specific message

* `messageStatus` - Using `MS-103` message status you can receive the only pending messages.
* `uid_s` - Identifier of the message received from a push notification (`uid` field from a push notification)
* `pwdids` - Identifier of connection to which the message relates to (`forDID` field from a push notification)

### iOS
```objC
[appDelegate.sdkApi downloadMessages:@"MS-103"
        uid_s:@"message uuid"
        pwdids:@"connectionDid"
        completion:^(NSError *error, NSString* messages) {
            // ...
        }];
```

## 2. Parsing result

Received `messages` string is an JSON array string containing the list of received messages for each particular connection:
* `pairwiseDID` - DID of a connection to which messages relate.
* `msgs` - the list of messages related to connection.

For each entry of `msgs` array, following fields should be noted:

* `uid` - UID of message, required to perform operations with message
* `type` - type of message. This field could contain different values depending on protocol used (See `me.connect.sdk.java.message.MessageType` for reference)
* `decryptedPayload` - message payload. It has different contents depending on message type and should be processed according to it. For reference see other parts of documentation.

Base message types (`type` field):

### Sample of a message received from the Cloud Agent

#### Pending proof request message
```json
[
    {
        "statusCode":"MS-103",
        "payload":"None",
        "senderDID":"Ch2Vk1ctZaPhMkYRs6Xipu",
        "uid":"5d8cbac5-4781-463a-b89e-ac82bf95aa2c",
        "type":"aries",
        "refMsgId":"None",
        "deliveryDetails":[
    
        ],
        "decryptedPayload":"{\"@msg\":\"{\\\"@id\\\":\\\"1315d726-582e-4a2b-af12-7bc0ee3473b5\\\",\\\"@type\\\":\\\"did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/present-proof/1.0/request-presentation\\\",\\\"comment\\\":\\\"proof_from_alice\\\",\\\"request_presentations~attach\\\":[{\\\"@id\\\":\\\"libindy-request-presentation-0\\\",\\\"data\\\":{\\\"base64\\\":\\\"eyJuYW1lIjoicHJvb2ZfZnJvbV9hbGljZSIsIm5vbl9yZXZva2VkIjpudWxsLCJub25jZSI6IjgyOTI3NTY5NjEwMzk4MDY2NTg5MjY4MSIsInJlcXVlc3RlZF9hdHRyaWJ1dGVzIjp7ImF0dHJpYnV0ZV8wIjp7Im5hbWUiOiJNZW1iZXJJRCJ9fSwicmVxdWVzdGVkX3ByZWRpY2F0ZXMiOnt9LCJ2ZXIiOiIxLjAiLCJ2ZXJzaW9uIjoiMS4wIn0=\\\"},\\\"mime-type\\\":\\\"application/json\\\"}]}\",\"@type\":{\"fmt\":\"json\",\"name\":\"presentation-request\",\"ver\":\"1.0\"}}"
    }
]
```

## 3. Process parsed message 

Iterate over received messages and apply them either to existing state objects or create a new one.  
1. The first loop goes over objects containing `pairwiseDID/msgs` pairs.
2. The nested loop goes over entries from `msgs` field.

## 4. Update message status as reviewed

After processing received messages you need to update their status on the Cloud Agent to avoid their repeatedly receiving and handling during the next downloads.

Parameters:
* `messageStatus` - desired message type, e.g. `"MS-106"` (reviewed)
* `handledMessage` - JSON string with following structure:
    ```json
    [
        {
            "pairwiseDID" : "pwDID", // DID of connection
             "uids": ["uid"] // list of UID's of processed messages related to the connection
        },
        ...
    ]
    ```

  ### iOS
  ```objC
  [appDelegate.sdkApi updateMessages:messageStatus
          pwdidsJson:handledMessage
          completion:^(NSError *error) {
              // ...
          }];
  ```
  
  ### Android
  ```java
  UtilsApi.vcxUpdateMessages(messageStatus, handledMessage).get()
  ```

## Examples

### Download pending messages

Following the links below you can find examples of functions that download, parse, and collect all pending messages.

* iOS - [downloadAllMessages](/examples/ios/VCXHelpers/CMMessage.m)
* Android - [getAllPendingMessages](/examples/android/MSDKSampleAppJava/lib/src/main/java/msdk/java/handlers/Messages.java)

### Update message status

Following the links below you can find examples of functions that updates status of messages.

* iOS - [updateMessageStatus](/examples/ios/VCXHelpers/CMMessage.m)
* Android - [updateMessageStatus](/examples/android/MSDKSampleAppJava/lib/src/main/java/msdk/java/handlers/Messages.java)

## Next Step

Congratulations! Now your application can download and process messages from a Cloud Agent.
You are ready to read how to [establish connections](5.Connections.md) with other parties.
