---
# System prepended metadata

title: 打造股市小幫手：使用 Discord Bot 結合 Fugle Realtime API 取得即時股價資訊
tags: [' 理財機器人', ' 股市小幫手', ' 台股 API', ' Discord Bot', Python, ' Fugle']

---

---
tags: Python, Discord Bot, Fugle, 台股 API, 股市小幫手, 理財機器人
---

# 打造股市小幫手：使用 Discord Bot 結合 Fugle Realtime API 取得即時股價資訊

股市投資是許多人關注的焦點之一，而隨著數位科技的進步，利用程式自動化獲取股市資訊已經漸漸成為一種新趨勢！本篇將手把手帶大家了解如何透過 Python Discord Bot 結合 Fugle Realtime API，幫助你可以在 Discord 上獲取股市即時資訊，打造一個方便實用的股市小幫手！

## 事前準備

在開始之前，你需要準備以下工作：

1. **創建 Discord Bot**：在 Discord 開發者平台上建立一個新的 Bot 並取得 Token。
2. **取得 Fugle API Key**：在 Fugle Developer 金鑰申請及管理頁上註冊富果會員並取得，方便後續取得台股即時行情資訊。

### 創建 Discord Bot

首先，我們需要建立一個 Discord Bot 並設定好相關權限。

1. 登入 Discord 帳號：https://discord.com/
2. 前往 Discord Developers：https://discord.com/developers/applications
3. 點選右上角的 New Application
    ![new_application](https://hackmd.io/_uploads/r143r7PfA.png)
    輸入機器人名點選同意後按下 create
    ![create_bot](https://hackmd.io/_uploads/H1fArmwMC.png)
4. 點選左側功能欄的 Bot 設定頁面
    ![create_bot-1](https://hackmd.io/_uploads/Hk4kImvzC.png)
    下滑至 Privileged Gateway Intents 區塊，開啟三個功能選項並按下 Save Change，方便後續操作機器人
    ![bot_setting-2](https://hackmd.io/_uploads/ryjeLXvzR.png)
5. 點選左側功能欄的 OAuth2 設定頁面，勾選 bot 以及 點選 Administrator 賦予機器人所有權限
    ![OAuth2](https://hackmd.io/_uploads/BkAbIQwMR.png)
    最下方的 GENERATED URL  即是邀請機器人到伺服器中的連結
    ![OAuth2-2](https://hackmd.io/_uploads/HJdzLmPzA.png)
6. 前往上方的連結即可進入邀請頁面，點選要加入的伺服器
    ![bot_login-1](https://hackmd.io/_uploads/SyzEUQvz0.png)
    點選授權
    ![bot_login-3](https://hackmd.io/_uploads/rJzBIQwzC.png)
7. 頻道中機器人出現在成員列表中以及歡迎訊息，代表機器人創建成功
    ![bot_著陸畫面](https://hackmd.io/_uploads/S1_vImwf0.png)
8. 回到 Bot 設置頁面，點選 Reset Token 複製 Token，並妥善保存，參考步驟如下：
    ![取得_token-1](https://hackmd.io/_uploads/rJgdUXvzR.png)
    點選 `Yes, do it!`
    ![取得_token-2](https://hackmd.io/_uploads/Sy9OImDGC.png) 
    點選 Copy
    ![取得_token-3](https://hackmd.io/_uploads/rkCO8mPzC.png)

### 取得 Fugle API Key

1. 登入／註冊富果會員：https://www.fugle.tw/account/register
2. 前往富果 developer 金鑰申請頁：https://developer.fugle.tw/docs/key/
3. 在行情 API 區，點選新增 API key 後輸入 API Key 名稱
    ![輸入_key_name](https://hackmd.io/_uploads/r1p2IXwzC.png)
    複製 API Key 並妥善留存
    ![複製_API_Key](https://hackmd.io/_uploads/Bkr6IQDfA.png)

## Discord Bot 程式碼撰寫

完成事前準備中的創建 Discord Bot 及取得 Fugle realtime API key 後，即可進入 Discord Bot 指令的部分。執行 Discord Bot 指令大致分為三種方式，分別為：關鍵字、前綴符號指令及斜線指令，本篇以前綴符號指令進行實作。

### 安裝套件

這裡需要安裝 [discord.py](http://discord.py)  套件方便後續與 Discord Bot 溝通

```bash
$ pip install discord.py
```

接著安裝 fugle-marketdata 套件方便後續取得即時行情數據

```bash
$ pip install fugle-marketdata
```

### 建立相關設定

載入相關套件，並進行相關設定包含 discord 設置及連接，以及輸入個人的 Discord Bot Token 及 Fugle API Key

```python
# 載入相關套件
import discord
from discord.ext import commands
from fugle_marketdata import RestClient
import pandas as pd

# 設置所需的目的
intents = discord.Intents.default()
intents.message_content = True  # 啟用訊息內容

# 與 discord 進行連接，並設置前綴指令為 "!"
bot = commands.Bot(command_prefix="!", intents=intents)

# 輸入您的 Discord Bot Token
DISCORD_TOKEN = 'YOUR_DISCORD_BOT_TOKEN'

# 輸入您的 Fugle API Key
FUGLE_API_KEY = 'YOUR_FUGLE_API_KEY'
```

### 資料處理

透過富果行情 API 取得台股行情數據 
```python
# 透過 http 取得富果行情 API
fugle_client = RestClient(api_key=FUGLE_API_KEY)
stock = fugle_client.stock  # Stock REST API client

# 訂定取得個股資訊的 function 方便後續取得個股價格資訊
def get_stock_info(symbol):

    quote_data = stock.intraday.quote(symbol=str(symbol))
    # 股名
    symbol_name = quote_data['name']  
    # 最新價格
    latest_price = quote_data['lastTrade']['price']
    # 漲跌幅
    change_percent = quote_data['changePercent']
    # 成交額
    trade_value = quote_data['total']['tradeValue']
    
    # 興櫃股的成交量以股為單位，這邊轉換成以張為單位
    if quote_data['market'] == "ESB":
        trade_volume = quote_data['total']['tradeVolume']/1000
    else:
        trade_volume = quote_data['total']['tradeVolume']
        
    return symbol_name, latest_price, change_percent, trade_volume, trade_value

# 訂定取得市場資訊的 function 方便後續取得市場資訊    
def get_rank_info(market, rank_type):

    if rank_type == "percent":
        rank_list = stock.snapshot.movers(market=str(market),
                                            direction = 'up',
                                            change = rank_type)
    elif rank_type in ["volume", "value"]:
        rank_list = stock.snapshot.actives(market=str(market),
                                            trade = rank_type)

    rank_data = pd.DataFrame(rank_list['data'][:40])

    # 因富果的 snapshot 包含可轉債及 etf，若希望單純取出一般股票，需過濾 etf 及 可轉債等商品，取 top20 資料
    rank_data = rank_data[(rank_data['symbol'].str.len() == 4) & ~rank_data['symbol'].str.startswith('00')][:20]

    return rank_data[['symbol', 'name', 'closePrice', 'change', 'changePercent', 'tradeVolume', 'tradeValue']]
```

### 建立 Discord Bot 函數

#### `@bot.event` 函數

`@bot.event` 主要是用於定義事件處理函數。事件指的是在 Discord 伺服器上發生的特定事情，例如加入伺服器、發送訊息等事件。

```python
# 機器人登入
@bot.event
async def on_ready():
    print(f'Logged in as {bot.user.name}')
```

#### `@bot.command` 函數

`@bot.command` 主要是用於定義命令處理函數。這些函數對應於特定的命令，用戶可以在聊天中輸入這些命令來觸發相對應的函數。命令通常以特定的前綴開始（在這個例子中是 "!"），接著是命令名稱和可能的參數。

**`!symbol` 指令** - 透過 `get_stock_info(symbol)` 獲取特定股票的即時資訊，包括股票名稱、最新價格、最新漲跌幅、累計成交量等。程式碼如下：

```python
@bot.command()
async def symbol(ctx, symbol: str):
    try:
        # 使用 symbol 參數取得個股價量資料
        symbol_name, latest_price, change_percent, trade_volume, trade_value = get_stock_info(symbol.upper())

        # 定義預計顯示的訊息
        message = (
            f'股票名稱：{symbol_name}\n'
            f'最新價格：{latest_price} 元\n'
            f'最新漲跌幅：{change_percent} %\n'
            f'累計成交量：{trade_volume} 張\n'
        )
		
        # 整理金額單位，方便訊息顯示
        if trade_value / 10000 > 10000:
            message += f'累計成交額：{trade_value / 100000000} 億\n'
        else:
            message += f'累計成交額：{trade_value / 10000} 萬\n'
        
        # 加入富果個股查詢連結
        message += f'個股查詢：https://www.fugle.tw/ai/{symbol.upper()}\n'
        
        # 指數不會有報告連結
        if 'IX' not in symbol.upper(): 
		    # 加入富果直送報告連結
            message += f'相關報告連結：https://blog.fugle.tw/tag/{symbol.upper()}'
        
        await ctx.send(message)
    
    except KeyError:
        message = ('查無此標的，請換檔股票試試！')
        await ctx.send(message)
```

**`!market` 指令** - 透過 `get_rank_info(market, rank_type)` 獲取特定市場的股票排行列表，包括排行榜類型（漲跌幅、成交額、成交量） 等即時市場資訊。程式碼如下：

```python
@bot.command()
async def market(ctx, market: str, rank: str):
    try:
        df = get_rank_info(market=market.upper(), rank_type=rank)

        # 假設你有一個 DataFrame 'df'
        df_string = df.to_string(index=False)  # 轉換成字符串

        # 於 Discord 發送訊息
        await ctx.send(f"```{df_string}```")  # 使用 Markdown 的代碼塊格式化

    except KeyError:
        message = ('查無此市場，請選擇 `TSE`, `OTC` 或 `ESB` ！')
        await ctx.send(message)
```

### 啟動 Discord Bot

```python
# 啟動 Discord Bot
bot.run(DISCORD_TOKEN)
```

## 實作結果

執行以上 sample code 會回傳 `Logged in as stock bot` 結果，代表機器人已成功登入
![sample code demo](https://hackmd.io/_uploads/Byb5aQPGC.png)

接著到 discord 聊天訊息直接填入程式碼範例中所設置的指令
- !symbol [股票代碼 ex.2330]
    - 範例：`!symbol 2330`
- !market [市場 ex. tse or otc or esb] [排序方式 ex.percent, volume, value]
    - 範例：`!market tse percent`

會回傳以下結果
![discord bot demo (1)](https://hackmd.io/_uploads/S1IaWIwGA.gif)



## 總結
在以上範例中，我們使用了 `discord.py` 套件來建立一個 Discord Bot，並且引入了 [Fugle Realtime API](https://developer.fugle.tw/docs/data/http-api/getting-started) 來取得台股即時行情資訊！
您也可以根據自身需求實作更多實用的功能，例如加入更多股市資訊的指令、結合交易 API 或者加入更多資料源進行參考。希望這篇文章對你有所幫助，讓你可以更方便地獲取股市資訊，做出更明智的投資決策！