glm 的 2api 思路

30 天前
 flyingelement

处理了新增的签名问题。截止 20251007 有效

加上轮询,上下文和转 OpenAI 逻辑就是一个成熟的 2api 项目

对于带历史对话的,参数 t 是最近一次 user content

防止有人不知道还是提一下,token 来自网页 cookie 的 token 值,目前看来是长期有效

import time, hmac, hashlib, requests, uuid, json, base64

token = ""

def decode_jwt_payload(token):
    parts = token.split('.')
    payload = parts[1]

    padding = 4 - len(payload) % 4
    if padding != 4:
        payload += '=' * padding

    decoded = base64.urlsafe_b64decode(payload)
    return json.loads(decoded)

def zs(e, t, timestamp):
    r = str(timestamp)
    i = f"{e}|{t}|{r}"
    n = timestamp // (5 * 60 * 1000)
    key = "junjie".encode('utf-8')
    o = hmac.new(key, str(n).encode('utf-8'), hashlib.sha256).hexdigest()
    signature = hmac.new(o.encode('utf-8'), i.encode('utf-8'), hashlib.sha256).hexdigest()

    return {
        "signature": signature,
        "timestamp": timestamp
    }

def make_request():
    payload = decode_jwt_payload(token)
    user_id = payload['id']
    chat_id = str(uuid.uuid4())
    timestamp = int(time.time() * 1000)
    request_id = str(uuid.uuid4())

    t = input("Hello, how can I help you ?\n - ")

    e = f"requestId,{request_id},timestamp,{timestamp},user_id,{user_id}"

    result = zs(e, t, timestamp)
    signature = result["signature"]

    url = "https://chat.z.ai/api/chat/completions"
    params = {
        "timestamp": timestamp,
        "requestId": request_id,
        "user_id": user_id,
        "token": token,
        "current_url": f"https://chat.z.ai/c/{chat_id}",
        "pathname": f"/c/{chat_id}",
        "signature_timestamp": timestamp
    }

    headers = {
        "Authorization": f"Bearer {token}",
        "X-FE-Version": "prod-fe-1.0.95",
        "X-Signature": signature
    }

    payload = {
        "stream": True,
        "model": "GLM-4-6-API-V1",
        "messages": [
            {"role": "user", "content": t}
        ],
        "params": {},
        "features": {
            "image_generation": False,
            "web_search": False,
            "auto_web_search": False,
            "preview_mode": True,
        },
        "enable_thinking": True,
        "chat_id": chat_id,
        "id": str(uuid.uuid4())
    }

    response = requests.post(url, params=params, headers=headers, json=payload, stream=True)
    response.raise_for_status()

    for chunk in response.iter_content(chunk_size=8192):
        if chunk:
            print(chunk.decode('utf-8'), end='')

if __name__ == "__main__":
    make_request()
1139 次点击
所在节点    程序员
2 条回复
retain
30 天前
好好的开个会员不好吗? 也没多贵
justxwy
26 天前
谢谢分享

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://ex.noerr.eu.org/t/1163567

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX