Magnificat Daily Prayers Integration
This document describes the integration with Magnificat, a provider of liturgical content, to automatically import daily prayers and publish them to Aleteia WordPress sites.
Overview
The Magnificat integration enables Aleteia to offer daily prayer content (morning prayer, meditation, evening prayer) sourced from the Magnificat webservice. The system:
- Imports prayer content from the Magnificat API on a scheduled basis
- Stores the content locally in PostgreSQL for management and caching
- Publishes prayer references to WordPress sites via XML-RPC
- Serves the actual HTML content via a dedicated endpoint that WordPress embeds
This architecture decouples the prayer content from WordPress, allowing for centralized management and efficient caching while WordPress handles the presentation layer.
Architecture Overview
Data Flow:
| Step | Description |
|---|---|
| ① | Scheduled job fetches prayer content from Magnificat API (every 6 hours) |
| ② | Prayer references are published to WordPress via XML-RPC |
| ③ | WordPress pages request prayer HTML via iframe |
| ④ | Rails serves cached HTML content to the reader's browser |
Import Flow
The import process runs automatically on a schedule and can also be triggered manually.
Schedule
The import job runs on the following schedule:
| Setting | Value | Description |
|---|---|---|
| Cron Expression | 47 */6 * * * UTC | Every 6 hours at minute 47 |
| Date Range | Yesterday to +30 days | Configurable via settings |
| Locales | en (US), fr (FR) | Mapped to Magnificat edition codes |
Import Process Details
- Date Range Calculation: The job imports prayers from yesterday through 30 days into the future (configurable)
- Feature Flag Check: Each locale is controlled by the
magnificatFlipper feature flag scoped to the edition - API Request: Calls the Magnificat webservice with date, locale, and channel parameters
- Upsert Logic: Uses
item_id+localeas the unique key to update existing records or create new ones - Child Handling: Children prayers are destroyed and recreated on each import to handle structure changes
- Publish Scheduling: After import, a publish job is queued for each affected
PrayerPost
Error Handling
If the Magnificat webservice fails:
- An error email is sent to the configured address (
magnificat_emailsetting) - Errors within 1 week are reported to Rollbar
- Errors beyond 1 week are logged but not escalated (content may not exist yet)
WordPress Publishing Flow
After import, each PrayerPost is published to the corresponding WordPress site.
WordPress Post Structure
| Field | Value | Description |
|---|---|---|
| Post Type | daily_prayer | Custom post type in WordPress |
| Post Status | draft | Posts are created as drafts |
| Post Title | Localized date | e.g., "Mercoled 22 Gennaio 2025" |
| Custom Field Key | contents_items | Array of prayer references |
Custom Fields Structure
The contents_items custom field contains a PHP-serialized array:
[
{
"title": "Morning Prayer",
"raw_id": 12345,
"is_morning_prayer": true
},
{
"title": "Daily Meditation",
"raw_id": 12346,
"is_daily_meditation": true
},
{
"title": "Evening Prayer",
"raw_id": 12347,
"is_evening_prayer": true
}
]
The raw_id field contains the DailyPrayer record ID, which WordPress uses to fetch the HTML content.
Update vs Create Logic
- Create: First time a date/locale combination is published. Sets flags (
is_morning_prayer, etc.) based on position heuristics. - Update: Merges new prayer IDs with existing custom items, preserving any custom content added directly in WordPress.
Content Exposure
WordPress sites fetch the actual prayer HTML content from the Rails application.
Endpoint Details
| Property | Value |
|---|---|
| URL | /daily_prayers/:id |
| Method | GET |
| Response | Raw HTML (no layout) |
| Cache | 1 hour, public, conditional GET support |
| Headers | CORS enabled for iframe embedding |
Caching Strategy
The endpoint implements efficient caching:
- HTTP Caching:
Cache-Control: public, max-age=3600, must-revalidate=false - Conditional Requests: Uses
stale?with the record'supdated_atfor ETag/Last-Modified support - CDN-Friendly: Public caching allows CDN and browser caching
Iframe Embedding
WordPress templates embed the prayer content via iframes:
<iframe
src="https://reports.aleteia.org/daily_prayers/12345"
style="width: 100%; min-height: 300px; border: none;">
</iframe>
The allow_iframe! callback sets appropriate headers for cross-origin embedding.
Configuration
Settings
Configure the integration via the Settings model in Avo admin:
| Setting | Default | Description |
|---|---|---|
magnificat_days | 30 | Number of future days to import |
magnificat_channel | ALT | Magnificat channel identifier |
magnificat_email | [email protected] | Error notification recipient |
Environment Variables
| Variable | Required | Description |
|---|---|---|
MAGNIFICAT_URL | Yes | Base URL of the Magnificat webservice |
PRAYER_POST_UPDATES | No | Set to false to disable updates (default: true) |
Feature Flag
The integration uses a Flipper feature flag to control which locales are enabled:
| Flag | Type | Description |
|---|---|---|
magnificat | Edition-scoped | Enable/disable import per locale |
To enable for a specific locale in the Flipper UI:
- Navigate to
/flipper - Find the
magnificatfeature - Enable for the
edition:enoredition:fractor
Admin Operations
The Avo admin panel provides interfaces for managing prayer content.
DailyPrayer Resource
Located at /resources/daily_prayers:
- View: See all imported prayers with date, name, locale
- Filters: Filter by edition (locale) and date range
- Content Preview: Embedded iframe showing rendered HTML
- Relationships: Navigate to parent prayer or associated PrayerPost
PrayerPost Resource
Located at /resources/prayer_posts:
- View: See all WordPress posts with publish status
- External Link: Direct link to the post on WordPress
- Relationships: See associated DailyPrayer records
Manual Republish
To force republish a prayer post (e.g., after manual corrections):
- Navigate to
/resources/prayer_posts - Select the post(s) to republish
- Run the "Republish Post" action
- The publish job will run immediately with
force: true
This bypasses the PRAYER_POST_UPDATES flag and updates the WordPress post regardless of the setting.
Viewing on WordPress
Each PrayerPost provides quick links:
- Show URL: Preview the post on WordPress (even if draft)
- Edit URL: Direct link to WordPress admin editor
Troubleshooting
Common Issues
| Issue | Possible Cause | Solution |
|---|---|---|
| Prayers not importing | Feature flag disabled | Enable magnificat for the edition |
| Webservice errors | API unavailable | Check magnificat_email for notifications |
| Stale content | Updates disabled | Check PRAYER_POST_UPDATES env var |
| Missing content on Aleteia | Post in draft status | Publish the post in WordPress |
Logs
Key log messages to look for:
Importing webservice content- Start of import for date/localeImported daily prayer- Individual prayer savedPrayer post successfully published- WordPress post createdWebservice error- API failure (check email)