Add multi-channel support for stock updates
Bot now supports sending updates to multiple Discord channels simultaneously. Changes: - CHANNEL_ID accepts comma-separated list of channel IDs - Config parses and validates multiple channel IDs - Hourly and market close updates sent to all configured channels - Update .env.example to show multi-channel format - Document multi-channel configuration in README Example: CHANNEL_ID=1442203998932304035,9876543210123456789 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# Discord Configuration
|
||||
DISCORD_TOKEN=your_discord_bot_token_here
|
||||
CHANNEL_ID=your_channel_id_here
|
||||
CHANNEL_ID=your_channel_id_here,optional_second_channel_id
|
||||
|
||||
# Bot Configuration
|
||||
COMMAND_PREFIX=!
|
||||
|
||||
@@ -159,11 +159,16 @@ Environment variables in `.env`:
|
||||
| Variable | Description | Default |
|
||||
|----------|-------------|---------|
|
||||
| `DISCORD_TOKEN` | Your Discord bot token | Required |
|
||||
| `CHANNEL_ID` | Discord channel ID for updates | Required |
|
||||
| `CHANNEL_ID` | Discord channel ID(s) for updates (comma-separated for multiple) | Required |
|
||||
| `COMMAND_PREFIX` | Command prefix for bot | `!` |
|
||||
| `PRIMARY_TICKER` | Stock ticker for hourly updates | `PYPL` |
|
||||
| `UPDATE_INTERVAL_HOURS` | Hours between updates | `1` |
|
||||
|
||||
**Multi-Channel Support:** To send updates to multiple channels, provide comma-separated channel IDs:
|
||||
```
|
||||
CHANNEL_ID=1442203998932304035,9876543210123456789
|
||||
```
|
||||
|
||||
## Switching Stock API Providers
|
||||
|
||||
The bot is designed with an abstract API layer. To switch providers:
|
||||
|
||||
23
bot.py
23
bot.py
@@ -36,7 +36,7 @@ class StockBot(commands.Bot):
|
||||
logger.info("Using Yahoo Finance API for stock data")
|
||||
|
||||
self.scheduler = AsyncIOScheduler(timezone=pytz.timezone('America/New_York'))
|
||||
self.target_channel_id = int(Config.CHANNEL_ID)
|
||||
self.target_channel_ids = [int(id) for id in Config.CHANNEL_IDS]
|
||||
self.primary_ticker = Config.PRIMARY_TICKER
|
||||
|
||||
async def setup_hook(self):
|
||||
@@ -67,14 +67,15 @@ class StockBot(commands.Bot):
|
||||
"""Called when bot successfully connects to Discord."""
|
||||
logger.info(f'Bot connected as {self.user.name} (ID: {self.user.id})')
|
||||
logger.info(f'Monitoring ticker: {self.primary_ticker}')
|
||||
logger.info(f'Target channel ID: {self.target_channel_id}')
|
||||
logger.info(f'Target channel IDs: {self.target_channel_ids}')
|
||||
|
||||
# Verify channel exists
|
||||
channel = self.get_channel(self.target_channel_id)
|
||||
if channel:
|
||||
logger.info(f'Target channel found: #{channel.name}')
|
||||
else:
|
||||
logger.error(f'Could not find channel with ID {self.target_channel_id}')
|
||||
# Verify channels exist
|
||||
for channel_id in self.target_channel_ids:
|
||||
channel = self.get_channel(channel_id)
|
||||
if channel:
|
||||
logger.info(f'Target channel found: #{channel.name} (ID: {channel_id})')
|
||||
else:
|
||||
logger.error(f'Could not find channel with ID {channel_id}')
|
||||
|
||||
async def send_hourly_update(self):
|
||||
"""Send hourly stock price update if market is open."""
|
||||
@@ -83,7 +84,8 @@ class StockBot(commands.Bot):
|
||||
return
|
||||
|
||||
logger.info(f"Sending hourly update for {self.primary_ticker}")
|
||||
await self.send_stock_update(self.primary_ticker, self.target_channel_id)
|
||||
for channel_id in self.target_channel_ids:
|
||||
await self.send_stock_update(self.primary_ticker, channel_id)
|
||||
|
||||
async def send_market_close_update(self):
|
||||
"""Send stock price update at market close on trading days."""
|
||||
@@ -92,7 +94,8 @@ class StockBot(commands.Bot):
|
||||
return
|
||||
|
||||
logger.info(f"Sending market close update for {self.primary_ticker}")
|
||||
await self.send_stock_update(self.primary_ticker, self.target_channel_id)
|
||||
for channel_id in self.target_channel_ids:
|
||||
await self.send_stock_update(self.primary_ticker, channel_id)
|
||||
|
||||
async def send_stock_update(self, ticker: str, channel_id: int):
|
||||
"""
|
||||
|
||||
10
config.py
10
config.py
@@ -10,6 +10,7 @@ class Config:
|
||||
# Discord configuration
|
||||
DISCORD_TOKEN = os.getenv('DISCORD_TOKEN')
|
||||
CHANNEL_ID = os.getenv('CHANNEL_ID')
|
||||
CHANNEL_IDS = [id.strip() for id in os.getenv('CHANNEL_ID', '').split(',') if id.strip()]
|
||||
COMMAND_PREFIX = os.getenv('COMMAND_PREFIX', '!')
|
||||
|
||||
# Stock configuration
|
||||
@@ -36,10 +37,15 @@ class Config:
|
||||
print("ERROR: CHANNEL_ID not set in environment")
|
||||
return False
|
||||
|
||||
if not cls.CHANNEL_IDS:
|
||||
print("ERROR: No valid channel IDs found in CHANNEL_ID")
|
||||
return False
|
||||
|
||||
try:
|
||||
int(cls.CHANNEL_ID)
|
||||
for channel_id in cls.CHANNEL_IDS:
|
||||
int(channel_id)
|
||||
except ValueError:
|
||||
print("ERROR: CHANNEL_ID must be a numeric Discord channel ID")
|
||||
print("ERROR: CHANNEL_ID must contain numeric Discord channel IDs (comma-separated)")
|
||||
return False
|
||||
|
||||
if cls.STOCK_API_PROVIDER == 'finnhub' and not cls.FINNHUB_API_KEY:
|
||||
|
||||
Reference in New Issue
Block a user