api.3 / app /gs_daily.py
Celeskry's picture
Update app/gs_daily.py
f8c0d0e verified
# app/gs_daily.py
import httpx
from typing import Dict, Any
ACT_ID = "e202102251931481"
HOME_URL = "https://sg-hk4e-api.hoyolab.com/event/sol/home"
INFO_URL = "https://sg-hk4e-api.hoyolab.com/event/sol/info"
SIGN_URL = "https://sg-hk4e-api.hoyolab.com/event/sol/sign"
ROLE_URL = "https://api-os-takumi.hoyoverse.com/binding/api/getUserGameRolesByCookie"
class GSDailyApp:
def __init__(self):
self.client: httpx.AsyncClient | None = None
async def start(self):
self.client = httpx.AsyncClient(timeout=15)
async def stop(self):
if self.client:
await self.client.aclose()
def _headers(self, cookie: str):
return {
"Cookie": cookie,
"User-Agent": "Mozilla/5.0",
"Accept": "application/json"
}
async def _get_home(self, cookie: str):
r = await self.client.get(
HOME_URL,
headers=self._headers(cookie),
params={"act_id": ACT_ID}
)
return r.json()
async def _get_info(self, cookie: str):
r = await self.client.get(
INFO_URL,
headers=self._headers(cookie),
params={"act_id": ACT_ID}
)
return r.json()
async def _sign(self, cookie: str):
r = await self.client.post(
SIGN_URL,
headers=self._headers(cookie),
json={"act_id": ACT_ID}
)
return r.json()
async def _get_role(self, cookie: str):
r = await self.client.get(
ROLE_URL,
headers=self._headers(cookie),
params={"game_biz": "hk4e_global"}
)
return r.json()
async def run_daily_and_capture(
self,
cookie_string: str,
discord_id: str,
server_input: str
) -> Dict[str, Any]:
try:
home_data = await self._get_home(cookie_string)
if home_data.get("retcode") != 0:
return {"ok": False, "error": home_data.get("message", "Home API lỗi")}
awards = home_data.get("data", {}).get("awards", [])
total_days_month = len(awards)
info_data = await self._get_info(cookie_string)
if info_data.get("retcode") != 0:
return {"ok": False, "error": info_data.get("message", "Info API lỗi")}
info = info_data.get("data", {})
total_signed = info.get("total_sign_day", 0)
is_signed = info.get("is_sign", False)
claimed = False
risk_code = 0
if not is_signed:
sign_data = await self._sign(cookie_string)
risk_code = sign_data.get("risk_code", 0)
if sign_data.get("retcode") == 0:
claimed = True
total_signed += 1
elif sign_data.get("retcode") == -5003:
claimed = False
else:
return {"ok": False, "error": sign_data.get("message", "Sign API lỗi")}
today_index = max(total_signed - 1, 0)
today_reward = (
awards[today_index] if today_index < len(awards) else None
)
tomorrow_reward = (
awards[total_signed] if total_signed < len(awards) else None
)
role_data = await self._get_role(cookie_string)
if role_data.get("retcode") != 0:
return {"ok": False, "error": "Không lấy được danh sách tài khoản"}
roles = role_data.get("data", {}).get("list", [])
if not roles:
return {"ok": False, "error": "Cookie không có tài khoản Genshin"}
region_map = {
"asia": "os_asia",
"america": "os_usa",
"usa": "os_usa",
"na": "os_usa",
"europe": "os_euro",
"eu": "os_euro",
"tw": "os_cht",
"hk": "os_cht"
}
target_region = region_map.get(server_input.lower())
if not target_region:
return {"ok": False, "error": "Server không hợp lệ"}
selected_role = None
for r in roles:
if r.get("region") == target_region:
selected_role = r
break
if not selected_role:
return {"ok": False, "error": f"Không tìm thấy tài khoản ở server {server_input}"}
uid = selected_role.get("game_uid")
nickname = selected_role.get("nickname")
level = selected_role.get("level")
region = selected_role.get("region")
server_name_map = {
"os_asia": "Asia",
"os_euro": "EU",
"os_usa": "NA",
"os_cht": "TW/HK"
}
server_name = server_name_map.get(region, region)
missing_days = max(total_days_month - total_signed, 0)
return {
"ok": True,
"claimed": claimed,
"discord_id": discord_id,
"nickname": nickname,
"uid": uid,
"server": server_name,
"adventure_rank": level,
"signed_days": total_signed,
"total_days_month": total_days_month,
"missing_days": missing_days,
"today_reward": {
"name": today_reward.get("name"),
"count": today_reward.get("cnt"),
"icon": today_reward.get("icon")
} if today_reward else None,
"tomorrow_reward": {
"name": tomorrow_reward.get("name"),
"count": tomorrow_reward.get("cnt"),
"icon": tomorrow_reward.get("icon")
} if tomorrow_reward else None,
"risk_code": risk_code
}
except Exception as e:
return {"ok": False, "error": f"Internal error: {str(e)}"}