Files
daily-notification-plugin/AI_INTEGRATION_GUIDE.md
Matthew Raymer 37753bb051 docs: add comprehensive integration guides and diagnostic method documentation
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.
2025-11-06 10:08:18 +00:00

13 KiB

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

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:

{
  "dependencies": {
    "@timesafari/daily-notification-plugin": "^1.0.1"
  }
}

Command

npm install @timesafari/daily-notification-plugin

Verification

# 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

npx cap sync android
npx cap sync ios

Verification

# 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:

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <application>
        <!-- existing content -->
    </application>
</manifest>

After:

<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:

<application>
    <activity android:name=".MainActivity">
        <!-- existing activity config -->
    </activity>
</application>

After:

<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

# 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:

<dict>
    <key>CFBundleName</key>
    <string>App</string>
    <!-- other keys -->
</dict>

After:

<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

# 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:

import { createApp } from 'vue'
import App from './App.vue'

const app = createApp(App)
app.mount('#app')

After:

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

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

// 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

# Android
cd android
./gradlew assembleDebug

# iOS
cd ios
pod install
# Then build in Xcode

Test Commands

# 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:

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:

# 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

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: