An open-source configurable Python Discord bot that posts daily foreign exchange rates, stock, and commodities prices to a Discord channel.
Built to run as a one-shot scheduled job using GitHub Actions — no servers, no background workers, no idle costs.
- Configurable base currency (default:
IDR) - Multiple currency exchange in one config
- Configurable market symbols using Yahoo Finance (
yfinance) - Scheduled execution via GitHub Actions (cron)
- Sends one Discord message and exits cleanly
- Can be run locally with a
.envfile - Free, serverless, and easy to maintain
Currently only supports commodities in troy ounce price and sent in gram price.
📊 Daily Market Update
Friday, 30 January 2026
💱 FX Rates
1 USD = 16,756 IDR
1 SGD = 13,238 IDR
1 MYR = 4,270 IDR
1 AUD = 11,814 IDR
1 EUR = 20,021 IDR
1 GBP = 23,108 IDR
📈 Stocks
^JKSE: 8,329.15
^GSPC: 6,939.03
⛏️ Commodities
Gold: 2,785,436.35 IDR
Silver: 55,950.42 IDR
The workflow uses GitHub Actions Environments.
Defined environments:
staging(for testing, manual runs supported viaworkflow_dispatch)production(default, for cron job)
All configuration is provided via GitHub Actions Environments (and via .env for local development).
(GitHub → Settings → Secrets and variables → Actions → Secrets)
or
(GitHub → Settings → Environments → {environment} → Secrets)
These variables are required.
| Variable | Description |
|---|---|
DISCORD_TOKEN |
Discord bot token |
DISCORD_CHANNEL_ID |
Target Discord channel ID |
(GitHub → Settings → Secrets and variables → Actions → Variables)
or
(GitHub → Settings → Environments → {environment} → Variables)
| Variable | Description | Default |
|---|---|---|
BASE_CURRENCY |
Base currency for FX rates | IDR |
CURRENCIES |
Comma-separated currency list | USD,SGD,MYR,AUD,EUR,GBP |
SYMBOLS |
Comma-separated list of stock in Yahoo Finance symbols (see the symbol format below) | ^JKSE,^GSPC |
GOODS |
Comma-separated list of commodities with their Yahoo Finance symbols (Name:Symbol, see the symbol format below, currently only supports commodities in troy ounce price and sent in gram price) |
Gold:GC=F,Silver:SI=F |
TIMEZONE |
Timezone for the date in Discord message | Asia/Jakarta |
The stock and commodities symbols must follow yfinance or Yahoo Finance conventions.
Example:
SYMBOLS=^JKSE,^GSPC
GOODS=Gold:GC=F,Silver:SI=F| Market | Example |
|---|---|
| Indexes | ^GSPC, ^JKSE |
| US stocks | AAPL, META, TSLA |
| Indonesia stocks | BBCA.JK, TLKM.JK |
| Other exchanges | Use exchange suffix (e.g. .L, .HK) |
| Commodities | GC=F (gold), SI=F (silver) |
Most symbols available on Yahoo Finance will work. Search on Yahoo Finance and use the ticker shown: https://finance.yahoo.com.
The bot runs via GitHub Actions on a cron schedule.
Default schedule:
schedule:
- cron: '0 2 * * *'- Runs daily at 02:00 UTC (the free GitHub Actions can be delayed)
- The schedule can be adjusted directly in the workflow file
- Manual runs supported via
workflow_dispatch
Local development uses a .env file.
- Copy the example file:
cp env.example .env- Fill in required values:
DISCORD_TOKEN=your_bot_token
DISCORD_CHANNEL_ID=your_channel_id- Customize configuration:
BASE_CURRENCY=IDR
CURRENCIES=USD,SGD,MYR,AUD,EUR,GBP
SYMBOLS=^JKSE,^GSPC
GOODS=Gold:GC=F,Silver:SI=F
TIMEZONE=Asia/Jakarta- Install dependencies and run:
pip install -r requirements.txt
python bot.py- GitHub Actions starts the workflow
- Python script fetches:
- Exchange rates from
open.er-api.com - Market prices using
yfinance
- Exchange rates from
- Bot logs into Discord
- Sends one message
- Bot shuts down gracefully
No persistent service, no open ports, no background workers.
MIT License