{
"Sid": "AllowStreamProdAccount",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::185583345998:root"
},
"Action": "SNS:Publish",
"Resource": "arn:aws:sns:us-west-2:1111111111:customer-sns-topic"
}SNS
Stream can send payloads of all events from your application to an Amazon SNS topic 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 SNS.
SNS removes the chance of losing data for Chat events by providing a large, scalable message exchange that delivers events generated by Stream Chat to as many consumers as you like.
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 SNS topic through the Stream Dashboard or programmatically using the REST API or an SDK with Server Side Authorization.
There are 2 ways to configure authentication on your SNS topic:
By providing a key and secret
Or by having Stream's AWS account assume a role on your SNS topic. With this option you omit the key and secret, but instead you set up a resource-based policy to grant Stream Publish permission on your SNS topic. The following policy needs to be attached to your topic (replace the value of Resource with the fully qualified ARN of your topic):
To configure an SNS topic, 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 SNS hook while preserving existing hooks
const existingHooks = response.event_hooks || [];
const newSNSHook = {
enabled: true,
hook_type: "sns",
sns_topic_arn: "arn:aws:sns:us-east-1:123456789012:sns-topic",
sns_region: "us-east-1",
sns_auth_type: "keys", // or "resource" for role-based auth
sns_key: "yourkey",
sns_secret: "yoursecret",
event_types: [], // empty array = all events
};
// STEP 3: Update with complete array including existing hooks
await client.updateAppSettings({
event_hooks: [...existingHooks, newSNSHook],
});
// Test the SNS connection
await client.testSNSSettings({
sns_topic_arn: "arn:aws:sns:us-east-1:123456789012:sns-topic",
sns_key: "yourkey",
sns_secret: "yoursecret",
});from getstream.models import EventHook
# 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()
existing_hooks = response.data.app.event_hooks or []
print("Current event hooks:", existing_hooks)
# STEP 2: Add SNS hook while preserving existing hooks
new_sns_hook = EventHook(
enabled=True,
hook_type="sns",
sns_topic_arn="arn:aws:sns:us-east-1:123456789012:sns-topic",
sns_region="us-east-1",
sns_auth_type="keys", # or "resource" for role-based auth
sns_key="yourkey",
sns_secret="yoursecret",
event_types=[], # empty array = all events
)
# STEP 3: Update with complete array including existing hooks
client.update_app(
event_hooks=existing_hooks + [new_sns_hook]
)
# Test the SNS connection
client.check_sns(sns_key="yourkey", sns_secret="yoursecret", sns_topic_arn="arn:aws:sns:us-east-1:123456789012:sns-topic")require 'getstream_ruby'
Models = GetStream::Generated::Models
# 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.common.get_app
existing_hooks = response.app.event_hooks || []
puts "Current event hooks:", existing_hooks
# STEP 2: Add SNS hook while preserving existing hooks
new_sns_hook = {
'enabled' => true,
'hook_type' => 'sns',
'sns_topic_arn' => 'arn:aws:sns:us-east-1:123456789012:sns-topic',
'sns_region' => 'us-east-1',
'sns_auth_type' => 'keys', # or "resource" for role-based auth
'sns_key' => 'yourkey',
'sns_secret' => 'yoursecret',
'event_types' => [] # empty array = all events
}
# STEP 3: Update with complete array including existing hooks
client.common.update_app(Models::UpdateAppRequest.new(
event_hooks: existing_hooks + [new_sns_hook]
))
# Test the SNS connection
client.common.check_sns(Models::CheckSNSRequest.new(
sns_key: 'yourkey',
sns_secret: 'yoursecret',
sns_topic_arn: 'arn:aws:sns:us-east-1:123456789012:sns-topic'
))// 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->getApp();
$existingHooks = $response->getData()->app->eventHooks ?? [];
// STEP 2: Add SNS hook while preserving existing hooks
$newSNSHook = new Models\EventHook(
enabled: true,
hookType: "sns",
snsTopicArn: "arn:aws:sns:us-east-1:123456789012:sns-topic",
snsRegion: "us-east-1",
snsAuthType: "keys", // or "resource" for role-based auth
snsKey: "yourkey",
snsSecret: "yoursecret",
eventTypes: [], // empty array = all events
);
// STEP 3: Update with complete array including existing hooks
$client->updateApp(new Models\UpdateAppRequest(
eventHooks: array_merge($existingHooks, [$newSNSHook]),
));
// Test the SNS connection
$client->checkSNS(new Models\CheckSNSRequest(
snsTopicArn: "arn:aws:sns:us-east-1:123456789012:sns-topic",
snsKey: "yourkey",
snsSecret: "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.GetApp(ctx, &getstream.GetAppRequest{})
if err != nil {
log.Fatal(err)
}
existingHooks := settings.Data.App.EventHooks
fmt.Printf("Current event hooks: %+v\n", existingHooks)
// STEP 2: Add SNS hook while preserving existing hooks
newSNSHook := getstream.EventHook{
HookType: getstream.PtrTo("sns"),
Enabled: getstream.PtrTo(true),
EventTypes: []string{}, // empty slice = all events
SnsTopicArn: getstream.PtrTo("arn:aws:sns:us-east-1:123456789012:sns-topic"),
SnsRegion: getstream.PtrTo("us-east-1"),
SnsAuthType: getstream.PtrTo("keys"), // or "resource" for role-based auth
SnsKey: getstream.PtrTo("yourkey"),
SnsSecret: getstream.PtrTo("yoursecret"),
}
// STEP 3: Update with complete array including existing hooks
allHooks := append(existingHooks, newSNSHook)
_, err = client.UpdateApp(ctx, &getstream.UpdateAppRequest{
EventHooks: allHooks,
})
if err != nil {
log.Fatal(err)
}
// Test the SNS connection
client.CheckSNS(ctx, &getstream.CheckSNSRequest{
SnsTopicArn: getstream.PtrTo("arn:aws:sns:us-east-1:123456789012:sns-topic"),
SnsKey: getstream.PtrTo("yourkey"),
SnsSecret: getstream.PtrTo("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
var response = client.getApp(GetAppRequest.builder().build()).execute().getData();
var existingHooks = response.getApp().getEventHooks();
System.out.println("Current event hooks: " + existingHooks);
// STEP 2: Add SNS hook while preserving existing hooks
var newSNSHook = EventHook.builder()
.hookType("sns")
.enabled(true)
.eventTypes(Collections.emptyList()) // empty list = all events
.snsTopicArn("arn:aws:sns:us-east-1:123456789012:sns-topic")
.snsRegion("us-east-1")
.snsAuthType("keys") // or "resource" for role-based auth
.snsKey("yourkey")
.snsSecret("yoursecret")
.build();
// STEP 3: Update with complete array including existing hooks
var allHooks = new ArrayList<>(existingHooks);
allHooks.add(newSNSHook);
client.updateApp(UpdateAppRequest.builder()
.eventHooks(allHooks)
.build()).execute();
// Test the SNS connection
client.checkSNS(CheckSNSRequest.builder()
.snsKey("yourkey")
.snsSecret("yoursecret")
.snsTopicArn("arn:aws:sns:us-east-1:123456789012:sns-topic")
.build()).execute();// 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.GetAppAsync();
var existingHooks = settings.Data.App.EventHooks ?? new List<EventHook>();
Console.WriteLine($"Current event hooks: {existingHooks}");
// STEP 2: Add SNS hook while preserving existing hooks
var newSNSHook = new EventHook
{
HookType = "sns",
Enabled = true,
EventTypes = new List<string>(), // empty list = all events
SnsTopicArn = "arn:aws:sns:us-east-1:123456789012:sns-topic",
SnsRegion = "us-east-1",
SnsAuthType = "keys", // or "resource" for role-based auth
SnsKey = "yourkey",
SnsSecret = "yoursecret",
};
// STEP 3: Update with complete array including existing hooks
var allHooks = new List<EventHook>(existingHooks) { newSNSHook };
await client.UpdateAppAsync(new UpdateAppRequest
{
EventHooks = allHooks,
});
// Test the SNS connection
await client.CheckSNSAsync(new CheckSNSRequest
{
SnsKey = "yourkey",
SnsSecret = "yoursecret",
SnsTopicArn = "arn:aws:sns:us-east-1:123456789012:sns-topic",
});Configuration Options
The following options are available when configuring an SNS event hook:
| Option | Type | Description | Required |
|---|---|---|---|
| id | string | Unique identifier for the event hook | No. If empty, it will generate an ID. |
| enabled | boolean | Boolean flag to enable/disable the hook | Yes |
| hook_type | string | Must be set to "sns" | Yes |
| sns_topic_arn | string | The AWS SNS topic ARN | Yes |
| sns_region | string | The AWS region where the SNS topic is located (e.g., "us-east-1") | Yes |
| sns_auth_type | string | Authentication type: "keys" for access key/secret or "resource" for role-based auth | Yes |
| sns_key | string | AWS access key ID (required if auth_type is "keys") | Yes if using key auth |
| sns_secret | string | AWS secret access key (required if auth_type is "keys") | Yes if using key auth |
| event_types | array | Array of event types this hook should handle | No. Not provided or empty array means subscribe to all existing and future events. |
SNS Best practices and Assumptions
- Set the maximum message size set to 256 KB.
Messages bigger than the maximum message size will be dropped.