diff --git a/internal/providers/geminiweb/page.go b/internal/providers/geminiweb/page.go index f866d64..91a2c1a 100644 --- a/internal/providers/geminiweb/page.go +++ b/internal/providers/geminiweb/page.go @@ -132,58 +132,89 @@ func SelectModel(page *rod.Page, model string) error { } func SendPrompt(page *rod.Page, prompt string) error { + fmt.Printf("[GeminiWeb] Finding input field...\n") + // 嘗試多種可能的輸入框選擇器 selectors := []string{ - `textarea[aria-label*="message" i]`, - `textarea[placeholder*="message" i]`, `textarea`, `[contenteditable="true"]`, `[role="textbox"]`, + `div[contenteditable="true"]`, + `div[role="textbox"]`, + `.ql-editor`, `rich-textarea`, } var textarea *rod.Element var err error for _, sel := range selectors { + fmt.Printf(" Trying selector: %s\n", sel) textarea, err = page.Element(sel) if err == nil { + fmt.Printf(" Found with: %s\n", sel) break } } if err != nil { - return fmt.Errorf("input field not found after trying selectors %v: %w", selectors, err) + return fmt.Errorf("input field not found after trying all selectors: %w", err) } + fmt.Printf("[GeminiWeb] Typing prompt (%d chars)...\n", len(prompt)) if err := textarea.Input(prompt); err != nil { return fmt.Errorf("failed to input prompt: %w", err) } - time.Sleep(300 * time.Millisecond) + fmt.Printf("[GeminiWeb] Finding send button...\n") + time.Sleep(500 * time.Millisecond) // 嘗試多種可能的發送按鈕選擇器 btnSelectors := []string{ + `button[type="submit"]`, `button[aria-label*="Send" i]`, `button[aria-label*="submit" i]`, - `button[type="submit"]`, - `button svg`, + `button:has(svg)`, + `button`, } var sendBtn *rod.Element for _, sel := range btnSelectors { + fmt.Printf(" Trying button selector: %s\n", sel) sendBtn, err = page.Element(sel) if err == nil { + // 檢查是否是發送按鈕(不是其他按鈕) + ariaLabel, _ := sendBtn.Attribute("aria-label") + text, _ := sendBtn.Text() + if ariaLabel != nil || text != "" { + fmt.Printf(" Found button with aria-label=%v text=%s\n", ariaLabel, truncate(text, 20)) + } + } + if err == nil { + fmt.Printf(" Found send button with: %s\n", sel) break } } if err != nil { - return fmt.Errorf("send button not found: %w", err) + // 嘗試按 Enter 鍵發送 + fmt.Printf("[GeminiWeb] No send button found, trying Enter key...\n") + if err := page.Keyboard.Press('\n'); err != nil { + return fmt.Errorf("failed to press Enter: %w", err) + } + return nil } + fmt.Printf("[GeminiWeb] Clicking send button...\n") return sendBtn.Click(proto.InputMouseButtonLeft, 1) } +func truncate(s string, max int) string { + if len(s) <= max { + return s + } + return s[:max] + "..." +} + func WaitForResponse(page *rod.Page, onChunk func(text string), onThinking func(thinking string), onComplete func()) error { lastText := "" lastThinking := "" diff --git a/internal/providers/geminiweb/provider.go b/internal/providers/geminiweb/provider.go index 3866014..52b801d 100644 --- a/internal/providers/geminiweb/provider.go +++ b/internal/providers/geminiweb/provider.go @@ -113,34 +113,26 @@ func (p *Provider) Generate(ctx context.Context, model string, messages []apityp fmt.Printf("[GeminiWeb] Not logged in - continuing without login\n") if visible { - // 開啟可見瀏覽器,提示使用者可以登入 + // 如果瀏覽器可見,提示使用者可以登入,但繼續執行不等待 fmt.Println("\n========================================") - fmt.Println("Browser is now open. You can:") - fmt.Println("1. Log in to Gemini (to use your account)") - fmt.Println("2. Or continue without login (limited functionality)") - fmt.Println("\nPress Enter when ready to continue...") + fmt.Println("Browser is open. You can:") + fmt.Println("1. Log in to Gemini now (to use your account)") + fmt.Println("2. Continue without login") + fmt.Println("\nThe request will proceed without waiting.") + fmt.Println("If you log in during this session, cookies will be saved automatically.") fmt.Println("========================================\n") - // 等待使用者按 Enter - var input string - fmt.Scanln(&input) - - // 檢查是否已登入 - if IsLoggedIn(page) { - fmt.Printf("[GeminiWeb] Login detected! Saving cookies for future use...\n") - cookies, err := GetPageCookies(page) - if err != nil { - fmt.Printf("[GeminiWeb] Warning: could not get cookies: %v\n", err) - } else { - if err := SaveCookiesToFile(cookies, session.CookieFile); err != nil { - fmt.Printf("[GeminiWeb] Warning: could not save cookies: %v\n", err) - } else { - fmt.Printf("[GeminiWeb] Saved %d cookies to %s\n", len(cookies), session.CookieFile) + // 異步保存 cookies(如果使用者登入了) + go func() { + time.Sleep(30 * time.Second) // 給使用者 30 秒登入 + if IsLoggedIn(page) { + cookies, err := GetPageCookies(page) + if err == nil { + SaveCookiesToFile(cookies, session.CookieFile) + fmt.Printf("[GeminiWeb] Saved %d cookies for future use\n", len(cookies)) } } - } else { - fmt.Printf("[GeminiWeb] Continuing without login\n") - } + }() } }