PolymarketNotify (PolymarketNotify v0.1.0)

Copy Markdown View Source

Notification controls + channels for the Polymarket bot.

Two layers:

  • Controls (PolymarketNotify.Controls) — the core: what the user wants to see and where, as per-category defaults (:fills, :resolutions, :errors, :daily_summary, …) with per-strategy overrides. So you can route fills for the AI strategy to Telegram while muting fills for the surge bots, etc.
  • Channels (PolymarketNotify.Channel) — pluggable delivery: Telegram, Discord, Webhook, Log. A channel just ships text.

Strategy is identified by its tag (any string) — built-in or a user-written strategy alike — so custom strategies get their own notification settings with no code change here.

notify/3 is best-effort: it consults the controls, and if the (category, strategy, value) passes, fans the message out to that category's channels. Nothing configured / not allowed ⇒ silent no-op. It never raises into the caller.

Config:

config :polymarket_notify,
  channels: %{
    telegram: {PolymarketNotify.Telegram, [bot_token: {:system, "TELEGRAM_BOT_TOKEN"}, chat_id: ...]},
    log: {PolymarketNotify.Log, []}
  },
  controls: PolymarketNotify.Controls.default()

Summary

Functions

Deliver message for category. Options

Resolve a literal, {:system, "VAR"} (env), or nil. Channels use this for secrets.

Functions

notify(category, message, opts \\ [])

@spec notify(atom(), String.t(), keyword()) :: :ok

Deliver message for category. Options:

  • :strategy — strategy tag (for per-strategy overrides).
  • :value — magnitude (e.g. fill notional, P&L) for threshold filters.
  • :controls / :channels — inject (tests); else app config / defaults.

Returns :ok (always; best-effort).

resolve(value)

@spec resolve(term()) :: term()

Resolve a literal, {:system, "VAR"} (env), or nil. Channels use this for secrets.