mirror of
https://github.com/prosolis/gogobee.git
synced 2026-07-15 08:32:41 +00:00
Two things, entangled in the working tree because 20d1f92 was mislabeled
(its message claimed "device grant" but it only deleted registration.yaml.example
and left the failed appservice+/sync hybrid in client.go):
1. Land the MAS OAuth 2.0 device grant that was running in prod but never
committed: masauth.go + client.go rewrite. Bot stays a normal user so /sync
works; refresh token persisted in data/mas_auth.json.
2. Add "appservice" as an alternate transport behind AUTH_MODE (default
"masdevice" = unchanged device-grant path, instant rollback):
- internal/bot/session.go: Session abstraction unifying both transports
(OnEventType/Run/Stop); NewSession dispatches on AuthMode.
- internal/bot/appservice.go: as_token auth (MAS-durable, no login/MFA/expiry),
cryptohelper MSC4190 device creation, crypto machine fed from Synapse
transaction pushes (to-device/device-lists/OTK) instead of /sync, inbound
decrypt+redispatch, and lazy per-room StateStore backfill (encryption +
members) so replies in encrypted rooms encrypt to the right recipients.
- main.go: NewSession/sess.OnEventType/sess.Run in place of the /sync loop.
- .env.example: AUTH_MODE, AS_REGISTRATION, AS_LISTEN_HOST/PORT, HOMESERVER_DOMAIN.
The appservice path fixes the earlier hybrid's fatal flaw (Synapse forbids AS
users from /sync) by using the transaction/push model. Bot-side only; Synapse
registration + experimental_features (msc2409/msc3202/msc4190) and E2EE cutover
are the next steps. Build + vet green (CGO=1 -tags goolm).
163 lines
8.1 KiB
Plaintext
163 lines
8.1 KiB
Plaintext
# ---- Matrix Connection ----
|
|
# GogoBee authenticates via the MAS (Matrix Authentication Service) OAuth 2.0
|
|
# device grant. No password/token goes here: on first run the bot prints a URL
|
|
# + code to approve ONCE in a browser (logged in as BOT_USER_ID), then stores a
|
|
# refresh token in DATA_DIR/mas_auth.json and refreshes silently thereafter.
|
|
# To force re-authorization, delete data/mas_auth.json.
|
|
HOMESERVER_URL=https://matrix.example.com
|
|
BOT_USER_ID=@gogobee:example.com
|
|
BOT_DISPLAY_NAME=GogoBee
|
|
|
|
# ---- Auth mode ----
|
|
# masdevice (default) — MAS OAuth 2.0 device grant over /sync (above).
|
|
# appservice — Matrix appservice: the registration's as_token is the
|
|
# credential (no login/MFA/expiry, MAS-durable). The bot
|
|
# runs an HTTP listener and receives events over Synapse's
|
|
# transaction push instead of /sync (Synapse forbids AS
|
|
# users from /sync). E2EE rides MSC3202/MSC2409 + MSC4190.
|
|
AUTH_MODE=masdevice
|
|
# The following are required only when AUTH_MODE=appservice:
|
|
AS_REGISTRATION= # path to the appservice registration YAML (as_token/hs_token/namespaces)
|
|
AS_LISTEN_HOST= # bind address for the transaction listener (e.g. 0.0.0.0 or a tailnet IP)
|
|
AS_LISTEN_PORT= # bind port; Synapse's registration url must reach host:port
|
|
HOMESERVER_DOMAIN= # server_name, e.g. example.com (derives the bot MXID from sender_localpart)
|
|
|
|
# Which rooms the bot posts scheduled content to (comma-separated room IDs)
|
|
BROADCAST_ROOMS=!roomid:example.com
|
|
|
|
# The daily 08:00 WOTD auto-post is disabled by default.
|
|
# Set to true to enable it. The !wotd command and passive WOTD
|
|
# usage tracking work regardless of this setting.
|
|
ENABLE_WOTD_POST=false
|
|
|
|
# Admins who can run admin-only commands (comma-separated Matrix user IDs)
|
|
ADMIN_USERS=@yourmxid:example.com
|
|
|
|
# ---- Runtime ----
|
|
DATA_DIR=./data
|
|
LOG_LEVEL=info
|
|
|
|
# ---- External API Keys (all optional) ----
|
|
RAWG_API_KEY=
|
|
DREAMDICT_URL=http://127.0.0.1:7777
|
|
CALENDARIFIC_API_KEY=
|
|
HOLIDAY_COUNTRIES=US,GB,CA,AU,PT,IN,JP,DE,FR,BR,MX,IT,ES,KR,NL,SE,NO,IE,NZ,ZA,PH
|
|
OPENWEATHER_API_KEY=
|
|
FINNHUB_API_KEY=
|
|
BANDSINTOWN_API_KEY=
|
|
TMDB_API_KEY=
|
|
SERPAPI_KEY= # SerpAPI key for image fetching (esteemed members)
|
|
|
|
# ---- Self-Hosted Services (optional) ----
|
|
LIBRETRANSLATE_URL=
|
|
OLLAMA_HOST=
|
|
OLLAMA_MODEL=
|
|
LLM_SAMPLE_RATE=0.15 # 0.0-1.0, fraction of non-keyword messages to classify (1.0 = all)
|
|
|
|
# ---- Feature Flags ----
|
|
FEATURE_URL_PREVIEW=
|
|
FEATURE_SHADE=
|
|
FEATURE_TRIVIA=true # set to "false" to disable trivia
|
|
FEATURE_ESTEEMED= # set to anything to enable satirical esteemed member posts
|
|
ESTEEMED_ROOM= # room ID for esteemed member posts (separate from broadcast rooms)
|
|
|
|
# ---- Games & Economy ----
|
|
GAMES_ROOM= # room ID where game commands work (trivia, hangman, blackjack, holdem, wordle, flip)
|
|
EURO_COOLDOWN_SECONDS=30 # cooldown between passive euro earning
|
|
EURO_DEBT_REMINDER=true # weekly DM reminder if in debt
|
|
EURO_STARTING_CAP=2500 # max starting balance from corpus
|
|
HANGMAN_MAX_WRONG_GUESSES=6
|
|
HANGMAN_SOLUTION_BONUS_MULTIPLIER=2
|
|
HANGMAN_PHRASE_FILE= # path to newline-delimited phrase file
|
|
BLACKJACK_TIMEOUT_SECONDS=60 # auto-play timeout per player turn
|
|
BLACKJACK_AUTOPLAY_THRESHOLD=15
|
|
BLACKJACK_MIN_BET=1
|
|
BLACKJACK_MAX_BET=500
|
|
BLACKJACK_DEBT_LIMIT=1000 # max debt before betting disabled
|
|
UNO_MIN_BET=10 # minimum wager in euros (solo)
|
|
UNO_POT_TAUNT_THRESHOLD=500 # pot size at which GogoBee starts taunting
|
|
UNO_MULTI_MIN_BET=25 # minimum ante for multiplayer UNO
|
|
UNO_MULTI_MAX_BET=500 # maximum ante for multiplayer UNO
|
|
UNO_MULTI_LOBBY_TIMEOUT=300 # lobby expiry in seconds (default 300 = 5min)
|
|
UNO_MULTI_TURN_TIMEOUT=30 # auto-play timeout in seconds (default 30)
|
|
UNO_MULTI_MAX_AUTOPLAY=3 # consecutive auto-plays before forfeit
|
|
|
|
# Texas Hold'em
|
|
HOLDEM_SMALL_BLIND=10 # small blind amount
|
|
HOLDEM_BIG_BLIND=20 # big blind amount
|
|
HOLDEM_MIN_BUYIN=200 # minimum balance to join
|
|
HOLDEM_MAX_BUYIN=2000 # maximum stack at buy-in
|
|
HOLDEM_TIMEOUT_SECONDS=90 # action timeout per turn
|
|
HOLDEM_NPC_NAME=TwinBee # NPC bot display name
|
|
HOLDEM_NPC_HOUSE_BALANCE=10000 # NPC starting bankroll
|
|
HOLDEM_CFR_POLICY=data/policy.gob # path to CFR policy file
|
|
|
|
# Wordle
|
|
WORDLE_DEFAULT_LENGTH=5 # default word length (5, 6, or 7)
|
|
|
|
# ---- Space Groups (automatic room grouping for community-wide leaderboards) ----
|
|
SPACE_GROUP_THRESHOLD=50 # % of smaller room's members that must overlap (1-100, default 50)
|
|
|
|
# ---- Missing Members (!haveyouseenthem / !missing) ----
|
|
MISSING_THRESHOLD_DAYS=14 # days of inactivity before considered missing
|
|
MISSING_MAX_DAYS=90 # days after which they're considered gone, not missing
|
|
MISSING_MIN_MESSAGES=10 # minimum lifetime messages to be eligible
|
|
MISSING_EXCLUDE_USERS= # comma-separated user IDs to never list as missing
|
|
|
|
# ---- Encryption ----
|
|
QUOTE_ENCRYPTION_KEY= # Base64-encoded 32-byte AES-256 key (required for !quote)
|
|
|
|
# ---- Moderation (disabled by default) ----
|
|
FEATURE_MODERATION= # set to "true" to enable the moderation system
|
|
MOD_WORDLIST= # path to newline-delimited word list file
|
|
MOD_WORDLIST_VARIATIONS=true # check leetspeak/spaced variants
|
|
MOD_STRIKE_EXPIRY_DAYS=30 # strikes expire after N days
|
|
MOD_MUTE_DURATION_MINUTES=60 # temp mute duration on strike 2
|
|
MOD_MAX_STRIKES=3 # strikes before permanent ban
|
|
MOD_FLOOD_MESSAGE_COUNT=5 # messages within window = flood
|
|
MOD_FLOOD_MESSAGE_WINDOW_SECONDS=10
|
|
MOD_FLOOD_IMAGE_COUNT=3 # images/files within window = flood
|
|
MOD_FLOOD_IMAGE_WINDOW_SECONDS=30
|
|
MOD_MAX_MESSAGE_LENGTH=2000 # max chars per message (0 = disabled)
|
|
MOD_REPEAT_COUNT=3 # same message N times = strike
|
|
MOD_REPEAT_WINDOW_SECONDS=60
|
|
MOD_REPEAT_SIMILARITY_THRESHOLD=0.85
|
|
MOD_MENTION_MAX=5 # max unique @mentions per message
|
|
MOD_MENTION_FLOOD_COUNT=3
|
|
MOD_MENTION_FLOOD_WINDOW_SECONDS=30
|
|
MOD_LINK_RATE_NEW_MEMBER=3 # max links per window (new members only)
|
|
MOD_LINK_RATE_WINDOW_SECONDS=60
|
|
MOD_INVITE_MAX_PER_HOUR=5
|
|
MOD_JOIN_LEAVE_COUNT=3 # join/leave cycles = flag (no auto-strike)
|
|
MOD_JOIN_LEAVE_WINDOW_MINUTES=10
|
|
MOD_NEW_MEMBER_DAYS=14 # accounts newer than N days = stricter thresholds
|
|
MOD_NEW_MEMBER_FLOOD_MULTIPLIER=0.5
|
|
MOD_ADMIN_ROOM= # dedicated admin room for mod notifications
|
|
MOD_DM_ON_ACTION=true # DM users when action is taken
|
|
|
|
# ---- Miniflux RSS ----
|
|
MINIFLUX_URL= # Miniflux instance URL (e.g. https://rss.example.com)
|
|
MINIFLUX_API_KEY= # Miniflux API key
|
|
MINIFLUX_POLL_INTERVAL=15 # minutes between polls (default 15)
|
|
MINIFLUX_DEFAULT_ROOM= # default room for feed posts (falls back to BROADCAST_ROOMS)
|
|
MINIFLUX_MAX_PER_POLL=5 # max entries per feed per poll (default 5)
|
|
|
|
# ---- Rate Limits (per user per day) ----
|
|
RATELIMIT_WEATHER=5
|
|
RATELIMIT_TRANSLATE=20
|
|
RATELIMIT_CONCERTS=10
|
|
|
|
# ---- Email Nag (one-shot migration helper: collect+verify missing Authentik emails over Matrix DM) ----
|
|
FEATURE_EMAIL_NAG= # set to "true" to enable
|
|
EMAIL_NAG_AUTHENTIK_URL= # e.g. https://authentik.parodia.dev
|
|
EMAIL_NAG_AUTHENTIK_TOKEN= # Authentik service-account token, scoped to user write
|
|
EMAIL_NAG_RESEND_KEY= # Resend API key (sends the verification code)
|
|
EMAIL_NAG_MAIL_FROM= # e.g. Parodia <noreply@mail.parodia.dev>
|
|
EMAIL_NAG_HOME_DOMAIN= # Matrix server name, e.g. parodia.dev (builds @user:domain)
|
|
EMAIL_NAG_TARGETS= # comma-separated Authentik usernames to nag (== Matrix localparts)
|
|
EMAIL_NAG_CODE_TTL=30m # verification code lifetime (default 30m)
|
|
EMAIL_NAG_MAX_ATTEMPTS=5 # wrong-code attempts before restart (default 5)
|
|
EMAIL_NAG_MAX_SENDS_PER_HOUR=5 # cap on verification emails per user per rolling hour (anti-spam, default 5)
|
|
EMAIL_NAG_SWEEP_DELAY=2s # delay between DMs during the startup sweep (default 2s)
|
|
EMAIL_NAG_REPROMPT_COOLDOWN= # re-nag non-responders whose last prompt is older than this (e.g. 72h); empty/0 = nag once
|