feat: Use IDLE by default to keep a long-lived connection with the mail server; allow forced polling for servers with poor IDLE/NOOP support.
This commit is contained in:
parent
a78c92448e
commit
cb19ee997d
4 changed files with 18 additions and 16 deletions
|
|
@ -490,7 +490,7 @@ Use an inbox as a channel: PicoClaw connects via IMAP to read new mail and (opti
|
||||||
"password": "YOUR_APP_PASSWORD",
|
"password": "YOUR_APP_PASSWORD",
|
||||||
"mailbox": "INBOX",
|
"mailbox": "INBOX",
|
||||||
"check_interval": 30,
|
"check_interval": 30,
|
||||||
"use_idle": true,
|
"forced_polling": false,
|
||||||
"use_tls": true,
|
"use_tls": true,
|
||||||
"allow_from": ["allowed-sender@example.com"],
|
"allow_from": ["allowed-sender@example.com"],
|
||||||
"attachment_dir": "/path/to/save/attachments",
|
"attachment_dir": "/path/to/save/attachments",
|
||||||
|
|
@ -507,8 +507,8 @@ Use an inbox as a channel: PicoClaw connects via IMAP to read new mail and (opti
|
||||||
| `imap_server`, `imap_port` | IMAP server (e.g. 993 with TLS). |
|
| `imap_server`, `imap_port` | IMAP server (e.g. 993 with TLS). |
|
||||||
| `username`, `password` | Mailbox login; 163/QQ require app password. |
|
| `username`, `password` | Mailbox login; 163/QQ require app password. |
|
||||||
| `mailbox` | Folder to watch (default `INBOX`). |
|
| `mailbox` | Folder to watch (default `INBOX`). |
|
||||||
| `use_idle` | `true`: use IMAP IDLE when supported (push); `false`: poll every `check_interval` seconds. |
|
| `forced_polling` | When the server does not implement IDLE/NOOP per spec, set `true` to use application-level polling; leave `false` normally. |
|
||||||
| `check_interval` | Polling interval in seconds when IDLE is off or unsupported (default 30). |
|
| `check_interval` | Polling interval in seconds when using forced polling or when IDLE is unsupported (default 30). |
|
||||||
| `allow_from` | Allowed sender addresses; only their mails trigger the agent. |
|
| `allow_from` | Allowed sender addresses; only their mails trigger the agent. |
|
||||||
| `attachment_dir` | Directory to save attachments; leave empty to skip saving. |
|
| `attachment_dir` | Directory to save attachments; leave empty to skip saving. |
|
||||||
| `smtp_server`, `smtp_port`, `smtp_use_tls` | Optional; if set, the agent can send replies. |
|
| `smtp_server`, `smtp_port`, `smtp_use_tls` | Optional; if set, the agent can send replies. |
|
||||||
|
|
|
||||||
|
|
@ -79,10 +79,10 @@
|
||||||
"password": "your_password",
|
"password": "your_password",
|
||||||
"mailbox": "INBOX",
|
"mailbox": "INBOX",
|
||||||
"check_interval": 30,
|
"check_interval": 30,
|
||||||
|
"forced_polling": false,
|
||||||
"use_tls": true,
|
"use_tls": true,
|
||||||
"allow_from": ["allowed_email@example.com"],
|
"allow_from": ["allowed_email@example.com"],
|
||||||
"attachment_dir": "~/.picoclaw/workspace/attachments",
|
"attachment_dir": "~/.picoclaw/workspace/attachments",
|
||||||
"use_idle": true,
|
|
||||||
"smtp_server": "smtp.example.com--eg:smtp.qq.com",
|
"smtp_server": "smtp.example.com--eg:smtp.qq.com",
|
||||||
"smtp_port": 465,
|
"smtp_port": 465,
|
||||||
"smtp_use_tls": true
|
"smtp_use_tls": true
|
||||||
|
|
|
||||||
|
|
@ -310,12 +310,13 @@ func (c *EmailChannel) checkLoop(ctx context.Context) {
|
||||||
// Run one check immediately
|
// Run one check immediately
|
||||||
c.checkNewEmails()
|
c.checkNewEmails()
|
||||||
|
|
||||||
if c.config.UseIdle {
|
if !c.config.ForcedPolling {
|
||||||
|
// support IDLE user idle loop, waiting for server push update
|
||||||
c.runIdleLoop(ctx, interval)
|
c.runIdleLoop(ctx, interval)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Polling mode
|
// not support IDLE user polling mode, check new emails every interval
|
||||||
c.mu.Lock()
|
c.mu.Lock()
|
||||||
c.checkTicker = time.NewTicker(interval)
|
c.checkTicker = time.NewTicker(interval)
|
||||||
ticker := c.checkTicker
|
ticker := c.checkTicker
|
||||||
|
|
|
||||||
|
|
@ -149,15 +149,16 @@ type LINEConfig struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type EmailConfig struct {
|
type EmailConfig struct {
|
||||||
Enabled bool `json:"enabled" env:"PICOCLAW_CHANNELS_EMAIL_ENABLED"`
|
Enabled bool `json:"enabled" env:"PICOCLAW_CHANNELS_EMAIL_ENABLED"`
|
||||||
IMAPServer string `json:"imap_server" env:"PICOCLAW_CHANNELS_EMAIL_IMAP_SERVER"`
|
IMAPServer string `json:"imap_server" env:"PICOCLAW_CHANNELS_EMAIL_IMAP_SERVER"`
|
||||||
IMAPPort int `json:"imap_port" env:"PICOCLAW_CHANNELS_EMAIL_IMAP_PORT"`
|
IMAPPort int `json:"imap_port" env:"PICOCLAW_CHANNELS_EMAIL_IMAP_PORT"`
|
||||||
Username string `json:"username" env:"PICOCLAW_CHANNELS_EMAIL_USERNAME"`
|
Username string `json:"username" env:"PICOCLAW_CHANNELS_EMAIL_USERNAME"`
|
||||||
Password string `json:"password" env:"PICOCLAW_CHANNELS_EMAIL_PASSWORD"`
|
Password string `json:"password" env:"PICOCLAW_CHANNELS_EMAIL_PASSWORD"`
|
||||||
Mailbox string `json:"mailbox" env:"PICOCLAW_CHANNELS_EMAIL_MAILBOX"` // 默认 "INBOX"
|
Mailbox string `json:"mailbox" env:"PICOCLAW_CHANNELS_EMAIL_MAILBOX"` // 默认 "INBOX"
|
||||||
CheckInterval int `json:"check_interval" env:"PICOCLAW_CHANNELS_EMAIL_CHECK_INTERVAL"` // seconds, default 30; used for polling when IDLE disabled or unsupported
|
CheckInterval int `json:"check_interval" env:"PICOCLAW_CHANNELS_EMAIL_CHECK_INTERVAL"` // seconds, default 30; used for polling when IDLE disabled or unsupported
|
||||||
UseIdle bool `json:"use_idle" env:"PICOCLAW_CHANNELS_EMAIL_USE_IDLE"` // use IMAP IDLE (push) when server supports it; otherwise poll
|
UseTLS bool `json:"use_tls" env:"PICOCLAW_CHANNELS_EMAIL_USE_TLS"`
|
||||||
UseTLS bool `json:"use_tls" env:"PICOCLAW_CHANNELS_EMAIL_USE_TLS"`
|
// ForcedPolling: when the mail server does not implement IDLE/NOOP per spec (e.g. NOOP does not return * EXISTS), set true to use application-level polling (check new mail at CheckInterval). Leave false under normal conditions.
|
||||||
|
ForcedPolling bool `json:"forced_polling" env:"PICOCLAW_CHANNELS_EMAIL_FORCED_POLLING"`
|
||||||
AllowFrom FlexibleStringSlice `json:"allow_from" env:"PICOCLAW_CHANNELS_EMAIL_ALLOW_FROM"`
|
AllowFrom FlexibleStringSlice `json:"allow_from" env:"PICOCLAW_CHANNELS_EMAIL_ALLOW_FROM"`
|
||||||
AttachmentDir string `json:"attachment_dir" env:"PICOCLAW_CHANNELS_EMAIL_ATTACHMENT_DIR"`
|
AttachmentDir string `json:"attachment_dir" env:"PICOCLAW_CHANNELS_EMAIL_ATTACHMENT_DIR"`
|
||||||
// SMTP send (optional, if not configured, Send is not available)
|
// SMTP send (optional, if not configured, Send is not available)
|
||||||
|
|
@ -332,7 +333,7 @@ func DefaultConfig() *Config {
|
||||||
Password: "",
|
Password: "",
|
||||||
Mailbox: "INBOX",
|
Mailbox: "INBOX",
|
||||||
CheckInterval: 30,
|
CheckInterval: 30,
|
||||||
UseIdle: true,
|
ForcedPolling: false,
|
||||||
UseTLS: true,
|
UseTLS: true,
|
||||||
AllowFrom: FlexibleStringSlice{},
|
AllowFrom: FlexibleStringSlice{},
|
||||||
SMTPServer: "",
|
SMTPServer: "",
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue