Back to skills
SkillHub ClubShip Full StackFull Stack

prayer-times

Get accurate Islamic prayer times (Fajr, Dhuhr, Asr, Maghrib, Isha) for any location worldwide using official calculation methods. Use when users ask about prayer times, Salat schedules, next prayer, or need to set up automated prayer reminders. Includes automated background reminder system that alerts users 10 minutes before, at prayer time, and 5 minutes after - even during conversations. Supports 20+ country-specific calculation methods including Morocco, Saudi Arabia, Egypt, Turkey, UAE, and more.

Packaged view

This page reorganizes the original catalog entry around fit, installability, and workflow context first. The original raw source lives below.

Stars
3,086
Hot score
99
Updated
March 20, 2026
Overall rating
C0.0
Composite score
0.0
Best-practice grade
B72.0

Install command

npx @skill-hub/cli install openclaw-skills-muslim-prayer-reminder

Repository

openclaw/skills

Skill path: skills/diepox/muslim-prayer-reminder

Get accurate Islamic prayer times (Fajr, Dhuhr, Asr, Maghrib, Isha) for any location worldwide using official calculation methods. Use when users ask about prayer times, Salat schedules, next prayer, or need to set up automated prayer reminders. Includes automated background reminder system that alerts users 10 minutes before, at prayer time, and 5 minutes after - even during conversations. Supports 20+ country-specific calculation methods including Morocco, Saudi Arabia, Egypt, Turkey, UAE, and more.

Open repository

Best for

Primary workflow: Ship Full Stack.

Technical facets: Full Stack.

Target audience: everyone.

License: Unknown.

Original source

Catalog source: SkillHub Club.

Repository owner: openclaw.

This is still a mirrored public skill entry. Review the repository before installing into production workflows.

What it helps with

  • Install prayer-times into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
  • Review https://github.com/openclaw/skills before adding prayer-times to shared team environments
  • Use prayer-times for development workflows

Works across

Claude CodeCodex CLIGemini CLIOpenCode

Favorites: 0.

Sub-skills: 0.

Aggregator: No.

Original source / Raw SKILL.md

---
name: prayer-times
description: Get accurate Islamic prayer times (Fajr, Dhuhr, Asr, Maghrib, Isha) for any location worldwide using official calculation methods. Use when users ask about prayer times, Salat schedules, next prayer, or need to set up automated prayer reminders. Includes automated background reminder system that alerts users 10 minutes before, at prayer time, and 5 minutes after - even during conversations. Supports 20+ country-specific calculation methods including Morocco, Saudi Arabia, Egypt, Turkey, UAE, and more.
---

# Prayer Times Skill

Get accurate Islamic prayer times for any location using the AlAdhan API with region-specific calculation methods, plus automated reminders that work in the background.

## Two Ways to Use This Skill

### 1. Query Prayer Times (Instant)
Ask about prayer times for any location, get next prayer info, or check specific dates.

### 2. Automated Reminders (Background)
Set up cron jobs that fetch daily prayer times and check periodically for reminders. Alerts you:
- **10 minutes before** prayer time
- **At prayer time** ("Salat First")
- **5 minutes after** (if you're still chatting)

**To set up reminders:** See [references/setup-reminders.md](references/setup-reminders.md) for complete guide.

## Quick Start

### Get today's prayer times

**By city and country:**
```bash
cd scripts/
python3 get_prayer_times.py --city Mecca --country "Saudi Arabia"
python3 get_prayer_times.py --city Istanbul --country Turkey
python3 get_prayer_times.py --city Cairo --country Egypt
```

**By coordinates:**
```bash
python3 get_prayer_times.py --lat 21.4225 --lon 39.8262  # Mecca
```

**With next prayer info:**
```bash
python3 get_prayer_times.py --city Istanbul --country Turkey --next --timezone 3
```

### Output
```
πŸ“ Mecca, Saudi Arabia
πŸ“† 10 Feb 2026
πŸŒ™ 22-08-1447
πŸ”’ Method: 4

πŸ•Œ Fajr     05:37
πŸŒ… Sunrise  06:54
πŸ•Œ Dhuhr    12:35
πŸ•Œ Asr      15:50
πŸ•Œ Maghrib  18:16
πŸ•Œ Isha     19:46

⏳ Next: Maghrib at 18:16 (in 15 minutes)
```

## Calculation Methods

The script **automatically selects** the correct calculation method based on country:

- **Morocco** β†’ Method 21 (official)
- **Saudi Arabia** β†’ Method 4 (Umm Al-Qura)
- **Egypt** β†’ Method 5 (Egyptian Authority)
- **Turkey** β†’ Method 13 (Diyanet)
- **UAE** β†’ Method 16 (Dubai)
- And 15+ more countries...

**When to override:** Only specify `--method` if you need a different calculation than the country default.

For full method list and details, see [references/methods.md](references/methods.md).

## Script Reference

### `get_prayer_times.py`

**Location:** `scripts/get_prayer_times.py`

**Purpose:** Fetch prayer times for any location.

**Arguments:**
- `--city <name>` - City name (e.g., "Rabat")
- `--country <name>` - Country name (e.g., "Morocco")
- `--lat <float>` - Latitude coordinate
- `--lon <float>` - Longitude coordinate
- `--method <id>` - Calculation method ID (1-24, optional)
- `--date <DD-MM-YYYY>` - Specific date (optional, defaults to today)
- `--timezone <hours>` - Timezone offset from UTC for "next prayer" calculation
- `--next` - Show next prayer and time remaining
- `--json` - Output as JSON

**Returns:**
- Exit code 0 on success
- Exit code 1 on failure
- JSON or formatted text output

### `check_prayer_reminder.py`

**Location:** `scripts/check_prayer_reminder.py`

**Purpose:** Check if it's time to send a prayer reminder. Designed for periodic cron execution.

**Arguments:**
- `--prayer-times <path>` - Path to prayer_times.json file (required)
- `--timezone <hours>` - Timezone offset from UTC (required)
- `--json` - Output as JSON

**Returns:**
- Exit code 0 - No reminder needed
- Exit code 1 - Reminder needed (message printed to stdout)
- Exit code 2 - Error loading prayer times

**Reminder Windows:**
- **Before:** 9-11 minutes before prayer time
- **Now:** -1 to +2 minutes from prayer time
- **After:** 4-6 minutes after prayer time

## Common Usage Patterns

### 1. Get prayer times for user's city
```bash
python3 get_prayer_times.py --city "User's City" --country "User's Country" --next --timezone <offset>
```

### 2. Set up automated daily fetch
```python
from get_prayer_times import get_prayer_times
import json

# Fetch and save
times = get_prayer_times(city="Rabat", country="Morocco")
with open('prayer_times.json', 'w') as f:
    json.dump(times, f)
```

### 3. Check next prayer
```python
from get_prayer_times import get_prayer_times, get_next_prayer

times = get_prayer_times(city="Rabat", country="Morocco")
next_prayer = get_next_prayer(times, timezone_offset=1)  # GMT+1 for Morocco

print(f"Next: {next_prayer['name']} in {next_prayer['hours_until']}h {next_prayer['minutes_until']}m")
```

### 4. Set up automated reminders (recommended)

**Complete setup guide:** [references/setup-reminders.md](references/setup-reminders.md)

**Quick setup:**
1. Create daily fetch job (runs at midnight):
   - Fetches today's prayer times
   - Saves to `prayer_times.json`

2. Create reminder check job (runs every 5 min):
   - Checks if it's time to remind
   - Sends alert to active session
   - Three-stage reminders: before, during, after

**Example prompts to set up:**
```
Set up prayer time reminders for Mecca, Saudi Arabia (GMT+3). 
Fetch daily at midnight and check every 5 minutes.
```

```
Set up prayer time reminders for Istanbul, Turkey (GMT+3). 
Fetch daily at midnight and check every 5 minutes.
```

```
Set up prayer time reminders for Cairo, Egypt (GMT+2). 
Fetch daily at midnight and check every 5 minutes.
```

This enables background reminders even while chatting - you'll never miss Salat!

## Important Notes

### Network Requirements
The AlAdhan API (api.aladhan.com) may be unreachable from some datacenter IPs (e.g., DigitalOcean β†’ Hetzner routing issues).

**Solution:** Use Cloudflare WARP or similar VPN to route traffic through Cloudflare's network.

**Quick fix:**
```bash
# Install Cloudflare WARP
curl -fsSL https://pkg.cloudflareclient.com/pubkey.gpg | sudo gpg --yes --dearmor --output /usr/share/keyrings/cloudflare-warp-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/cloudflare-warp-archive-keyring.gpg] https://pkg.cloudflareclient.com/ $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/cloudflare-client.list
sudo apt update && sudo apt install cloudflare-warp
warp-cli register
warp-cli connect
```

### Accuracy
- Always use country-specific methods when available (e.g., method 21 for Morocco)
- Coordinates provide more accurate results than city names
- Times are in 24-hour format (HH:MM)

### Timezones
The API returns times in **local time** for the queried location. When calculating "time until next prayer", use the appropriate timezone offset.

## API Source
- **Provider:** AlAdhan (Islamic Network)
- **Endpoint:** https://api.aladhan.com
- **Documentation:** https://aladhan.com/prayer-times-api
- **Free tier:** No API key required, rate limited
- **Reliability:** High (99%+ uptime)

## Examples

### Example 1: User asks "What are the prayer times in Mecca?"
```bash
python3 get_prayer_times.py --city Mecca --country "Saudi Arabia"
```

### Example 2: User asks "When is the next prayer?"
```bash
python3 get_prayer_times.py --city Istanbul --country Turkey --next --timezone 3
```

### Example 3: User provides coordinates
```bash
python3 get_prayer_times.py --lat 40.7128 --lon -74.0060 --next --timezone -5
# New York coordinates
```

### Example 4: User wants specific date
```bash
python3 get_prayer_times.py --city Cairo --country Egypt --date 15-03-2026
```

## Testing the Skill

Test the script locally:
```bash
cd scripts/
python3 get_prayer_times.py --city Rabat --country Morocco --next --timezone 1
```

Expected output should show 5 prayer times (Fajr, Dhuhr, Asr, Maghrib, Isha) plus Sunrise, and indicate the next upcoming prayer if `--next` is used.


---

## Referenced Files

> The following files are referenced in this skill and included for context.

### references/setup-reminders.md

```markdown
# Setting Up Automated Prayer Reminders

This guide shows how to set up automated prayer reminders that work in the background and notify you before, during, and after prayer times - even while you're chatting.

## Overview

The reminder system consists of:

1. **Daily Prayer Time Fetch** - Runs at midnight to get today's prayer times
2. **Periodic Reminder Check** - Runs every 5-10 minutes to check if it's time to remind
3. **Three-Stage Reminders**:
   - **10 minutes before** - Heads up that prayer is approaching
   - **At prayer time** - "Salat First" reminder
   - **5 minutes after** - Gentle reminder if still chatting

## Setup Instructions

### Step 1: Set Your Location and Timezone

First, determine your:
- **City and Country** (e.g., "Mecca, Saudi Arabia", "Istanbul, Turkey", "Cairo, Egypt")
- **Timezone offset** from UTC (e.g., +3 for Saudi Arabia, +3 for Turkey, +2 for Egypt)

### Step 2: Create Daily Prayer Time Fetch Job

This cron job fetches fresh prayer times at midnight local time.

```javascript
{
  "name": "prayer-times:daily-fetch",
  "schedule": {
    "kind": "cron",
    "expr": "0 0 * * *",           // Midnight
    "tz": "Africa/Casablanca"      // Your timezone
  },
  "sessionTarget": "isolated",
  "payload": {
    "kind": "agentTurn",
    "message": "Fetch today's prayer times:\n\n1. Run: python3 /path/to/get_prayer_times.py --city YourCity --country YourCountry --json > prayer_times.json\n2. Verify prayer_times.json was created\n3. Silent operation - only alert if fetch fails after retry",
    "timeoutSeconds": 60
  },
  "delivery": {
    "mode": "none"
  },
  "enabled": true
}
```

**Replace:**
- `YourCity` β†’ Your city name
- `YourCountry` β†’ Your country name
- `/path/to/` β†’ Path where skill scripts are located
- `Africa/Casablanca` β†’ Your timezone (use same format)

### Step 3: Create Periodic Reminder Check Job

This job checks every 5-10 minutes if it's time to remind about prayer.

```javascript
{
  "name": "prayer-times:reminder-check",
  "schedule": {
    "kind": "every",
    "everyMs": 300000               // 5 minutes (300,000 ms)
  },
  "sessionTarget": "isolated",
  "payload": {
    "kind": "agentTurn",
    "message": "Check if it's time for Salat reminder:\n\n1. Run: python3 /path/to/check_prayer_reminder.py --prayer-times prayer_times.json --timezone OFFSET\n2. If exit code is 1, send the reminder message to the main session\n3. If exit code is 0, do nothing (HEARTBEAT_OK)\n4. If exit code is 2, log error (missing prayer times)",
    "timeoutSeconds": 30
  },
  "delivery": {
    "mode": "announce",
    "channel": "last"                // Send to last active channel
  },
  "enabled": true
}
```

**Replace:**
- `OFFSET` β†’ Your timezone offset (e.g., 1 for GMT+1)
- `/path/to/` β†’ Path where skill scripts are located

### Step 4: Add Jobs via OpenClaw CLI

Use the `cron` tool to add these jobs:

**Option A: Via Chat**
```
Add a cron job to fetch prayer times daily at midnight and check every 5 minutes for reminders. Use Rabat, Morocco (timezone +1).
```

**Option B: Via Tool Call**
Use the `cron` tool with action `add` and the job objects above.

## Configuration Examples

### Morocco (GMT+1)
```javascript
// Daily fetch
"expr": "0 0 * * *"
"tz": "Africa/Casablanca"

// Reminder check
"message": "...--timezone 1..."
```

### Saudi Arabia (GMT+3)
```javascript
// Daily fetch
"expr": "0 0 * * *"
"tz": "Asia/Riyadh"

// Reminder check
"message": "...--timezone 3..."
```

### Egypt (GMT+2)
```javascript
// Daily fetch
"expr": "0 0 * * *"
"tz": "Africa/Cairo"

// Reminder check
"message": "...--timezone 2..."
```

### Turkey (GMT+3)
```javascript
// Daily fetch
"expr": "0 0 * * *"
"tz": "Europe/Istanbul"

// Reminder check
"message": "...--timezone 3..."
```

## How Reminders Work

### Reminder Windows

The check script looks for three reminder windows:

1. **Before (9-11 minutes)**
   - Triggers: 10 minutes before prayer time (Β±1 min buffer)
   - Message: "πŸ•Œ Salat approaching: Asr in 10 minutes (16:43)"

2. **Now (-1 to +2 minutes)**
   - Triggers: At prayer time (Β±2 min buffer)
   - Message: "πŸ•Œ Salat First: Asr time is now (16:43)"

3. **After (-6 to -4 minutes)**
   - Triggers: 5 minutes after prayer started (Β±1 min buffer)
   - Message: "πŸ•Œ Salat reminder: Asr started 5 minutes ago (16:43)"

### Why These Windows?

- **Wide windows (Β±1-2 min)** ensure reminders don't get missed if check runs at slightly different times
- **5-minute check interval** balances responsiveness with resource usage
- **Three stages** provide multiple opportunities to catch the prayer

## Testing

### Test Prayer Time Fetch
```bash
python3 get_prayer_times.py --city YourCity --country YourCountry --json > prayer_times.json
cat prayer_times.json
```

### Test Reminder Check
```bash
# Should output "HEARTBEAT_OK" if no reminder needed
python3 check_prayer_reminder.py --prayer-times prayer_times.json --timezone OFFSET

# To test near prayer time, manually edit prayer_times.json with a time 10 minutes from now
```

### Test Cron Jobs
```
List my cron jobs
```

Should show:
- `prayer-times:daily-fetch`
- `prayer-times:reminder-check`

## Adjusting Check Frequency

### More Frequent (Every 2 Minutes)
```javascript
"everyMs": 120000  // 2 minutes
```

### Less Frequent (Every 10 Minutes)
```javascript
"everyMs": 600000  // 10 minutes
```

**Recommendation:** 5 minutes is a good balance. More frequent uses more resources; less frequent risks missing reminders.

## Troubleshooting

### Prayer times not fetching
- Check network connectivity to api.aladhan.com
- Verify city/country names are correct
- Check if VPN is needed (see main SKILL.md)

### Reminders not appearing
- Verify `prayer_times.json` exists and is updated daily
- Check timezone offset is correct
- Confirm cron jobs are enabled and running
- Test manually with scripts

### Wrong prayer times
- Ensure correct calculation method for your country
- Verify coordinates if using lat/lon instead of city

### Too many/few reminders
- Adjust check frequency (everyMs)
- Modify reminder windows in check_prayer_reminder.py

## Maintenance

### Disable Temporarily
```
Disable my prayer-times cron jobs
```

### Re-enable
```
Enable my prayer-times cron jobs
```

### Remove Completely
```
Remove all prayer-times cron jobs
```

## Cost Estimate

Running these cron jobs:
- **Daily fetch**: ~500-800 tokens/day
- **Reminder checks**: ~200-300 tokens/check Γ— 288 checks/day = ~60K tokens/day
- **Total**: ~60-65K tokens/day (~$1.80-2.00/month at $0.03/1K tokens)

The reminders check frequently but only alert when needed, keeping the cost manageable while providing reliable notifications.

```

### references/methods.md

```markdown
# Prayer Time Calculation Methods

Different regions use different calculation methods for determining prayer times. The method ID must be specified when fetching prayer times.

## Common Methods

| ID | Name | Region | Fajr Angle | Isha Angle |
|----|------|--------|------------|------------|
| 2 | Muslim World League (MWL) | Europe, Far East, parts of America | 18Β° | 17Β° |
| 4 | Umm Al-Qura University | Saudi Arabia, Gulf | 18.5Β° | 90 min after Maghrib |
| 5 | Egyptian General Authority | Egypt, Syria, Lebanon, Malaysia | 19.5Β° | 17.5Β° |
| 9 | Kuwait | Kuwait | 18Β° | 17.5Β° |
| 10 | Qatar | Qatar | 18Β° | 90 min after Maghrib |
| 13 | Diyanet | Turkey | 18Β° | 17Β° |
| 16 | Dubai (experimental) | UAE | 18.2Β° | 18.2Β° |
| 18 | Tunisia | Tunisia | 18Β° | 18Β° |
| 19 | Algeria | Algeria | 18Β° | 17Β° |
| 21 | Morocco | Morocco | 19Β° | 17Β° |
| 24 | Jordan | Jordan | 18Β° | 18Β° |

## Method Selection Guide

**Automatic Selection:**
The script automatically selects the correct method based on country:
- Morocco β†’ Method 21
- Saudi Arabia β†’ Method 4
- Egypt β†’ Method 5
- Turkey β†’ Method 13
- UAE β†’ Method 16
- And more...

**Manual Override:**
Use `--method <id>` to override automatic selection.

## Full List of Methods

For complete list, see: https://api.aladhan.com/v1/methods

## Important Notes

1. **Use country-specific methods when available** - They match official government calculations
2. **Method 2 (MWL) is a safe default** - But may not match local conventions
3. **Angles matter** - Different angles can result in 10-30 minute differences in Fajr/Isha
4. **Government standards** - Some countries (Morocco, Saudi Arabia) have official calculation methods that should always be used

## Examples

### Morocco (Official)
```bash
python3 get_prayer_times.py --city Rabat --country Morocco
# Auto-selects method 21
```

### Custom Method
```bash
python3 get_prayer_times.py --city London --country UK --method 2
# Uses Muslim World League for London
```

### Coordinates with Method
```bash
python3 get_prayer_times.py --lat 34.0209 --lon -6.8416 --method 21
# Rabat coordinates with Morocco method
```

```

### scripts/get_prayer_times.py

```python
#!/usr/bin/env python3
"""
Get prayer times for any location using AlAdhan API
Supports multiple calculation methods for different regions
"""
import requests
import json
import sys
from datetime import datetime, timedelta
from pathlib import Path

def get_prayer_times(city=None, country=None, latitude=None, longitude=None, method=None, date=None):
    """
    Fetch prayer times from AlAdhan API
    
    Args:
        city: City name (e.g., "Rabat")
        country: Country name (e.g., "Morocco")
        latitude: Latitude coordinate
        longitude: Longitude coordinate
        method: Calculation method ID (defaults based on location)
        date: Date string in DD-MM-YYYY format (defaults to today)
    
    Returns:
        dict with prayer times or None if failed
    """
    
    # Default method selection based on country
    method_map = {
        "Morocco": 21,
        "Saudi Arabia": 4,
        "Egypt": 5,
        "Turkey": 13,
        "Jordan": 24,
        "Algeria": 19,
        "Tunisia": 18,
        "UAE": 16,
        "Kuwait": 9,
        "Qatar": 10,
    }
    
    if method is None and country in method_map:
        method = method_map[country]
    elif method is None:
        method = 2  # Default to Muslim World League
    
    # Get date
    if date is None:
        date = datetime.now().strftime('%d-%m-%Y')
    
    try:
        # Use city/country or coordinates
        if city and country:
            url = f"https://api.aladhan.com/v1/timingsByCity/{date}"
            params = {
                "city": city,
                "country": country,
                "method": method
            }
        elif latitude and longitude:
            url = f"https://api.aladhan.com/v1/timings/{date}"
            params = {
                "latitude": latitude,
                "longitude": longitude,
                "method": method
            }
        else:
            print("Error: Must provide either city/country or coordinates", file=sys.stderr)
            return None
        
        response = requests.get(url, params=params, timeout=15)
        response.raise_for_status()
        
        data = response.json()
        
        if data.get('code') == 200:
            timings = data['data']['timings']
            date_info = data['data']['date']
            
            return {
                "source": "api.aladhan.com",
                "location": f"{city}, {country}" if city else f"Lat: {latitude}, Lon: {longitude}",
                "date": date_info['readable'],
                "hijri": date_info['hijri']['date'],
                "gregorian": date_info['gregorian']['date'],
                "method": method,
                "prayers": {
                    "Fajr": timings['Fajr'],
                    "Sunrise": timings['Sunrise'],
                    "Dhuhr": timings['Dhuhr'],
                    "Asr": timings['Asr'],
                    "Maghrib": timings['Maghrib'],
                    "Isha": timings['Isha']
                }
            }
        else:
            print(f"API error: {data.get('code')}", file=sys.stderr)
            return None
            
    except requests.exceptions.Timeout:
        print("Error: API request timed out", file=sys.stderr)
        return None
    except requests.exceptions.ConnectionError as e:
        print(f"Error: Connection failed - {e}", file=sys.stderr)
        print("Tip: Check if api.aladhan.com is reachable or if VPN is needed", file=sys.stderr)
        return None
    except Exception as e:
        print(f"Error: {e}", file=sys.stderr)
        return None

def get_next_prayer(prayers_data, timezone_offset=0):
    """
    Find the next prayer time
    
    Args:
        prayers_data: Dict with 'prayers' key containing prayer times
        timezone_offset: Hours offset from UTC (e.g., +1 for Morocco)
    
    Returns:
        dict with next prayer info or None if all prayers passed
    """
    utc_now = datetime.utcnow()
    local_now = utc_now + timedelta(hours=timezone_offset)
    
    prayers = prayers_data['prayers']
    prayer_order = ['Fajr', 'Dhuhr', 'Asr', 'Maghrib', 'Isha']
    
    for prayer_name in prayer_order:
        if prayer_name in prayers:
            time_str = prayers[prayer_name]
            hour, minute = map(int, time_str.split(':'))
            prayer_time = local_now.replace(hour=hour, minute=minute, second=0, microsecond=0)
            
            diff_minutes = (prayer_time - local_now).total_seconds() / 60
            
            if diff_minutes > 0:
                hours = int(diff_minutes // 60)
                minutes = int(diff_minutes % 60)
                
                return {
                    "name": prayer_name,
                    "time": time_str,
                    "hours_until": hours,
                    "minutes_until": minutes,
                    "total_minutes": int(diff_minutes)
                }
    
    # All prayers passed, return tomorrow's Fajr
    return {
        "name": "Fajr",
        "time": prayers.get('Fajr', 'N/A'),
        "tomorrow": True
    }

if __name__ == "__main__":
    import argparse
    
    parser = argparse.ArgumentParser(description='Get Islamic prayer times')
    parser.add_argument('--city', help='City name')
    parser.add_argument('--country', help='Country name')
    parser.add_argument('--lat', type=float, help='Latitude')
    parser.add_argument('--lon', type=float, help='Longitude')
    parser.add_argument('--method', type=int, help='Calculation method ID (1-24)')
    parser.add_argument('--date', help='Date in DD-MM-YYYY format')
    parser.add_argument('--timezone', type=int, default=0, help='Timezone offset from UTC')
    parser.add_argument('--next', action='store_true', help='Show next prayer time')
    parser.add_argument('--json', action='store_true', help='Output as JSON')
    
    args = parser.parse_args()
    
    # Get prayer times
    result = get_prayer_times(
        city=args.city,
        country=args.country,
        latitude=args.lat,
        longitude=args.lon,
        method=args.method,
        date=args.date
    )
    
    if not result:
        sys.exit(1)
    
    # Output format
    if args.json:
        print(json.dumps(result, ensure_ascii=False, indent=2))
    else:
        print(f"πŸ“ {result['location']}")
        print(f"πŸ“† {result['date']}")
        print(f"πŸŒ™ {result['hijri']}")
        print(f"πŸ”’ Method: {result['method']}")
        print()
        for prayer, time in result['prayers'].items():
            emoji = "πŸŒ…" if prayer == "Sunrise" else "πŸ•Œ"
            print(f"{emoji} {prayer:8s} {time}")
        
        if args.next:
            next_info = get_next_prayer(result, args.timezone)
            print()
            if next_info.get('tomorrow'):
                print(f"⏳ All prayers passed. Next: Fajr tomorrow at {next_info['time']}")
            else:
                if next_info['hours_until'] > 0:
                    print(f"⏳ Next: {next_info['name']} at {next_info['time']} (in {next_info['hours_until']}h {next_info['minutes_until']}m)")
                else:
                    print(f"⏳ Next: {next_info['name']} at {next_info['time']} (in {next_info['minutes_until']} minutes)")

```

### scripts/check_prayer_reminder.py

```python
#!/usr/bin/env python3
"""
Check if it's time to send a prayer reminder
Designed to run periodically (every 5-10 minutes via cron)
Returns exit code 1 if reminder needed, 0 if not
"""
import json
import sys
from datetime import datetime, timedelta
from pathlib import Path

def get_local_time(timezone_offset):
    """Get current local time with timezone offset"""
    utc_now = datetime.utcnow()
    return utc_now + timedelta(hours=timezone_offset)

def load_prayer_times(prayer_times_file):
    """Load today's prayer times from JSON file"""
    if not prayer_times_file.exists():
        print(f"❌ Prayer times file not found: {prayer_times_file}", file=sys.stderr)
        return None
    
    try:
        with open(prayer_times_file, 'r', encoding='utf-8') as f:
            data = json.load(f)
            return data.get('prayers', {})
    except Exception as e:
        print(f"❌ Error reading prayer times: {e}", file=sys.stderr)
        return None

def parse_time(time_str, current_time):
    """Parse prayer time string (HH:MM) to datetime"""
    hour, minute = map(int, time_str.split(':'))
    return current_time.replace(hour=hour, minute=minute, second=0, microsecond=0)

def check_prayer_reminder(prayers, timezone_offset):
    """
    Check if we should send a prayer reminder
    
    Returns dict with reminder info or None
    """
    local_now = get_local_time(timezone_offset)
    
    # Only check the 5 main prayers (skip Sunrise)
    main_prayers = {
        "Fajr": prayers.get("Fajr"),
        "Dhuhr": prayers.get("Dhuhr"),
        "Asr": prayers.get("Asr"),
        "Maghrib": prayers.get("Maghrib"),
        "Isha": prayers.get("Isha")
    }
    
    for prayer_name, prayer_time_str in main_prayers.items():
        if not prayer_time_str:
            continue
            
        prayer_time = parse_time(prayer_time_str, local_now)
        
        # Calculate time difference in minutes
        diff_minutes = (prayer_time - local_now).total_seconds() / 60
        
        # 10 minutes before (9-11 min window to avoid missing it)
        if 9 <= diff_minutes <= 11:
            return {
                "type": "before",
                "prayer": prayer_name,
                "time": prayer_time_str,
                "minutes_until": int(diff_minutes),
                "message": f"πŸ•Œ Salat approaching: {prayer_name} in {int(diff_minutes)} minutes ({prayer_time_str})"
            }
        
        # During prayer time (0 to 2 minutes after start)
        elif -1 <= diff_minutes <= 2:
            return {
                "type": "now",
                "prayer": prayer_name,
                "time": prayer_time_str,
                "message": f"πŸ•Œ Salat First: {prayer_name} time is now ({prayer_time_str})"
            }
        
        # 5 minutes after start (4-6 min window for missed reminder)
        elif -6 <= diff_minutes <= -4:
            return {
                "type": "after",
                "prayer": prayer_name,
                "time": prayer_time_str,
                "minutes_ago": int(abs(diff_minutes)),
                "message": f"πŸ•Œ Salat reminder: {prayer_name} started {int(abs(diff_minutes))} minutes ago ({prayer_time_str})"
            }
    
    return None

if __name__ == "__main__":
    import argparse
    
    parser = argparse.ArgumentParser(description='Check if it\'s time for prayer reminder')
    parser.add_argument('--prayer-times', required=True, help='Path to prayer_times.json file')
    parser.add_argument('--timezone', type=int, required=True, help='Timezone offset from UTC (e.g., 1 for GMT+1)')
    parser.add_argument('--json', action='store_true', help='Output as JSON')
    
    args = parser.parse_args()
    
    # Load prayer times
    prayer_times_file = Path(args.prayer_times)
    prayers = load_prayer_times(prayer_times_file)
    
    if not prayers:
        sys.exit(2)  # Exit code 2 = error loading prayer times
    
    # Check for reminder
    reminder = check_prayer_reminder(prayers, args.timezone)
    
    if reminder:
        if args.json:
            print(json.dumps(reminder, ensure_ascii=False, indent=2))
        else:
            print(reminder['message'])
        sys.exit(1)  # Exit code 1 = reminder needed
    else:
        if not args.json:
            print("HEARTBEAT_OK")
        sys.exit(0)  # Exit code 0 = no reminder needed

```



---

## Skill Companion Files

> Additional files collected from the skill directory layout.

### README.md

```markdown
# πŸ•Œ Prayer Times - Automated Salat Reminders for OpenClaw

Never forget about the most important thing in your day and life. **Prayer is your first priority.**

This OpenClaw skill provides accurate Islamic prayer times for any location worldwide, with automated background reminders that ensure you never miss Salat - even during busy conversations.

[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
[![OpenClaw](https://img.shields.io/badge/OpenClaw-Skill-green.svg)](https://openclaw.ai)

## ✨ Features

### 🌍 Global Prayer Times
- **20+ countries** with official calculation methods
- **Any location** - city/country or GPS coordinates
- **Automatic method selection** - no manual configuration
- **Next prayer countdown** - know exactly when Salat is coming
- **Specific date support** - plan ahead for travel

### πŸ”” Automated Background Reminders
The core feature that makes this special:

- **10 minutes before** - "πŸ•Œ Salat approaching: Asr in 10 minutes (16:43)"
- **At prayer time** - "πŸ•Œ Salat First: Asr time is now (16:43)"
- **5 minutes after** - "πŸ•Œ Salat reminder: Asr started 5 minutes ago (16:43)"

**Works during conversations** - No need to ask. The reminders appear automatically while you're chatting, ensuring you never forget.

**Set up once, works forever** - Updates daily automatically via cron jobs. Zero maintenance required.

### 🌐 Supported Countries

Automatically uses official calculation methods for:

πŸ‡²πŸ‡¦ Morocco | πŸ‡ΈπŸ‡¦ Saudi Arabia | πŸ‡ͺπŸ‡¬ Egypt | πŸ‡ΉπŸ‡· Turkey | πŸ‡¦πŸ‡ͺ UAE | πŸ‡°πŸ‡Ό Kuwait | πŸ‡ΆπŸ‡¦ Qatar | πŸ‡―πŸ‡΄ Jordan | πŸ‡©πŸ‡Ώ Algeria | πŸ‡ΉπŸ‡³ Tunisia

Plus 10+ more countries with Muslim World League as default fallback.

## ⚠️ CRITICAL: Read This First

**[CRITICAL_SETUP.md](CRITICAL_SETUP.md)** - Essential guide to ensure prayer reminders NEVER fail.

Prayer is not optional. The reminder system must be 100% reliable. Read the critical setup guide to:
- Verify cron jobs at every session
- Test the system properly
- Fix issues immediately if something breaks

**Don't skip this.** Missing a prayer reminder is a critical failure.

## πŸ“¦ Installation

### Prerequisites
- [OpenClaw](https://openclaw.ai) installed and running
- Internet connection (for AlAdhan API)

### Install the Skill

**Option 1: Direct Install (from GitHub)**
```bash
git clone https://github.com/diepox/openclaw-prayer-times.git
cd openclaw-prayer-times
# Copy to your OpenClaw skills directory
cp -r . ~/.openclaw/skills/prayer-times/
```

**Option 2: Via OpenClaw CLI**
```
/skill install prayer-times.skill
```

## πŸš€ Quick Start

### 1. Query Prayer Times

Just ask OpenClaw:

```
What are the prayer times in Rabat today?
When is the next prayer?
Show me prayer times for Mecca
What are the prayer times in Cairo on March 15, 2026?
```

**Example Output:**
```
πŸ“ Mecca, Saudi Arabia
πŸ“† 10 Feb 2026
πŸŒ™ 22-08-1447
πŸ”’ Method: 4

πŸ•Œ Fajr     05:37
πŸŒ… Sunrise  06:54
πŸ•Œ Dhuhr    12:35
πŸ•Œ Asr      15:50
πŸ•Œ Maghrib  18:16
πŸ•Œ Isha     19:46

⏳ Next: Maghrib at 18:16 (in 15 minutes)
```

### 2. Set Up Automated Reminders

This is where the magic happens. One command sets up everything:

```
Set up prayer time reminders for [Your City], [Your Country] (GMT+[offset]). 
Fetch daily at midnight and check every 5 minutes.
```

**Examples:**
```
Set up prayer time reminders for Mecca, Saudi Arabia (GMT+3). 
Fetch daily at midnight and check every 5 minutes.
```

```
Set up prayer time reminders for Istanbul, Turkey (GMT+3). 
Fetch daily at midnight and check every 5 minutes.
```

**That's it!** Two cron jobs are created:
1. **Daily fetch** (midnight) - Gets fresh prayer times for your location
2. **Reminder check** (every 5 min) - Alerts you when it's time

**From now on, you'll receive automatic reminders** - even while chatting about completely different topics.

## πŸ“– Documentation

### Core Files

- **[SKILL.md](SKILL.md)** - Complete skill documentation and usage guide
- **[setup-reminders.md](references/setup-reminders.md)** - Detailed reminder setup guide
- **[methods.md](references/methods.md)** - Calculation methods for all countries
- **[example-cron-jobs.json](references/example-cron-jobs.json)** - Copy-paste cron templates

### Scripts

- **[get_prayer_times.py](scripts/get_prayer_times.py)** - Query prayer times for any location
- **[check_prayer_reminder.py](scripts/check_prayer_reminder.py)** - Automated reminder checker
- **[fetch_prayer_times.py](scripts/fetch_prayer_times.py)** - Morocco-specific fetcher (legacy)

## 🎯 Use Cases

- **Daily reminders** - Never miss Salat during work, study, or conversations
- **Travel planning** - Check prayer times before trips
- **Multi-location monitoring** - Track times for family in different cities
- **Ramadan preparation** - Accurate Iftar and Suhoor times
- **Mosque coordination** - Sync with local prayer schedules

## πŸ”§ Advanced Configuration

### Custom Calculation Method

By default, the skill auto-selects the correct method for your country. To override:

```bash
python3 scripts/get_prayer_times.py --city London --country UK --method 2
```

See [methods.md](references/methods.md) for all available methods.

### Adjust Reminder Frequency

Default is every 5 minutes. To change:

```javascript
// In your cron job configuration
"everyMs": 300000  // 5 minutes (default)
"everyMs": 120000  // 2 minutes (more frequent)
"everyMs": 600000  // 10 minutes (less frequent)
```

See [setup-reminders.md](references/setup-reminders.md) for complete guide.

## 🌐 Network Considerations

The skill uses the [AlAdhan API](https://aladhan.com/prayer-times-api) which may be unreachable from some datacenter IPs due to routing issues.

**Solution:** If you're running OpenClaw on a VPS/datacenter, you may need Cloudflare WARP VPN:

```bash
curl -fsSL https://pkg.cloudflareclient.com/pubkey.gpg | sudo gpg --yes --dearmor --output /usr/share/keyrings/cloudflare-warp-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/cloudflare-warp-archive-keyring.gpg] https://pkg.cloudflareclient.com/ $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/cloudflare-client.list
sudo apt update && sudo apt install cloudflare-warp
warp-cli register
warp-cli connect
```

See [SKILL.md](SKILL.md) for more details.

## πŸ’° Cost Estimate

Running automated reminders costs approximately:

- **Daily fetch:** ~500-800 tokens/day
- **Reminder checks:** ~60K tokens/day
- **Total:** ~$1.80-2.00/month (at $0.03/1K tokens)

**Worth every cent** to never miss Salat! 🀲

## 🀝 Contributing

Contributions are welcome! Whether it's:

- Adding support for more calculation methods
- Improving documentation
- Fixing bugs
- Translating to other languages

Please feel free to open an issue or submit a pull request.

## πŸ“„ License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

## πŸ™ Credits

- **API Provider:** [AlAdhan](https://aladhan.com) / Islamic Network
- **Creator:** L'Modir ([OpenClaw](https://openclaw.ai))
- **Framework:** [OpenClaw](https://openclaw.ai) - AI agent framework

## 🌟 Support

- **Documentation:** [docs.openclaw.ai](https://docs.openclaw.ai)
- **Community:** [Discord](https://discord.com/invite/clawd)
- **Issues:** [GitHub Issues](https://github.com/diepox/openclaw-prayer-times/issues)

## ⭐ Star This Repo

If this skill helps you maintain your Salat, please ⭐ star this repo to help others discover it!

---

**Made with ❀️ for the Muslim community**

> "Indeed, prayer has been decreed upon the believers at specified times." - Quran 4:103

May Allah accept your prayers 🀲 Alhamdulillah!

```

### _meta.json

```json
{
  "owner": "diepox",
  "slug": "muslim-prayer-reminder",
  "displayName": "Prayer Times - Automated Salat Reminders",
  "latest": {
    "version": "0.1.0",
    "publishedAt": 1770739200788,
    "commit": "https://github.com/openclaw/skills/commit/faeead8b0315a5d71a512dbd04c9f347293754e0"
  },
  "history": []
}

```

### references/example-cron-jobs.json

```json
{
  "description": "Example cron jobs for automated prayer reminders",
  "note": "Replace placeholders with your actual values before using",
  
  "jobs": [
    {
      "name": "prayer-times:daily-fetch",
      "schedule": {
        "kind": "cron",
        "expr": "0 0 * * *",
        "tz": "Africa/Casablanca"
      },
      "sessionTarget": "isolated",
      "payload": {
        "kind": "agentTurn",
        "message": "Fetch today's prayer times:\n\n1. Run: cd /root/.openclaw/workspace && python3 skills/prayer-times/scripts/get_prayer_times.py --city YOUR_CITY --country YOUR_COUNTRY --json > prayer_times.json\n2. Verify prayer_times.json was created with today's times\n3. Silent operation - only alert if fetch fails after retry\n\nReplace YOUR_CITY and YOUR_COUNTRY with the user's location.\n\nThis ensures fresh prayer times are available for reminder checks.",
        "timeoutSeconds": 60
      },
      "delivery": {
        "mode": "none"
      },
      "enabled": true
    },
    {
      "name": "prayer-times:reminder-check",
      "schedule": {
        "kind": "every",
        "everyMs": 300000
      },
      "sessionTarget": "isolated",
      "payload": {
        "kind": "agentTurn",
        "message": "Check if it's time for Salat reminder:\n\n1. Run: cd /root/.openclaw/workspace && python3 skills/prayer-times/scripts/check_prayer_reminder.py --prayer-times prayer_times.json --timezone 1\n2. If exit code is 1, the script outputs the reminder message - send it to the user\n3. If exit code is 0, no reminder needed (return HEARTBEAT_OK)\n4. If exit code is 2, prayer times file is missing or invalid - log error\n\nThis checks every 5 minutes for three reminder windows: 10 min before, at prayer time, and 5 min after.",
        "timeoutSeconds": 30
      },
      "delivery": {
        "mode": "announce",
        "channel": "last"
      },
      "enabled": true
    }
  ],
  
  "placeholders": {
    "YOUR_CITY": "Your city name (e.g., Mecca, Istanbul, Cairo)",
    "YOUR_COUNTRY": "Your country name (e.g., Saudi Arabia, Turkey, Egypt)",
    "YOUR_TIMEZONE": "Your timezone (e.g., Asia/Riyadh, Europe/Istanbul, Africa/Cairo)",
    "YOUR_OFFSET": "Your UTC offset (e.g., 3 for GMT+3, 2 for GMT+2)",
    "check_interval_ms": 300000,
    "note": "Replace placeholders with your actual location and timezone"
  },
  
  "common_timezones": {
    "Morocco": {
      "tz": "Africa/Casablanca",
      "offset": 1
    },
    "Saudi Arabia": {
      "tz": "Asia/Riyadh",
      "offset": 3
    },
    "Egypt": {
      "tz": "Africa/Cairo",
      "offset": 2
    },
    "Turkey": {
      "tz": "Europe/Istanbul",
      "offset": 3
    },
    "UAE": {
      "tz": "Asia/Dubai",
      "offset": 4
    },
    "Kuwait": {
      "tz": "Asia/Kuwait",
      "offset": 3
    },
    "Qatar": {
      "tz": "Asia/Qatar",
      "offset": 3
    },
    "Jordan": {
      "tz": "Asia/Amman",
      "offset": 2
    },
    "Algeria": {
      "tz": "Africa/Algiers",
      "offset": 1
    },
    "Tunisia": {
      "tz": "Africa/Tunis",
      "offset": 1
    }
  }
}

```

### scripts/fetch_prayer_times.py

```python
#!/usr/bin/env python3
"""
Fetch today's prayer times for Rabat, Morocco
Using AlAdhan API (https://aladhan.com/prayer-times-api)
Endpoint: GET /timings/{date}
"""
import requests
import json
from datetime import datetime, timedelta

MOROCCO_UTC_OFFSET = 1

def get_morocco_time():
    """Get current time in Morocco (GMT+1)"""
    utc_now = datetime.utcnow()
    return utc_now + timedelta(hours=MOROCCO_UTC_OFFSET)

def fetch_prayer_times_aladhan(city=None, country=None, latitude=None, longitude=None):
    """
    Fetch from AlAdhan API
    API docs: https://aladhan.com/prayer-times-api#get-/timings/-date-
    
    Args:
        city: City name
        country: Country name
        latitude: Latitude coordinate
        longitude: Longitude coordinate
    """
    try:
        local_time = get_morocco_time()
        date_str = local_time.strftime('%d-%m-%Y')
        
        # Determine method based on country
        method_map = {
            "Morocco": 21,
            "Saudi Arabia": 4,
            "Egypt": 5,
            "Turkey": 13,
            "Jordan": 24,
            "Algeria": 19,
            "Tunisia": 18,
            "UAE": 16,
            "Kuwait": 9,
            "Qatar": 10,
        }
        
        method = method_map.get(country, 2)  # Default to Muslim World League
        
        # AlAdhan API endpoint
        if latitude and longitude:
            url = f"https://api.aladhan.com/v1/timings/{date_str}"
            params = {
                "latitude": latitude,
                "longitude": longitude,
                "method": method
            }
            location = f"Lat: {latitude}, Lon: {longitude}"
        elif city and country:
            url = f"https://api.aladhan.com/v1/timingsByCity/{date_str}"
            params = {
                "city": city,
                "country": country,
                "method": method
            }
            location = f"{city}, {country}"
        else:
            print("❌ Must provide either city/country or coordinates")
            return None
        
        print(f"πŸ”„ Calling: {url}")
        print(f"   Location: {location}")
        print(f"   Method: {method}")
        
        response = requests.get(url, params=params, timeout=10)
        response.raise_for_status()
        
        data = response.json()
        
        if data.get('code') == 200:
            timings = data['data']['timings']
            date_info = data['data']['date']
            
            return {
                "source": "api.aladhan.com",
                "location": location,
                "date": date_info['readable'],
                "hijri": date_info['hijri']['date'],
                "gregorian": date_info['gregorian']['date'],
                "method": method,
                "prayers": {
                    "Fajr": timings['Fajr'],
                    "Sunrise": timings['Sunrise'],
                    "Dhuhr": timings['Dhuhr'],
                    "Asr": timings['Asr'],
                    "Maghrib": timings['Maghrib'],
                    "Isha": timings['Isha']
                }
            }
        else:
            print(f"❌ API returned code: {data.get('code')}")
            return None
            
    except requests.exceptions.Timeout:
        print("❌ AlAdhan API timeout (10s)")
        return None
    except requests.exceptions.ConnectionError as e:
        print(f"❌ AlAdhan API connection error: {e}")
        return None
    except Exception as e:
        print(f"❌ AlAdhan API error: {e}")
        return None

def get_today_prayer_times(city="Rabat", country="Morocco", latitude=None, longitude=None):
    """
    Fetch today's prayer times using AlAdhan API
    
    Args:
        city: City name (default: Rabat)
        country: Country name (default: Morocco)
        latitude: Optional latitude coordinate
        longitude: Optional longitude coordinate
    """
    print("=" * 60)
    if latitude and longitude:
        print(f"Fetching today's prayer times for coordinates: {latitude}, {longitude}")
    else:
        print(f"Fetching today's prayer times for {city}, {country}")
    
    local_time = get_morocco_time()
    print(f"Current time: {local_time.strftime('%Y-%m-%d %H:%M:%S')}")
    print("=" * 60)
    print()
    
    # Try AlAdhan API
    print("πŸ”„ Fetching from AlAdhan API...")
    result = fetch_prayer_times_aladhan(city, country, latitude, longitude)
    
    if result:
        print(f"βœ… Success with {result['source']}")
        return result
    
    print()
    print("❌ Failed to fetch prayer times - check network connectivity")
    print("πŸ’‘ Tip: You may need Cloudflare WARP VPN if running on a VPS")
    return None

if __name__ == "__main__":
    import argparse
    
    parser = argparse.ArgumentParser(description='Fetch today\'s Islamic prayer times')
    parser.add_argument('--city', help='City name (e.g., Rabat)')
    parser.add_argument('--country', help='Country name (e.g., Morocco)')
    parser.add_argument('--lat', type=float, help='Latitude')
    parser.add_argument('--lon', type=float, help='Longitude')
    parser.add_argument('--output', default='today_prayer_times.json', help='Output JSON file')
    
    args = parser.parse_args()
    
    # Validate input
    if not (args.city and args.country) and not (args.lat and args.lon):
        print("❌ Error: Must provide either --city and --country, or --lat and --lon")
        print("\nExamples:")
        print("  python3 fetch_prayer_times.py --city Rabat --country Morocco")
        print("  python3 fetch_prayer_times.py --lat 34.0209 --lon -6.8416")
        exit(1)
    
    # Fetch prayer times
    times = get_today_prayer_times(
        city=args.city,
        country=args.country,
        latitude=args.lat,
        longitude=args.lon
    )
    
    if times:
        print()
        print("=" * 60)
        print("πŸ“… TODAY'S PRAYER TIMES")
        print("=" * 60)
        print(f"πŸ“ Location: {times.get('location', 'N/A')}")
        print(f"πŸ“‘ Source: {times['source']}")
        print(f"πŸ“† Date: {times.get('date', 'N/A')}")
        if 'hijri' in times:
            print(f"πŸŒ™ Hijri: {times['hijri']}")
        if 'method' in times:
            print(f"πŸ”’ Method: {times['method']}")
        print()
        
        for prayer, time in times['prayers'].items():
            emoji = "πŸŒ…" if prayer == "Sunrise" else "πŸ•Œ"
            print(f"{emoji} {prayer:8s} {time}")
        
        print("=" * 60)
        
        # Save for use by check script
        with open(args.output, 'w', encoding='utf-8') as f:
            json.dump(times, f, ensure_ascii=False, indent=2)
        
        print(f"βœ… Saved to {args.output}")
    
    else:
        exit(1)

```

prayer-times | SkillHub