skip to Main Content

I built a Python API that subscribes people to an SNS topic to receive emails about their Spotify accounts. I have a single topic that I publish all the emails to.

I am aware that I can set a subscription filter policy when I create a subscription from console. However, boto3 needs the subscription ARN to set a filter, and the ARN needs the email to be confirmed.

How to set the filter when creating the subscription from boto3, like in the console?

EDIT

>>> import boto3
>>> sns = boto3.client('sns')
>>> sns.subscribe(TopicArn='{the_arn}', Protocol='EMAIL', Endpoint='{an_email}')
{'SubscriptionArn': 'pending confirmation', ...

According to boto3 sns documentation, in order to set the FilterPolicy attribute, I need the subscription ARN.

The example in the docs:

import boto3

sns = boto3.resource('sns')
subscription = sns.Subscription('arn')

response = subscription.set_attributes(
    AttributeName='FilterPolicy',
    AttributeValue={policy json}
)

2

Answers


  1. Chosen as BEST ANSWER

    I ended up replacing SNS with SQS and a Lambda function that sends the emails instead. The filtering is done inside the lambda, plus it sends a pretty text/html instead of the SNS json emails. Will keep the question open if someone comes up with an answer.


  2. SNS subscription filtering is necessary if several clients may subscribe to the same topic. Otherwise you will receive messages addressed to other clients. Possible solution is to create client ID which is unique for each client instance, add it to request attributes, and filter out responses having different ‘clientId’ attribute.

    Boto3 allows to specify filter policy in subscribe method:

    client_id = str(uuid.uuid4())
    
    client_subscription = sns_client.subscribe(
        TopicArn=...,
        Protocol=...,
        Endpoint=...,
        ReturnSubscriptionArn=True,
        Attributes={
           'FilterPolicy': json.dumps({
               'clientId': [
                   client_id
               ]
           })
        }
        )['SubscriptionArn']
    

    In the example we create SNS subscription which passes messages with the given value of ‘clientId’ attribute.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search