{
"Sid": "AllowStreamProdAccount",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::185583345998:root"
},
"Action": "SQS:SendMessage",
"Resource": "arn:aws:sqs:us-west-2:1111111111:customer-sqs-for-stream"
}
SQS
Stream can send payloads of all events from your application to an Amazon SQS queue you own.
A chat application with a lot of users generates a lots of events. With a standard Webhook configuration, events are posted to your server and can overwhelm unprepared servers during high-use periods. While the server is out, it will not be able to receive Webhooks and will fail to process them. One way to avoid this issue is to use Stream Chat’s support for sending webhooks to Amazon SQS.
SQS removes the chance of losing data for Chat events by providing a large, scalable bucket that holds events generated by Stream Chat in a queue for your server or other .
The complete list of supported events is identical to those sent through webhooks and can be found on the Events page.
Configuration
You can configure your SQS queue through the Stream Dashboard or using the Dashboard or programmatically using the REST API or an SDK with Server Side Authorization.
There are 2 ways to configure authentication on your SQS queue:
By providing a key and secret
Or by having Stream’s AWS account assume a role on your SQS queue. With this option you omit the key and secret, but instead you set up a resource-based policy to grant Stream SendMessage permission on your SQS queue. The following policy needs to be attached to your queue (replace the value of Resource with the fully qualified ARN of your queue):
Using the Dashboard
- Go to the Stream Dashboard
- Select your app
- Navigate to your app’s settings until “Webhook & Event Configuration” section
- Click on “Add Integration”
- Add and configure SQS hook
At this point, you can click Test SQS to have Stream’s servers test their connection with SQS and report back.
Using Server-Side SDKs
To configure an SQS queue, use the event_hooks
array and Update App Settings method:
// Note: Any previously existing hooks not included in event_hooks array will be deleted.
// Get current settings first to preserve your existing configuration.
// STEP 1: Get current app settings to preserve existing hooks
const response = await client.getAppSettings();
console.log("Current event hooks:", response.event_hooks);
// STEP 2: Add SQS hook while preserving existing hooks
const existingHooks = response.event_hooks || [];
const newSQSHook = {
enabled: true,
hook_type: "sqs",
sqs_queue_url: "https://sqs.us-east-1.amazonaws.com/123456789012/MyQueue",
sqs_region: "us-east-1",
sqs_auth_type: "keys", // or "resource" for role-based auth
sqs_key: "yourkey",
sqs_secret: "yoursecret",
event_types: [], // empty array = all events
};
// STEP 3: Update with complete array including existing hooks
await client.updateAppSettings({
event_hooks: [...existingHooks, newSQSHook],
});
// Test the SQS connection
await client.testSQSSettings();
# Note: Any previously existing hooks not included in event_hooks array will be deleted.
# Get current settings first to preserve your existing configuration.
# STEP 1: Get current app settings to preserve existing hooks
response = client.get_app_settings()
existing_hooks = response.get("event_hooks", [])
print("Current event hooks:", existing_hooks)
# STEP 2: Add SQS hook while preserving existing hooks
new_sqs_hook = {
"enabled": True,
"hook_type": "sqs",
"sqs_queue_url": "https://sqs.us-east-1.amazonaws.com/123456789012/MyQueue",
"sqs_region": "us-east-1",
"sqs_auth_type": "keys", # or "resource" for role-based auth
"sqs_key": "yourkey",
"sqs_secret": "yoursecret",
"event_types": [] # empty array = all events
}
# STEP 3: Update with complete array including existing hooks
client.update_app_settings(
event_hooks=existing_hooks + [new_sqs_hook]
)
# Test the SQS connection
client.check_sqs("yourkey", "yoursecret", "https://sqs.us-east-1.amazonaws.com/123456789012/MyQueue")
# Note: Any previously existing hooks not included in event_hooks array will be deleted.
# Get current settings first to preserve your existing configuration.
# STEP 1: Get current app settings to preserve existing hooks
response = client.get_app_settings
existing_hooks = response["event_hooks"] || []
puts "Current event hooks:", existing_hooks
# STEP 2: Add SQS hook while preserving existing hooks
new_sqs_hook = {
"enabled" => true,
"hook_type" => "sqs",
"sqs_queue_url" => "https://sqs.us-east-1.amazonaws.com/123456789012/MyQueue",
"sqs_region" => "us-east-1",
"sqs_auth_type" => "keys", # or "resource" for role-based auth
"sqs_key" => "yourkey",
"sqs_secret" => "yoursecret",
"event_types" => [] # empty array = all events
}
# STEP 3: Update with complete array including existing hooks
client.update_app_settings(
event_hooks: existing_hooks + [new_sqs_hook]
)
# Test the SQS connection
client.check_sqs('yourkey', 'yoursecret', 'https://sqs.us-east-1.amazonaws.com/123456789012/MyQueue')
// Note: Any previously existing hooks not included in event_hooks array will be deleted.
// Get current settings first to preserve your existing configuration.
// STEP 1: Get current app settings to preserve existing hooks
$response = $client->getAppSettings();
$existingHooks = $response['event_hooks'] ?? [];
echo "Current event hooks: " . json_encode($existingHooks);
// STEP 2: Add SQS hook while preserving existing hooks
$newSQSHook = [
'enabled' => true,
'hook_type' => 'sqs',
'sqs_queue_url' => 'https://sqs.us-east-1.amazonaws.com/123456789012/MyQueue',
'sqs_region' => 'us-east-1',
'sqs_auth_type' => 'keys', // or 'resource' for role-based auth
'sqs_key' => 'yourkey',
'sqs_secret' => 'yoursecret',
'event_types' => [] // empty array = all events
];
// STEP 3: Update with complete array including existing hooks
$client->updateAppSettings([
'event_hooks' => array_merge($existingHooks, [$newSQSHook])
]);
// Test the SQS connection
$client->checkSqs([
'sqs_queue_url' => 'https://sqs.us-east-1.amazonaws.com/123456789012/MyQueue',
'sqs_key' => 'yourkey',
'sqs_secret' => 'yoursecret'
]);
// Note: Any previously existing hooks not included in event_hooks array will be deleted.
// Get current settings first to preserve your existing configuration.
// STEP 1: Get current app settings to preserve existing hooks
settings, err := client.GetAppSettings(ctx)
if err != nil {
log.Fatal(err)
}
existingHooks := settings.App.EventHooks
fmt.Printf("Current event hooks: %+v\n", existingHooks)
// STEP 2: Add SQS hook while preserving existing hooks
newSQSHook := EventHook{
HookType: SQSHook,
Enabled: true,
EventTypes: []string{}, // empty slice = all events
SQSQueueURL: "https://sqs.us-east-1.amazonaws.com/123456789012/MyQueue",
SQSRegion: "us-east-1",
SQSAuthType: "keys", // or "resource" for role-based auth
SQSKey: "yourkey",
SQSSecret: "yoursecret",
}
// STEP 3: Update with complete array including existing hooks
allHooks := append(existingHooks, newSQSHook)
_, err = client.UpdateAppSettings(ctx, NewAppSettings().SetEventHooks(allHooks))
if err != nil {
log.Fatal(err)
}
// Test the SQS connection
req := &CheckSQSRequest{
SqsURL: "https://sqs.us-east-1.amazonaws.com/123456789012/MyQueue",
SqsKey: "yourkey",
SqsSecret: "yoursecret",
}
client.CheckSqs(ctx, req)
// Note: Any previously existing hooks not included in event_hooks array will be deleted.
// Get current settings first to preserve your existing configuration.
// STEP 1: Get current app settings to preserve existing hooks
App.AppGetResponse response = App.get().request();
List<App.EventHook> existingHooks = response.getApp().getEventHooks();
System.out.println("Current event hooks: " + existingHooks);
// STEP 2: Add SQS hook while preserving existing hooks
App.EventHook newSQSHook = new App.EventHook();
newSQSHook.setHookType(App.HookType.SQS);
newSQSHook.setEnabled(true);
newSQSHook.setEventTypes(Collections.emptyList()); // empty list = all events
newSQSHook.setSqsQueueURL("https://sqs.us-east-1.amazonaws.com/123456789012/MyQueue");
newSQSHook.setSqsRegion("us-east-1");
newSQSHook.setSqsAuthType(App.AuthType.KEYS); // or RESOURCE for role-based auth
newSQSHook.setSqsKey("yourkey");
newSQSHook.setSqsSecret("yoursecret");
// STEP 3: Update with complete array including existing hooks
List<App.EventHook> allHooks = new ArrayList<>(existingHooks);
allHooks.add(newSQSHook);
App.update().eventHooks(allHooks).request();
// Test the SQS connection
App.checkSqs()
.sqsKey("yourkey")
.sqsSecret("yoursecret")
.sqsUrl("https://sqs.us-east-1.amazonaws.com/123456789012/MyQueue")
.request();
// Note: Any previously existing hooks not included in event_hooks array will be deleted.
// Get current settings first to preserve your existing configuration.
// STEP 1: Get current app settings to preserve existing hooks
var settings = await client.GetAppSettingsAsync();
var existingHooks = settings.App.EventHooks ?? new List<EventHook>();
Console.WriteLine($"Current event hooks: {existingHooks}");
// STEP 2: Add SQS hook while preserving existing hooks
var newSQSHook = new EventHook
{
HookType = HookType.SQS,
Enabled = true,
EventTypes = new List<string>(), // empty list = all events
SqsQueueUrl = "https://sqs.us-east-1.amazonaws.com/123456789012/MyQueue",
SqsRegion = "us-east-1",
SqsAuthType = AuthType.Keys, // or Resource for role-based auth
SqsKey = "yourkey",
SqsSecret = "yoursecret"
};
// STEP 3: Update with complete array including existing hooks
var allHooks = new List<EventHook>(existingHooks) { newSQSHook };
await client.UpdateAppSettingsAsync(new AppSettingsRequest
{
EventHooks = allHooks
});
// Test the SQS connection
await appClient.CheckSqsPushAsync(new AppCheckSqsRequest
{
SqsKey = "yourkey",
SqsSecret = "yoursecret",
SqsUrl = "https://sqs.us-east-1.amazonaws.com/123456789012/MyQueue",
});
See the Multi-Event Hooks documentation for complete details.
SQS Permissions
Stream needs the right permissions on your SQS queue to be able to send events to it. If updates are not showing up in your queue add the following permission policy to the queue:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1459523779000",
"Effect": "Allow",
"Action": [
"sqs:GetQueueUrl",
"sqs:SendMessage",
"sqs:SendMessageBatch",
"sqs:GetQueueAttributes"
],
"Resource": ["arn:aws:sqs:region:acc_id:queue_name"]
}
]
}
Here’s an example list of messages read from your SQS queue:
{
"type": "message.new",
"cid": "messaging:fun-d5f396e3-fbaf-469c-9b45-8837b4f75baa",
"message": {
"id": "8bffc454-e1da-4d91-8b88-a87853dfb41c",
"text": "Welcome to the Community!",
"html": "<p>Welcome to the Community!</p>\n",
"type": "regular",
"user": {
"id": "tommaso-52ec3a5f-e916-469f-bf54-b53b5247a4b0",
"role": "user",
"created_at": "2020-03-30T07:54:46.207332Z",
"updated_at": "2020-03-30T07:54:46.207719Z",
"banned": false,
"online": false
},
"attachments": [],
"latest_reactions": [],
"own_reactions": [],
"reaction_counts": null,
"reaction_scores": {},
"reply_count": 0,
"created_at": "2020-03-30T07:54:46.277381Z",
"updated_at": "2020-03-30T07:54:46.277382Z",
"mentioned_users": []
},
"user": {
"id": "tommaso-52ec3a5f-e916-469f-bf54-b53b5247a4b0",
"role": "user",
"created_at": "2020-03-30T07:54:46.207332Z",
"updated_at": "2020-03-30T07:54:46.207719Z",
"banned": false,
"online": false,
"channel_unread_count": 0,
"channel_last_read_at": "2020-03-30T07:54:46.270208768Z",
"total_unread_count": 0,
"unread_channels": 0,
"unread_count": 0
},
"created_at": "2020-03-30T07:54:46.295138Z",
"members": [
{
"user_id": "thierry-735d0d44-8bf1-40df-81db-fa83363ac790",
"user": {
"id": "tommaso-52ec3a5f-e916-469f-bf54-b53b5247a4b0",
"role": "user",
"created_at": "2020-03-30T07:54:46.207332Z",
"updated_at": "2020-03-30T07:54:46.207719Z",
"banned": false,
"online": false
},
"created_at": "2020-03-30T07:54:46.255628Z",
"updated_at": "2020-03-30T07:54:46.255628Z"
}
],
"channel_type": "messaging",
"channel_id": "fun-d5f396e3-fbaf-469c-9b45-8837b4f75baa"
}
SQS Best practices and Assumptions
- Set the maximum message size set to 256 KB.
Messages bigger than the maximum message size will be dropped.
- Set up a dead-letter queue for your main queue.
This queue will hold the messages that couldn’t be processed successfully and is useful for debugging your application.