Documentation Index
Fetch the complete documentation index at: https://mintlify.com/trustlessmatt/discord-exporter-bot/llms.txt
Use this file to discover all available pages before exploring further.
Overview
The Discord Exporter Bot includes an automatic daily digest task that runs on a schedule without manual intervention. By default, it generates a team digest every day at 12:00 AM Eastern Time.
How It Works
The daily_digest_task is implemented using Discord.py’s @tasks.loop decorator:
@tasks.loop(hours=24)
async def daily_digest_task():
"""Automatically generate daily digest at scheduled time."""
logger.info("Running scheduled daily digest")
result = await run_digest_pipeline(bot, config, config.default_hours)
if result["success"]:
logger.info("✅ Daily digest completed successfully")
else:
logger.error(f"Daily digest failed: {result.get('error', 'Unknown error')}")
See bot.py:659-669.
Default Schedule
Hour of day (0-23) to run the digest in Eastern Time
- Default:
0 (12:00 AM ET)
- Timezone: America/New_York (handles DST automatically)
- Frequency: Every 24 hours
Eastern Time with DSTThe bot uses ZoneInfo("America/New_York") which automatically handles
Daylight Saving Time transitions. No manual adjustments needed.
Task Lifecycle
1. Bot Startup
When the bot connects to Discord:
@bot.event
async def on_ready():
logger.info(f"{bot.user} has connected to Discord!")
if not daily_digest_task.is_running():
daily_digest_task.start()
logger.info("Daily digest task started")
See bot.py:594-608.
2. Initial Wait Period
The task calculates how long to wait until the next scheduled time:
@daily_digest_task.before_loop
async def before_daily_digest():
"""Wait until scheduled time to start the loop."""
await bot.wait_until_ready()
now = datetime.now(config.eastern_tz)
target_time = now.replace(hour=config.scheduled_hour, minute=0, second=0, microsecond=0)
if now.time() >= target_time.time():
target_time += timedelta(days=1)
wait_seconds = (target_time - now).total_seconds()
logger.info(f"⏰ Waiting {wait_seconds/3600:.1f} hours until first digest at {config.scheduled_hour}:00am ET")
await asyncio.sleep(wait_seconds)
See bot.py:672-685.
Example: Bot starts at 3 PM
Example: Bot starts at 11 PM
Example: Bot starts at 1 AM
Bot starts: 3:00 PM ET
Target time: 12:00 AM ET (next day)
Wait time: 9 hours
Log output:
⏰ Waiting 9.0 hours until first digest at 0:00am ET
Bot starts: 11:00 PM ET
Target time: 12:00 AM ET (1 hour away)
Wait time: 1 hour
Log output:
⏰ Waiting 1.0 hours until first digest at 0:00am ET
Bot starts: 1:00 AM ET (already past 12 AM)
Target time: 12:00 AM ET (next day)
Wait time: 23 hours
Log output:
⏰ Waiting 23.0 hours until first digest at 0:00am ET
3. Recurring Execution
After the first run, the task repeats every 24 hours at the same time.
Customizing the Schedule
You can change the scheduled hour by modifying the Config class in bot.py:
@dataclass
class Config:
# ... other fields ...
scheduled_hour: int = 9 # 9am ET
Digest will run at 9:00 AM Eastern Time every day.@dataclass
class Config:
# ... other fields ...
scheduled_hour: int = 18 # 6pm ET
Digest will run at 6:00 PM Eastern Time every day.To make it configurable without code changes, you could modify the Config:@dataclass
class Config:
scheduled_hour: int = field(default=0)
@classmethod
def from_env(cls) -> "Config":
# ... existing code ...
scheduled = os.getenv("SCHEDULED_HOUR", "0")
return cls(
# ... other fields ...
scheduled_hour=int(scheduled)
)
Then in .env:
What Gets Generated
The scheduled task runs the complete digest pipeline:
- Export: Last 24 hours of messages (configurable via
config.default_hours)
- AI Analysis: Claude processes the transcript
- Save: Markdown digest saved to
Daily Digests/
- Git Push: Automatic commit/push if GitHub is configured
This is identical to running !digest manually.
Logs and Monitoring
Startup Logs
2026-03-04 15:00:00 - INFO - DiscordExporterBot#1234 has connected to Discord!
2026-03-04 15:00:00 - INFO - Connected to: My Team Server
2026-03-04 15:00:00 - INFO - Daily digest task started
2026-03-04 15:00:00 - INFO - ⏰ Waiting 9.0 hours until first digest at 0:00am ET
Execution Logs
2026-03-05 00:00:00 - INFO - Running scheduled daily digest
2026-03-05 00:00:02 - INFO - Starting export for last 24 hours from My Team Server
2026-03-05 00:00:05 - INFO - Exported 45 messages from #engineering
2026-03-05 00:00:06 - INFO - Exported 32 messages from #product
2026-03-05 00:00:07 - INFO - Export complete: 147 messages from 5 channels
2026-03-05 00:00:12 - INFO - Saved digest to Daily Digests/2026-03-04 - Team Digest.md
2026-03-05 00:00:14 - INFO - Successfully pushed Daily Digests/2026-03-04 - Team Digest.md to GitHub
2026-03-05 00:00:14 - INFO - ✅ Daily digest completed successfully
2026-03-05 00:00:00 - INFO - Running scheduled daily digest
2026-03-05 00:00:02 - ERROR - Error calling Claude API: Rate limit exceeded
2026-03-05 00:00:02 - ERROR - Daily digest failed: Failed to generate digest
Failed digests do not crash the bot. The task will retry at the next
scheduled time (24 hours later).
Checking Task Status
You can verify the task is running by checking logs for:
Daily digest task started
⏰ Waiting X hours until first digest at 0:00am ET
If you don’t see these logs, the task may not have started properly.
Task Behavior
Error Handling
- Export failures: Logged and reported, task continues
- Claude API errors: Logged and reported, task continues
- GitHub push failures: Logged but digest still saved locally
- Task crashes: Bot remains online, task retries at next interval
Restart Behavior
If the bot restarts:
- Task recalculates wait time to next scheduled hour
- Does not run immediately if schedule was missed
- Waits until next scheduled time (e.g., next midnight)
If you want to generate a digest immediately after restart, use the manual
!digest command.
Comparison: Manual vs Scheduled
| Feature | !digest Command | Scheduled Task |
|---|
| Trigger | Manual Discord command | Automatic on schedule |
| Time Range | Configurable (1-720 hours) | Fixed (24 hours) |
| Discord Output | Preview posted in channel | No Discord message |
| File Output | Same markdown format | Same markdown format |
| GitHub Push | Yes (if configured) | Yes (if configured) |
| When to Use | On-demand analysis, custom ranges | Daily team summaries |
Configuration Reference
Relevant Config fields for scheduled tasks:
@dataclass
class Config:
scheduled_hour: int = 0 # Hour to run (0-23, ET)
default_hours: int = 24 # Time range for scheduled digest
digests_dir: str = "Daily Digests" # Output directory
eastern_tz: ZoneInfo = ... # Timezone (handles DST)
See bot.py:21-39 for full configuration.
Advanced: Custom Task Intervals
The @tasks.loop(hours=24) decorator supports other intervals:
@tasks.loop(hours=12)
async def daily_digest_task():
# Runs twice per day
from discord.ext import tasks
import datetime
@tasks.loop(hours=24)
async def weekly_digest_task():
if datetime.datetime.now().weekday() == 0: # Monday
# Run weekly digest
result = await run_digest_pipeline(bot, config, 168) # 7 days
from discord.ext import tasks
import datetime
@tasks.loop(time=datetime.time(hour=9, minute=0, tzinfo=config.eastern_tz))
async def daily_digest_task():
# Runs at exactly 9:00 AM ET every day
This is simpler than manual wait calculation but requires Discord.py 2.0+.
Troubleshooting
Task Not Running
- Check startup logs for “Daily digest task started”
- Verify bot is online with
!export command
- Check scheduled hour in Config matches your expectation
- Review timezone - scheduled_hour is in Eastern Time, not UTC
Digest Not Appearing
- Check logs for “Running scheduled daily digest”
- Verify ANTHROPIC_API_KEY is set
- Check output directory exists and is writable
- Review file naming - digests use previous day’s date if run at midnight
GitHub Push Failing
- Verify GITHUB_REPO_URL and GITHUB_TOKEN are set
- Check repository permissions - token needs push access
- Review git logs in bot output for specific errors
- Test manual commit to verify credentials work
- !digest - Generate digest manually on demand
- !export - Export messages without AI analysis