← 返回列表 實戰案例

Python + Opera API 自動匯出每日訂房報表:從手動複製到一鍵執行

在飯店營運中,數據的「即時性」與「準確性」決定了服務的深度。然而,許多櫃檯主管每天仍花費 15 至 20 分鐘執行重複性的動作:登入系統、篩選欄位、匯出 Excel、再手動轉貼。

本篇文章將從技術層面切換,教你如何利用 Python 串接 Oracle Opera Cloud API,將這段冗長流程縮短為一秒鐘的自動化腳本。


為什麼你需要這套自動化流程?

現行作業痛點

  • 耗時低效:每日手動勾選欄位並匯出,工時碎片化。
  • 人為錯誤:格式轉換過程容易引發房態誤判或帳務落差。
  • 孤島數據:手動匯出的 Excel 難義直接與後續的 AI 通知系統或儀表板串接。

自動化後的效益

  • 開檔即用:每日定時執行,管理者上班第一秒即可取得標準化 CSV。
  • 資安合規:透過 API 最小權限設定,僅存取必要報表範圍,優於整帳號登入。
  • 釋放人力:讓專業人員聚焦於「賓客異常處理」而非「數據搬運」。

前置準備

1. 環境設定

建議建立虛擬環境以維持套件整潔:

python -m venv venv
source venv/bin/activate
pip install requests pandas python-dotenv schedule

2. 專案目錄結構

.
├── .env                # 存放憑證與路徑
├── opera_client.py     # OAuth 認證模組
├── report_generator.py # 資料抓取與轉換模組
├── main.py             # 程式主入口
└── output/             # 自動產出之報表存放區

完整程式碼實作

認證模組 (opera_client.py)

負責處理 OAuth2 流程,確保每次請求都具備有效的 Access Token。

import requests
import os
from dotenv import load_dotenv

load_dotenv()

class OperaClient:
    def __init__(self):
        self.base_url = os.getenv("OPERA_BASE_URL")
        self.client_id = os.getenv("OPERA_CLIENT_ID")
        self.client_secret = os.getenv("OPERA_CLIENT_SECRET")
        self.property_id = os.getenv("OPERA_PROPERTY_ID")
        self.access_token = None

    def get_token(self):
        auth_url = f"{self.base_url}/identity/oauth2/v1/token"
        payload = {
            "grant_type": "client_credentials",
            "client_id": self.client_id,
            "client_secret": self.client_secret,
            "scope": "reservations.read reports.export"
        }
        response = requests.post(auth_url, data=payload)
        response.raise_for_status()
        self.access_token = response.json()["access_token"]
        return self.access_token

    def get_headers(self):
        return {
            "Authorization": f"Bearer {self.access_token}",
            "Content-Type": "application/json",
            "x-hotel-id": self.property_id
        }

報表處理模組 (report_generator.py)

利用 Pandas 處理資料結構,並強制使用 utf-8-sig 編碼以相容 Excel 繁體顯示。

import pandas as pd
import os
from datetime import datetime, timedelta

class ReportGenerator:
    def __init__(self, opera_client):
        self.client = opera_client

    def fetch_arrivals(self, date_str=None):
        if not date_str:
            date_str = (datetime.now() + timedelta(days=1)).strftime("%Y-%m-%d")
        
        # 實際開發請串接真實 API Endpoint
        mock_data = [
            {
                "confirmation_no": "OPR20240520001",
                "guest_name": "張小明",
                "room_type": "Deluxe King",
                "room_number": "808",
                "arrival_time": "15:00",
                "special_requests": "高樓層、無煙房",
                "channel": "官網直訂"
            }
        ]
        return mock_data

    def transform_to_df(self, raw_data):
        df = pd.DataFrame(raw_data)
        df["exported_at"] = datetime.now().strftime("%Y-%m-%d %H:%M")
        return df

    def save_csv(self, df, filename=None):
        if not filename:
            date_str = datetime.now().strftime("%Y%m%d")
            filename = f"arrivals_{date_str}.csv"
        
        output_path = os.path.join(os.getenv("OUTPUT_PATH", "./output"), filename)
        os.makedirs(os.path.dirname(output_path), exist_ok=True)
        df.to_csv(output_path, index=False, encoding="utf-8-sig")
        return output_path

測試與維運建議

  1. 認證失敗排查:確認憑證未過期、權限範圍與 API 文件一致。
  2. 中文亂碼:CSV 務必使用 utf-8-sig,避免 Excel 開啟時出現編碼錯誤。
  3. 穩定性部署:在伺服器端建議設定為 systemd service,確保每日清晨 06:00 定時觸發。

結語

自動化系統的目的不是為了取代專業人才,而是為了 「釋放」 人才。透過 Python 與 Opera API 的結合,我們讓櫃檯主管從繁瑣的數據搬運中解脫,回歸到最核心的任務:提供有溫度的賓客服務。

💡 專業合作諮詢 若您的物業需要建立自動化報表排程、跨平台數據同步或客製化 AI 預警系統,歡迎透過 [email protected] 與我聯繫討論。

#Python #OperaAPI #飯店自動化 #數位轉型

更多飯店自動化心法?

訂閱專欄,掌握每週 AI 營運實戰。

立即訂閱