支持远程url吗
This commit is contained in:
@@ -68,7 +68,7 @@ func (c *Client) SetProxy(proxy string) {
|
||||
c.proxy = strings.TrimSpace(proxy)
|
||||
}
|
||||
|
||||
func (c *Client) GenerateImage(ctx context.Context, accessToken, prompt, model, aspectRatio, resolution string, refs [][]byte) ([]byte, map[string]any, error) {
|
||||
func (c *Client) GenerateImage(ctx context.Context, accessToken, prompt, model, aspectRatio, resolution string, refs [][]byte, downloadResult bool) ([]byte, map[string]any, error) {
|
||||
// Everything except the generation submit egresses on the local IP. Only
|
||||
// startImageGeneration (the /backend-api/f/conversation POST) goes through
|
||||
// the proxy; the bootstrap / chat-requirements / reference upload / prepare
|
||||
@@ -130,6 +130,17 @@ func (c *Client) GenerateImage(ctx context.Context, accessToken, prompt, model,
|
||||
if len(urls) == 0 {
|
||||
return nil, nil, errors.New("no image urls resolved")
|
||||
}
|
||||
meta := map[string]any{
|
||||
"provider": "chatgpt",
|
||||
"model": model,
|
||||
"conversation_id": conversationID,
|
||||
"image_url": urls[0], // auth-gated (files.oaiusercontent.com) — needs the account token to fetch
|
||||
}
|
||||
// downloadResult=false: skip the (auth-gated) download and return just the URL;
|
||||
// the caller proxies it via OpenAsset with the account token.
|
||||
if !downloadResult {
|
||||
return nil, meta, nil
|
||||
}
|
||||
images, err := c.downloadBytes(ctx, session, accessToken, urls)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
@@ -137,11 +148,36 @@ func (c *Client) GenerateImage(ctx context.Context, accessToken, prompt, model,
|
||||
if len(images) == 0 {
|
||||
return nil, nil, errors.New("download produced no bytes")
|
||||
}
|
||||
return images[0], map[string]any{
|
||||
"provider": "chatgpt",
|
||||
"model": model,
|
||||
"conversation_id": conversationID,
|
||||
}, nil
|
||||
return images[0], meta, nil
|
||||
}
|
||||
|
||||
// OpenAsset streams an auth-gated ChatGPT image URL (files.oaiusercontent.com)
|
||||
// using the generating account's token — a plain GET 403s. Mirrors downloadBytes
|
||||
// but returns a live stream instead of buffering.
|
||||
func (c *Client) OpenAsset(ctx context.Context, accessToken, rawURL string) (io.ReadCloser, string, error) {
|
||||
session, err := c.newDirectSession(accessToken)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, rawURL, nil)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
req.Header = c.baseHeaders(accessToken)
|
||||
req.Header.Set("accept", "*/*")
|
||||
resp, err := session.Do(req)
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf("%w: %v", ErrTemporaryUpstream, err)
|
||||
}
|
||||
if resp.StatusCode != 200 {
|
||||
resp.Body.Close()
|
||||
return nil, "", fmt.Errorf("%w: chatgpt asset status %d", ErrTemporaryUpstream, resp.StatusCode)
|
||||
}
|
||||
ct := strings.TrimSpace(resp.Header.Get("Content-Type"))
|
||||
if ct == "" {
|
||||
ct = "image/png"
|
||||
}
|
||||
return resp.Body, ct, nil
|
||||
}
|
||||
|
||||
func ExtractAccountInfo(token string) map[string]any {
|
||||
|
||||
Reference in New Issue
Block a user