.env.example
Copy this file to.env in the project root and fill in your values:
Variable reference
Required
Telegram bot token issued by @BotFather. Create a new bot with the
/newbot command to obtain one.OpenAI API key used to call the GPT model for the AI curation layer. Obtain one from the OpenAI platform.
OpenAI
OpenAI model used for deal curation. Must be a valid model name accessible with your API key.Default:
gpt-4o-miniLayer 1 filters
Minimum discount percentage a deal must have to pass the deterministic filter. Accepted range:
0–100.Default: 50Minimum Metacritic score required for a game to pass the quality check. Set to
0 to disable the Metacritic check entirely and rely solely on the Steam rating. Accepted range: 0–100.Default: 70Minimum Steam community rating percentage required. A game passes the quality check if it meets either this threshold or the Metacritic threshold. Accepted range:
0–100.Default: 70Maximum sale price in USD after the discount is applied. Deals priced above this value are excluded. Accepted range:
1–999.Default: 60Number of deals to fetch from the CheapShark API per run. A larger value gives the AI more candidates to evaluate. The CheapShark API caps this at
60. Accepted range: 1–60.Default: 60Deduplication
Number of days to suppress repeat notifications for the same game. A game that was already broadcast will be excluded from subsequent runs for this many days. Accepted range:
1–365.Default: 7Scheduler
Cron expression that controls when the daily deal broadcast runs. The schedule is evaluated in the America/Bogota (UTC-5) timezone. See the Scheduler page for examples.Default:
0 9 * * * (every day at 9:00 AM Bogotá time)CRON_SCHEDULE is validated as a syntactically valid cron expression at startup using node-cron. If the value is invalid, the bot will throw an error and refuse to start.Startup validation
src/config.ts validates all values when the process starts:
required()— throws if the variable is missing or empty.optionalInt()— parses the value as an integer and throws if it is not a number or falls outside the declared[min, max]range.validatedCron()— passes the expression throughnode-cron.validate()and throws on an invalid cron string.