feat: 初始化 ChatGPT Team 管理机器人
核心功能: - 实现基于 Telegram Inline Button 交互的后台面板与用户端 - 支持通过账密登录和 RT (Refresh Token) 方式添加 ChatGPT Team 账号 - 支持管理、拉取和删除待处理邀请,支持一键清空多余邀请 - 支持按剩余容量自动生成邀请兑换码,支持分页查看与一键清空未使用兑换码 - 随机邀请功能:成功拉人后自动核销兑换码 - 定时检测 Token 状态,实现自动续订/刷新并拦截封禁账号 (处理 401/402 错误) 系统与配置: - 使用 PostgreSQL 数据库管理账号、邀请和兑换记录 - 支持在端内动态添加、移除管理员 - 完善 Docker 部署配置与 .gitignore 规则
This commit is contained in:
88
internal/chatgpt/client.go
Normal file
88
internal/chatgpt/client.go
Normal file
@@ -0,0 +1,88 @@
|
||||
package chatgpt
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"golang.org/x/net/proxy"
|
||||
)
|
||||
|
||||
const (
|
||||
oaiClientVersion = "prod-eddc2f6ff65fee2d0d6439e379eab94fe3047f72"
|
||||
userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36"
|
||||
openaiClientID = "app_EMoamEEZ73f0CkXaXp7hrann"
|
||||
)
|
||||
|
||||
// Client wraps HTTP operations with common headers and optional proxy.
|
||||
type Client struct {
|
||||
httpClient *http.Client
|
||||
proxyURL string
|
||||
}
|
||||
|
||||
// NewClient creates a ChatGPT API client with optional proxy support.
|
||||
func NewClient(proxyURL string) *Client {
|
||||
c := &Client{proxyURL: proxyURL}
|
||||
c.httpClient = c.buildHTTPClient()
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *Client) buildHTTPClient() *http.Client {
|
||||
transport := &http.Transport{
|
||||
TLSClientConfig: &tls.Config{MinVersion: tls.VersionTLS12},
|
||||
IdleConnTimeout: 90 * time.Second,
|
||||
}
|
||||
|
||||
if c.proxyURL != "" {
|
||||
parsed, err := url.Parse(c.proxyURL)
|
||||
if err == nil {
|
||||
scheme := parsed.Scheme
|
||||
if scheme == "socks5" || scheme == "socks5h" {
|
||||
var auth *proxy.Auth
|
||||
if parsed.User != nil {
|
||||
pass, _ := parsed.User.Password()
|
||||
auth = &proxy.Auth{
|
||||
User: parsed.User.Username(),
|
||||
Password: pass,
|
||||
}
|
||||
}
|
||||
dialer, dErr := proxy.SOCKS5("tcp", parsed.Host, auth, proxy.Direct)
|
||||
if dErr == nil {
|
||||
if ctxDialer, ok := dialer.(proxy.ContextDialer); ok {
|
||||
transport.DialContext = ctxDialer.DialContext
|
||||
} else {
|
||||
transport.DialContext = func(ctx context.Context, network, addr string) (net.Conn, error) {
|
||||
return dialer.Dial(network, addr)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
transport.Proxy = http.ProxyURL(parsed)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return &http.Client{
|
||||
Transport: transport,
|
||||
Timeout: 60 * time.Second,
|
||||
}
|
||||
}
|
||||
|
||||
// buildHeaders returns common headers for ChatGPT backend API calls.
|
||||
func buildHeaders(token, chatgptAccountID string) http.Header {
|
||||
h := http.Header{}
|
||||
h.Set("Accept", "*/*")
|
||||
h.Set("Accept-Language", "zh-CN,zh;q=0.9")
|
||||
h.Set("Authorization", fmt.Sprintf("Bearer %s", token))
|
||||
h.Set("Chatgpt-Account-Id", chatgptAccountID)
|
||||
h.Set("Oai-Client-Version", oaiClientVersion)
|
||||
h.Set("Oai-Language", "zh-CN")
|
||||
h.Set("User-Agent", userAgent)
|
||||
h.Set("Origin", "https://chatgpt.com")
|
||||
h.Set("Referer", "https://chatgpt.com/admin/members")
|
||||
return h
|
||||
}
|
||||
Reference in New Issue
Block a user