fix: Don't wait for user input during login flow

- Remove blocking 'Press Enter' prompt
- Continue without waiting when no session exists
- Save cookies asynchronously if user logs in during session
- Add debug output for finding input field and send button
- Try Enter key as fallback for sending message
This commit is contained in:
王性驊 2026-04-03 00:51:55 +08:00
parent 9f41d3b5b5
commit 24459ffcfe
2 changed files with 53 additions and 30 deletions

View File

@ -132,58 +132,89 @@ func SelectModel(page *rod.Page, model string) error {
} }
func SendPrompt(page *rod.Page, prompt string) error { func SendPrompt(page *rod.Page, prompt string) error {
fmt.Printf("[GeminiWeb] Finding input field...\n")
// 嘗試多種可能的輸入框選擇器 // 嘗試多種可能的輸入框選擇器
selectors := []string{ selectors := []string{
`textarea[aria-label*="message" i]`,
`textarea[placeholder*="message" i]`,
`textarea`, `textarea`,
`[contenteditable="true"]`, `[contenteditable="true"]`,
`[role="textbox"]`, `[role="textbox"]`,
`div[contenteditable="true"]`,
`div[role="textbox"]`,
`.ql-editor`,
`rich-textarea`, `rich-textarea`,
} }
var textarea *rod.Element var textarea *rod.Element
var err error var err error
for _, sel := range selectors { for _, sel := range selectors {
fmt.Printf(" Trying selector: %s\n", sel)
textarea, err = page.Element(sel) textarea, err = page.Element(sel)
if err == nil { if err == nil {
fmt.Printf(" Found with: %s\n", sel)
break break
} }
} }
if err != nil { 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 { if err := textarea.Input(prompt); err != nil {
return fmt.Errorf("failed to input prompt: %w", err) 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{ btnSelectors := []string{
`button[type="submit"]`,
`button[aria-label*="Send" i]`, `button[aria-label*="Send" i]`,
`button[aria-label*="submit" i]`, `button[aria-label*="submit" i]`,
`button[type="submit"]`, `button:has(svg)`,
`button svg`, `button`,
} }
var sendBtn *rod.Element var sendBtn *rod.Element
for _, sel := range btnSelectors { for _, sel := range btnSelectors {
fmt.Printf(" Trying button selector: %s\n", sel)
sendBtn, err = page.Element(sel) sendBtn, err = page.Element(sel)
if err == nil { 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 break
} }
} }
if err != nil { 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) 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 { func WaitForResponse(page *rod.Page, onChunk func(text string), onThinking func(thinking string), onComplete func()) error {
lastText := "" lastText := ""
lastThinking := "" lastThinking := ""

View File

@ -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") fmt.Printf("[GeminiWeb] Not logged in - continuing without login\n")
if visible { if visible {
// 開啟可見瀏覽器,提示使用者可以登入 // 如果瀏覽器可見,提示使用者可以登入,但繼續執行不等待
fmt.Println("\n========================================") fmt.Println("\n========================================")
fmt.Println("Browser is now open. You can:") fmt.Println("Browser is open. You can:")
fmt.Println("1. Log in to Gemini (to use your account)") fmt.Println("1. Log in to Gemini now (to use your account)")
fmt.Println("2. Or continue without login (limited functionality)") fmt.Println("2. Continue without login")
fmt.Println("\nPress Enter when ready to continue...") 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") fmt.Println("========================================\n")
// 等待使用者按 Enter // 異步保存 cookies如果使用者登入了
var input string go func() {
fmt.Scanln(&input) time.Sleep(30 * time.Second) // 給使用者 30 秒登入
if IsLoggedIn(page) {
// 檢查是否已登入 cookies, err := GetPageCookies(page)
if IsLoggedIn(page) { if err == nil {
fmt.Printf("[GeminiWeb] Login detected! Saving cookies for future use...\n") SaveCookiesToFile(cookies, session.CookieFile)
cookies, err := GetPageCookies(page) fmt.Printf("[GeminiWeb] Saved %d cookies for future use\n", len(cookies))
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)
} }
} }
} else { }()
fmt.Printf("[GeminiWeb] Continuing without login\n")
}
} }
} }