docs/platform/integrations/push/expo-push.mdx
This guide explains the process of configuring and using Expo Push with Novu, from getting your credentials to sending your first notification.
Before you can send notifications, you must connect your Expo project to Novu by generating an access token and adding it to your integration settings.
Generate an access token from your dashboard. This token authorizes Novu to send notifications on behalf of your project.
<Steps> <Step title="Log in to Expo"> Sign in at the [Expo console](https://expo.dev/). </Step> <Step title="Open Access Token"> Navigate to the **Credentials** section in the project settings sidebar. Click [**Access Token**](https://expo.dev/settings/access-tokens).  </Step> <Step title="Create a token"> A menu appears. </Step> <Step title="Generate the token"> Give it a descriptive name, and then click **Generate New Token**.  </Step> <Step title="Copy the token"> Copy and save the generated access token. You need it in the next step.  </Step> </Steps>Next, add the access token to your Expo integration in the Novu dashboard.
<Steps> <Step title="Log in to the Novu dashboard"> Open the [Novu Dashboard](https://dashboard.novu.co). </Step> <Step title="Open Integration Store"> On the Novu dashboard, navigate to the **Integration Store**. </Step> <Step title="Connect a provider"> In the **Integration Store**, click **Connect provider** to begin setup. </Step> <Step title="Select Expo Push"> In the **Push** tab, choose **Expo Push** from the provider list. </Step> <Step title="Paste the access token"> In the Expo integration form, paste the access token that you copied from Expo into the **Access Token** field.  </Step> <Step title="Create the integration"> Review your credentials, then click **Create Integration** to save. </Step> </Steps>Once your integration is configured, you can start sending push notifications by registering your subscribers' device tokens and triggering a workflow.
Before Novu can send a push notification to a subscriber (user), you must associate their device's unique push token with their Novu subscriber profile.
You can do this by making an API call to update the subscriber's credentials.
<Tabs> <Tab title="Node.js"> ```typescript import { Novu } from '@novu/api'; import { ChatOrPushProviderEnum } from "@novu/api/models/components";const novu = new Novu({ secretKey: "<NOVU_SECRET_KEY>" });
await novu.subscribers.credentials.update( { providerId: ChatOrPushProviderEnum.Expo, integrationIdentifier: "string", credentials: { deviceTokens: ["token1", "token2"] }, }, "subscriberId" );
</Tab>
<Tab title="Python">
```python
import os
import novu_py
from novu_py import Novu
with Novu(secret_key=os.getenv("NOVU_SECRET_KEY", "")) as novu:
novu.subscribers.credentials.update(
subscriber_id="subscriberId",
update_subscriber_channel_request_dto={
"provider_id": novu_py.ChatOrPushProviderEnum.EXPO,
"credentials": {"deviceTokens": ["token1", "token2"]},
"integration_identifier": "string",
},
)
novugo "github.com/novuhq/novu-go"
"github.com/novuhq/novu-go/models/components"
)
s := novugo.New(novugo.WithSecurity(os.Getenv("NOVU_SECRET_KEY")))
res, err := s.Subscribers.Credentials.Update(context.Background(), "subscriberId", components.UpdateSubscriberChannelRequestDto{ ProviderID: components.ChatOrPushProviderEnumExpo, IntegrationIdentifier: novugo.String("string"), Credentials: components.ChannelCredentials{ DeviceTokens: []string{"token1", "token2"}, }, }, nil)
</Tab>
<Tab title="PHP">
```php
use novu;
use novu\Models\Components;
$sdk = novu\Novu::builder()->setSecurity('<NOVU_SECRET_KEY>')->build();
$sdk->subscribersCredentials->update(
subscriberId: 'subscriberId',
updateSubscriberChannelRequestDto: new Components\UpdateSubscriberChannelRequestDto(
providerId: Components\ChatOrPushProviderEnum::Expo,
integrationIdentifier: 'string',
credentials: new Components\ChannelCredentials(
deviceTokens: ['token1', 'token2'],
),
),
);
var sdk = new NovuSDK(secretKey: "<NOVU_SECRET_KEY>");
await sdk.Subscribers.Credentials.UpdateAsync( subscriberId: "subscriberId", updateSubscriberChannelRequestDto: new UpdateSubscriberChannelRequestDto() { ProviderId = ChatOrPushProviderEnum.Expo, IntegrationIdentifier = "string", Credentials = new ChannelCredentials() { DeviceTokens = new List<string> { "token1", "token2" }, }, });
</Tab>
<Tab title="Java">
```java
import co.novu.Novu;
import co.novu.models.components.*;
import java.util.List;
Novu novu = Novu.builder().secretKey("<NOVU_SECRET_KEY>").build();
novu.subscribers().credentials().update()
.subscriberId("subscriberId")
.body(UpdateSubscriberChannelRequestDto.builder()
.providerId(ChatOrPushProviderEnum.EXPO)
.integrationIdentifier("string")
.credentials(ChannelCredentials.builder()
.deviceTokens(List.of("token1", "token2"))
.build())
.build())
.call();
Now you're ready to send a push notification.
<Tabs> <Tab title="Node.js"> ```typescript import { Novu } from '@novu/api';const novu = new Novu({ secretKey: "<NOVU_SECRET_KEY>" });
await novu.trigger({ workflowId: "workflowId", to: { subscriberId: "SUBSCRIBER_ID", }, payload: {}, });
</Tab>
<Tab title="Python">
```python
import os
import novu_py
from novu_py import Novu
with Novu(secret_key=os.getenv("NOVU_SECRET_KEY", "")) as novu:
novu.trigger(trigger_event_request_dto=novu_py.TriggerEventRequestDto(
workflow_id="workflowId",
to={"subscriber_id": "SUBSCRIBER_ID"},
payload={},
))
novugo "github.com/novuhq/novu-go"
"github.com/novuhq/novu-go/models/components"
)
s := novugo.New(novugo.WithSecurity(os.Getenv("NOVU_SECRET_KEY")))
res, err := s.Trigger(context.Background(), components.TriggerEventRequestDto{ WorkflowID: "workflowId", To: components.CreateToSubscriberPayloadDto(components.SubscriberPayloadDto{ SubscriberID: "SUBSCRIBER_ID", }), Payload: map[string]any{}, }, nil)
</Tab>
<Tab title="PHP">
```php
use novu;
use novu\Models\Components;
$sdk = novu\Novu::builder()->setSecurity('<NOVU_SECRET_KEY>')->build();
$sdk->trigger(
triggerEventRequestDto: new Components\TriggerEventRequestDto(
workflowId: 'workflowId',
to: new Components\SubscriberPayloadDto(subscriberId: 'SUBSCRIBER_ID'),
payload: {},
),
);
var sdk = new NovuSDK(secretKey: "<NOVU_SECRET_KEY>");
await sdk.TriggerAsync(triggerEventRequestDto: new TriggerEventRequestDto() { WorkflowId = "workflowId", To = To.CreateSubscriberPayloadDto(new SubscriberPayloadDto() { SubscriberId = "SUBSCRIBER_ID" }), Payload = {}, });
</Tab>
<Tab title="Java">
```java
import co.novu.Novu;
import co.novu.models.components.*;
Novu novu = Novu.builder().secretKey("<NOVU_SECRET_KEY>").build();
novu.trigger()
.body(TriggerEventRequestDto.builder()
.workflowId("workflowId")
.to(To2.of(SubscriberPayloadDto.builder().subscriberId("SUBSCRIBER_ID").build()))
.payload({})
.build())
.call();
const novu = new Novu({ secretKey: "<NOVU_SECRET_KEY>" });
await novu.trigger({ workflowId: "workflowId", to: { subscriberId: "subscriber-id-123", }, payload: { "orderId": "12345" }, overrides: { "providers": { "expo": { "title": "Order Update", "body": "Your order #12345 has been shipped!", "data": { "deepLink": "myapp://orders/12345", "orderId": "12345" }, "sound": "default", "priority": "high", "ttl": 3600 } } }, });
</Tab>
<Tab title="Python">
```python
import os
import novu_py
from novu_py import Novu
with Novu(secret_key=os.getenv("NOVU_SECRET_KEY", "")) as novu:
novu.trigger(trigger_event_request_dto=novu_py.TriggerEventRequestDto(
workflow_id="workflowId",
to={"subscriber_id": "subscriber-id-123"},
payload={
"orderId": "12345"
},
overrides={
"providers": {
"expo": {
"title": "Order Update",
"body": "Your order #12345 has been shipped!",
"data": {
"deepLink": "myapp://orders/12345",
"orderId": "12345"
},
"sound": "default",
"priority": "high",
"ttl": 3600
}
}
},
))
novugo "github.com/novuhq/novu-go"
"github.com/novuhq/novu-go/models/components"
)
s := novugo.New(novugo.WithSecurity(os.Getenv("NOVU_SECRET_KEY")))
res, err := s.Trigger(context.Background(), components.TriggerEventRequestDto{ WorkflowID: "workflowId", To: components.CreateToSubscriberPayloadDto(components.SubscriberPayloadDto{ SubscriberID: "subscriber-id-123", }), Payload: map[string]any{ "orderId": "12345" }, Overrides: map[string]any{ "providers": { "expo": { "title": "Order Update", "body": "Your order #12345 has been shipped!", "data": { "deepLink": "myapp://orders/12345", "orderId": "12345" }, "sound": "default", "priority": "high", "ttl": 3600 } } }, }, nil)
</Tab>
<Tab title="PHP">
```php
use novu;
use novu\Models\Components;
$sdk = novu\Novu::builder()->setSecurity('<NOVU_SECRET_KEY>')->build();
$sdk->trigger(
triggerEventRequestDto: new Components\TriggerEventRequestDto(
workflowId: 'workflowId',
to: new Components\SubscriberPayloadDto(subscriberId: 'subscriber-id-123'),
payload: {
"orderId": "12345"
},
overrides: {
"providers": {
"expo": {
"title": "Order Update",
"body": "Your order #12345 has been shipped!",
"data": {
"deepLink": "myapp://orders/12345",
"orderId": "12345"
},
"sound": "default",
"priority": "high",
"ttl": 3600
}
}
},
),
);
var sdk = new NovuSDK(secretKey: "<NOVU_SECRET_KEY>");
await sdk.TriggerAsync(triggerEventRequestDto: new TriggerEventRequestDto() { WorkflowId = "workflowId", To = To.CreateSubscriberPayloadDto(new SubscriberPayloadDto() { SubscriberId = "subscriber-id-123" }), Payload = { "orderId": "12345" }, Overrides = { "providers": { "expo": { "title": "Order Update", "body": "Your order #12345 has been shipped!", "data": { "deepLink": "myapp://orders/12345", "orderId": "12345" }, "sound": "default", "priority": "high", "ttl": 3600 } } }, });
</Tab>
<Tab title="Java">
```java
import co.novu.Novu;
import co.novu.models.components.*;
Novu novu = Novu.builder().secretKey("<NOVU_SECRET_KEY>").build();
novu.trigger()
.body(TriggerEventRequestDto.builder()
.workflowId("workflowId")
.to(To2.of(SubscriberPayloadDto.builder().subscriberId("subscriber-id-123").build()))
.payload({
"orderId": "12345"
})
.overrides({
"providers": {
"expo": {
"title": "Order Update",
"body": "Your order #12345 has been shipped!",
"data": {
"deepLink": "myapp://orders/12345",
"orderId": "12345"
},
"sound": "default",
"priority": "high",
"ttl": 3600
}
}
})
.build())
.call();