Matthew Meszaros
b8a8ec4743
Merge remote-tracking branch 'origin/main' into feat/unibox-rail-layout-per-member
2026-10-01 22:58:31 -07:00
Matthew Meszaros
8f89c36756
feat: refresh the open conversation for inbox events that name only a message id, give unibox refresh keys added just before a max-wait flush a trailing flush, cancel a shared unibox overview computation once its last caller leaves and bound it and GET /unibox/overview at 30s, include scheduled sends in the coalesced inbox refresh, and word the slow pgxpool acquire log as acquire time rather than saturation
2026-10-01 22:41:00 -07:00
Matthew Meszaros
54a05027cc
feat: save the unibox scope rail's favorites, row and section order and hidden rows to the member's account per workspace through a unibox_rail view with a validated layout on /me/views, synced from the dashboard store so every device shows the same rail while folds and widths stay per browser
2026-10-01 22:37:23 -07:00
Matthew Meszaros
dc2cffd786
feat: coalesce and dedupe unibox realtime refreshes in useRealtimeEvents, forward TanStack Query abort signals through every unibox client and the shared Request helper with cancellations kept out of error handling, share one organization-scoped unibox overview computation per second with in-flight dedup and write-time invalidation, bound interactive unibox reads at 30s including pool wait, and log slow pgxpool connection acquisitions
2026-10-01 22:25:53 -07:00
Matthew Meszaros
e25b31f992
Merge pull request #772 from warmbly/fix/unibox-template-html-body
...
feat: send a unibox template's HTML body as written by giving the compose and reply composers an HTML mode, keep that HTML in compose and reply drafts, and render the text part server-side for HTML-only sends
2026-10-01 04:22:11 +00:00
Matthew Meszaros
f41b377f0c
feat: offer the Advisor's campaign hold only while a mailbox is still sending cold, reseed warmup when an AI tool switches a mailbox on or starts warmup, and fix the mailbox switch's bulk selection, double clicks and revoked-mailbox hints
2026-09-30 21:02:00 -07:00
Matthew Meszaros
588591684b
feat: send a unibox template's HTML body as written by giving the compose and reply composers an HTML mode, keep that HTML in compose and reply drafts, and render the text part server-side for HTML-only sends
2026-09-30 20:46:22 -07:00
Matthew Meszaros
7ea17c0150
feat: let a switched-off mailbox be switched back on from its row menu, warmup menu, drawer, settings and the selection bar, and make the Advisor's stop-cold-sending fixes hold the mailbox from campaigns instead of switching it off
2026-09-30 20:45:42 -07:00
Matthew Meszaros
d64adcc191
Merge remote-tracking branch 'origin/main' into feat/cloud-domain-redirects
2026-09-30 07:18:51 -07:00
Matthew Meszaros
7b526be901
feat: write a Cloud-served root redirect here before asking Warmbly Cloud (one workspace per domain, enforced by a unique index), roll it back on Cloud's refusal and keep it pending through an outage, release Cloud redirects no workspace here has any more from the sweep, resend a target Cloud holds stale, stop a mirrored redirect only on Cloud's definite refusals, read a proxy gateway error as transient and order the certificate and port verdicts correctly, validate linked domains with the shared hostname check, share one proxy name map, and trim comments
2026-09-30 06:59:55 -07:00
Matthew Meszaros
75f764dc67
feat: require a verified Cloud Tasks token with a pinned audience on task webhooks, manage_settings on integration OAuth and a fresh membership check at every mailbox and integration OAuth finish, user verification for passkey sign-in, ended sessions before a password reset or ban reports success, and a revoked session when a rotated refresh token is replayed; remove the internal DEK delete route, log credential path parameters by name, hold remote images in received mail until the reader loads them, add Calendly and Cal.com signing keys with inbound URL rotation, keep automation signing secrets out of connection responses, and apply the password rules to the bootstrap password
2026-09-30 06:46:24 -07:00
Matthew Meszaros
41d43f64be
feat: check that a verified root redirect actually reaches visitors by opening the domain over http and https and naming what answered instead (Traefik, nginx, Caddy, a rewritten Host header, a missing certificate, a closed port) with per-proxy fix steps in the sending domain drawer, and let a self-hosted instance linked to Warmbly Cloud have Cloud serve and certify its redirects (connect in place from the redirect tab, the bulk dialog or a page banner), with Cloud-side linked-instance redirect endpoints under a per-instance limit, migration 000237, labelled tracking answers and a 503 when the redirect lookup is unavailable, and the sending domains, Warmbly Cloud, data control, install, OpenAPI, API and error code docs updated
2026-09-30 06:04:00 -07:00
Matthew Meszaros
045d13d281
feat: let segment membership writes take the same contact selection limits as every other bulk action, raise select-all to 250,000 contacts and explicit id batches to 10,000, check the research batch cap in the dashboard before confirming, and document the new limits in the guides, error codes and OpenAPI spec
2026-09-30 06:13:14 +02:00
Matthew Meszaros
4b0446042a
Merge pull request #750 from warmbly/feature/batch-inbox-placement-tests
...
feat: run one inbox placement test across many sending mailboxes as a placement batch, with server-side sender scopes, sampling, bounded concurrent execution, fleet grouping and coverage
2026-09-29 17:59:48 +00:00
Matthew Meszaros
d162f0aaf6
Merge pull request #748 from warmbly/fix/gmail-archive-unibox-inbox-sync
...
feat: file Gmail mail where Gmail moves it (archive, delete, spam, back to inbox) via an UPDATE_FOLDER event resolved against provider_folder, repair rows already stranded in the unibox Inbox with a six-hourly Gmail folder reconciliation, and close the open unibox conversation on a scope change with a close button in the reader header
2026-09-29 17:57:41 +00:00
Matthew Meszaros
80ecadb1e6
Merge remote-tracking branch 'origin/main' into feature/batch-inbox-placement-tests
2026-09-29 10:51:41 -07:00
Matthew Meszaros
3290360333
feat: keep the Gmail folder reconciliation going past a message Gmail refuses, list the inbox by label, remove rows Gmail no longer has, retry a failed pass after 15 minutes, report each Gmail move once per tick, answer the internal listing with a fixed error, and keep the conversation open when widening to All mail
2026-09-29 10:40:34 -07:00
Matthew Meszaros
d99a09825f
feat: run one inbox placement test across many sending mailboxes as a placement batch (issue #736 ): server-side sender scopes (a campaign's senders or the whole workspace, filtered by provider, domain, tag and untested days) and sampling (random, percent stratified by provider or domain, per domain, per provider) snapshotted at creation, a runner that starts senders under per-workspace and instance-wide concurrency and a start rate with defer or skip for unavailable mailboxes, aggregate placement by sending domain, sending provider and recipient provider, fleet coverage, cancel, credits agreed per batch, org transfer, operator settings in the admin panel, dashboard pages and dialog, CLI commands, agent tools, OpenAPI and docs
2026-09-29 10:19:46 -07:00
Matthew Meszaros
0ed98a8c55
feat: copy up to two colleagues on every email a campaign sends one lead (campaign_lead_cc, migrations 000230-000231) with a drawer CC editor that suggests same-company contacts, hold a copied contact's own lead so nobody gets two threads, count a copy's reply as the lead's, opt out every copy on a link unsubscribe, drop a bounced or refused copy without bouncing the lead, skip suppressed campaign CC and BCC addresses, and document the endpoints, CLI, skills and OpenAPI
2026-09-29 09:53:27 -07:00
Matthew Meszaros
e2f319cfd8
feat: file Gmail mail where Gmail moves it (archive, delete, spam, back to inbox) via an UPDATE_FOLDER event resolved against provider_folder, repair rows already stranded in the unibox Inbox with a six-hourly Gmail folder reconciliation, and close the open unibox conversation on a scope change with a close button in the reader header
2026-09-29 09:43:13 -07:00
Matthew Meszaros
f88ecd7b4c
feat: rebuild the new campaign flow as Leads, Emails, Schedule and Review with a lead-list picker, the full step editor and a live launch plan, keep unlaunched campaigns as server drafts that reopen in the flow from the campaigns list and a Continue setup button, simulate POST /campaigns-estimate day by day under warmup graduation, warmup mail sharing the send spacing, other campaigns, health holds and follow-up waits, retire one-time emails (migration 000229 drops campaigns.kind, the list type filter and badge go), enlarge the step subject field, and lift the editor popovers above dialogs
2026-09-29 01:37:07 -07:00
Matthew Meszaros
4c1fc9604b
Merge pull request #729 from warmbly/fix/cloud-warmup-standing-gates
...
feat: hold Warmbly Cloud's warmup standing on a linked self-hosted instance so campaign gates, pacing, lifecycle and account health enforce a cloud quarantine, block or throttle
2026-09-28 17:58:49 +00:00
Matthew Meszaros
b3518dd775
feat: resolve the unibox contact panel's sender through the thread's campaign send when the reply comes from an address that is not a contact (alias, second domain, forward, or another workspace mailbox), via thread_id and account_id on GET /contacts/lookup with a match field, gated on unibox access and the API key mailbox allowlist, show a Replied from line and keep a loaded contact on a failed refetch, skip every workspace mailbox when picking the other party, apply the same match to Pause follow-ups when answering the sender, and document it
2026-09-28 09:03:19 -07:00
Matthew Meszaros
a749a8e353
feat: hold Warmbly Cloud's warmup standing on a linked self-hosted instance, syncing each enrolled mailbox's health into cloud_link_mailboxes so campaign gates, send plans, lifecycle, risk pacing, account health and the Advisor enforce a cloud quarantine, block or throttle, fire the usual health webhooks and realtime events, and carry a hold into the local pool on unenroll
2026-09-28 08:46:40 -07:00
Matthew Meszaros
4a68ca783f
feat: answer an out-of-range contact import list limit with the range that endpoint accepts (1 to 100, default 50) instead of the generic limit message
2026-09-27 22:20:48 -07:00
Matthew Meszaros
f8221384f6
feat: let contact file uploads use their own 50 MB cap instead of the global 10 MB one and say when a file is too large, refuse an import list limit below one, hold an imported update to the contact size limit, keep a company logo laid out while it lazy-loads, neutralize formula cells in the sync error download, settle the draft save indicator when an edit is undone, and document the draft save route
2026-09-27 22:10:02 -07:00
Matthew Meszaros
f4f219b7c5
feat: run contact file imports as background jobs (upload once, a whole-file check of new, existing, repeated and invalid rows, a chunked leased runner with live CONTACT_IMPORT_PROGRESS, history, cancel, a draft that autosaves and survives a reload, remembered mappings, and a failed-rows CSV under the file's own headers), match existing contacts across the workspace, batch updates and fail a bad row alone, keep imported verdicts on update, scope every import write to the importing workspace, rebuild the import wizard with icons and inline segment creation, show company logos and the inbox provider on the contact avatar, and hide contact columns the list has no data for
2026-09-27 21:50:10 -07:00
Matthew Meszaros
62fac73c3d
feat: write a paid placement test before charging it and roll it back on a refused charge, take the agreed price as max_credits, refuse hand-picked seeds the sender's day cannot cover or that are not connected by name, refund only what a monthly reset has not expired and net refunds out of spend limits, bound the refund pass with a partial index, and re-filter a cloud panel's seeds by provider
2026-09-27 21:16:12 -07:00
Matthew Meszaros
4924d2c88d
feat: let a placement test target chosen seed inboxes or providers, add a quick pace that sends copies seconds apart, charge credits with explicit consent for tests past the monthly free allowance with automatic refunds for tests that deliver nothing, and add a Seeds picker to the compose window
2026-09-27 21:16:12 -07:00
Matthew Meszaros
55c5bdcf61
feat: let inbox tagging confirm an out-of-office return date by asking whether the phrase the parser read it from says when the sender is back, send the hold to the workspace fallback on a clear no below 0.40, store the date asked about in a new inbox_tag_results.return_date column (migration 000223), and show the date and answer on the tagging review page
2026-09-27 20:28:44 -07:00
Matthew Meszaros
e0bab213e7
feat: refuse an Accept-Language qvalue outside 0 to 1, NaN included, in both the backend and the tracking proxy so the two always pick the same unsubscribe page language
2026-09-27 05:06:41 -07:00
Matthew Meszaros
5e745618b1
feat: read opt-out replies in every tagging language with a phrase list per language, quote markers for the 16 tagging languages that had none, and a matcher that folds accents and handles scripts without spaces, and serve the recipient-facing unsubscribe pages (backend and tracking-domain proxy) in the browser's language across all tagging languages with right-to-left layout and an English fallback
2026-09-27 04:54:57 -07:00
Matthew Meszaros
f00591b6e1
feat: read a campaign's first send inside the summary query instead of a separate untenanted lookup, file campaign hourly stats under the same UTC day as the daily series, treat any instant passed as a campaign period day as its calendar day, share one from/to parser between the analytics API and get_campaign_stats, chart All time from the campaign's creation day alongside the summary so an analytics error cannot leave the overview loading, and roll period presets over at UTC midnight
2026-09-26 23:00:30 -07:00
Matthew Meszaros
0b809dee40
feat: scope campaign analytics to an optional from/to send cohort (summary, step performance, engagement and the daily chart read the same UTC days, total_contacts and emails_pending stay campaign-wide, date_range reports the resolved period), count the whole last day in campaign compare and daily stats, add a 7d/30d/90d/all-time/custom period picker to the campaign overview and its share image, take the period in get_campaign_stats, the warmbly and warmblyctl CLIs and the Make and Zapier modules, close a date picker's calendar alone on Escape, and document it in the analytics guide, API reference, MCP table and OpenAPI
2026-09-26 22:42:19 -07:00
Matthew Meszaros
1b45c630bb
feat: end a removed member's sessions and OAuth app grants through a removal hook detached from the request, refuse OAuth tokens whose holder is no longer a member, clear and detach a session selection that outlived its membership, gate subscription checkout, portal and cancel on manage_billing in the API and the dashboard, re-read org channel permissions live on member, role and ownership changes and withhold gated events while they cannot be read, drop the unrouted GitHub releases webhook handler, and correct v1 and release trigger paths in the docs
2026-09-26 22:07:54 -07:00
Matthew Meszaros
fcb303e5b9
Merge pull request #705 from warmbly/fix/action-required-automated-mail-visibility
...
feat: keep automated notifications that need the recipient's action in the inbox with an Action required label, view and notification
2026-09-27 04:45:43 +00:00
Matthew Meszaros
faa9cac061
feat: release a notification for retry when only workspace questions were asked and the call failed, count an unasked notification recheck as failed, read the workspace languages when skipping empty notices, and keep a built-in label name valid only on the question that already saved it
2026-09-26 21:40:42 -07:00
Matthew Meszaros
9d0f60801c
feat: file an offline notification unasked when the action check fails, bring a reopened verdict's message back to the inbox, skip empty notices and require the built-in check on --recheck-notifications, keep workspace labels saved before a built-in took the name, keep the sender's subject out of the action-required notification and send it off the ingest path, and default omitted outreach settings fields on PATCH
2026-09-26 21:36:11 -07:00
Matthew Meszaros
86c5a06893
feat: disconnect a removed member's realtime sockets from the event broadcaster so campaign and account channels end too, and keep invalidating the remaining cached sessions when one invalidation fails
2026-09-26 21:30:03 -07:00
Matthew Meszaros
2df8991db5
feat: scope every session request to a workspace its user is still a member of, deselect a removed member's workspace on all their sessions, disconnect their realtime sockets on removal, and correct the singular /organization paths in the API docs
2026-09-26 21:18:49 -07:00
Matthew Meszaros
c6027fecde
Merge pull request #694 from warmbly/fix/premium-warmup-pool-partners
...
feat: borrow the best proven free warmup mailboxes whenever a premium mailbox has too few outside-workspace partners, reserve a quarter of every inbox's daily warmup capacity for premium senders, and show the pool and partner cap in the mailbox drawer
2026-09-26 05:07:38 +00:00
Matthew Meszaros
6e62c500c3
feat: borrow the best proven free warmup mailboxes whenever a premium mailbox has fewer outside-workspace partners than max(25, its warmup ceiling) so siblings no longer block borrowing, keep a quarter of every inbox's daily warmup capacity for premium senders, and show the pool and any partner cap on today's target in the mailbox drawer
2026-09-25 21:47:36 -07:00
Matthew Meszaros
caf1852217
feat: keep placement seeds out of warmup pools as recipients too, store a probe's Message-ID before the send, hold queued probes against the sender's day and size a test to what is left, claim due monitors so one replica runs each, write comparison halves in one transaction, scan each seed's mail once per tick, keep test history when a mailbox is deleted, default to 20 seeds a minute apart, and render cloud-panel tests without a real lead by default
2026-09-25 21:46:09 -07:00
Matthew Meszaros
7f324a38ac
feat: open inbox placement tests to workspaces with probes rendered like the campaign send and paced as placement tasks, Message-ID matching instead of a subject token and warmup header, instance, workspace and Warmbly Cloud seed panels, a tracking comparison, scheduled campaign monitors with alerts and optional auto-pause, monthly allowances, realtime updates and org transfer registration
2026-09-25 20:48:15 -07:00
Matthew Meszaros
0fedc7abe6
feat: default tracking hosts to link.<domain>, set one tracking subdomain and redirect website for every domain in mailbox imports and on Sending domains with a per-domain dropdown to override each, add POST /emails/domains/bulk that goes through the inbox vendor's API where it can, add multi-select with check DNS, copy records, CSV export, clear tracking and remove redirect to Sending domains, and fix the sandbox seed's deliverability conflict target
2026-09-25 09:30:36 -07:00
Matthew Meszaros
9dee88bcb2
feat: keep conversations the inbox tagger judges automated (security alerts, verification codes, notifications, bounces, auto-replies) out of Inbox, Unread, mailbox and tag views and the unread badge and list them in the Automated view via a new unibox automated filter and overview counts, map no-reply header verdicts to Notification, and rename the automatic labels to plain words (Interested, Meeting, Needs reply, Follow up, Gone quiet and more) with a migration that renames, merges and prunes the old ones
2026-09-24 20:08:45 -07:00
Matthew Meszaros
d8e99877b2
feat: let an update finish work in flight instead of cutting it off, by having the import runner stop claiming on shutdown, hand back rows that never started without counting the claim and finish the rows it is connecting on an uncancelled context, the backend wait up to 45 seconds for those rows and for in-flight connects, the event bus finish the message being handled before it stops reading, and node units, the repository compose file and the installer's stack allow 60 seconds before a forced stop, with the grace period documented for Railway, Docker and Kubernetes
2026-09-24 18:31:06 +02:00
Matthew Meszaros
06f4a270cc
feat: keep the mailbox imports menu live and self-explaining (deferred rather than dropped progress events, a five-second refresh while an import runs, each import's state and what it waits on in words, a badge for imports that need you, and an × that hides an import for the workspace through POST /emails/imports/:id/dismiss with migration 000211, stopping a running one first), show the vendor's own status and the Microsoft and Google time expectations on rows being authorized, record a vendor row's mail host so it gets its provider icon and a working Sign in, drop the Fix button from rows the vendor is authorizing, and count warming mailboxes rather than connected ones in the pool banner, refreshed when mailboxes change
2026-09-24 17:46:46 +02:00
Matthew Meszaros
b196b3c8be
feat: count warmup placements exactly once through a consumer sweep that seeds history in batches instead of a locking migration backfill, add a concurrent unplaced-receipt index, publish WARMUP_PLACEMENT only when a receipt is counted, share one spam-flag list across warmup, placement tests and unibox folders, name ranked mailboxes from their own rows, default from to 30 days before to, keep ScrollStrip scrolling to itself, refresh account statuses at most every 5 minutes, and document rescued as requested
2026-09-24 05:28:51 -07:00
Matthew Meszaros
b2d54fc873
feat: record where every warmup email lands (inbox, Gmail tab, spam) per sender, day and recipient host in warmup_placement_daily, serve it from GET /analytics/warmup/placement, cap mailbox health at the measured 7-day inbox rate, and show it as an Inbox column, a mailbox Deliverability tab and a workspace placement section; replace every visible native checkbox in the dashboard with a themed Checkbox and make the mailbox drawer's tab bar scroll
2026-09-24 05:28:51 -07:00