Eric's ESPN Fantasy Football Openclaw Skill, acronymed backwards for a better name.
Project SOFFEE is an open-source initiative to build a native, conversational AI assistant for fantasy football leagues. Deployed as an OpenClaw skill, the agent assumes the persona of "Sofie" — an autonomous, Slack-native commissioner's assistant.
Sofie bridges the gap between disparate fantasy sports platforms and the modern chat environments where leagues actually communicate, serving as a data retrieval engine, roster manager, and automated content generator.
For the full executive summary and phased roadmap, see
meta/SOFFEE.md.
At its heart, fantasy football serves as a vital social engine for maintaining lifelong friendships. SOFFEE is engineered to augment human interaction rather than automate it away. Sofie's automated briefings, performance recaps, and persona are specifically tuned to ignite league banter, cultivate competitive rivalries, and prompt frequent manager engagement.
Sofie does not use a standard OAuth flow for individual league managers. Instead, she operates entirely using the Commissioner's ESPN credentials.
Because there is no official, public ESPN Fantasy API, Sofie authenticates by piggybacking on the Commissioner's browser session cookies (SWID and espn_s2). This gives the bot "Commissioner Access" to execute roster moves for any team in the league.
- You must provide your cookies: To run Sofie, the Commissioner must extract their
SWIDandespn_s2cookies from their browser and place them in the.envfile. - Never share your
.env: These cookies provide access to your entire ESPN account. DO NOT commit them to GitHub. If you are not the one hosting the OpenClaw server, you must implicitly trust the person who is. - The Slack ID Mapping is your firewall: Because Sofie has the power to drop any player in the league,
SOFFEE_SLACK_USER_TO_TEAM_MAPis your only line of defense. Sofie cross-references the Slack User ID of the person issuing a command against this mapping before executing a move. You must configure this mapping accurately to prevent managers from modifying other people's rosters.
- Log into your ESPN Fantasy account on a desktop browser.
- Right-click anywhere and select Inspect to open Developer Tools.
- Go to the Application (Chrome/Edge) or Storage (Firefox) tab.
- Under the Cookies section, select
http://fantasy.espn.com. - Find the
SWIDvalue (looks like{UUID}) and theespn_s2value (a very long string). - Paste these into your
.envfile.
| Phase | Focus | Architecture |
|---|---|---|
| v0 | Slack MVP | Monolithic OpenClaw skill (ESPN hardcoded) |
| v1 | Architecture Refactor | soffee-core (PyPI) + soffee-skill (ClawHub) |
| v2+ | Multi-Platform | Universal Interface + provider adapters |
| Path | Purpose |
|---|---|
apps/ |
Standalone Python applications, each with its own pyproject.toml |
libs/ |
Shared Python libraries used across applications |
testing/ |
Shared test utilities, fixtures, and helpers |
scripts/ |
Utility and automation scripts |
templates/ |
Template files for scaffolding new apps and libs |
meta/adr/ |
Architecture Decision Records — the logbook of why decisions were made |
meta/plans/ |
Project plans and roadmaps |
docs-src/ |
Source files for generated documentation (MkDocs) |
.github/ |
GitHub-specific configuration (issue templates, PR templates, CI workflows) |
| ADR | Decision |
|---|---|
| ADR-002 | Python 3.12+ as minimum version |
| ADR-015 | uv for dependency management |
| ADR-004 | pytest for testing |
| ADR-005 | Ruff for linting and formatting |
| ADR-006 | Docker for containerization |
| ADR-007 | Monorepo /apps structure |
See meta/adr/ for the full list of Architecture Decision Records.
Sofie connects to your Slack workspace using Slack Socket Mode, a secure, bidirectional connection managed by the OpenClaw framework.
To deploy Sofie, your Slack App must request the following OAuth scopes:
| Scope | Purpose |
|---|---|
chat:write |
Post messages to channels and direct messages |
chat:write.public |
Post to public channels |
reactions:read |
Read message reactions |
channels:read |
List and view channel information |
users:read |
Read user profiles and information |
Enable Event Subscriptions in your Slack App and subscribe to:
app_mention— Listen for mentions of Sofiemessage.channels— Listen to channel messagesmessage.im— Listen to direct messages
Once your Slack App is configured, set the following environment variables:
SLACK_APP_TOKEN=xapp-1-XXXXXXXXXXXXXXX # Socket Mode App Token
SLACK_BOT_TOKEN=xoxb-XXXXXXXXXXXXXXX # Bot User OAuth Token
ESPN_SWID={YOUR-ESPN-SWID} # ESPN SWID cookie value
ESPN_S2=YOUR_ESPN_S2_COOKIE # ESPN espn_s2 cookie value
ESPN_LEAGUE_ID=123456 # ESPN fantasy league ID
ESPN_YEAR=2025 # Active season year
SOFFEE_SLACK_USER_TO_TEAM_MAP='{"U1234567890": 1, "U0987654321": 2}'
SOFFEE_BROADCAST_CHANNEL=#nfl-updates
SOFFEE_CRON_SUNDAY_10AM=0 15 * * 0
SOFFEE_CRON_SUNDAY_12PM=0 17 * * 0
SOFFEE_CRON_SUNDAY_430PM=30 21 * * 0
SOFFEE_CRON_SUNDAY_8PM=0 1 * * 1
SOFFEE_CRON_MONDAY_TUESDAY_7AM=0 12 * * 1,2SOFFEE_SLACK_USER_TO_TEAM_MAP must be a JSON object mapping each Slack user ID to the ESPN team ID that person is allowed to manage. Do not let users supply slack_user_id manually in chat; roster actions should use the real Slack actor ID from OpenClaw/Slack context.
See .env.example for a template. For detailed setup instructions, refer to the Configuration section in SKILL.md.
# Install Python 3.12+
pyenv install 3.12
pyenv local 3.12
# Install uv
pip install uv
# Install pre-commit hooks
pip install pre-commit
pre-commit install
# Run local quality checks
./scripts/local-ci-check.shThis project is licensed under the MIT License.