

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 在 Amazon SNS 中套用訂閱篩選條件政策
<a name="message-filtering-apply"></a>

Amazon SNS 中的訊息篩選可讓您根據篩選政策，選擇性地傳送訊息給訂閱者。這些政策會定義訊息必須符合的條件，才能交付至訂閱。雖然原始訊息傳遞是可能影響訊息處理的選項，但訂閱篩選條件不需要運作。

您可以使用 Amazon SNS 主控台將篩選政策套用到 Amazon SNS 訂閱。或者，若要以程式設計方式套用政策，您可以使用 Amazon SNS API、 AWS Command Line Interface (AWS CLI) 或任何支援 Amazon SNS 的 AWS SDK。您也可以使用 AWS CloudFormation。

**啟用原始訊息傳遞**

原始訊息傳遞可確保訊息承載依原狀交付給訂閱者，無需任何額外的編碼或轉換。當訂閱者需要原始訊息格式進行處理時，這會很有用。不過，原始訊息傳遞與訂閱篩選條件的功能不直接相關。

**套用訂閱篩選條件**

若要將訊息篩選條件套用至訂閱，您可以使用 JSON 語法定義篩選條件政策。此政策指定訊息必須符合的條件，才能交付至訂閱。篩選條件可以根據訊息屬性，例如訊息屬性、訊息結構，甚至是訊息內容。

**原始訊息交付與訂閱篩選條件之間的關係**

雖然啟用原始訊息傳遞可能會影響訂閱者交付和處理訊息的方式，但這不是使用訂閱篩選條件的先決條件。不過，在訂閱者需要原始訊息格式而不進行任何修改的情況下，啟用原始訊息傳遞可能比訂閱篩選條件更有益。

**有效篩選的考量事項**

實作訊息篩選時，請考慮應用程式和訂閱者的特定需求。定義準確符合訊息傳遞條件的篩選政策，以確保有效率且目標性的訊息分發。

**重要**  
AWS IAM 和 Amazon SNS 等 服務會使用稱為最終一致性的分散式運算模型。對訂閱篩選原則進行新增或變更，最多需要 15 分鐘才能完全生效。

## AWS 管理主控台
<a name="message-filtering-apply-console"></a>

1. 登入 [Amazon SNS 主控台](https://console.aws.amazon.com/sns/home)。

1. 在導覽面板上，選擇 **Subscriptions (訂閱)**。

1. 選取訂閱，然後選擇 **Edit** (編輯)。

1. 在 **Edit** (編輯) 頁面上，展開 **Subscription filter policy** (訂閱篩選政策) 區段。

1. 選擇**以屬性為基礎的篩選**或**以承載為基礎的篩選**。

1. 在 **JSON editor** (JSON 編輯器) 欄位中，提供您篩選政策的 **JSON 內文**。

1. 選擇**儲存變更**。

   Amazon SNS 套用您的篩選政策到訂閱。

## AWS CLI
<a name="message-filtering-apply-cli"></a>

若要使用 AWS Command Line Interface (AWS CLI) 套用篩選條件政策，請使用 [https://docs.aws.amazon.com/cli/latest/reference/sns/set-subscription-attributes.html](https://docs.aws.amazon.com/cli/latest/reference/sns/set-subscription-attributes.html)命令，如下列範例所示。對於 `--attribute-name` 選項，指定 `FilterPolicy`。針對 `--attribute-value`，請指定 **JSON 政策**。

```
$ aws sns set-subscription-attributes --subscription-arn {{arn:aws:sns: ...}} --attribute-name FilterPolicy --attribute-value {{'{"store":["example_corp"],"event":["order_placed"]}'}}
```

若要為您的政策提供有效的 JSON，請使用雙引號括住屬性名稱和值。您也必須用引號括住整個政策引數。若要避免逸出引號，您可以如上方範例所示，使用單引號括住政策，並用雙引號括住 JSON 名稱和值。

若您想要從以屬性為基礎 (預設) 切換到以承載為基礎的訊息篩選，也可以使用 [set-subscription-attributes](https://docs.aws.amazon.com/cli/latest/reference/sns/set-subscription-attributes.html) 命令。對於 `--attribute-name` 選項，指定 `FilterPolicyScope`。對於 `--attribute-value`，請指定 `MessageBody`。

```
$ aws sns set-subscription-attributes --subscription-arn arn:aws:sns: ... --attribute-name FilterPolicyScope --attribute-value MessageBody
```

如果要確認是否已套用篩選政策，請使用 `get-subscription-attributes` 命令。如以下範例所示，內部輸出中的屬性應顯示您的 `FilterPolicy` 索引鍵的篩選政策：

```
$ aws sns get-subscription-attributes --subscription-arn {{arn:aws:sns: ...}}
{
    "Attributes": {
        "Endpoint": "endpoint . . .", 
        "Protocol": "https",
        "RawMessageDelivery": "false", 
        "EffectiveDeliveryPolicy": "delivery policy . . .",
        "ConfirmationWasAuthenticated": "true", 
        "FilterPolicy": "{\"store\": [\"example_corp\"], \"event\": [\"order_placed\"]}", 
        "FilterPolicyScope": "MessageAttributes",
        "Owner": "111122223333", 
        "SubscriptionArn": "arn:aws:sns: . . .", 
        "TopicArn": "arn:aws:sns: . . ."
    }
}
```

## AWS SDKs
<a name="message-filtering-apply-sdks"></a>

下列程式碼範例示範如何使用 `SetSubscriptionAttributes`。

**重要**  
如果您使用適用於 Java 2.x 的 SDK 範例，則類別 `SNSMessageFilterPolicy` 非可立即運作。如需如何安裝此類別的指示，請參閱 GitHub 網站的[範例](https://github.com/awsdocs/aws-doc-sdk-examples/blob/main/javav2/example_code/sns/src/main/java/com/example/sns/SNSMessageFilterPolicy.java)。

------
#### [ CLI ]

**AWS CLI**  
**設定訂閱屬性**  
下列 `set-subscription-attributes` 範例會將 `RawMessageDelivery` 屬性設定為 SQS 訂閱。  

```
aws sns set-subscription-attributes \
    --subscription-arn {{arn:aws:sns:us-east-1:123456789012:mytopic:f248de18-2cf6-578c-8592-b6f1eaa877dc}} \
    --attribute-name {{RawMessageDelivery}} \
    --attribute-value {{true}}
```
此命令不會產生輸出。  
下列 `set-subscription-attributes` 範例會將 `FilterPolicy` 屬性設定為 SQS 訂閱。  

```
aws sns set-subscription-attributes \
    --subscription-arn {{arn:aws:sns:us-east-1:123456789012:mytopic:f248de18-2cf6-578c-8592-b6f1eaa877dc}} \
    --attribute-name {{FilterPolicy}} \
    --attribute-value "{ \"anyMandatoryKey\": [\"any\", \"of\", \"these\"] }"
```
此命令不會產生輸出。  
下列 `set-subscription-attributes` 範例會從 SQS 訂閱移除 `FilterPolicy` 屬性。  

```
aws sns set-subscription-attributes \
    --subscription-arn {{arn:aws:sns:us-east-1:123456789012:mytopic:f248de18-2cf6-578c-8592-b6f1eaa877dc}} \
    --attribute-name {{FilterPolicy}} \
    --attribute-value {{"{}"}}
```
此命令不會產生輸出。  
+  如需 API 詳細資訊，請參閱《AWS CLI 命令參考》**中的 [SetSubscriptionAttributes](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/sns/set-subscription-attributes.html)。

------
#### [ Java ]

**SDK for Java 2.x**  
 GitHub 上提供更多範例。尋找完整範例，並了解如何在 [AWS 程式碼範例儲存庫](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/javav2/example_code/sns#code-examples)中設定和執行。

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.sns.SnsClient;
import software.amazon.awssdk.services.sns.model.SnsException;
import java.util.ArrayList;

/**
 * Before running this Java V2 code example, set up your development
 * environment, including your credentials.
 *
 * For more information, see the following documentation topic:
 *
 * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
 */
public class UseMessageFilterPolicy {
    public static void main(String[] args) {
        final String usage = """

                Usage:    <subscriptionArn>

                Where:
                   subscriptionArn - The ARN of a subscription.

                """;

        if (args.length != 1) {
            System.out.println(usage);
            System.exit(1);
        }

        String subscriptionArn = args[0];
        SnsClient snsClient = SnsClient.builder()
                .region(Region.US_EAST_1)
                .build();

        usePolicy(snsClient, subscriptionArn);
        snsClient.close();
    }

    public static void usePolicy(SnsClient snsClient, String subscriptionArn) {
        try {
            SNSMessageFilterPolicy fp = new SNSMessageFilterPolicy();
            // Add a filter policy attribute with a single value
            fp.addAttribute("store", "example_corp");
            fp.addAttribute("event", "order_placed");

            // Add a prefix attribute
            fp.addAttributePrefix("customer_interests", "bas");

            // Add an anything-but attribute
            fp.addAttributeAnythingBut("customer_interests", "baseball");

            // Add a filter policy attribute with a list of values
            ArrayList<String> attributeValues = new ArrayList<>();
            attributeValues.add("rugby");
            attributeValues.add("soccer");
            attributeValues.add("hockey");
            fp.addAttribute("customer_interests", attributeValues);

            // Add a numeric attribute
            fp.addAttribute("price_usd", "=", 0);

            // Add a numeric attribute with a range
            fp.addAttributeRange("price_usd", ">", 0, "<=", 100);

            // Apply the filter policy attributes to an Amazon SNS subscription
            fp.apply(snsClient, subscriptionArn);

        } catch (SnsException e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
    }
}
```
+  如需 API 詳細資訊，請參閱 *AWS SDK for Java 2.x API 參考*中的 [SetSubscriptionAttributes](https://docs.aws.amazon.com/goto/SdkForJavaV2/sns-2010-03-31/SetSubscriptionAttributes)。

------
#### [ Python ]

**適用於 Python 的 SDK (Boto3)**  
 GitHub 上提供更多範例。尋找完整範例，並了解如何在 [AWS 程式碼範例儲存庫](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/python/example_code/sns#code-examples)中設定和執行。

```
class SnsWrapper:
    """Encapsulates Amazon SNS topic and subscription functions."""

    def __init__(self, sns_resource):
        """
        :param sns_resource: A Boto3 Amazon SNS resource.
        """
        self.sns_resource = sns_resource


    @staticmethod
    def add_subscription_filter(subscription, attributes):
        """
        Adds a filter policy to a subscription. A filter policy is a key and a
        list of values that are allowed. When a message is published, it must have an
        attribute that passes the filter or it will not be sent to the subscription.

        :param subscription: The subscription the filter policy is attached to.
        :param attributes: A dictionary of key-value pairs that define the filter.
        """
        try:
            att_policy = {key: [value] for key, value in attributes.items()}
            subscription.set_attributes(
                AttributeName="FilterPolicy", AttributeValue=json.dumps(att_policy)
            )
            logger.info("Added filter to subscription %s.", subscription.arn)
        except ClientError:
            logger.exception(
                "Couldn't add filter to subscription %s.", subscription.arn
            )
            raise
```
+  如需 API 詳細資訊，請參閱 *AWS SDK for Python (Boto3) API 參考*中的 [SetSubscriptionAttributes](https://docs.aws.amazon.com/goto/boto3/sns-2010-03-31/SetSubscriptionAttributes)。

------
#### [ SAP ABAP ]

**適用於 SAP ABAP 的開發套件**  
 GitHub 上提供更多範例。尋找完整範例，並了解如何在 [AWS 程式碼範例儲存庫](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/sap-abap/services/sns#code-examples)中設定和執行。

```
    TRY.
        lo_sns->setsubscriptionattributes(
            iv_subscriptionarn = iv_subscription_arn
            iv_attributename  = 'FilterPolicy'
            iv_attributevalue = iv_filter_policy ).
        MESSAGE 'Added filter policy to subscription.' TYPE 'I'.
      CATCH /aws1/cx_snsnotfoundexception.
        MESSAGE 'Subscription does not exist.' TYPE 'E'.
    ENDTRY.
```
+  如需 API 詳細資訊，請參閱《適用於 *AWS SAP ABAP 的 SDK API 參考*》中的 [SetSubscriptionAttributes](https://docs.aws.amazon.com/sdk-for-sap-abap/v1/api/latest/index.html)。

------

## Amazon SNS API
<a name="message-filtering-apply-api"></a>

若要使用 Amazon SNS API 套用篩選政策，請提出 [https://docs.aws.amazon.com/sns/latest/api/API_SetSubscriptionAttributes.html](https://docs.aws.amazon.com/sns/latest/api/API_SetSubscriptionAttributes.html) 動作的請求。將 `AttributeName` 參數設定為 `FilterPolicy`，然後將 `AttributeValue` 參數設定為您的篩選政策 JSON。

若您想要從以屬性為基礎 (預設) 切換到以承載為基礎的訊息篩選，也可以使用 [https://docs.aws.amazon.com/sns/latest/api/API_SetSubscriptionAttributes.html](https://docs.aws.amazon.com/sns/latest/api/API_SetSubscriptionAttributes.html) 動作。將 `AttributeName` 參數設定為 `FilterPolicyScope`，並將 `AttributeValue` 參數設定為 `MessageBody`。

## AWS CloudFormation
<a name="message-filtering-apply-cloudformation"></a>

若要使用 套用篩選政策 CloudFormation，請使用 JSON 或 YAML 範本來建立 CloudFormation 堆疊。如需詳細資訊，請參閱*AWS CloudFormation 《 使用者指南*》中的 `AWS::SNS::Subscription` 資源的 [`FilterPolicy` 屬性](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-sns-subscription.html#cfn-sns-subscription-filterpolicy)和[範例 CloudFormation 範本](https://github.com/aws-samples/aws-sns-samples/blob/master/templates/SNS-Subscription-Attributes-Tutorial-CloudFormation.template)。

1. 登入 [CloudFormation 主控台](https://console.aws.amazon.com/cloudformation)。

1. 選擇 **Create Stack** (建立堆疊)。

1. 在 **Select Template** (選擇範本) 頁面中，選擇 **Upload a template to Amazon S3** (上傳範本到 Amazon S3)、選擇檔案，並選擇 **Next** (下一步)。

1. 在 **Specify Details** (指定詳細資訊) 頁面上，執行下列作業：

   1. 在 **Stack Name** (堆疊名稱) 中輸入 `MyFilterPolicyStack`。

   1. 對於 **myHttpEndpoint**，輸入要訂閱到主題的 HTTP 端點。
**提示**  
若您沒有 HTTP 端點，請建立一個。

1. 在 **Options** (選項) 頁面上，選擇 **Next** (下一步)。

1. 在 **Review** (檢閱) 頁面上，選擇 **Create** (建立)。