Originally published at: Amazon SNS with Delphi: Push notifications, SMS and publish-subscribe pattern | landgraf.dev
Amazon SNS is a managed service that provides message delivery from publishers to subscribers (also known as producers and consumers). Publishers subscribers by sending messages to a topic, which is a logical access point and communication channel. Clients can subscribe to the SNS topic and receive published messages using a supported endpoint type, such as Amazon Kinesis Data Firehose, Amazon SQS, AWS Lambda, HTTP, email, mobile push notifications, and mobile text messages (SMS).
It’s an affordable service. At the time this article was written, sending 1 million push notifications costs $0.50, while sending 1 million notifications via HTTP(S) costs $0.60. You can find more by visiting Amazon SNS pricing page.
- Application integration: Applications can communicate with each other by sending message to topics and receiving messages via notifications. For example, you can develop an application that publishes a message to an SNS topic whenever an order is placed for a product. This message can be consumed by other applications for further processing.
- Application alerts: Applications can send notifications when something happen, for example, when a critical error occurs, or when a specific indicator value is higher than a threshold.
- User notifications: Amazon SNS can send push email messages and text messages (SMS messages) to individuals or groups. For example, you could send e-commerce order confirmations as user notifications.
- Mobile push notifications: And of course, you can send push notifications to your mobile applications to notify your users of any important information related to your app.
Using Amazon SNS with AWS SDK for Delphi
You can refer to our first article about AWS SDK for Delphi to learn more about the concepts, credentials and basic usage. Once you learn about it, you can easily use the following code snippets to perform some specific operations using Amazon SNS.
To start with, you should of course create the SNS client:
var Client: IAmazonSimpleNotificationService; begin Client := TAmazonSimpleNotificationServiceClient.Create; end;
The following code shows how to create a topic (which you can use to publish messages to it) and get its ARN, which will be used for further operations:
var TopicArn: string; begin TopicArn := Client.CreateTopic('test-name').TopicArn; end;
You can then set or get the topic attributes, or even delete it if you need to:
var TopicArn: string; SetAttrRequest: ISetTopicAttributesRequest; GetAttrResponse: IGetTopicAttributesResponse; begin // set topic attribute SetAttrRequest := TSetTopicAttributesRequest.Create(TopicArn, 'DisplayName', 'My topic'); Client.SetTopicAttributes(SetAttrRequest);
// verify topic attributes
GetAttrResponse := Client.GetTopicAttributes(TopicArn);
DisplayName := GetAttrResponse.Attributes[‘DisplayName’]);
// delete new topic
Next step is to add subscriptions to the topic. You can setup it to send notifications to HTTP endpoints, e-mail, SMS messages, other Amazon services, etc. The following example shows how to subscribe the topic to an e-mail address, so messages published to topic will be sent via e-mail. This example waits for the subscription operation to finish to get the subscription ARN. With the subscription ARN you can later perform operations on it, like removing the subscription.
function SubscribeTopic(const TopicArn, EmailAddress: string): string; var Latest: TDateTime; Response: IListSubscriptionsByTopicResponse; begin // subscribe an email address to the topic Client.Subscribe(TSubscribeRequest.Create(TopicArn, 'email', EmailAddress));
// wait until subscription has been confirmed, wait time for two minutes
Latest := IncMinute(Now, 2);
while Now < Latest do
// get subscriptions for topic
Response := Client.ListSubscriptionsByTopic(TopicArn);
// test whether the subscription has been confirmed
if Response.Subscriptions.SubscriptionArn <> ‘PendingConfirmation’ then
Sleep(15 * 1000);
And this is another example of subscription. In this case, we’re subscribing to an Amazon SQS queue. Messages will be forwarded to the queue, which can be later processed by reading the existing messages in the queue. The example also sets proper permission to the queue, otherwise the SNS topic wouldn’t have permission to send messages to it.
function SubscribeQueue(Client: IAmazonSimpleNotificationService; const TopicArn: string; SQSClient: IAmazonSQS; const SQSQueueUrl: string): string; var GetAttrResponse: IGetQueueAttributesResponse; GetAttrRequest: IGetQueueAttributesRequest; SQSQueueArn: string; Policy: TPolicy; PolicyStr: string; TopicArn: string; SetAttrRequest: ISetQueueAttributesRequest; begin // Get the queue's existing policy and ARN GetAttrRequest := TGetQueueAttributesRequest.Create; GetAttrRequest.QueueUrl := SQSQueueUrl; GetAttrRequest.AttributeNames.Add(TSQSConsts.ATTRIBUTE_ALL); GetAttrResponse := SQSClient.GetQueueAttributes(GetAttrRequest); SQSQueueArn := GetAttrResponse.Attributes['QueueArn'];
if GetAttrResponse.Attributes.TryGetValue(‘Policy’, PolicyStr) then
Policy := TPolicy.FromJson(PolicyStr)
Policy := TPolicy.Create;
if not HasSQSPermission(Policy, TopicArn, SQSQueueArn) then
AddSQSPermission(Policy, TopicArn, SQSQueueArn);
Result := Client.Subscribe(TopicArn, ‘sqs’, SQSQueueArn).SubscriptionArn;
SetAttrRequest := TSetQueueAttributesRequest.Create;
SetAttrRequest.QueueUrl := SQSQueueUrl;
Once topic is created and has some subscriptions to it, all you need to do is publish messages to the topic. The messages will be then sent to the subscribers:
// publish a message to the topic Client.Publish(TPublishRequest.Create(TopicArn, 'Test message', 'Subject'));
If you also want to write code for the subscribers, you can read the sent message and process it. Messages are sent as JSON format, and AWS SDK for Delphi already provides high-level classes to process it. You can easily parse the message from JSON and even validate it. Each message sent from Amazon SNS has a signature generated from a certificate. The message provides an URL you can use to download a certificate and check if the signature is valid by using the certificate’s public key. AWS SDK for Delphi automatically does that for you (download the certificate and check the valid signature) with a single line of code:
// Parse an SNS message from JSON and validate signature: function GetMessage(const Json: string): AWS.SNS.Message.TMessage; begin Result := AWS.SNS.Message.TMessage.ParseMessage(Json); if not Result.IsMessageSignatureValid then raise Exception.Create('Invalid message: bad signature'); end;
And finally, a totally different example, the code used to send a mobile push notification to an arbitrary mobile number.
var Client: IAmazonSimpleNotificationService; Request: IPublishRequest; begin Client := TAmazonSimpleNotificationServiceClient.Create; Request := TPublishRequest.Create; Request.PhoneNumber := '+184298765321'; Request.Message := 'Hello from AWS SDK for Delphi!'; Client.Publish(Request); end;
Stay tuned for more services to be added to AWS SDK for Delphi! You can also be part of it. Let us know what do you think and what service you want to be added, and why. Share your needs, we can listen and adjust our roadmap, depending on community feedback. And of course, also feel free to comment below with your thoughts and what did you think about Amazon SNS support.