@chainsaws/sns
v0.1.2
Published
Typed SNS wrapper for Node.js with a Python-style API for topics, publish flows, and subscriptions.
Maintainers
Readme
@chainsaws/sns
Typed SNS wrapper for Node.js with a Python-style API for topics, publish flows, and subscriptions.
Requirements
- Node.js
>= 22 - AWS credentials available through the normal AWS SDK resolution chain, or explicit static credentials in config
Installation
npm install @chainsaws/sns
yarn add @chainsaws/sns
pnpm add @chainsaws/snsThis package is ESM-only.
Quick Start
import { SNSAPI, SNSMessage } from "@chainsaws/sns";
const sns = new SNSAPI({
region: "ap-northeast-2",
});
const topic = await sns.create_topic("orders");
await sns.publish(
topic.topic_arn,
new SNSMessage({
message: JSON.stringify({ order_id: "o_123" }),
subject: "order.created",
}),
);Package Surface
Most applications only need:
SNSAPISNSMessageSNSTopicSNSSubscription
The package also exports:
LowLevelSNSSNSMessageAttributesBatchPublishResultBatchSubscribeResultcreate_sns_api_config(...)SNSException
Creating the Client
All config fields are optional. When they are omitted, the AWS SDK falls back to its normal credential and region resolution chain.
import { SNSAPI, create_sns_api_config } from "@chainsaws/sns";
const config = create_sns_api_config({
region: "ap-northeast-2",
endpoint: process.env.SNS_ENDPOINT,
max_pool_connections: 100,
credentials: {
accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
sessionToken: process.env.AWS_SESSION_TOKEN,
},
});
const sns = new SNSAPI(config);Constructor shortcuts mirror the Python package and override config values:
const sns = new SNSAPI(
{ region: "ap-northeast-2" },
{ region: "us-east-1" },
);Use the second argument only when you want Python-style constructor overrides without mutating a shared config object.
Topics
create_topic
const topic = await sns.create_topic(
"orders",
"Orders",
{
Version: "2012-10-17",
},
{
healthyRetryPolicy: {
numRetries: 3,
},
},
{
env: "prod",
},
);
console.log(topic.topic_arn);policy and delivery_policy are serialized as compact JSON strings before being sent to AWS.
delete_topic
await sns.delete_topic(topic.topic_arn);list_topics
for await (const topic of sns.list_topics()) {
console.log(topic.topic_name, topic.topic_arn);
}Publishing
publish
await sns.publish(
topic.topic_arn,
new SNSMessage({
message: JSON.stringify({ hello: "world" }),
subject: "demo",
message_attributes: {
source: {
string_value: "worker",
data_type: "String",
},
},
}),
);SNSMessage keeps the Python model shape on purpose. It is useful when you want
stable handling for:
- message attributes
message_structure- FIFO
message_group_id - FIFO
message_deduplication_id
The high-level API also accepts a raw string:
await sns.publish(topic.topic_arn, "hello");publish_to_target
await sns.publish_to_target(
"arn:aws:sns:ap-northeast-2:123456789012:endpoint/APNS/app/device",
"direct payload",
);publish_to_phone
await sns.publish_to_phone("+821012341234", "verification code: 123456");SNS SMS publishing rejects fields that AWS does not support for SMS:
subjectmessage_structuremessage_group_idmessage_deduplication_id
batch_publish
const result = await sns.batch_publish(topic.topic_arn, [
"first",
new SNSMessage({ message: "second" }),
]);
console.log(result.success_count);
console.log(result.failure_count);batch_publish uses SNS PublishBatch internally and preserves FIFO fields such as message_group_id and message_deduplication_id.
Subscriptions
subscribe
const subscription = await sns.subscribe(
topic.topic_arn,
"https",
"https://example.com/webhook",
true,
{
priority: ["high"],
},
);
console.log(subscription.subscription_arn);Supported protocols:
httphttpsemailemail-jsonsmssqsapplicationlambdafirehose
confirm_subscription
const subscriptionArn = await sns.confirm_subscription(
topic.topic_arn,
"token-value",
true,
);unsubscribe
await sns.unsubscribe(subscription.subscription_arn);list_subscriptions
for await (const subscription of sns.list_subscriptions(topic.topic_arn)) {
console.log(subscription.protocol, subscription.endpoint);
}list_all_subscriptions
for await (const subscription of sns.list_all_subscriptions()) {
console.log(subscription.topic_arn, subscription.endpoint);
}batch_subscribe
const result = await sns.batch_subscribe(topic.topic_arn, [
{
protocol: "email",
endpoint: "[email protected]",
},
{
protocol: "https",
endpoint: "https://example.com/webhook",
raw_message_delivery: true,
},
]);
console.log(result.successful);
console.log(result.failed);Each subscription request must include protocol and endpoint.
batch_unsubscribe
const result = await sns.batch_unsubscribe([
"arn:aws:sns:ap-northeast-2:123456789012:orders:sub-1",
"arn:aws:sns:ap-northeast-2:123456789012:orders:sub-2",
]);
console.log(result.success_count);Attribute APIs
Topic attributes
const topicAttrs = await sns.get_topic_attributes(topic.topic_arn);
await sns.set_topic_attributes(topic.topic_arn, "DisplayName", "Orders");Subscription attributes
const attrs = await sns.get_subscription_attributes(subscription.subscription_arn);
await sns.set_subscription_attributes(
subscription.subscription_arn,
"RawMessageDelivery",
"true",
);Low-Level Adapter
LowLevelSNS is also exported for callers who want the thin AWS SDK adapter directly.
import { LowLevelSNS } from "@chainsaws/sns";
const low = new LowLevelSNS({ region: "ap-northeast-2" });
const messageId = await low.publish({
topic_arn: "arn:aws:sns:ap-northeast-2:123456789012:orders",
message: "hello",
});LowLevelSNS is the thin AWS SDK adapter. It owns request-shape translation,
pagination plumbing, and small batch chunking, but does not construct the
higher-level model classes for you.
Exported Models
The package exports the currently useful SNS model types and classes, including:
SNSAPIConfigSNSMessageAttributesSNSMessageSNSTopicSNSSubscriptionSNSBatchSubscriptionRequestBatchPublishResultBatchSubscribeResultSNSException
SNSClient is exported as a backward-compatible alias of SNSAPI.
Compatibility Notes
The current Node package covers the topic, publish, and subscription surface already used by the Python package. It is not trying to be a full opinionated framework on top of SNS; it stays close to AWS plus a small amount of Python parity glue.
