Skip to main content

Almanac bot for Twitter.

Project description

Almanac Bot

PyPi package Docker Hub

A Twitter bot that tweets historical events (ephemeris) on their anniversary dates. Each day, it finds events that happened on that calendar date (any year) and tweets them with localized text.

Features

  • Tweets historical events on their anniversary (month+day matching)
  • Supports multiple events per day
  • Template variables: ${date} (localized) and ${years_ago} (calculated)
  • Idempotency: won't tweet the same event twice on the same day
  • Dry-run mode for testing without sending tweets
  • Stateless execution triggered by external scheduler (Ofelia)

Dependencies

Quick Start

1. Create configuration

cp config.ini.default config.ini

Fill in the Twitter API credentials and other settings:

[language]
locale=ca_ES  # or en_US, es_ES, etc.

[twitter]
bearer_token=...
consumer_key=...
consumer_secret=...
access_token_key=...
access_token_secret=...

[postgresql]
user=almanac
password=almanac
hostname=postgres
database=almanac

2. Launch with Docker Compose

just docker-up
# or: docker compose up -d

This starts:

  • postgres: PostgreSQL database
  • almanac-bot: The bot container (kept alive for scheduled execution)
  • ofelia: Scheduler that triggers the bot daily at 8:00 AM

3. Load ephemeris data

just docker-load-data
# or: docker exec -it almanac-bot uv run python -m typer almanacbot.data_loader run

CSV format (init_db.csv):

date;text;location
1899-11-29 12:00 Europe/Madrid;El ${date}, avui fa ${years_ago} anys...;(41.38,2.17)

Usage

Manual execution

# Run once (will tweet if there are events for today)
just docker-run

# Dry-run mode (shows what would be tweeted without sending)
just docker-dry-run

Scheduled execution

The bot is automatically triggered by Ofelia at 8:00 AM daily. Check the schedule in compose.yaml:

labels:
  ofelia.job-exec.almanac.schedule: "0 0 8 * * *"  # Daily at 8 AM

View logs

just docker-logs            # Bot logs
just docker-logs-scheduler  # Scheduler logs (follow mode)

Development

Run tests

just test            # Unit tests
just test-cov        # With coverage report
just test-integration  # Integration tests (starts postgres automatically)

Linting

just lint      # Check for issues
just lint-fix  # Auto-fix issues

Build Docker image

just docker-build

Database

Schema

The ephemeris table stores historical events:

CREATE TABLE almanac.ephemeris (
    id serial primary key,
    date timestamp with time zone not null,
    text text not null,
    location point default null,
    last_tweeted_at timestamp with time zone default null
);

Clean database

just docker-clean-db

Just Commands Reference

just help  # Show all available commands
Command Description
just docker-up Start all services
just docker-down Stop all services
just docker-serve Start and follow logs
just docker-load-data Load ephemeris from CSV
just docker-run Run bot manually
just docker-dry-run Run without tweeting
just docker-logs View bot logs
just docker-logs-scheduler View scheduler logs
just docker-build Build Docker image
just docker-clean-db Remove database volume
just test Run unit tests
just test-cov Run tests with coverage
just test-integration Run integration tests
just lint Check code style
just lint-fix Fix code style

Architecture

                    Ofelia (scheduler)
                           │
                           │ triggers daily at 8 AM
                           ▼
┌─────────────────────────────────────────────────────┐
│                   almanac-bot                       │
│                                                     │
│  1. Query ephemeris for today (month+day match)     │
│  2. Filter out already-tweeted (idempotency)        │
│  3. Tweet each event                                │
│  4. Mark as tweeted (last_tweeted_at)               │
│  5. Exit                                            │
└─────────────────────────────────────────────────────┘
                           │
                           ▼
                      PostgreSQL

Production Deployment (Docker Swarm)

For production deployment on Docker Swarm:

1. Create Docker secrets

# Create secret from your config.ini file
docker secret create almanac_config /path/to/config.ini

2. Prepare the stack directory

mkdir -p /path/to/almanac-bot/{init_db,postgres}

# Copy the database init script (creates schema on first run)
cp postgres/init-ephemeris-db.sh /path/to/almanac-bot/postgres/

# Copy your ephemeris CSV data
cp your_data.csv /path/to/almanac-bot/init_db/init_db.csv

3. Configure the stack

# Copy the example and adjust paths
cp docker-compose.swarm.example.yaml /path/to/almanac-bot/docker-compose.swarm.yaml

# Edit the file and update volume paths to match your directory

4. Deploy

docker stack deploy -c /path/to/almanac-bot/docker-compose.swarm.yaml almanac

5. Load ephemeris data into database

After the stack is running, load the CSV data into PostgreSQL:

# Find the bot container
docker ps | grep almanac-bot

# Load the CSV into the database
docker exec <container_id> uv run python -m typer almanacbot.data_loader run

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

almanac_bot-1.1.3.tar.gz (9.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

almanac_bot-1.1.3-py3-none-any.whl (12.2 kB view details)

Uploaded Python 3

File details

Details for the file almanac_bot-1.1.3.tar.gz.

File metadata

  • Download URL: almanac_bot-1.1.3.tar.gz
  • Upload date:
  • Size: 9.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for almanac_bot-1.1.3.tar.gz
Algorithm Hash digest
SHA256 92572ddad2cb24b7dd8527274b5961963ac47629ef6594ea0f23f6e4f3f4a9e3
MD5 bb86e05cff287ebaa0a6acbf3d6ade88
BLAKE2b-256 1dcb276ccd8711e50376566477aa838a8c77860a9403e5183dcca417d6b76ae5

See more details on using hashes here.

Provenance

The following attestation bundles were made for almanac_bot-1.1.3.tar.gz:

Publisher: pypi-publish.yaml on logoff/almanac-bot

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file almanac_bot-1.1.3-py3-none-any.whl.

File metadata

  • Download URL: almanac_bot-1.1.3-py3-none-any.whl
  • Upload date:
  • Size: 12.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for almanac_bot-1.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 17972c8ca0f0ae78e71bf07a55cbda69300088a603c84e0afb4c37ac4cdb2919
MD5 b98aeade264b54156cd935b0be72850c
BLAKE2b-256 7c3e238337df62ce0c4c90f31320cf219eacd60f544b7f54e86136e9dc305061

See more details on using hashes here.

Provenance

The following attestation bundles were made for almanac_bot-1.1.3-py3-none-any.whl:

Publisher: pypi-publish.yaml on logoff/almanac-bot

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page