Files
skill-template/logistics-tracker/scripts/main.py
2026-04-04 10:35:02 +08:00

142 lines
4.4 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import requests
import sys
import os
import subprocess
def get_api_key(key_name):
"""从api-key-vault读取Key"""
vault_path = os.path.join(
os.path.dirname(__file__),
"..", "..", # 从scripts/退到logistics-tracker/再退到OpenClaw/
"api-key-vault", "scripts", "vault.py"
)
vault_path = os.path.normpath(vault_path)
result = subprocess.run(
["python", vault_path, "get", key_name],
capture_output=True, text=True
)
key = result.stdout.strip()
if not key or key == "ERROR:KEY_NOT_FOUND":
return None
return key
def check_entitlement(skill_slug):
auth_base = (os.getenv("JIANGCHANG_AUTH_BASE_URL") or "").strip().rstrip("/")
if not auth_base:
return True, ""
user_id = (os.getenv("JIANGCHANG_USER_ID") or "").strip()
if not user_id:
return False, "鉴权失败缺少用户身份JIANGCHANG_USER_ID"
auth_api_key = (os.getenv("JIANGCHANG_AUTH_API_KEY") or "").strip()
timeout = int((os.getenv("JIANGCHANG_AUTH_TIMEOUT_SECONDS") or "5").strip())
headers = {"Content-Type": "application/json"}
if auth_api_key:
headers["Authorization"] = f"Bearer {auth_api_key}"
payload = {
"user_id": user_id,
"skill_slug": skill_slug,
"trace_id": (os.getenv("JIANGCHANG_TRACE_ID") or "").strip(),
"context": {"entry": "main.py"},
}
try:
res = requests.post(
f"{auth_base}/api/entitlements/check",
json=payload,
headers=headers,
timeout=timeout,
)
except requests.RequestException as exc:
return False, f"鉴权请求失败:{exc}"
if res.status_code != 200:
return False, f"鉴权服务异常HTTP {res.status_code}"
try:
body = res.json()
except ValueError:
return False, "鉴权服务异常:返回非 JSON"
code = body.get("code")
data = body.get("data") or {}
if code != 200:
return False, str(body.get("msg") or "鉴权失败")
if not data.get("allow", False):
return False, str(data.get("reason") or "未购买或已过期")
return True, ""
def query_tracking(tracking_number):
api_key = get_api_key("17track")
if not api_key:
return "错误未找到17track的API Key请先运行\npython api-key-vault/scripts/vault.py set 17track 你的Key"
url = "https://api.17track.net/track/v2.2/gettrackinfo"
headers = {
"Content-Type": "application/json",
"17token": api_key
}
body = {
"data": [{"number": tracking_number}]
}
try:
response = requests.post(url, json=body, headers=headers, timeout=10)
result = response.json()
accepted = result.get("data", {}).get("accepted", [])
if not accepted:
return f"抱歉,单号 {tracking_number} 查询不到信息,可能还未入网,请稍后再试。"
track_info = accepted[0].get("track", {})
providers = track_info.get("tracking", {}).get("providers", [])
if not providers or not providers[0].get("events"):
return f"📦 单号:{tracking_number}\n该单号已入网,暂无轨迹更新,请稍后再查。"
events = providers[0]["events"]
latest = events[0]
recent_lines = []
for e in events[:3]:
time = e.get("time_iso", "")
location = e.get("location", "") or "未知"
desc = e.get("description", "")
recent_lines.append(f" · {time} {location} {desc}")
recent_text = "\n".join(recent_lines)
return (
f"📦 单号:{tracking_number}\n"
f"📍 最新状态:{latest.get('description', '未知')}\n"
f"🕐 更新时间:{latest.get('time_iso', '未知')}\n"
f"🗺 最新位置:{latest.get('location', '未知')}\n\n"
f"最近轨迹:\n{recent_text}"
)
except requests.exceptions.Timeout:
return "查询超时,请稍后重试。"
except Exception as e:
return f"查询失败:{str(e)}"
def main(argv=None) -> int:
args = argv if argv is not None else sys.argv[1:]
if len(args) < 1:
print("用法python main.py <单号>")
return 1
ok, reason = check_entitlement("logistics-tracker")
if not ok:
print(f"{reason}")
return 1
print(query_tracking(args[0]))
return 0
if __name__ == "__main__":
raise SystemExit(main())