[Video](https://www.youtube.com/watch?v=_TrXJXkIZBs)

Notifications allow your Cloud-to-cloud integration to use
Google Assistant to communicate with users about important
device-related events or changes. You can implement notifications to alert
users to timely device events, for example when someone is at the door, or to
report on a requested device state change, such as when a door lock bolt has
been successfully engaged or has jammed.

Your Cloud-to-cloud integration can send the following types of
notifications to users:

- **Proactive notifications** : Alerts the user of a smart home
  device event without any preceding user requests to their devices, such as the
  doorbell ringing.

- **Follow-up responses**: A confirmation that a device command request
  succeeded or failed, for example when locking a door. Use these alerts for
  device commands that take time to complete. Follow-up responses are only
  supported when device command requests are sent from smart speakers and smart
  displays.

Assistant provides these notifications to users as
announcements on smart speakers and smart displays. Proactive notifications
are turned off by default.
Users have the ability to turn on or off all proactive notifications from the
[Google Home app (GHA)](https://play.google.com/store/apps/details?id=com.google.android.apps.chromecast.app).

## Events that trigger notifications

When device events occur, your fulfilment sends a notification request
to Google. The device traits that your Cloud-to-cloud integration
supports determines what types of notification events are available and the
data you can include in those notifications.

The following traits support proactive notifications:

| Trait | Events |
|---|---|
| [ObjectDetection](https://developers.home.google.com/cloud-to-cloud/traits/objectdetection.md.txt) | Objects detected by the device, such as when a recognized face is detected at the door. For example: *"Alice and Bob are at the front door."* |
| [RunCycle](https://developers.home.google.com/cloud-to-cloud/traits/runcycle.md.txt) | Device completes a cycle. For example: *"The washing machine cycle has completed."* |
| [SensorState](https://developers.home.google.com/cloud-to-cloud/traits/sensorstate.md.txt) | Device detects a supported sensor state. For example: *"The smoke detector detects smoke."* |

<br />

The following traits support follow-up responses:

| Trait | Events |
|---|---|
| [LockUnlock](https://developers.home.google.com/cloud-to-cloud/traits/lockunlock.md.txt) | Completion status and state change following execution of the `action.devices.commands.LockUnlock` device command. For example: *"The front door has been locked"* or *"The front door is jammed."* |
| [NetworkControl](https://developers.home.google.com/cloud-to-cloud/traits/networkcontrol.md.txt) | Completion status and state change following execution of the `action.devices.commands.TestNetworkSpeed` device command. For example: *"Your network speed test has finished. The download speed on the office router is currently 80.2 Kbps, and the upload speed is 9.3 Kbps."* |
| [OpenClose](https://developers.home.google.com/cloud-to-cloud/traits/openclose.md.txt) | Completion status and state change following execution of the `action.devices.commands.OpenClose` device command. For example: *"The front door has opened"* or *"The front door couldn't be opened."* |

All device types support notifications for the applicable traits.

## Build notifications for your Cloud-to-cloud integration

Add notifications to your Cloud-to-cloud integration in these
stages:

1. Indicate to Google if notifications are enabled from your smart home device app. If users turn notifications on or off in your app, send a `SYNC` request to inform Google of the device change.
2. When a relevant device event or state change occurs that triggers a notification, send a notification request by calling the Report State `reportStateAndNotification` API. If the device state changed, you can send both a state and notification payload together in your Report State and Notification call.

The following sections cover these steps in more detail.

### Indicate if notifications are enabled in your app

Users can choose whether they want to receive proactive notifications by
enabling this feature in the GHA. In the app for your
smart home device, you can also optionally add the ability for
users to explicitly toggle notifications from the device, for example, from
your app settings.

> [!NOTE]
> **Note:** Users will not receive proactive notifications unless this feature is turned on in the GHA. See [Manage your Google Home app notifications](https://support.google.com/googlenest/answer/7161371) to learn how users enable GHA notifications.

Indicate to Google that notifications are enabled for your device by making
a [Request SYNC](https://developers.home.google.com/cloud-to-cloud/integration/request-sync.md.txt) call
to update device data. You should send a `SYNC` request like this whenever
users change this setting in your app.

In your `SYNC` response, send one of these updates:

- If the user explicitly toggled notifications on in your device app, or if you do not provide a toggle option, set the `devices.notificationSupportedByAgent` property to `true`.
- If the user explicitly toggled notifications off in your device app, set the `devices.notificationSupportedByAgent` property to `false`.

The following snippet shows an example of how to set your SYNC response:

    devices: [{
       id: 'device123',
       ...
       notificationSupportedByAgent: true,
    }]

### Send notification requests to Google

To trigger notifications on the Assistant, your
fulfillment sends a notification payload to the Google Home Graph
via a [Report State and Notification API call](https://developers.home.google.com/cloud-to-cloud/integration/notifications.md.txt#send-notification).

#### Enable the Google HomeGraph API

1. In the Google Cloud Console, go to the **HomeGraph API** page.

   [Go to the HomeGraph API page](https://console.cloud.google.com/apis/api/homegraph.googleapis.com/overview)
2. Select the project that matches your smart home project ID.
3. Click **ENABLE**.

#### Create a Service Account Key

Follow these instructions to generate a service account key from the Google Cloud Console:
**Note** : Ensure that you are using the correct GCP project when performing these steps. This is the project that matches your smart home project ID.

1. In the Google Cloud Console, go to the **Service accounts** page.

   [Go to the Service Accounts page](https://console.cloud.google.com/iam-admin/serviceaccounts).

   You may need to select a project before you're taken to the Service Accounts page.
2. Click **Create service account**.

3. In the **Service account name** field, enter a name.

4. In the **Service account ID** field, enter a ID.

5. In the **Service account description** field, enter a description.

6. Click **Create and continue**.

7. From the **Role** dropdown, select **Service Accounts** \> **Service Account OpenID Connect Identity Token Creator**.

8. Click **Continue**.

9. Click **Done**.

10. Select the service account you just created from the list of service accounts and
    select **Manage keys** from the
    **Actions** menu.

11. Select **Add key** \> **Create new key**.

12. For the **Key type** , select the **JSON** option.

13. Click **Create**. A JSON file that contains your key
    downloads to your computer.

For detailed instructions and information about creating service account keys, see [Create
and delete service account keys](https://cloud.google.com/iam/docs/keys-create-delete#creating) on the Google Cloud Console Help site.

#### Send the notification

Make the notification request call using the
[`devices.reportStateAndNotification`](https://developers.home.google.com/reference/home-graph/rest/v1/devices/reportStateAndNotification.md.txt) API.
Your JSON request must include an `eventId`, which is a unique ID generated by
your platform for the event triggering the notification. The `eventId` should
be a random ID that is different every time you send a notification request.

In the `notifications` object that you pass in your API call, include a
`priority` value which defines how the notification should be presented. Your
`notifications` object may include different fields depending on the device
trait.

> [!NOTE]
> **Note:** If a device state change triggered the notification, remember to update Home Graph by sending the state payload together with the notification payload in your Report State and Notification call.

Follow one of these paths to set the payload and call the API:

- [Send a proactive notification payload](https://developers.home.google.com/cloud-to-cloud/integration/notifications.md.txt#proactive-notification-payload)
- [Send a follow-up response payload](https://developers.home.google.com/cloud-to-cloud/integration/notifications.md.txt#follow-up-response-payload)

##### Send a proactive notification payload

To call the API, select an option from one of these tabs:

### HTTP

The Home Graph API provides an
[HTTP endpoint](https://developers.home.google.com/reference/home-graph/rest.md.txt)

1. Use the downloaded service account JSON file to create a JSON Web Token (JWT). For more information, see [Authenticating Using a Service Account](https://cloud.google.com/endpoints/docs/openapi/service-account-authentication).
2. Obtain an OAuth 2.0 access token with the `https://www.googleapis.com/auth/homegraph` scope using [oauth2l](https://github.com/google/oauth2l):

```
oauth2l fetch --credentials service-account.json \
  --scope https://www.googleapis.com/auth/homegraph
```
3. Create the JSON request with the `agentUserId`. Here's a sample JSON request for Report State and Notification:

```console
{
  "agentUserId": "PLACEHOLDER-USER-ID",
  "eventId": "PLACEHOLDER-EVENT-ID",
  "requestId": "PLACEHOLDER-REQUEST-ID",
  "payload": {
    "devices": {
      "notifications": {
        "PLACEHOLDER-DEVICE-ID": {
          "ObjectDetection": {
            "priority": 0,
            "detectionTimestamp": 1534875126750,
            "objects": {
              "named": [
                "Alice"
              ],
              "unclassified": 2
            }
          }
        }
      }
    }
  }
}
```
4. Combine the Report State and Notification JSON and the token in your HTTP POST request to the Google Home Graph endpoint. Here's an example of how to make the request in the command line using `curl`, as a test:

```
curl -X POST -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d @request-body.json \
  "https://homegraph.googleapis.com/v1/devices:reportStateAndNotification"
```

### gRPC

The Home Graph API provides a
[gRPC endpoint](https://developers.home.google.com/reference/home-graph/rpc.md.txt)

1. Get the [protocol buffers service definition](https://github.com/googleapis/googleapis/blob/master/google/home/graph/v1/homegraph.proto) for the Home Graph API.
2. Follow the gRPC developer documentation to generate client stubs for one of the [supported languages](https://grpc.io/docs/languages/).
3. Call the [ReportStateAndNotification](https://developers.home.google.com/reference/home-graph/rpc/google.home.graph.v1.md.txt#google.home.graph.v1.HomeGraphApiService.ReportStateAndNotification) method.

### Node.js

The [Google APIs
Node.js Client](https://www.npmjs.com/package/googleapis) provides bindings for the Home Graph
API.

1. Initialize the [`google.homegraph`](https://googleapis.dev/nodejs/googleapis/latest/homegraph/classes/Homegraph.html) service using [Application Default Credentials](https://www.npmjs.com/package/googleapis#application-default-credentials).
2. Call the [`reportStateAndNotification`](https://googleapis.dev/nodejs/googleapis/latest/homegraph/classes/Resource$Devices.html#reportStateAndNotification) method with the [ReportStateAndNotificationRequest](https://googleapis.dev/nodejs/googleapis/latest/homegraph/interfaces/Schema$ReportStateAndNotificationRequest.html). It returns a `Promise` with the [ReportStateAndNotificationResponse](https://googleapis.dev/nodejs/googleapis/latest/homegraph/interfaces/Schema$ReportStateAndNotificationResponse.html).

```javascript
const homegraphClient = homegraph({
  version: 'v1',
  auth: new GoogleAuth({
    scopes: 'https://www.googleapis.com/auth/homegraph'
  })
});

const res = await homegraphClient.devices.reportStateAndNotification({
  requestBody: {
    agentUserId: 'PLACEHOLDER-USER-ID',
    eventId: 'PLACEHOLDER-EVENT-ID',
    requestId: 'PLACEHOLDER-REQUEST-ID',
    payload: {
      devices: {
        notifications: {
          'PLACEHOLDER-DEVICE-ID': {
            ObjectDetection: {
              priority: 0,
              detectionTimestamp: 1534875126750,
              objects: {
                named: ['Alice'],
                unclassified: 2
              }
            }
          }
        }
      }
    }
  }
});
    
```

### Java

The [HomeGraph API Client Library for Java](https://github.com/googleapis/google-api-java-client-services/tree/master/clients/google-api-services-homegraph/v1)
provides bindings for the Home Graph API.

1. Initialize the [`HomeGraphApiService`](https://googleapis.dev/java/google-api-services-homegraph/latest/com/google/api/services/homegraph/v1/HomeGraphService.html) using [Application
   Default Credentials](https://github.com/googleapis/google-auth-library-java#application-default-credentials).
2. Call the [`reportStateAndNotification`](https://googleapis.dev/java/google-api-services-homegraph/latest/com/google/api/services/homegraph/v1/HomeGraphService.Devices.html#reportStateAndNotification-com.google.api.services.homegraph.v1.model.ReportStateAndNotificationRequest-) method with the [`ReportStateAndNotificationRequest`](https://googleapis.dev/java/google-api-services-homegraph/latest/com/google/api/services/homegraph/v1/model/ReportStateAndNotificationRequest.html). It returns a [`ReportStateAndNotificationResponse`](https://googleapis.dev/java/google-api-services-homegraph/latest/com/google/api/services/homegraph/v1/model/ReportStateAndNotificationResponse.html).

```java
// Get Application Default credentials.
GoogleCredentials credentials =
    GoogleCredentials.getApplicationDefault()
        .createScoped(List.of("https://www.googleapis.com/auth/homegraph"));

// Create Home Graph service client.
HomeGraphService homegraphService =
    new HomeGraphService.Builder(
            GoogleNetHttpTransport.newTrustedTransport(),
            GsonFactory.getDefaultInstance(),
            new HttpCredentialsAdapter(credentials))
        .setApplicationName("HomeGraphExample/1.0")
        .build();

// Build device notification payload.
Map<?, ?> notifications =
    Map.of(
        "ObjectDetection",
        Map.of(
            "priority", 0,
            "detectionTimestamp", 1534875126,
            "objects", Map.of("named", List.of("Alice"), "unclassifed", 2)));

// Send notification.
ReportStateAndNotificationRequest request =
    new ReportStateAndNotificationRequest()
        .setRequestId("PLACEHOLDER-REQUEST-ID")
        .setAgentUserId("PLACEHOLDER-USER-ID")
        .setEventId("PLACEHOLDER-EVENT-ID")
        .setPayload(
            new StateAndNotificationPayload()
                .setDevices(
                    new ReportStateAndNotificationDevice()
                        .setNotifications(Map.of("PLACEHOLDER-DEVICE-ID", notifications))));
homegraphService.devices().reportStateAndNotification(request);
    
```

##### Send a follow-up response payload

The payload for a follow-up response contains the status of the request, error
codes for event failures, if applicable, and the valid `followUpToken`,
provided during the `EXECUTE` intent request. The `followUpToken` must be used
within five minutes to remain valid and to properly associate the response
with the original request.

> [!IMPORTANT]
> **Important:** Follow-up responses should only be sent when your device responds with `PENDING` in the execution response, to avoid overwhelming users with notifications.

The following snippet shows an example `EXECUTE` request payload with a
`followUpToken` field.

```
{
  "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
  "inputs": [{
    "intent": "action.devices.EXECUTE",
    "payload": {
      "commands": [{
        "devices": [{
          "id": "123",
        }],
        "execution": [{
          "command": "action.devices.commands.TestNetworkSpeed",
          "params": {
            "testDownloadSpeed": true,
            "testUploadSpeed": false,
            "followUpToken": "PLACEHOLDER"
          }
        }]
      }]
    }
  }]
};
```

Google uses the `followUpToken` to output the notification only on the device
the user was originally interacting with, and not broadcast to across all the
user's devices.

To call the API, select an option from one of these tabs:

### HTTP

The Home Graph API provides an
[HTTP endpoint](https://developers.home.google.com/reference/home-graph/rest.md.txt)

1. Use the downloaded service account JSON file to create a JSON Web Token (JWT). For more information, see [Authenticating Using a Service Account](https://cloud.google.com/endpoints/docs/openapi/service-account-authentication).
2. Obtain an OAuth 2.0 access token with the `https://www.googleapis.com/auth/homegraph` scope using [oauth2l](https://github.com/google/oauth2l):

```
oauth2l fetch --credentials service-account.json \
  --scope https://www.googleapis.com/auth/homegraph
```
3. Create the JSON request with the `agentUserId`. Here's a sample JSON request for Report State and Notification:

```console
{
  "agentUserId": "PLACEHOLDER-USER-ID",
  "eventId": "PLACEHOLDER-EVENT-ID",
  "requestId": "PLACEHOLDER-REQUEST-ID",
  "payload": {
    "devices": {
      "notifications": {
        "PLACEHOLDER-DEVICE-ID": {
          "NetworkControl": {
            "priority": 0,
            "followUpResponse": {
              "status": "SUCCESS",
              "followUpToken": "PLACEHOLDER",
              "networkDownloadSpeedMbps": 23.3,
              "networkUploadSpeedMbps": 10.2
            }
          }
        }
      }
    }
  }
}
```
4. Combine the Report State and Notification JSON and the token in your HTTP POST request to the Google Home Graph endpoint. Here's an example of how to make the request in the command line using `curl`, as a test:

```
curl -X POST -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d @request-body.json \
  "https://homegraph.googleapis.com/v1/devices:reportStateAndNotification"
```

### gRPC

The Home Graph API provides a
[gRPC endpoint](https://developers.home.google.com/reference/home-graph/rpc.md.txt)

1. Get the [protocol buffers service definition](https://github.com/googleapis/googleapis/blob/master/google/home/graph/v1/homegraph.proto) for the Home Graph API.
2. Follow the gRPC developer documentation to generate client stubs for one of the [supported
   languages](https://grpc.io/docs/languages/).
3. Call the [ReportStateAndNotification](https://developers.home.google.com/reference/home-graph/rpc/google.home.graph.v1.md.txt#google.home.graph.v1.HomeGraphApiService.ReportStateAndNotification) method.

### Node.js

The [Google APIs
Node.js Client](https://www.npmjs.com/package/googleapis) provides bindings for the Home Graph
API.

1. Initialize the [`google.homegraph`](https://googleapis.dev/nodejs/googleapis/latest/homegraph/classes/Homegraph.html) service using [Application Default Credentials](https://www.npmjs.com/package/googleapis#application-default-credentials).
2. Call the [`reportStateAndNotification`](https://googleapis.dev/nodejs/googleapis/latest/homegraph/classes/Resource$Devices.html#reportStateAndNotification) method with the [ReportStateAndNotificationRequest](https://googleapis.dev/nodejs/googleapis/latest/homegraph/interfaces/Schema$ReportStateAndNotificationRequest.html). It returns a `Promise` with the [ReportStateAndNotificationResponse](https://googleapis.dev/nodejs/googleapis/latest/homegraph/interfaces/Schema$ReportStateAndNotificationResponse.html).

```javascript
const followUpToken = executionRequest.inputs[0].payload.commands[0].execution[0].params.followUpToken;

const homegraphClient = homegraph({
  version: 'v1',
  auth: new GoogleAuth({
    scopes: 'https://www.googleapis.com/auth/homegraph'
  })
});

const res = await homegraphClient.devices.reportStateAndNotification({
  requestBody: {
    agentUserId: 'PLACEHOLDER-USER-ID',
    eventId: 'PLACEHOLDER-EVENT-ID',
    requestId: 'PLACEHOLDER-REQUEST-ID',
    payload: {
      devices: {
        notifications: {
          'PLACEHOLDER-DEVICE-ID': {
            NetworkControl: {
              priority: 0,
              followUpResponse: {
                status: 'SUCCESS',
                followUpToken,
                networkDownloadSpeedMbps: 23.3,
                networkUploadSpeedMbps: 10.2,
              }
            }
          }
        }
      }
    }
  }
});
    
```

### Java

The [HomeGraph API Client Library for Java](https://github.com/googleapis/google-api-java-client-services/tree/master/clients/google-api-services-homegraph/v1)
provides bindings for the Home Graph API.

1. Initialize the [`HomeGraphApiService`](https://googleapis.dev/java/google-api-services-homegraph/latest/com/google/api/services/homegraph/v1/HomeGraphService.html) using [Application Default Credentials](https://github.com/googleapis/google-auth-library-java#application-default-credentials)
2. Call the [`reportStateAndNotification`](https://googleapis.dev/java/google-api-services-homegraph/latest/com/google/api/services/homegraph/v1/HomeGraphService.Devices.html#reportStateAndNotification-com.google.api.services.homegraph.v1.model.ReportStateAndNotificationRequest-) method with the [`ReportStateAndNotificationRequest`](https://googleapis.dev/java/google-api-services-homegraph/latest/com/google/api/services/homegraph/v1/model/ReportStateAndNotificationRequest.html). It returns a [`ReportStateAndNotificationResponse`](https://googleapis.dev/java/google-api-services-homegraph/latest/com/google/api/services/homegraph/v1/model/ReportStateAndNotificationResponse.html)

```java
// Get Application Default credentials.
GoogleCredentials credentials =
    GoogleCredentials.getApplicationDefault()
        .createScoped(List.of("https://www.googleapis.com/auth/homegraph"));

// Create Home Graph service client.
HomeGraphService homegraphService =
    new HomeGraphService.Builder(
            GoogleNetHttpTransport.newTrustedTransport(),
            GsonFactory.getDefaultInstance(),
            new HttpCredentialsAdapter(credentials))
        .setApplicationName("HomeGraphExample/1.0")
        .build();

// Extract follow-up token.
ExecuteRequest.Inputs executeInputs = (Inputs) executeRequest.getInputs()[0];
String followUpToken =
    (String)
        executeInputs
            .getPayload()
            .getCommands()[0]
            .getExecution()[0]
            .getParams()
            .get("followUpToken");

// Build device follow-up response payload.
Map<?, ?> followUpResponse =
    Map.of(
        "NetworkControl",
        Map.of(
            "priority",
            0,
            "followUpResponse",
            Map.of(
                "status",
                "SUCCESS",
                "followUpToken",
                followUpToken,
                "networkDownloadSpeedMbps",
                23.3,
                "networkUploadSpeedMbps",
                10.2)));

// Send follow-up response.
ReportStateAndNotificationRequest request =
    new ReportStateAndNotificationRequest()
        .setRequestId("PLACEHOLDER-REQUEST-ID")
        .setAgentUserId("PLACEHOLDER-USER-ID")
        .setEventId("PLACEHOLDER-EVENT-ID")
        .setPayload(
            new StateAndNotificationPayload()
                .setDevices(
                    new ReportStateAndNotificationDevice()
                        .setNotifications(Map.of("PLACEHOLDER-DEVICE-ID", followUpResponse))));
homegraphService.devices().reportStateAndNotification(request);
    
```

## Logging

Notifications support event logging as outlined in the [Cloud logging for
Cloud-to-cloud](https://developers.home.google.com/cloud-to-cloud/analytics/monitoring).
These logs are useful for testing and maintaining notifications quality within
your Action.

The following is the schema of a `notificationLog` entry:

| Property | Description |
|---|---|
| `requestId` | Notification request ID. |
| `structName` | Name of the notification struct, such as "ObjectDetection". |
| `status` | Indicates the [status](https://developers.home.google.com/cloud-to-cloud/integration/notifications.md.txt#example-statuses) of the notification. |

The `status` field includes various statuses that may indicate errors in the
notification payload. Some of these may only be available on Actions that have
not been launched to production.

Example statuses include:

| Status | Description |
|---|---|
| `EVENT_ID_MISSING` | Indicates that the required `eventId` field is missing. |
| `PRIORITY_MISSING` | Indicates that a `priority` field is missing. |
| `NOTIFICATION_SUPPORTED_BY_AGENT_FALSE` | Indicates that the notifying device's `notificationSupportedByAgent` property provided in `SYNC` is false. |
| `NOTIFICATION_ENABLED_BY_USER_FALSE` | Indicates that the user has not enabled notifications on the notifying device in the GHA. *This status is only available on integrations that have not been launched to production.* |
| `NOTIFYING_DEVICE_NOT_IN_STRUCTURE` | Indicates that the user has not assigned the notifying device to a Home/Structure. *This status is only available on integrations that have not been launched to production.* |

In addition to these general statuses that can apply to all notifications, the
`status` field may also include trait-specific statuses where applicable (for
example, `OBJECT_DETECTION_DETECTION_TIMESTAMP_MISSING`).