SNS message publishing enables delivery of messages to topics and direct endpoints with support for various protocols, message attributes, batch operations, and FIFO ordering.
Publishes a message to a topic, direct endpoint, or phone number with comprehensive formatting and attribute support.
/**
* Publishes a message to an Amazon SNS topic, direct endpoint, or phone number
* Supports various protocols and message formatting options
*/
class PublishCommand {
constructor(input: PublishInput);
}
interface PublishInput {
/** ARN of the topic to publish to */
TopicArn?: string | undefined;
/** ARN of the target endpoint or mobile platform endpoint */
TargetArn?: string | undefined;
/** Phone number for direct SMS delivery */
PhoneNumber?: string | undefined;
/** The message content to send (required) */
Message: string | undefined;
/** Subject line for email protocols */
Subject?: string | undefined;
/** Message structure format ("json" for platform-specific formatting) */
MessageStructure?: string | undefined;
/** Custom message attributes */
MessageAttributes?: Record<string, MessageAttributeValue> | undefined;
/** Message group ID for FIFO topics */
MessageGroupId?: string | undefined;
/** Message deduplication ID for FIFO topics */
MessageDeduplicationId?: string | undefined;
}
interface PublishResponse {
/** Unique identifier assigned to the published message */
MessageId?: string;
/** Sequence number for FIFO topics */
SequenceNumber?: string;
}
type MessageAttributeMap = Record<string, MessageAttributeValue>;
interface MessageAttributeValue {
/** Data type of the attribute ("String", "Number", "Binary", or custom type) */
DataType: string;
/** String value for String and Number data types */
StringValue?: string;
/** Binary data for Binary data type */
BinaryValue?: Uint8Array;
/** List of string values for String.Array data type */
StringListValues?: string[];
/** List of binary values for Binary.Array data type */
BinaryListValues?: Uint8Array[];
}Basic Usage Examples:
import { SNSClient, PublishCommand } from "@aws-sdk/client-sns";
const client = new SNSClient({ region: "us-east-1" });
// Publish to topic
const result = await client.send(new PublishCommand({
TopicArn: "arn:aws:sns:us-east-1:123456789012:MyTopic",
Message: "Hello from SNS!",
Subject: "Test Message"
}));
// Publish SMS directly to phone number
const smsResult = await client.send(new PublishCommand({
PhoneNumber: "+1234567890",
Message: "Your verification code is 123456"
}));
// Publish to mobile platform endpoint
const pushResult = await client.send(new PublishCommand({
TargetArn: "arn:aws:sns:us-east-1:123456789012:endpoint/APNS/MyApp/device-token",
Message: JSON.stringify({
APNS: JSON.stringify({
aps: {
alert: "New message available",
badge: 1,
sound: "default"
}
})
}),
MessageStructure: "json"
}));Message Attributes Example:
const result = await client.send(new PublishCommand({
TopicArn: "arn:aws:sns:us-east-1:123456789012:MyTopic",
Message: "Order processed successfully",
MessageAttributes: {
orderId: {
DataType: "String",
StringValue: "ORDER-12345"
},
priority: {
DataType: "Number",
StringValue: "1"
},
orderTotal: {
DataType: "Number.currency",
StringValue: "99.99"
},
customerData: {
DataType: "Binary",
BinaryValue: new Uint8Array([1, 2, 3, 4])
},
tags: {
DataType: "String.Array",
StringListValues: ["urgent", "vip", "express"]
}
}
}));FIFO Topic Publishing:
const fifoResult = await client.send(new PublishCommand({
TopicArn: "arn:aws:sns:us-east-1:123456789012:OrderProcessing.fifo",
Message: "New order received",
MessageGroupId: "order-processing",
MessageDeduplicationId: `order-${Date.now()}`,
MessageAttributes: {
orderId: {
DataType: "String",
StringValue: "ORDER-67890"
}
}
}));Publishes multiple messages in a single request for improved performance and reduced API calls.
/**
* Publishes up to 10 messages to an Amazon SNS topic in a single request
* Provides improved throughput and reduced costs for bulk messaging
*/
class PublishBatchCommand {
constructor(input: PublishBatchInput);
}
interface PublishBatchInput {
/** ARN of the topic to publish to */
TopicArn: string;
/** List of messages to publish (maximum 10) */
PublishRequestEntries: PublishBatchRequestEntry[];
}
interface PublishBatchRequestEntry {
/** Unique identifier for this message within the batch */
Id: string;
/** The message content */
Message: string;
/** Subject line for email protocols */
Subject?: string;
/** Message structure format */
MessageStructure?: string;
/** Message attributes */
MessageAttributes?: MessageAttributeMap;
/** Message group ID for FIFO topics */
MessageGroupId?: string;
/** Message deduplication ID for FIFO topics */
MessageDeduplicationId?: string;
}
interface PublishBatchResponse {
/** Successfully published messages */
Successful?: PublishBatchResultEntry[];
/** Failed message entries */
Failed?: BatchResultErrorEntry[];
}
interface PublishBatchResultEntry {
/** ID of the successfully published message */
Id?: string;
/** Unique message identifier assigned by SNS */
MessageId?: string;
/** Sequence number for FIFO topics */
SequenceNumber?: string;
}
interface BatchResultErrorEntry {
/** ID of the failed message */
Id?: string;
/** Error code */
Code?: string;
/** Error message */
Message?: string;
/** Whether the error is sender's fault */
SenderFault?: boolean;
}Batch Publishing Examples:
const batchResult = await client.send(new PublishBatchCommand({
TopicArn: "arn:aws:sns:us-east-1:123456789012:MyTopic",
PublishRequestEntries: [
{
Id: "msg1",
Message: "First message",
Subject: "Message 1",
MessageAttributes: {
priority: {
DataType: "Number",
StringValue: "1"
}
}
},
{
Id: "msg2",
Message: "Second message",
Subject: "Message 2",
MessageAttributes: {
priority: {
DataType: "Number",
StringValue: "2"
}
}
},
{
Id: "msg3",
Message: "Third message",
Subject: "Message 3"
}
]
}));
// Process results
batchResult.Successful?.forEach(success => {
console.log(`Message ${success.Id} published with ID: ${success.MessageId}`);
});
batchResult.Failed?.forEach(failure => {
console.log(`Message ${failure.Id} failed: ${failure.Message}`);
});FIFO Batch Publishing:
const fifoBatch = await client.send(new PublishBatchCommand({
TopicArn: "arn:aws:sns:us-east-1:123456789012:OrderProcessing.fifo",
PublishRequestEntries: [
{
Id: "order1",
Message: "Order 1 processing",
MessageGroupId: "order-group-1",
MessageDeduplicationId: "order-1-dedup"
},
{
Id: "order2",
Message: "Order 2 processing",
MessageGroupId: "order-group-1",
MessageDeduplicationId: "order-2-dedup"
},
{
Id: "order3",
Message: "Order 3 processing",
MessageGroupId: "order-group-2",
MessageDeduplicationId: "order-3-dedup"
}
]
}));For platform-specific message formatting, use JSON message structure to send different payloads to different protocols.
interface JSONMessageStructure {
default: string; // Default message for unsupported protocols
email?: string; // Email-specific message
http?: string; // HTTP endpoint message
https?: string; // HTTPS endpoint message
sqs?: string; // SQS queue message
sms?: string; // SMS message
APNS?: string; // Apple Push Notification Service
APNS_SANDBOX?: string; // APNS sandbox
GCM?: string; // Google Cloud Messaging
ADM?: string; // Amazon Device Messaging
BAIDU?: string; // Baidu Cloud Push
MPNS?: string; // Microsoft Push Notification Service
WNS?: string; // Windows Push Notification Service
MACOS?: string; // macOS notifications
MACOS_SANDBOX?: string; // macOS sandbox
}JSON Message Example:
const jsonMessage = {
default: "New notification available",
email: "You have a new notification. Please check your dashboard.",
sms: "New notification - check app",
APNS: JSON.stringify({
aps: {
alert: {
title: "New Notification",
body: "You have a new message"
},
badge: 1,
sound: "default",
"content-available": 1
},
customData: {
notificationId: "12345",
category: "message"
}
}),
GCM: JSON.stringify({
notification: {
title: "New Notification",
body: "You have a new message"
},
data: {
notificationId: "12345",
category: "message"
}
})
};
await client.send(new PublishCommand({
TopicArn: "arn:aws:sns:us-east-1:123456789012:MyTopic",
Message: JSON.stringify(jsonMessage),
MessageStructure: "json"
}));Comprehensive list of supported data types for message attributes.
interface MessageAttributeDataTypes {
/** String data type */
String: string;
/** Numeric data type */
Number: string;
/** Binary data type */
Binary: string;
/** Custom string types with namespace */
'String.customType': string;
/** Custom number types */
'Number.customType': string;
/** Custom binary types */
'Binary.customType': string;
}Common Custom Data Types:
String.Array - Array of strings (use StringListValues)Binary.Array - Array of binary data (use BinaryListValues)Number.currency - Monetary valuesNumber.timestamp - Unix timestampsString.email - Email addressesString.url - URLsHigh-Throughput Publishing:
// Use batch publishing for better performance
const publishBatch = async (messages: string[]) => {
const batches: string[][] = [];
for (let i = 0; i < messages.length; i += 10) {
batches.push(messages.slice(i, i + 10));
}
for (const batch of batches) {
const entries = batch.map((message, index) => ({
Id: `msg-${index}`,
Message: message
}));
await client.send(new PublishBatchCommand({
TopicArn: "arn:aws:sns:us-east-1:123456789012:MyTopic",
PublishRequestEntries: entries
}));
}
};Error Handling:
import {
InvalidParameterException,
ThrottledException,
InternalErrorException
} from "@aws-sdk/client-sns";
try {
const result = await client.send(new PublishCommand({
TopicArn: "arn:aws:sns:us-east-1:123456789012:MyTopic",
Message: "Test message"
}));
console.log("Message published:", result.MessageId);
} catch (error) {
if (error instanceof InvalidParameterException) {
console.log("Invalid parameter:", error.message);
} else if (error instanceof ThrottledException) {
console.log("Request throttled, retry later");
} else if (error instanceof InternalErrorException) {
console.log("Service error, retry");
} else {
console.log("Unknown error:", error);
}
}Retry Logic for Batch Publishing:
const publishBatchWithRetry = async (
entries: PublishBatchRequestEntry[],
maxRetries = 3
) => {
let retryCount = 0;
let remainingEntries = entries;
while (remainingEntries.length > 0 && retryCount < maxRetries) {
try {
const result = await client.send(new PublishBatchCommand({
TopicArn: "arn:aws:sns:us-east-1:123456789012:MyTopic",
PublishRequestEntries: remainingEntries
}));
// Process successful entries
result.Successful?.forEach(success => {
console.log(`Published message ${success.Id}: ${success.MessageId}`);
});
// Retry failed entries
remainingEntries = result.Failed?.map(failure =>
remainingEntries.find(entry => entry.Id === failure.Id)
).filter(Boolean) || [];
if (remainingEntries.length > 0) {
retryCount++;
await new Promise(resolve => setTimeout(resolve, 1000 * retryCount));
}
} catch (error) {
retryCount++;
if (retryCount >= maxRetries) throw error;
await new Promise(resolve => setTimeout(resolve, 1000 * retryCount));
}
}
};