How biliTickerBuy Fetches Project Payload to Determine hotProject Status
The fetch_project_payload() function in interface/project.py attempts the new BiliBili API first, falls back to the legacy endpoint on any exception, and returns a normalized dictionary containing the hotProject boolean flag that indicates high-demand ticket status.
The mikumifa/biliTickerBuy repository determines whether a ticket sale qualifies as a "hot project" by fetching metadata from BiliBili's commerce APIs. This project payload fetching mechanism supports two API versions to ensure reliability, extracting the hotProject field to dynamically adjust purchasing strategies.
Entry Point: fetch_project_payload()
The primary interface for retrieving project metadata is located in interface/project.py. The fetch_project_payload() function serves as a resilient wrapper that implements a failover pattern between API versions.
def fetch_project_payload(request: Any, project_id: int) -> dict[str, Any]:
The function executes the following logic:
- Attempts to retrieve data via
_fetch_project_payload_new() - If any exception is raised, immediately falls back to
_fetch_project_payload_old() - Returns a standardized dictionary containing the
"hotProject"key
This dual-path approach ensures the ticket buyer can detect hot projects even when one API endpoint is deprecated or unstable.
New API Implementation
When the primary endpoint is available, _fetch_project_payload_new() performs a POST request to https://mall.bilibili.com/mall-search-items/items_detail/info with the itemsId parameter set to the target project ID.
The response validation checks both response["success"] and the errno field before proceeding. Upon successful retrieval, the raw payload passes through _normalize_new_project_payload(), which explicitly casts the hot status using:
"hotProject": bool(new_payload.get("hotProject", False)),
This normalization ensures consistent boolean typing regardless of how the API represents the flag.
Legacy API Fallback
If the new API raises an exception—whether from network failure, schema changes, or endpoint deprecation—the system falls back to _fetch_project_payload_old(). This legacy path sends a GET request to https://show.bilibili.com/api/ticket/project/getV2 with the project ID as a query parameter.
The legacy endpoint returns the data dictionary directly when errno == 0, which already contains the native hotProject field without requiring additional normalization.
Consuming hotProject in the Purchase Workflow
Downstream components consume this payload to optimize buying behavior. In task/buy.py, the code extracts the status into a local variable:
is_hot_project = bool(tickets_info.get("is_hot_project", False))
When payload["hotProject"] evaluates to True, the system triggers refresh_hot_and_warm() to upgrade the purchasing strategy. This allows the automation to adjust timing, polling intervals, or retry logic based on project demand intensity. The flag propagates through the application via structures defined in task/buy_helpers.py and surfaces in the UI configuration handled by tab/settings.py.
Fetching Example
from biliTickerBuy.interface.project import fetch_project_payload
from biliTickerBuy.util.request.BiliRequest import BiliRequest
request = BiliRequest()
project_id = 123456 # example project id
payload = fetch_project_payload(request=request, project_id=project_id)
if payload["hotProject"]:
print("🔥 This is a hot project!")
else:
print("Regular project.")
Integration in Buying Scripts
from biliTickerBuy.task.buy import main as buy_main
# buy_main internally calls fetch_project_payload,
# then uses refresh_hot_and_warm() to upgrade the strategy
# when payload["hotProject"] is True.
buy_main(project_input=123456, cookies_path="cookies.json")
Summary
- Dual API resilience:
interface/project.pyprioritizes the new mall API but automatically falls back to the legacy show API if exceptions occur. - Boolean normalization: The new API path explicitly casts the
hotProjectfield viabool()in_normalize_new_project_payload(), while the legacy API returns the raw field directly. - Strategy adjustment:
task/buy.pyreads the flag to triggerrefresh_hot_and_warm(), dynamically adapting the purchase behavior for high-demand events. - Cross-module propagation: The status flows from the API layer through
buy_helpers.pystructures and reaches user configuration intab/settings.py.
Frequently Asked Questions
What happens if both API endpoints fail?
If _fetch_project_payload_new() raises an exception and _fetch_project_payload_old() also fails, the exception propagates to the caller. The application does not provide a tertiary fallback, as the project metadata is required to determine ticket availability and purchasing parameters.
Why does the codebase maintain two different API endpoints?
BiliBili has migrated from the show.bilibili.com platform to the mall.bilibili.com commerce system. Maintaining both endpoints ensures compatibility with older project IDs while supporting new ticket releases that may only exist in the mall system.
How does the hotProject flag actually affect the buying behavior?
When payload["hotProject"] is True, the refresh_hot_and_warm() function in task/buy.py adjusts the purchase strategy. This typically involves modifying request intervals, prioritizing specific ticket tiers, or enabling more aggressive polling patterns to compete for limited inventory on high-demand releases.
Where is the request object initialized for these API calls?
The BiliRequest class defined in util/request/BiliRequest.py provides the authenticated session object passed as the request parameter to fetch_project_payload(). This class handles cookie management, headers, and base configuration required for BiliBili API authentication.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →