

# Getting started with Amazon Chime SDK messaging
Getting started

The topics in this section explain how to start building an Amazon Chime SDK messaging application.

**Topics**
+ [

# Creating an AppInstance for Amazon Chime SDK messaging
](create-app-instance.md)
+ [

# Making SDK calls from a back-end service for Amazon Chime SDK messaging
](call-from-backend.md)
+ [

# Authenticating end-user client applications for Amazon Chime SDK messaging
](auth-client-apps.md)
+ [

# Creating channels for Amazon Chime SDK messaging
](creating-channels.md)
+ [

# Sending messages in Amazon Chime SDK messaging
](send-messages.md)
+ [

# Using ExpirationSettings in Amazon Chime SDK messaging
](expiration.md)
+ [

# Using WebSockets to receive messages in Amazon Chime SDK messaging
](websockets.md)
+ [

# Configuring attachments in Amazon Chime SDK messaging
](configure-attachments.md)

# Creating an AppInstance for Amazon Chime SDK messaging
Creating an AppInstance

To use Amazon Chime SDK messaging, you must first create an Amazon Chime SDK `AppInstance` in your AWS account.

**Topics**
+ [

## Building an AppInstance
](#app-instance-steps)
+ [

## Creating an AppInstanceUser
](#create-app-instance-user)

## Building an AppInstance


**To create an `AppInstance` for messaging**

1. In the CLI, run `aws chime-sdk-identity create-app-instance --name NameOfAppInstance.`

1. In the create response, make note of the `AppInstanceArn`. `arn:aws:chime:region: aws_account_id:app-instance/app_instance_id`.

## Creating an AppInstanceUser


Once you create an `AppInstance`, you create an `AppInstanceUser` in that `AppInstance`. You typically do this when a user first registers or logs in to your app. You can also create an `AppInstanceUser` that acts on behalf of your back-end services.

The following example shows how to create a back-end `AppInstanceUser`:

```
aws chime-sdk-identity create-app-instance-user \
    --app-instance-arn "app_instance_arn" \
    --app-instance-user-id "back-end-worker" \
    --name "back-end-worker"
```

In the create response, note the `AppInstanceUserArn`. It takes this form: `arn:aws:chime:region: aws_account_id:app-instance/app_instance_id/user/app_instance_user_id`. In this example, `app_instance_user_id` is "back-end-worker."

**Note**  
As a best practice, when creating an `AppInstanceUser` for a client application, have the `AppInstanceUserId` match an existing unique ID for that user, such as the `sub` of an identity provider. The name is an optional placeholder that is attached to some API entities, such as a message sender. It allows you to control the display name of a user in one place, rather then needing to look it up from `AppInstanceUser` ARN, which is also attached as the sender of a message.

# Making SDK calls from a back-end service for Amazon Chime SDK messaging
Making SDK calls from a back-end service

Once you create a user to represent your back-end services, you create a channel, send messages to that channel, and read messages from that channel.

Run the following CLI command to create a public channel.

```
aws chime-sdk-messaging create-channel \
    --chime-bearer "app_instance_user_arn" \
    --app-instance-arn "app_instance_arn" \
    --name "firstChannel"
```

The command produces an ARN in this format: `arn:aws:chime:region:aws_account_id:app-instance/app_instance_id/channel/channel_id.`

**Topics**
+ [

## How IAM authorization works for back-end services
](#how-iam-works)
+ [

## Understanding implicit API authorization
](#api-implicit-auth)
+ [

## Sending and listing channel messages
](#send-list-msgs)

## How IAM authorization works for back-end services


In the CLI command from the previous section, note the `chime-bearer` parameter. It identifies the user that creates or interacts with resources such as channels and messages. Nearly all Amazon Chime SDK messaging APIs take `chime-bearer` as a parameter, except APIs meant to be called only by developers, such as `CreateAppInstance`.

The IAM permissions for Amazon Chime SDK messaging APIs require an `app-instance-user-arn `that matches the `chime-bearer` parameter. Additional ARNs—typically channel ARNs—might be required based on the API. For back-end services like the example above, this leads to IAM policies like the following example:

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": {
        "Effect": "Allow",
        "Action": [
            "chime:SendChannelMessage",
            "chime:ListChannelMessages",
            "chime:CreateChannelMembership",
            "chime:ListChannelMemberships",
            "chime:DeleteChannelMembership",
            "chime:CreateChannel",
            "chime:ListChannels",
            "chime:DeleteChannel"
        ],
        "Resource": [
            "arn:aws:chime:us-east-1:123456789012:app-instance/app_instance_id/user/back-end-worker",
            "arn:aws:chime:us-east-1:123456789012:app-instance/app_instance_id/channel/*"
        ]
    }
}
```

------

Note the `AppInstanceUser` ARN and channel ARN in the `Resource` section. This IAM policy example grants the back-end service permission to make API calls as the user with the ID of "back-end-worker." If you want your back-end service to be able to make calls for the people who use your app, change the `app_instance_user_arn` to `arn:aws:chime:region:aws_account_id:app-instance/app_instance_id/user/*`.

## Understanding implicit API authorization


In addition to IAM policies, the Amazon Chime SDK messaging APIs have implicit permissions. For example, an `AppInstanceUser` can only send a message or list a channel membership in channels to which the user belongs. One exception to this is an `AppInstanceUser` who was promoted to `AppInstanceAdmin`. By default, admins have permissions to all the channels in your app. For most use cases, you only need this for back-end services that contain significant business logic.

The following CLI command promotes a back-end user to an admin.

```
aws chime-sdk-identity create-app-instance-admin \
    --app-instance-admin-arn "app_instance_user_arn" \
    --app-instance-arn "app_instance_arn"
```

## Sending and listing channel messages


The following CLI command sends channel messages.

```
aws chime-sdk-messaging send-channel-message \
    --chime-bearer "app_instance_user_arn" \
    --channel-arn "channel_arn" \
    --content "hello world" \
    --type STANDARD \
    --persistence PERSISTENT
```

The following CLI commands list channel messages in reverse chronological order.
+ `aws chime list-channel-messages`
+ `aws chime-sdk-messaging list-channel-messages`

```
aws chime-sdk-messaging list-channel-messages \
    --chime-bearer "app_instance_user_arn" \
    --channel-arn "channel_arn"
```

# Authenticating end-user client applications for Amazon Chime SDK messaging
Authenticating end-user client applications

You can also run Amazon Chime SDK messaging from end-user client applications. [Making SDK calls from a back-end service for Amazon Chime SDK messaging](call-from-backend.md) explains how to make API calls such as create-channel, send-channel-message, and list-channel-messages. End user client applications such as browsers and mobile applications make these same API calls. Client applications can also connect via WebSocket to receive real time updates on messages and events to channels they are members of. This section covers how to give IAM credentials to a client application scoped to a specific app instance user. Once the end users have these credentials, they can make the API calls shown in [Making SDK calls from a back-end service for Amazon Chime SDK messaging](call-from-backend.md). To see a full demo of a client application, see [ https://github.com/aws-samples/amazon-chime-sdk/tree/main/apps/chat](https://github.com/aws-samples/amazon-chime-sdk/tree/main/apps/chat). For more information about receiving real-time messages from the channels that a client app belongs to, see [Using WebSockets to receive messages in Amazon Chime SDK messaging](websockets.md).

## Providing IAM credentials to end users


Amazon Chime SDK messaging integrates natively with AWS Identity and Access Management (IAM) policies to authenticate incoming requests. The IAM policy defines what an individual user can do. IAM policies can be crafted to provide scoped-down limited credentials for your use case. For more information on creating policies for Amazon Chime SDK messaging users, see [Example IAM roles for Amazon Chime SDK messaging](iam-roles.md).

If you have an existing identity provider, you have the following options for integrating your existing identity with Amazon Chime SDK messaging.
+ You can use your existing identity provider to authenticate users and then integrate the authentication service with AWS Security Token Service (STS) to create your own credential vending service for clients. STS provides APIs for assuming IAM Roles.
+ If you already have a SAML or OpenID compatible identity provider, we recommend using Amazon [Cognito Identity Pools](https://docs.aws.amazon.com/cognito/latest/developerguide/identity-pools.html), which abstract away calls to AWS STS [https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRoleWithSAML.html](https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRoleWithSAML.html) and [https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRoleWithWebIdentity.html](https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRoleWithWebIdentity.html). Amazon Cognito integrates with OpenID, SAML, and public identity providers such as Facebook, Login with Amazon, Google, and Sign in with Apple.

If you do not have an identity provider, you can get started with Amazon Cognito User Pools. For an example of how to use Amazon Cognito with the Amazon Chime SDK messaging features, see [ Build chat features into your application with Amazon Chime SDK messaging](https://aws.amazon.com/blogs/business-productivity/build-chat-features-into-your-application-with-amazon-chime-sdk-messaging/). 

Alternately, you can use the [AWS STS](https://docs.aws.amazon.com/STS/latest/APIReference/welcome.html) to create your own credential vending service or build your own identity provider.

**Using STS to vend credentials**  
If you already have an IDP such as ActiveDirectory LDAP, and you want to implement a custom credential vending service, or grant access to chat for non-authenticated meeting attendees, you can use the [AWS STS AssumeRole API](https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html). To do this, you first create an Amazon Chime SDK messaging SDK Role. For more information about creating that role, see [ Creating a role to delegate permissions to an IAM user ](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-user.html).

The IAM role would have permissions to the Amazon Chime SDK messaging action your application would use, similar to the following:

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "chime:GetMessagingSessionEndpoint"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "chime:SendChannelMessage",
                "chime:ListChannelMessages",
                "chime:CreateChannelMembership",
                "chime:ListChannelMemberships",
                "chime:DeleteChannelMembership",
                "chime:CreateChannelModerator",
                "chime:ListChannelModerators",
                "chime:DescribeChannelModerator",
                "chime:CreateChannel",
                "chime:DescribeChannel",
                "chime:ListChannels",
                "chime:DeleteChannel",
                "chime:RedactChannelMessage",
                "chime:UpdateChannelMessage",
                "chime:Connect",
                "chime:ListChannelBans",
                "chime:CreateChannelBan",
                "chime:DeleteChannelBan",
                "chime:ListChannelMembershipsForAppInstanceUser",
                "chime:AssociateChannelFlow",
                "chime:DisassociateChannelFlow",
                "chime:GetChannelMessageStatus"
            ],
            "Resource": [
            "arn:aws:chime:us-east-1:123456789012:app-instance/app_instance_id/user/my_applications_user_id",
            "arn:aws:chime:us-east-1:123456789012:app-instance/app_instance_id/channel/*"
    ]
        }
    ]
}
```

------

For this example, call this role the *ChimeMessagingSampleAppUserRole*.

Note the session tag in the *ChimeMessagingSampleAppUserRole* policy `${my_application_user_id}` in the user ARN resource. This session tag is parameterized in the [https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html](https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html) API call to limit the credentials returned to permissions for a single user.

The [https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html](https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html) and [https://docs.aws.amazon.com/STS/latest/APIReference/API_TagSesstion.html](https://docs.aws.amazon.com/STS/latest/APIReference/API_TagSesstion.html) APIs are called using an already credentialed IAM entity, such as an IAM user. The APIs can also be called by a different IAM role such as an [AWS Lambda run role](https://docs.aws.amazon.com/lambda/latest/dg/lambda-intro-execution-role.html). That IAM identity must have permissions to call `AssumeRole` and `TagSession` on the *ChimeMessagingSampleAppUserRole*. 

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
         {
            "Effect": "Allow",
            "Action": [ 
                "sts:AssumeRole",
                "sts:TagSession"
                ],
            "Resource": "arn:aws:iam::123456789012:role/ChimeMessagingSampleAppUserRole"
        }
    ]
}
```

------

 For this example, call this role the *ChimeSampleAppServerRole*.

You need to set up the `ChimeMessagingSampleAppUserRole` with a trust policy that allows the `ChimeMessagingSampleAppServerRole` to call the [STS AssumeRole API](https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html) on it. For more information about using trust policies with IAM roles, see [ How to use trust policies with IAM roles ](https://aws.amazon.com/blogs/security/how-to-use-trust-policies-with-iam-roles/). You can use the AWS IAM Roles Console to add this policy to the `ChimeMessagingSampleAppUserRole`. The following example shows a typical trust relationship.

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::123456789012:role/ChimeMessagingSampleAppServerRole"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}
```

------

 In a sample deployment, an [Amazon EC2](https://aws.amazon.com/ec2/) instance, or an AWS Lambda is launched with the `ChimeMessagingSampleAppServerRole`. The server then:

1. Performs any application specific authorization on a client's requests to receive credentials.

1. Calls STS `AssumeRole` on `ChimeMessagingSampleAppUserRole`, with a tag parameterizing the `${aws:PrincipalTag/my_applications_user_id}`.

1. Forwards the credentials returned in the `AssumeRole` call to the user.

The following example shows CLI command for assuming a role for step 2:

`aws sts assume-role --role-arn arn:aws:iam::my_aws_account_id:role/ChimeMessagingSampleAppUserRole --role-session-name demo --tags Key=my_applications_user_id,Value=123456789 ` 

# Creating channels for Amazon Chime SDK messaging
Creating channels

You and your end users can create channels. Once created, you or your end users also need to add members to the channel. Sample code for creating channels is available in the [sample application on GitHub](https://github.com/aws-samples/amazon-chime-sdk/tree/main/apps/chat).

For more information on creating channels and adding members, see:
+  [https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_messaging-chime_CreateChannel.html](https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_messaging-chime_CreateChannel.html) 
+  [https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_messaging-chime_CreateChannelMembership.html](https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_messaging-chime_CreateChannelMembership.html) 

# Sending messages in Amazon Chime SDK messaging
Sending messages

Use the [https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_messaging-chime_SendChannelMessage.html](https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_messaging-chime_SendChannelMessage.html) API to send messages. Sample code is available in a [sample application on GitHub](https://github.com/aws-samples/amazon-chime-sdk/tree/main/apps/chat). 

# Using ExpirationSettings in Amazon Chime SDK messaging
Using ExpirationSettings

When you create an `AppInstanceUser` or a `Channel`, you can use `ExpirationSettings` to configure those resources for automatic deletion. `ExpirationSettings` helps reduce storage costs and prevent resource-limit-exceeded issues. For example, you can delete unused channels after 7 days, or delete an `AppInstanceUser` that was only invoked for testing purposes.

For an `AppInstanceUser`, you specify the expiration period based on user creation time. For a `Channel`, you specify the expiration period based on the channel's creation time, or last message time. The latter allows you use message activities to customize automatic deletion.

**Important**  
Shortly after a resource expires, `ExpirationSettings` starts a background process to delete that resource. The process usually takes 6 hours, but that time can vary.  
Expired `AppInstanceUsers` and `Channels` that haven’t yet been deleted still appear as valid and active. You can update or remove their expiration settings, and the system honors your changes.

**Topics**
+ [

## Configuring ExpirationSettings
](#create-expiration)
+ [

## AWS CloudTrail events for expired resource deletion
](#ct-events)

## Configuring ExpirationSettings


The following sections explain how to configure the `ExpirationSettings` of an `AppInstanceUser` or a `Channel`. 

### Configuring ExpirationSettings when you create a resource


You can configure `ExpirationSettings` when you run the [https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_messaging-chime_CreateAppInstanceUser.html](https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_messaging-chime_CreateAppInstanceUser.html) or [https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_messaging-chime_CreateChannel.html](https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_messaging-chime_CreateChannel.html) APIs. If you set the `ExpirationSettings` parameter, you must grant the following IAM permissions:
+ `chime:PutAppInstanceUserExpirationSettings` when creating an `AppInstanceUser`
+ `chime:PutChannelExpirationSettings` when creating a `Channel`.

The following example uses the AWS CLI to create an `AppInstanceUser` that expires after a day.

```
aws chime-sdk-identity create-app-instance-user \
--app-instance-arn "app_instance_arn" \
--app-instance-user-id "backend-worker" \
--name "backend-worker" \
--expiration-settings '{
            "ExpirationDays": 1,
            "ExpirationCriterion": "CREATED_TIMESTAMP"
        }'
```

The following example uses the AWS CLI to create a `Channel` that expires after a day after it last receives a message.

```
aws chime-sdk-messaging create-channel \
--chime-bearer "app_instance_user_arn" \
--app-instance-arn "app_instance_arn" \
--name "firstChannel" \
--expiration-settings '{
            "ExpirationDays": 1,
            "ExpirationCriterion": "LAST_MESSAGE_TIMESTAMP"
        }'
```

### Using Put APIs to configure ExpirationSettings


You can also use the [https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_PutAppInstanceUserExpirationSettings.html](https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_PutAppInstanceUserExpirationSettings.html) and [https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_messaging-chime_PutChannelExpirationSettings.html](https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_messaging-chime_PutChannelExpirationSettings.html) APIs to create, update, and delete `ExpirationSettings`. 

The following example shows you to use the AWS CLI to update an `AppInstanceUser`'s `ExpirationSettings`.

```
aws chime-sdk-identity put-app-instance-user-expiration-settings \
--app-instance-user-arn "app_instance_user_arn" \
--expiration-settings '{
            "ExpirationDays": 30,
            "ExpirationCriterion": "CREATED_TIMESTAMP"
        }'
```

The following example shows you to use the AWS CLI to delete a channel's `ExpirationSettings`.

```
aws chime-sdk-messaging put-channel-expiration-settings \
--chime-bearer "app_instance_user_arn" \
--channel-arn "channel_arn"
```

## AWS CloudTrail events for expired resource deletion


After the system deletes an expired resource, it sends an `ExpireAppInstanceUser` or `ExpireChannel` event to AWS CloudTrail. The type of event depends on the type of deleted asset.

The following example shows an `AppInstanceUser` event.

```
{
    "eventVersion": "1.08",
    "userIdentity": {
        "accountId": "123456789012",
        "invokedBy": "chime.amazonaws.com"
    },
    "eventTime": "2023-03-15T00:00:00Z",
    "eventSource": "chime.amazonaws.com",
    "eventName": "ExpireAppInstanceUser",
    "awsRegion": "us-east-1",
    "sourceIPAddress": "chime.amazonaws.com",
    "userAgent": "chime.amazonaws.com",
    "requestParameters": null,
    "responseElements": null,
    "eventID": "12345678-1234-1234-1234-123456789012",
    "readOnly": false,
    "resources": [
        {
            "accountId": "123456789012",
            "type": "AWS::Chime::AppInstanceUser",
            "ARN": "arn:aws:chime:us-east-1:123456789012:app-instance/app-instance-id/user/user-id"
        }
    ],
    "eventType": "AwsServiceEvent",
    "managementEvent": true,
    "recipientAccountId": "123456789012",
    "serviceEventDetails": {
        "reason": "AppInstanceUser deleted due to expiration settings."
    },
    "eventCategory": "Management"
}
```

# Using WebSockets to receive messages in Amazon Chime SDK messaging
Using WebSockets to receive messages

 You can use the [Amazon Chime JS SDK](https://github.com/aws/amazon-chime-sdk-js) to receive messages using WebSockets, or you can use the WebSocket client library of your choice.

Follow these topics in the order listed to start using WebSockets:

**Topics**
+ [

## Defining an IAM policy
](#define-iam-policy)
+ [

## Retrieving the endpoint
](#retrieve-endpoint)
+ [

## Establishing the connection
](#connect-api)
+ [

## Using prefetch to deliver channel details
](#prefetch)
+ [

## Processing the events
](#process-events)

## Defining an IAM policy


To start, define an IAM policy that gives you permission to establish a WebSocket connection. The following example policy gives an `AppInstanceUser` permission to establish a WebSocket connection.

```
"Version": "2012-10-17",		 	 	 
"Statement": [
  {
    "Effect": "Allow",
    "Action: [
      "chime:Connect"
    ],
    "Resource": [
      "arn:aws:chime:region:{aws_account_id}:app-instance/{app_instance_id}/user/{app_instance_user_id}"
    ]
 },
 {
    "Effect": "Allow",
    "Action: [
      "chime:GetMessagingSessionEndpoint"
    ],
    "Resource": [
      "*"
    ]
 }
 ]
}
```

## Retrieving the endpoint


The following steps explain how to retrieve the endpoint used in a WebSocket connection.

1. Use the [https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_messaging-chime_GetMessagingSessionEndpoint.html](https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_messaging-chime_GetMessagingSessionEndpoint.html) API to retrieve the WebSocket endpoint. 

1. Use the URL returned by the [https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_messaging-chime_GetMessagingSessionEndpoint.html](https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_messaging-chime_GetMessagingSessionEndpoint.html) API to construct a Signature Version 4 Signed WebSocket URL. If you need help doing that, you can follow directions in the [Establishing the connection](#connect-api).
**Note**  
WebSocket URLs have the following form: `id.region.ws-messaging.chime.aws`

## Establishing the connection


 After you retrieve an endpoint, you use the connect API to establish a WebSocket connection to the Amazon Chime SDK back-end server and receive messages for an `AppInstanceUser`. You must use AWS Signature Version 4 to sign requests. For more information about signing a request, see [Signing AWS Requests with Signature Version 4](https://docs.aws.amazon.com/general/latest/gr/Signature Version 4_signing.html).

**Note**  
To retrieve the endpoint, you can invoke the [https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_messaging-chime_GetMessagingSessionEndpoint.html](https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_messaging-chime_GetMessagingSessionEndpoint.html) API. You can use the WebSocket client library of your choice to connect to the endpoint.

**Request Syntax**

```
GET /connect
?X-Amz-Algorithm=AWS4-HMAC-SHA256
&X-Amz-Credential=AKIARALLEXAMPLE%2F20201214%2Fregion%2Fchime%2Faws4_request
&X-Amz-Date=20201214T171359Z
&X-Amz-Expires=10
&X-Amz-SignedHeaders=host
&sessionId={sessionId}
&userArn={appInstanceUserArn}
&X-Amz-Signature=db75397d79583EXAMPLE
```

**URI Request Parameters**

All URI Request Query Parameters must be URL Encoded.

**X-Amz-Algorithm**

Identifies the version of AWS Signature and the algorithm that you used to calculate the signature. The Amazon Chime SDK supports only AWS Signature Version 4 authentication, so the value of this is `AWS4-HMAC-SHA256`.

**X-Amz-Credential**

In addition to your access key ID, this parameter also provides the AWS Region and service—the scope—for which the signature is valid. This value must match the scope you use in signature calculations. The general form for this parameter value is:

`<yourAccessKeyId>/<date>/<awsRegion>/<awsService >/aws4_request`

For example:

`AKIAIOSFODNN7EXAMPLE/20201214/us-east-1/chime/aws4_request`

**X-Amz-Date**

The date and time format must follow the ISO 8601 standard, and you must format it as `yyyyMMddTHHmmssZ`. For example, you must convert **08/01/2020 15:32:41.982-700** to Coordinated Universal Time (UTC) and submit it as `20200801T083241Z`.

**X-Amz-Signed-Headers**

Lists the headers that you used to calculate the signature. The following headers are required in the signature calculations:
+ The HTTP host header.
+ Any x-amz-\$1 headers that you plan to add to the request.

**Note**  
For added security, sign all the request headers that you plan to include in your request.

**X-Amz-Signatures**

Provides the signature to authenticate your request. This signature must match the signature that Amazon Chime SDK calculates. If it doesn't, Amazon Chime SDK denies the request. For example, `733255ef022bec3f2a8701cd61d4b371f3f28c9f19EXAMPLEd48d5193d7`.

**X-Amz-Security-Token**

Optional credential parameter if using credentials sourced from the Security Token Service. For more information about the service, see the [https://docs.aws.amazon.com/STS/latest/APIReference/](https://docs.aws.amazon.com/STS/latest/APIReference/welcome.html).

**SessionId**

Indicates a unique Id for the WebSocket connection being established.

**UserArn**

Indicates the identity of the `AppInstanceUser` trying to establish a connection. The value should be the ARN of the `AppInstanceUser`. For example, `arn:aws:chime:us%2Deast%2D1:123456789012:app%2Dinstance/694d2099%2Dcb1e%2D463e%2D9d64%2D697ff5b8950e/user/johndoe` 

## Using prefetch to deliver channel details
Using prefetch

When you establish a WebSocket connection, you can specify `prefetch-on=connect` in your query parameters to deliver `CHANNEL_DETAILS` events. The prefetch feature comes with the connect API, and the feature enables users to see an enriched chat view without extra API calls. Users can:
+ See a preview of the last channel message, plus its timestamp.
+ See the members of a channel.
+ See a channel's unread markers.

After a user connects with the prefetch parameter specified, the user receives the session established event, which indicates the connection has been established. The user then receives up to 50 `CHANNEL_DETAILS` events. If the user has less than 50 channels, the connect API prefetches all channels via `CHANNEL_DETAILS` events. If user has more than 50 channels, the API prefetches the top 50 channels that contain unread messages and the latest `LastMessageTimestamp` values. The `CHANNEL_DETAILS` events arrive in random order, and you receive events for all 50 channels.

Also, prefetch returns the following for `ChannelMessages` and `ChannelMemberships`:
+ **ChannelMessages** – List of [https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_messaging-chime_ChannelMessageSummary.html](https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_messaging-chime_ChannelMessageSummary.html) objects, ordered by `CreatedTimestamp` in descending order. Only includes the latest 20 messages visible to the user. If there are targeted messages in the channel that are not visible to the current user, then less than 20 messages might be returned. The `ChannelMessagesHasMore` boolean will be set to true to indicate there are more messages. Soft limit, adjustable at the AWS account level.
+ **ChannelMemberships** – List of [https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_messaging-chime_ChannelMembershipSummary.html](https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_messaging-chime_ChannelMembershipSummary.html) objects. Includes a maximum of 30 channel members. Soft limit, adjustable at AWS account level.

This example shows how to use `prefetch-on=connect`.

```
GET /connect
?X-Amz-Algorithm=AWS4-HMAC-SHA256
&X-Amz-Credential=AKIARALLEXAMPLE%2F20201214%2Fregion%2Fchime%2Faws4_request
&X-Amz-Date=20201214T171359Z
&X-Amz-Expires=10
&X-Amz-SignedHeaders=host
&sessionId=sessionId
&prefetch-on=connect
&userArn=appInstanceUserArn
&X-Amz-Signature=db75397d79583EXAMPLE
```

This example shows the response for one channel. You will receive responses for all 50 channels.

```
{
   "Headers": { 
        "x-amz-chime-event-type": "CHANNEL_DETAILS", 
        "x-amz-chime-message-type": "SYSTEM" 
        },
   "Payload": JSON.stringify"({
        Channel: [https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_messaging-chime_ChannelSummary.html](https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_messaging-chime_ChannelSummary.html) 
        ChannelMessages: List of [https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_messaging-chime_ChannelMessageSummary.html](https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_messaging-chime_ChannelMessageSummary.html)  
        ChannelMemberships: List of [https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_messaging-chime_ChannelMembershipSummary.html ](https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_messaging-chime_ChannelMembershipSummary.html )
        ReadMarkerTimestamp: Timestamp 
        ChannelMessagesHasMore: Boolean 
    })
}
```

## Processing the events


For an `AppInstanceUser` to receive messages after they establish a connection, you must add them to a channel. To do that, use the [https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_messaging-chime_CreateChannelMembership.html](https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_messaging-chime_CreateChannelMembership.html) API.

**Note**  
An `AppInstanceUser` always receives messages for all channels that they belong to. Messaging stops when the `AppInstance` user disconnects.

An `AppInstanceAdmin` and a `ChannelModerator` do not receive messages on a channel unless you use the [https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_messaging-chime_CreateChannelMembership.html](https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_messaging-chime_CreateChannelMembership.html) API to explicitly add them.

The following topics explain how to process events.

**Topics**
+ [

### Understanding message structures
](#message-structures)
+ [

### Handling disconnects
](#handle-disconnects)

### Understanding message structures


Every WebSocket message that you receive adheres to this format:

```
{
   "Headers": {"key": "value"},
   "Payload": "{\"key\": \"value\"}"
}
```

**Headers**  
Amazon Chime SDK messaging use the following header keys:
+ `x-amz-chime-event-type`
+ `x-amz-chime-message-type`
+ `x-amz-chime-event-reason`

The next section lists and describes the header's possible values and payloads.

**Payload**  
Websocket messages return JSON strings. The structure of the JSON strings depends on the `x-amz-event-type` headers. The following table lists the possible `x-amz-chime-event-type` values and payloads:

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/chime-sdk/latest/dg/websockets.html)

**x-amz-chime-message-type**  
The following table lists the `x-amz-chime-message-type` message types .


| Message type | Description | 
| --- | --- | 
| `STANDARD` | Sent when the websocket receives a STANDARD channel message. | 
| `CONTROL` | Sent when the WebSocket receives a CONTROL channel message. | 
| `SYSTEM` | All other websocket messages sent by Amazon Chime SDK Messaging. | 

**x-amz-chime-event-reason**  
This is an optional header supported for a specific use case. The header provides information about why a specific event was received.


| Event reason | Description | 
| --- | --- | 
| subchannel\$1DELETED | `DELETE_CHANNEL_MEMBERSHIP` events received by elastic channel moderators. Only seen by moderators after membership balancing deletes a sub-channel that they belonged to. | 

### Handling disconnects


Websockets can disconnect due to changes in network connectivity, or when credentials expire. After you open a WebSocket, the Amazon Chime SDK sends regular pings to the messaging client to ensure it is still connected. If the connection closes, the client receives a WebSocket close code. The client can try to reconnect, or not, depending on the close code. The following tables show the close codes that the client can use to reconnect.

For 1000 to 4000 closure codes, reconnect only for the following messages:


| Closure codes | Can reconnect | Reason | 
| --- | --- | --- | 
| 1001 | Yes | Normal closure | 
| 1006 | Yes | Abnormal closure | 
| 1011 | Yes | Internal server error | 
| 1012 | Yes | Service restart | 
| 1013 | Yes | Try again later | 
| 1014 | Yes | The server was acting as a gateway or proxy and received an invalid response from the upstream server. This is similar to the 502 HTTP Status Code. | 

For 4XXX codes, always reconnect *except* for the following messages:


| Closure codes | Can reconnect | Reason | 
| --- | --- | --- | 
| 4002 | No | Client initiated | 
| 4003 | No | Forbidden | 
| 4401 | No | Not authorized | 

When the application uses a close code to reconnect, the application should:

1. Call the [https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_messaging-chime_GetMessagingSessionEndpoint.html](https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_messaging-chime_GetMessagingSessionEndpoint.html) API again to obtain a new base URL. 

1. Refresh the IAM credentials if they've expired.

1. Connect via the WebSocket. 

If you use the amazon-chime-sdk-js library, this is handled for you if you implement the [needsRefresh()](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Credentials.html#needsRefresh-property) property and the [refresh()](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Credentials.html#refresh-property) method. For a working example, see [https://github.com/aws-samples/amazon-chime-sdk/blob/dc11c4c76c78d28f618577706bba2087919a5635/apps/chat/src/providers/AuthProvider.jsx\$1L93-L101](https://github.com/aws-samples/amazon-chime-sdk/blob/dc11c4c76c78d28f618577706bba2087919a5635/apps/chat/src/providers/AuthProvider.jsx#L93-L101).

# Configuring attachments in Amazon Chime SDK messaging
Configuring attachments

The Amazon Chime SDK allows you to use your own storage for message attachments, and include them as message metadata. Amazon Simple Storage Service (S3) is the easiest way to get started with attachments.

**To use S3 for attachments**

1. Create an S3 bucket to store attachments.

1. Create an IAM policy for the bucket that allows Amazon Chime SDK users to upload, download, and delete attachments from your S3 bucket.

1. Create an IAM role for use by your Identity provider to vend credentials to users for attachments.

The [sample application](https://github.com/aws-samples/amazon-chime-sdk/tree/main/apps/chat) provides an example of how to do this with Amazon S3, Amazon Cognito, and the Amazon Chime SDK.