Skip to main content
Happy sends push notifications to your mobile device when Claude Code requires input, encounters errors, or completes tasks. Stay informed about your AI coding sessions even when you’re away from your computer.

How It Works

Push notifications are automatically enabled when you install the Happy mobile app. The system uses Expo’s push notification service to deliver real-time alerts to your device.

Notification Flow

Technical Implementation

Token Registration

When the mobile app starts, it automatically registers for push notifications:
// Push token registration from sync.ts
private registerPushToken = async () => {
  // Only register on mobile platforms
  if (Platform.OS === 'web') {
    return;
  }

  // Request permission
  const { status: existingStatus } = await Notifications.getPermissionsAsync();
  let finalStatus = existingStatus;

  if (existingStatus !== 'granted') {
    const { status } = await Notifications.requestPermissionsAsync();
    finalStatus = status;
  }

  if (finalStatus !== 'granted') {
    console.log('Failed to get push token for push notification!');
    return;
  }

  // Get push token
  const projectId = Constants?.expoConfig?.extra?.eas?.projectId;
  const tokenData = await Notifications.getExpoPushTokenAsync({ projectId });
  
  // Register with server
  await registerPushToken(credentials, tokenData.data);
};

Server API

The Happy server provides REST endpoints for managing push tokens:

Register Push Token

POST /v1/push-tokens
Authorization: Bearer <token>
Content-Type: application/json

{
  "token": "ExponentPushToken[xxxxxxxxxxxxxxxxxxxxxx]"
}
Response:
{
  "success": true
}

Delete Push Token

DELETE /v1/push-tokens/:token
Authorization: Bearer <token>
Response:
{
  "success": true
}

Get All Push Tokens

GET /v1/push-tokens
Authorization: Bearer <token>
Response:
{
  "tokens": [
    {
      "id": "token-id",
      "token": "ExponentPushToken[xxx]",
      "createdAt": 1234567890,
      "updatedAt": 1234567890
    }
  ]
}

Database Schema

Push tokens are stored in the database with user association:
// Prisma model (conceptual)
model AccountPushToken {
  id        String   @id @default(cuid())
  accountId String
  token     String
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
  
  @@unique([accountId, token])
}

Notification Types

Happy sends notifications for various events:

Permission Requests

Claude Code needs approval to execute tools or access files

Error Alerts

Your AI coding session encountered an error

Task Completion

Claude Code finished a long-running task

User Input Required

Claude is waiting for your response

Permission Management

Happy requests notification permissions on first launch:

iOS

  • One-time permission prompt
  • Can be managed in iOS Settings → Notifications → Happy
  • Supports notification grouping and custom sounds

Android

  • Notification channels for different alert types
  • Granular control per notification category
  • Android 13+ requires explicit permission grant

Permission States

type NotificationPermissionStatus = 
  | 'granted'    // User approved notifications
  | 'denied'     // User declined notifications
  | 'undetermined' // Not yet asked
In development mode (__DEV__), push notifications are disabled to avoid unnecessary API calls during testing.

Automatic Token Refresh

The app automatically refreshes push tokens when:
  • App returns to foreground
  • User logs in or restores account
  • Token expires or becomes invalid
// App state listener triggers token refresh
AppState.addEventListener('change', (nextAppState) => {
  if (nextAppState === 'active') {
    // Invalidate push token sync to refresh
    this.pushTokenSync.invalidate();
  }
});

Expo Push Notification Service

Happy uses Expo’s push notification infrastructure:
  • Cross-platform: Works on both iOS and Android
  • Reliable delivery: High success rate with automatic retries
  • Free tier: Included with Expo
  • FCM/APNs integration: Uses Firebase Cloud Messaging and Apple Push Notification service

Token Format

Expo push tokens follow this format:
ExponentPushToken[xxxxxxxxxxxxxxxxxxxxxx]

Privacy & Security

Push notifications are designed with privacy in mind:
1

Token Storage

Push tokens are stored server-side with user association but no device metadata
2

Secure Transmission

All API calls use HTTPS with bearer token authentication
3

No Content in Notifications

Sensitive code or data is never included in push notification payloads
4

User Control

Users can disable notifications at any time through system settings

Troubleshooting

Not Receiving Notifications?

Verify that Happy has notification permissions in your device settings.iOS: Settings → Notifications → Happy
Android: Settings → Apps → Happy → Notifications
The app should automatically register on launch. If issues persist, try logging out and back in.
Ensure your device has an active internet connection. Push notifications require connectivity to Expo’s push service.
Push notifications are disabled in development builds (__DEV__). Use a production build to test notifications.

Platform-Specific Issues

  • Notifications may be delayed if Low Power Mode is enabled
  • Silent notifications require proper background mode configuration
  • APNs requires proper provisioning profiles

Configuration

Push notifications work out of the box with default settings. For advanced configuration:
// Notification handler configuration
Notifications.setNotificationHandler({
  handleNotification: async () => ({
    shouldShowAlert: true,
    shouldPlaySound: true,
    shouldSetBadge: false,
  }),
});

Next Steps

Mobile Access

Learn about the mobile apps for iOS and Android

Device Switching

Switch control between desktop and mobile

Server Component

Explore the server architecture and API

Build docs developers (and LLMs) love