Skip to main content

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:

  1. Imports prayer content from the Magnificat API on a scheduled basis
  2. Stores the content locally in PostgreSQL for management and caching
  3. Publishes prayer references to WordPress sites via XML-RPC
  4. 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:

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

SettingValueDescription
Cron Expression47 */6 * * * UTCEvery 6 hours at minute 47
Date RangeYesterday to +30 daysConfigurable via settings
Localesen (US), fr (FR)Mapped to Magnificat edition codes

Import Process Details

  1. Date Range Calculation: The job imports prayers from yesterday through 30 days into the future (configurable)
  2. Feature Flag Check: Each locale is controlled by the magnificat Flipper feature flag scoped to the edition
  3. API Request: Calls the Magnificat webservice with date, locale, and channel parameters
  4. Upsert Logic: Uses item_id + locale as the unique key to update existing records or create new ones
  5. Child Handling: Children prayers are destroyed and recreated on each import to handle structure changes
  6. 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_email setting)
  • 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

FieldValueDescription
Post Typedaily_prayerCustom post type in WordPress
Post StatusdraftPosts are created as drafts
Post TitleLocalized datee.g., "Mercoled 22 Gennaio 2025"
Custom Field Keycontents_itemsArray 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

PropertyValue
URL/daily_prayers/:id
MethodGET
ResponseRaw HTML (no layout)
Cache1 hour, public, conditional GET support
HeadersCORS enabled for iframe embedding

Caching Strategy

The endpoint implements efficient caching:

  1. HTTP Caching: Cache-Control: public, max-age=3600, must-revalidate=false
  2. Conditional Requests: Uses stale? with the record's updated_at for ETag/Last-Modified support
  3. 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:

SettingDefaultDescription
magnificat_days30Number of future days to import
magnificat_channelALTMagnificat channel identifier
magnificat_email[email protected]Error notification recipient

Environment Variables

VariableRequiredDescription
MAGNIFICAT_URLYesBase URL of the Magnificat webservice
PRAYER_POST_UPDATESNoSet to false to disable updates (default: true)

Feature Flag

The integration uses a Flipper feature flag to control which locales are enabled:

FlagTypeDescription
magnificatEdition-scopedEnable/disable import per locale

To enable for a specific locale in the Flipper UI:

  1. Navigate to /flipper
  2. Find the magnificat feature
  3. Enable for the edition:en or edition:fr actor

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

  1. Navigate to /resources/prayer_posts
  2. Select the post(s) to republish
  3. Run the "Republish Post" action
  4. 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

IssuePossible CauseSolution
Prayers not importingFeature flag disabledEnable magnificat for the edition
Webservice errorsAPI unavailableCheck magnificat_email for notifications
Stale contentUpdates disabledCheck PRAYER_POST_UPDATES env var
Missing content on AleteiaPost in draft statusPublish the post in WordPress

Logs

Key log messages to look for:

  • Importing webservice content - Start of import for date/locale
  • Imported daily prayer - Individual prayer saved
  • Prayer post successfully published - WordPress post created
  • Webservice error - API failure (check email)