# Notifications

One of the Selling Partner API's most powerful features is its [notifications](https://developer-docs.amazon.com/sp-api/docs/notifications-api-v1-use-case-guide) system, a way of getting data about various events pushed to your application rather than needing to constantly poll the API to check for new data. Polling often isn't even possible with the SP API, due to relatively low rate limits, so often notifications are the only way to capture the data you need.

This project is designed such that most notifications-related operations can be done either via an artisan command or by calling the `NotificationsService` class directly. If you're only subscribing one or two sellers to a couple notification types, using a command is easiest. If you're automating subscriptions for many sellers or notification types, you're probably better off calling the `NotificationsService` methods directly.

### Setup

* Set up an AWS SQS queue for receiving SQS-specific notifications:
  * Create a new Standard SQS queue on AWS
  * Edit the access policy of the SQS queue according to the instructions [here](https://developer-docs.amazon.com/sp-api/docs/notifications-api-v1-use-case-guide#step-1-grant-selling-partner-api-permission-to-write-to-your-sqs-queue)
  * Put the ARN of the SQS queue in the `SQS_ARN` environment variable, and the queue's URL in the `SQS_URL` variable.
  * Create a new SQS notifications destination by running `php artisan destination:create sqs`, and add the resulting SQS destination ID to the environment variables as instructed by the command's output
* Set up AWS EventBridge. For this, the `EVENTBRIDGE_ACCOUNT_ID` env var must be filled in with the account ID of the AWS IAM user that you want to use to interact with EventBridge. There are instructions on how to find your AWS Account ID [here](https://docs.aws.amazon.com/accounts/latest/reference/manage-acct-identifiers.html#FindAccountId). If your account ID has hyphens in it (`1111-2222-3333`), leave them out in the environment variable (`111122223333`).
  * Create a new AWS EventBridge destination (which we will attach notification subscriptions to) with `php artisan destination:create eventbridge`. Take the destination ID produced by the command and put it in the `EVENTBRIDGE_DESTINATION_ID` environment variable.
  * Set up EventBridge per steps 1 and 2 the instructions [here](https://developer-docs.amazon.com/sp-api/docs/notifications-api-v1-use-case-guide#step-2-configure-amazon-eventbridge-to-handle-notifications). Select the SQS queue you created in the previous step as the target for the EventBridge rule that those instructions walk you through creating.
* Set up the AWS resources needed to fetch notifications:

  * Create an IAM policy with this JSON definition, replacing the `Statement[0].Resource` value with the ARN of your SQS queue:

  ```json
  {
      "Version": "2012-10-17",
      "Statement": [
          {
              "Sid": "VisualEditor0",
              "Effect": "Allow",
              "Action": [
                  "sqs:DeleteMessage",
                  "sqs:PurgeQueue",
                  "sqs:ReceiveMessage"
              ],
              "Resource": "arn:aws:sqs:your-region:012345678901:your-queue-name"
          }
      ]
  }
  ```

  * Create an IAM user, copy its ARN, and create an access key for it in the `Security credentials` section of the user's page in the AWS console. Fill in the `SQS_ACCESS_KEY_ID` and `SQS_SECRET_ACCESS_KEY` environment variables with the access key ID and secret access key for the user you created earlier.
  * Create an IAM role, select `Custom trust policy`, and paste in this policy, replacing the `Statement[0].Principal.AWS` value with the ARN of the user you just created:

  ```json
  {
      "Version": "2012-10-17",
      "Statement": [
          {
              "Effect": "Allow",
              "Principal": {
                  "AWS": "arn:aws:iam::012345678901:user/your-user-name"
              },
              "Action": "sts:AssumeRole",
              "Condition": {}
          }
      ]
  }
  ```

  Then attach the policy you created earlier to this role, and fill in the `SQS_ROLE_ARN` environment variable with the role's ARN.

### Subscribing to notifications

#### **Using the Artisan command**

Run `php artisan notification:subscribe notification-type queue-type [ merchant-id ]`.

* `notification-type` is the type of notification you want to subscribe to.
* `queue-type` is the type of queue that the notification type is sent to (valid options are `sqs` or `eventbridge`). The SP API documentation [specifies the queue type](https://developer-docs.amazon.com/sp-api/docs/notification-type-values) for each notification type.
* `merchant-id` is the Amazon merchant ID of the seller you want to subscribe. If you don't specify a merchant ID, the command will subscribe to the notification type using the master credentials.

#### **Using the `NotificationsService` class**

```php
use App\Services\NotificationsService;
use SellingPartnerApi\Enums\AmazonQueueType;

$credentials = Credentials::master();
$notificationsService = new NotificationsService($credentials);
$queueType = AmazonQueueType::SQS;
$subscription = $notificationsService->subscribe('ACCOUNT_STATUS_CHANGE', $queueType);
```

`NotificationsService::subscribe()` returns a `Subscription` model, or `null` if the subscription already exists. It also accepts an optional `$processingDirective` parameter, which is an array of processing directives to be applied to the subscription. Processing directives and their use cases are documented [here](https://developer-docs.amazon.com/sp-api/docs/notifications-api-v1-use-case-guide#processing-directives).

### Unsubscribing from notifications

#### **Using the Artisan command**

To unsubscribe from a notification type, run `php artisan notification:unsubscribe notification-type [ merchant-id ]`.

* `notification-type` is the type of notification you want to unsubscribe from.
* `merchant-id` is the Amazon merchant ID of the seller you want to unsubscribe. If you don't specify a merchant ID, the command will unsubscribe from the notification type using the master credentials.

#### **Using the `NotificationsService` class**

```php
$credentials = Credentials::master();
$notificationsService = new NotificationsService($credentials);
$notificationsService->unsubscribe('ACCOUNT_STATUS_CHANGE');
```

There's a third way to unsubscribe from a particular notification type, which is by deleting the `Subscription` model:

```php
$amazonSubscriptionId = 'aaaa-bbbb-cccc-dddd';
$subscription = Subscription::firstWhere('amazon_subscription_id', $amazonSubscriptionId);
$subscription->delete();
```

### Processing notifications

When you subscribe to a notification type, add a corresponding case to the `match` block in `NotificationsService::processNotifications()` method, like so:

```php
match ($notification->type) {
    'ACCOUNT_STATUS_CHANGE' => static::processAccountStatusChangeNotification($notification),
    // ...
};
```

The `Notification` model's `payload` attribute contains the raw payload of the notification. Each notification type has a different payload structure, all of which are documented [here](https://developer-docs.amazon.com/sp-api/docs/notification-type-values).

Once your processing logic is complete, the `processNotifications()` method will automatically mark the notification as processed.

By default, all notifications older than 14 days are automatically deleted by a cron job. You can change this value by setting the `delete_after` option in the `notifications` section of the `config/spapi.php` config file.

{% hint style="info" %}
Depending on the number of inventory items you have and the notification types you subscribe to, you may receive a LOT of notifications. A certain amount of queue worker tuning may be required to keep up with the volume. This app has Laravel Horizon installed, which makes it much simpler to scale the queue workers. Horizon's documentation has detailed configuration instructions [here](https://laravel.com/docs/11.x/horizon).
{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.highsidelabs.co/sp-api-starter-kit/usage/notifications.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
