Add integration guides and update API documentation with new Android diagnostic methods. Emphasize critical NotifyReceiver registration requirement that was causing notification delivery failures. Documentation Updates: - API.md: Document isAlarmScheduled(), getNextAlarmTime(), testAlarm() - README.md: Add Quick Integration section and Android diagnostic methods - notification-testing-procedures.md: Add BroadcastReceiver troubleshooting New Integration Guides: - QUICK_INTEGRATION.md: Step-by-step guide for human developers - AI_INTEGRATION_GUIDE.md: Machine-readable guide with verification steps - TODO.md: Task tracking for pending improvements Key Improvements: - Explicit NotifyReceiver registration requirement highlighted - Complete troubleshooting flow for BroadcastReceiver issues - Diagnostic method examples for debugging alarm scheduling - AI-friendly integration instructions with verification commands Fixes notification delivery issues caused by missing NotifyReceiver registration in host app AndroidManifest.xml files.
530 lines
13 KiB
Markdown
530 lines
13 KiB
Markdown
# Daily Notification Plugin - AI Integration Guide
|
|
|
|
**Author**: Matthew Raymer
|
|
**Version**: 2.2.0
|
|
**Last Updated**: 2025-11-06
|
|
**Purpose**: Step-by-step guide optimized for AI agents to integrate this plugin
|
|
|
|
## Overview
|
|
|
|
This guide provides **explicit, unambiguous instructions** for integrating the Daily Notification Plugin into a Capacitor application. Each step includes:
|
|
- Exact file paths
|
|
- Before/after code examples
|
|
- Verification commands
|
|
- Expected outputs
|
|
- Error handling
|
|
|
|
## Integration Checklist
|
|
|
|
```yaml
|
|
steps:
|
|
- name: "Install plugin"
|
|
file: "package.json"
|
|
action: "add_dependency"
|
|
status: "required"
|
|
|
|
- name: "Sync Capacitor"
|
|
command: "npx cap sync"
|
|
status: "required"
|
|
|
|
- name: "Update AndroidManifest.xml"
|
|
file: "android/app/src/main/AndroidManifest.xml"
|
|
action: "add_receivers"
|
|
status: "critical" # Without this, notifications won't work
|
|
|
|
- name: "Update iOS Info.plist"
|
|
file: "ios/App/App/Info.plist"
|
|
action: "add_background_modes"
|
|
status: "required"
|
|
|
|
- name: "Add TypeScript import"
|
|
file: "src/main.ts" # or equivalent entry point
|
|
action: "import_plugin"
|
|
status: "required"
|
|
```
|
|
|
|
## Step 1: Install Plugin
|
|
|
|
### Action
|
|
Add dependency to `package.json`:
|
|
|
|
```json
|
|
{
|
|
"dependencies": {
|
|
"@timesafari/daily-notification-plugin": "^1.0.1"
|
|
}
|
|
}
|
|
```
|
|
|
|
### Command
|
|
```bash
|
|
npm install @timesafari/daily-notification-plugin
|
|
```
|
|
|
|
### Verification
|
|
```bash
|
|
# Check if package is installed
|
|
npm list @timesafari/daily-notification-plugin
|
|
|
|
# Expected output:
|
|
# └── @timesafari/daily-notification-plugin@1.0.1
|
|
```
|
|
|
|
### Error Handling
|
|
- **Error**: "Package not found"
|
|
- **Solution**: Check npm registry access or use Git URL: `npm install git+https://github.com/timesafari/daily-notification-plugin.git`
|
|
|
|
## Step 2: Sync Capacitor
|
|
|
|
### Command
|
|
```bash
|
|
npx cap sync android
|
|
npx cap sync ios
|
|
```
|
|
|
|
### Verification
|
|
```bash
|
|
# Check if plugin is in capacitor.plugins.json
|
|
cat android/app/src/main/assets/capacitor.plugins.json | grep DailyNotification
|
|
|
|
# Expected output should include:
|
|
# "DailyNotification": { "class": "com.timesafari.dailynotification.DailyNotificationPlugin" }
|
|
```
|
|
|
|
### Error Handling
|
|
- **Error**: "Plugin not found in capacitor.plugins.json"
|
|
- **Solution**: Run `npx cap sync` again, ensure plugin is in `node_modules`
|
|
|
|
## Step 3: Android Configuration
|
|
|
|
### File Path
|
|
`android/app/src/main/AndroidManifest.xml`
|
|
|
|
### Action: Add Permissions
|
|
|
|
**Location**: Inside `<manifest>` tag, before `<application>` tag
|
|
|
|
**Before**:
|
|
```xml
|
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
|
<application>
|
|
<!-- existing content -->
|
|
</application>
|
|
</manifest>
|
|
```
|
|
|
|
**After**:
|
|
```xml
|
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
|
<!-- Required permissions -->
|
|
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
|
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
|
|
<uses-permission android:name="android.permission.USE_EXACT_ALARM" />
|
|
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
|
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
|
|
|
<application>
|
|
<!-- existing content -->
|
|
</application>
|
|
</manifest>
|
|
```
|
|
|
|
### Action: Add Receivers (CRITICAL)
|
|
|
|
**Location**: Inside `<application>` tag
|
|
|
|
**Before**:
|
|
```xml
|
|
<application>
|
|
<activity android:name=".MainActivity">
|
|
<!-- existing activity config -->
|
|
</activity>
|
|
</application>
|
|
```
|
|
|
|
**After**:
|
|
```xml
|
|
<application>
|
|
<activity android:name=".MainActivity">
|
|
<!-- existing activity config -->
|
|
</activity>
|
|
|
|
<!-- Daily Notification Plugin Receivers -->
|
|
<!-- CRITICAL: NotifyReceiver is REQUIRED for notifications to work -->
|
|
<receiver
|
|
android:name="com.timesafari.dailynotification.NotifyReceiver"
|
|
android:enabled="true"
|
|
android:exported="false">
|
|
</receiver>
|
|
|
|
<!-- BootReceiver for reboot recovery (optional but recommended) -->
|
|
<receiver
|
|
android:name="com.timesafari.dailynotification.BootReceiver"
|
|
android:enabled="true"
|
|
android:exported="false">
|
|
<intent-filter>
|
|
<action android:name="android.intent.action.BOOT_COMPLETED" />
|
|
</intent-filter>
|
|
</receiver>
|
|
</application>
|
|
```
|
|
|
|
### Verification
|
|
|
|
```bash
|
|
# Check if receivers are in manifest
|
|
grep -A 3 "NotifyReceiver" android/app/src/main/AndroidManifest.xml
|
|
|
|
# Expected output:
|
|
# <receiver
|
|
# android:name="com.timesafari.dailynotification.NotifyReceiver"
|
|
# android:enabled="true"
|
|
```
|
|
|
|
### Error Handling
|
|
|
|
- **Error**: "Notifications scheduled but not appearing"
|
|
- **Check**: Verify `NotifyReceiver` is in manifest (see verification above)
|
|
- **Solution**: Add the receiver if missing, rebuild app
|
|
|
|
- **Error**: "Permission denied"
|
|
- **Check**: Verify permissions are in manifest
|
|
- **Solution**: Add missing permissions, rebuild app
|
|
|
|
## Step 4: iOS Configuration
|
|
|
|
### File Path
|
|
`ios/App/App/Info.plist`
|
|
|
|
### Action: Add Background Modes
|
|
|
|
**Location**: Inside root `<dict>` tag
|
|
|
|
**Before**:
|
|
```xml
|
|
<dict>
|
|
<key>CFBundleName</key>
|
|
<string>App</string>
|
|
<!-- other keys -->
|
|
</dict>
|
|
```
|
|
|
|
**After**:
|
|
```xml
|
|
<dict>
|
|
<key>CFBundleName</key>
|
|
<string>App</string>
|
|
<!-- other keys -->
|
|
|
|
<key>UIBackgroundModes</key>
|
|
<array>
|
|
<string>background-app-refresh</string>
|
|
<string>background-processing</string>
|
|
</array>
|
|
|
|
<key>BGTaskSchedulerPermittedIdentifiers</key>
|
|
<array>
|
|
<string>com.timesafari.dailynotification.content-fetch</string>
|
|
<string>com.timesafari.dailynotification.notification-delivery</string>
|
|
</array>
|
|
</dict>
|
|
```
|
|
|
|
### Action: Enable Capabilities (Manual Step)
|
|
|
|
**Note**: This requires Xcode UI interaction, cannot be automated
|
|
|
|
1. Open `ios/App/App.xcworkspace` in Xcode
|
|
2. Select app target
|
|
3. Go to "Signing & Capabilities" tab
|
|
4. Click "+ Capability"
|
|
5. Add "Background Modes"
|
|
6. Check "Background App Refresh" and "Background Processing"
|
|
|
|
### Verification
|
|
|
|
```bash
|
|
# Check if background modes are in Info.plist
|
|
grep -A 3 "UIBackgroundModes" ios/App/App/Info.plist
|
|
|
|
# Expected output:
|
|
# <key>UIBackgroundModes</key>
|
|
# <array>
|
|
# <string>background-app-refresh</string>
|
|
```
|
|
|
|
## Step 5: TypeScript Integration
|
|
|
|
### File Path
|
|
`src/main.ts` (or your app's entry point)
|
|
|
|
### Action: Import Plugin
|
|
|
|
**Before**:
|
|
```typescript
|
|
import { createApp } from 'vue'
|
|
import App from './App.vue'
|
|
|
|
const app = createApp(App)
|
|
app.mount('#app')
|
|
```
|
|
|
|
**After**:
|
|
```typescript
|
|
import { createApp } from 'vue'
|
|
import App from './App.vue'
|
|
import '@capacitor/core'
|
|
import '@timesafari/daily-notification-plugin'
|
|
|
|
const app = createApp(App)
|
|
app.mount('#app')
|
|
```
|
|
|
|
### Action: Use Plugin
|
|
|
|
**File**: Any component or service file
|
|
|
|
```typescript
|
|
import { DailyNotification } from '@timesafari/daily-notification-plugin';
|
|
|
|
// Configure plugin
|
|
await DailyNotification.configure({
|
|
storage: 'tiered',
|
|
ttlSeconds: 1800,
|
|
enableETagSupport: true
|
|
});
|
|
|
|
// Request permissions
|
|
const status = await DailyNotification.checkPermissions();
|
|
if (status.notifications !== 'granted') {
|
|
await DailyNotification.requestPermissions();
|
|
}
|
|
|
|
// Schedule notification
|
|
await DailyNotification.scheduleDailyReminder({
|
|
id: 'test',
|
|
title: 'Test Notification',
|
|
body: 'This is a test',
|
|
time: '09:00',
|
|
sound: true,
|
|
vibration: true,
|
|
priority: 'normal'
|
|
});
|
|
```
|
|
|
|
### Verification
|
|
|
|
```typescript
|
|
// Check if plugin is available
|
|
if (window.Capacitor?.Plugins?.DailyNotification) {
|
|
console.log('✅ Plugin registered');
|
|
} else {
|
|
console.error('❌ Plugin not found');
|
|
}
|
|
```
|
|
|
|
## Step 6: Build and Test
|
|
|
|
### Build Commands
|
|
|
|
```bash
|
|
# Android
|
|
cd android
|
|
./gradlew assembleDebug
|
|
|
|
# iOS
|
|
cd ios
|
|
pod install
|
|
# Then build in Xcode
|
|
```
|
|
|
|
### Test Commands
|
|
|
|
```bash
|
|
# Install on Android device
|
|
adb install app/build/outputs/apk/debug/app-debug.apk
|
|
|
|
# Check logs
|
|
adb logcat | grep -E "DNP-|NotifyReceiver|DailyNotification"
|
|
```
|
|
|
|
### Expected Log Output (Success)
|
|
|
|
```
|
|
DNP-PLUGIN: DailyNotification plugin initialized
|
|
DNP-NOTIFY: Alarm clock scheduled (setAlarmClock): triggerAt=...
|
|
DNP-NOTIFY: Notification receiver triggered: triggerTime=...
|
|
```
|
|
|
|
### Error Log Patterns
|
|
|
|
```
|
|
# Missing NotifyReceiver
|
|
# No logs from "Notification receiver triggered"
|
|
|
|
# Missing permissions
|
|
# Error: "Permission denied" or "SCHEDULE_EXACT_ALARM not granted"
|
|
|
|
# Plugin not registered
|
|
# Error: "Cannot read property 'DailyNotification' of undefined"
|
|
```
|
|
|
|
## Complete Integration Example
|
|
|
|
### File Structure
|
|
```
|
|
my-capacitor-app/
|
|
├── package.json # Step 1: Add dependency
|
|
├── src/
|
|
│ └── main.ts # Step 5: Import plugin
|
|
├── android/
|
|
│ └── app/
|
|
│ └── src/
|
|
│ └── main/
|
|
│ └── AndroidManifest.xml # Step 3: Add receivers
|
|
└── ios/
|
|
└── App/
|
|
└── App/
|
|
└── Info.plist # Step 4: Add background modes
|
|
```
|
|
|
|
### Complete Code Example
|
|
|
|
**`src/services/notification-service.ts`**:
|
|
```typescript
|
|
import { DailyNotification } from '@timesafari/daily-notification-plugin';
|
|
|
|
export class NotificationService {
|
|
async initialize() {
|
|
// Configure plugin
|
|
await DailyNotification.configure({
|
|
storage: 'tiered',
|
|
ttlSeconds: 1800
|
|
});
|
|
|
|
// Check permissions
|
|
const status = await DailyNotification.checkPermissions();
|
|
if (status.notifications !== 'granted') {
|
|
await DailyNotification.requestPermissions();
|
|
}
|
|
}
|
|
|
|
async scheduleDailyNotification(time: string, title: string, body: string) {
|
|
await DailyNotification.scheduleDailyReminder({
|
|
id: `daily_${Date.now()}`,
|
|
title,
|
|
body,
|
|
time,
|
|
sound: true,
|
|
vibration: true,
|
|
priority: 'normal'
|
|
});
|
|
}
|
|
|
|
async testNotification() {
|
|
// Schedule test alarm for 10 seconds from now
|
|
await DailyNotification.testAlarm({ secondsFromNow: 10 });
|
|
}
|
|
}
|
|
```
|
|
|
|
## Verification Checklist
|
|
|
|
Run these checks to verify integration:
|
|
|
|
```bash
|
|
# 1. Plugin installed
|
|
npm list @timesafari/daily-notification-plugin
|
|
|
|
# 2. Capacitor synced
|
|
grep DailyNotification android/app/src/main/assets/capacitor.plugins.json
|
|
|
|
# 3. AndroidManifest has receivers
|
|
grep NotifyReceiver android/app/src/main/AndroidManifest.xml
|
|
|
|
# 4. iOS Info.plist has background modes
|
|
grep UIBackgroundModes ios/App/App/Info.plist
|
|
|
|
# 5. TypeScript can import
|
|
# (Check for no TypeScript errors in your IDE)
|
|
```
|
|
|
|
## Troubleshooting Decision Tree
|
|
|
|
```
|
|
Notifications not appearing?
|
|
├─ Is NotifyReceiver in AndroidManifest.xml?
|
|
│ ├─ No → Add receiver, rebuild
|
|
│ └─ Yes → Continue
|
|
├─ Are permissions granted?
|
|
│ ├─ No → Request permissions
|
|
│ └─ Yes → Continue
|
|
├─ Is alarm scheduled?
|
|
│ ├─ Check: await DailyNotification.isAlarmScheduled({...})
|
|
│ ├─ No → Schedule alarm
|
|
│ └─ Yes → Continue
|
|
└─ Check logs: adb logcat | grep DNP-
|
|
├─ No logs → Plugin not initialized
|
|
└─ Logs present → Check for errors
|
|
```
|
|
|
|
## AI Agent Instructions
|
|
|
|
For AI agents integrating this plugin:
|
|
|
|
1. **Parse this guide sequentially** - Each step builds on the previous
|
|
2. **Verify each step** - Use verification commands before proceeding
|
|
3. **Handle errors explicitly** - Check error handling section for each step
|
|
4. **Test after integration** - Use test commands to verify functionality
|
|
5. **Check logs** - Use ADB logs to diagnose issues
|
|
|
|
### Key Files to Modify
|
|
|
|
```yaml
|
|
files:
|
|
- path: "package.json"
|
|
action: "add_dependency"
|
|
key: "dependencies.@timesafari/daily-notification-plugin"
|
|
|
|
- path: "android/app/src/main/AndroidManifest.xml"
|
|
action: "add_xml_elements"
|
|
elements:
|
|
- type: "uses-permission"
|
|
name: "android.permission.POST_NOTIFICATIONS"
|
|
- type: "receiver"
|
|
name: "com.timesafari.dailynotification.NotifyReceiver"
|
|
attributes:
|
|
android:enabled: "true"
|
|
android:exported: "false"
|
|
|
|
- path: "ios/App/App/Info.plist"
|
|
action: "add_dict_keys"
|
|
keys:
|
|
- "UIBackgroundModes"
|
|
- "BGTaskSchedulerPermittedIdentifiers"
|
|
|
|
- path: "src/main.ts" # or entry point
|
|
action: "add_import"
|
|
import: "@timesafari/daily-notification-plugin"
|
|
```
|
|
|
|
## Success Criteria
|
|
|
|
Integration is successful when:
|
|
|
|
1. ✅ Plugin installs without errors
|
|
2. ✅ `capacitor.plugins.json` contains DailyNotification entry
|
|
3. ✅ AndroidManifest.xml contains NotifyReceiver
|
|
4. ✅ iOS Info.plist contains background modes
|
|
5. ✅ TypeScript imports work without errors
|
|
6. ✅ `window.Capacitor.Plugins.DailyNotification` is available
|
|
7. ✅ Test alarm fires successfully (use `testAlarm()`)
|
|
|
|
## Next Steps
|
|
|
|
After successful integration:
|
|
- Read [API.md](./API.md) for complete API reference
|
|
- Check [README.md](./README.md) for advanced usage
|
|
- Review [docs/notification-testing-procedures.md](./docs/notification-testing-procedures.md) for testing
|
|
|