feat(discord): split decisions/news into second webhook channel
Adds DISCORD_WEBHOOK_DECISIONS_URL env var. If set, decision and news_alert posts go to that channel; all other events stay on the main webhook. Falls back to main webhook if not configured. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
be1adfb94c
commit
4e5051b8a8
@ -87,6 +87,7 @@ class Settings(BaseModel):
|
|||||||
openrouter_api_key: str = ""
|
openrouter_api_key: str = ""
|
||||||
cryptopanic_api_key: str = ""
|
cryptopanic_api_key: str = ""
|
||||||
discord_webhook_url: str = ""
|
discord_webhook_url: str = ""
|
||||||
|
discord_webhook_decisions_url: str = ""
|
||||||
db_path: str = "data/aitrader.db"
|
db_path: str = "data/aitrader.db"
|
||||||
|
|
||||||
|
|
||||||
@ -113,6 +114,7 @@ def get_settings() -> Settings:
|
|||||||
openrouter_api_key=os.getenv("OPENROUTER_API_KEY", ""),
|
openrouter_api_key=os.getenv("OPENROUTER_API_KEY", ""),
|
||||||
cryptopanic_api_key=os.getenv("CRYPTOPANIC_API_KEY", ""),
|
cryptopanic_api_key=os.getenv("CRYPTOPANIC_API_KEY", ""),
|
||||||
discord_webhook_url=os.getenv("DISCORD_WEBHOOK_URL", ""),
|
discord_webhook_url=os.getenv("DISCORD_WEBHOOK_URL", ""),
|
||||||
|
discord_webhook_decisions_url=os.getenv("DISCORD_WEBHOOK_DECISIONS_URL", ""),
|
||||||
db_path=os.getenv("AITRADER_DB", "data/aitrader.db"),
|
db_path=os.getenv("AITRADER_DB", "data/aitrader.db"),
|
||||||
)
|
)
|
||||||
return settings
|
return settings
|
||||||
|
|||||||
@ -22,16 +22,16 @@ def _enabled(settings: Settings) -> bool:
|
|||||||
return bool(settings.discord.enabled and settings.discord_webhook_url)
|
return bool(settings.discord.enabled and settings.discord_webhook_url)
|
||||||
|
|
||||||
|
|
||||||
def _post(settings: Settings, embed: dict[str, Any]) -> None:
|
def _post(settings: Settings, embed: dict[str, Any], channel: str = "trades") -> None:
|
||||||
if not _enabled(settings):
|
if not _enabled(settings):
|
||||||
return
|
return
|
||||||
|
if channel == "decisions" and settings.discord_webhook_decisions_url:
|
||||||
|
url = settings.discord_webhook_decisions_url
|
||||||
|
else:
|
||||||
|
url = settings.discord_webhook_url
|
||||||
embed.setdefault("timestamp", datetime.now(timezone.utc).isoformat())
|
embed.setdefault("timestamp", datetime.now(timezone.utc).isoformat())
|
||||||
try:
|
try:
|
||||||
r = requests.post(
|
r = requests.post(url, json={"embeds": [embed]}, timeout=8)
|
||||||
settings.discord_webhook_url,
|
|
||||||
json={"embeds": [embed]},
|
|
||||||
timeout=8,
|
|
||||||
)
|
|
||||||
if r.status_code >= 400:
|
if r.status_code >= 400:
|
||||||
log.warning("discord.post_failed", status=r.status_code, body=r.text[:200])
|
log.warning("discord.post_failed", status=r.status_code, body=r.text[:200])
|
||||||
except requests.RequestException as e:
|
except requests.RequestException as e:
|
||||||
@ -88,6 +88,7 @@ def notify_decision(settings: Settings, symbol: str, ensemble, label_a: str, lab
|
|||||||
{"name": "Rationale", "value": ensemble.rationale, "inline": False},
|
{"name": "Rationale", "value": ensemble.rationale, "inline": False},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
channel="decisions",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -227,4 +228,5 @@ def notify_news_alert(settings: Settings, symbol: str, headlines: list[dict[str,
|
|||||||
"color": color,
|
"color": color,
|
||||||
"description": top,
|
"description": top,
|
||||||
},
|
},
|
||||||
|
channel="decisions",
|
||||||
)
|
)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user