2b1a35dfe1
feat: make warmup spam placement only slow a mailbox down (watch at 10%, half-volume throttle at 20%, never quarantine, block or appeal) and judge it only at Google, Microsoft and Yahoo over verified deliveries, keep small-host spam out of the health bands, warmup and cold ramps and the advisor while still showing it beside the headline rate on the drawer and Deliverability, draw small-host partners whose own filter junks warmup mail less often, send each quarantine or block webhook once plus health_changed, release placement-only quarantines in 000220, and update the warmup, deliverability, advisor and API docs
Matthew Meszaros2026-09-26 22:07:30 -07:00
0550d2ec92
Merge pull request #704 from warmbly/fix/org-path-drift-and-membership
Matthew Meszaros2026-09-27 05:13:57 +00:00
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
Matthew Meszaros2026-09-26 22:07:54 -07:00
fcb303e5b9
Merge pull request #705 from warmbly/fix/action-required-automated-mail-visibility
Matthew Meszaros2026-09-27 04:45:43 +00:00
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
Matthew Meszaros2026-09-26 21:40:42 -07:00
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
Matthew Meszaros2026-09-26 21:36:11 -07:00
354d0c27e7
Merge remote-tracking branch 'origin/main' into feat/session-org-membership
Matthew Meszaros2026-09-26 21:30:03 -07:00
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
Matthew Meszaros2026-09-26 21:30:03 -07:00
90f3f57eb9
feat: keep automated notifications that need the recipient's action (failed payment, suspended account, suspicious sign-in, sending limit, expiring service) in the inbox with an Action required label, view and mail-that-needs-action notification, let workspace tagging questions also run on automated notifications, add warmblyctl inbox-tag backfill --recheck-notifications, and document it
Matthew Meszaros2026-09-26 21:28:00 -07:00
18d57e45eb
Merge pull request #701 from Maris-Business-Solutions/fix/org-risk-endpoint-path
Matthew Meszaros2026-09-27 04:20:50 +00:00
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
Matthew Meszaros2026-09-26 21:18:49 -07:00
2ac54e66b5
feat: call the workspace risk endpoint at /organization/current/risk in getOrganizationRisk so it matches the backend org route group and the sending-restricted banner loads instead of 404ing
Claude2026-09-27 01:25:28 +02:00
d95a1075de
Merge pull request #699 from warmbly/feature/contact-email-provider
Matthew Meszaros2026-09-26 13:52:02 +00:00
2c156ec07e
feat: hold the contact provider sweep lease by owner token with a compare-and-delete and end each run before it can expire, recognise Microsoft 365 tenant onmicrosoft.com domains for ESP matching, count checked domains with no known provider with other rather than undetected, and report an unknown-provider filter when saving it as a segment
Matthew Meszaros2026-09-26 06:47:29 -07:00
67a7cf9811
Merge pull request #698 from warmbly/feat/warmup-placement-by-host
Matthew Meszaros2026-09-26 13:45:11 +00:00
e7ce03f17e
feat: send a lone text body as a direct child of multipart/mixed when an SMTP message carries attachments, keeping multipart/alternative only when both text and HTML bodies are present
Matthew Meszaros2026-09-26 06:41:12 -07:00
8812cba439
feat: detect each contact's inbox provider from its domain's MX and SPF in a backend sweep, show it as a sortable Email provider column with the provider logo, filter and segment on it across contacts, campaign leads and segments, and use it for campaign ESP matching including Workspace and Microsoft 365 custom domains and the coverage panel's per-provider lead counts
Matthew Meszaros2026-09-26 06:33:44 -07:00
014ba06b3a
feat: weight warmup partners by the sender's verified spam rate per recipient mail host instead of per address domain, report deliverability warmup placement and the placement_in_spam webhook by mail host, mark IMAP warmup mail not-junk before it leaves Junk, send single-part text mail over SMTP with a fixed header order, and update the warmup, deliverability, analytics, webhook and OpenAPI docs
Matthew Meszaros2026-09-26 06:30:22 -07:00
af8b08d27a
feat: rank borrowed free warmup mailboxes strictly by provider then tenure then activity, build the two inbound-share candidate suffixes once, and correct the partner-limit wording in the drawer, OpenAPI, warmup and Warmbly Cloud docs and AGENTS.md
Matthew Meszaros2026-09-25 21:52:45 -07:00
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
Matthew Meszaros2026-09-25 21:47:36 -07:00
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
Matthew Meszaros2026-09-25 21:46:09 -07:00
989daede3c
feat: add the Placement tests dashboard with the test list, detail and comparison views, New test dialog, Seed inboxes tab, campaign step Test inbox placement action and Placement monitor card, live updates over PLACEMENT_TEST_UPDATED with a slow poll only while the socket is down, the two placement notification categories, and seed-aware warmup errors on Mailboxes
Matthew Meszaros2026-09-25 21:03:26 -07:00
291ed2ae15
feat: document inbox placement tests in a new guide and API reference page, with the endpoints, error codes, realtime event, notification categories, placement settings, Warmbly Cloud seed panel, export and import behavior, CLI commands, assistant tools, admin Seed panel page and sandbox seed inboxes, and add the endpoints to openapi.json
Matthew Meszaros2026-09-25 21:01:58 -07:00
c3e48538d6
feat: record no creator on a placement monitor set by an API key, and refuse a cloud-panel placement test on the linked workspace's allowance or the sender's daily limit before the cloud opens and charges it
Matthew Meszaros2026-09-25 20:58:30 -07:00
d84864a8cb
feat: seed six instance placement seed inboxes on their own domains in the sandbox and have the simulator file each placement copy into the seed's Inbox or Junk as a stand-in spam filter, stricter on Microsoft and Yahoo seeds and on tracked copy
Matthew Meszaros2026-09-25 20:57:47 -07:00
d4467ce10e
feat: add the admin Seed panel page to manage the instance placement seed inboxes, run operator tests and read every workspace's results, plus the placement allowance and pacing settings on the Configuration page
Matthew Meszaros2026-09-25 20:56:11 -07:00
bbcf8725c3
feat: add warmbly placement CLI commands for overview, test, list, view, cancel, seed inboxes and campaign monitors, the list_placement_tests, get_placement_test and run_placement_test assistant tools, and the placement commands in the warmbly-cli skill
Matthew Meszaros2026-09-25 20:56:02 -07:00
d91b78458b
feat: skip placement probes from a suspended workspace the same way warmup sends are skipped
Matthew Meszaros2026-09-25 20:53:52 -07:00
099233ed08
feat: cast the placement expiry cutoff to timestamptz so Postgres does not read it as an interval, and cover probe matching by Message-ID, expiry, cancellation, daily-budget charging, monitors, seed selection across host families and every create refusal with live and unit tests
Matthew Meszaros2026-09-25 20:52:48 -07:00
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
Matthew Meszaros2026-09-25 20:48:15 -07:00
7f1bae8cac
feat: default the OpenAI writing, agent and warmup content batch models to gpt-6-luna instead of gpt-4o-mini, gpt-4o and gpt-5-mini, and document the new preset default in the deployment guide
Matthew Meszaros2026-09-25 20:18:26 -07:00
8fda36b3da
feat: report a failed bulk sending-domain request as an error on each of its domains and keep running the remaining batches and the redirect half instead of stopping the whole setup
Matthew Meszaros2026-09-25 09:55:29 -07:00
d6e4c42e50
feat: give each domain in a bulk sending-domain setup a 20s deadline and send 25 per request so every batch answers inside the dashboard timeout, send each domain's resolved tracking host and website from the bulk dialog so a kept verified host is not replaced by the base subdomain, and release the CSV export's blob URL after the download starts
Matthew Meszaros2026-09-25 09:44:00 -07:00
356c215d37
feat: limit Check DNS now on Sending domains to tracking hosts still waiting for DNS so a verified host covering part of a domain is never extended to its other mailboxes
Matthew Meszaros2026-09-25 09:32:05 -07:00
6b9df08f3e
Merge remote-tracking branch 'origin/main' into feature/domain-bulk-setup
Matthew Meszaros2026-09-25 09:30:36 -07:00
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
Matthew Meszaros2026-09-25 09:30:36 -07:00
dd98c4b1fe
feat: record the campaign an inbox tag verdict was made with (migration 000216) so --recheck-cold-inbound asks only about verdicts made without one and never re-bills, keep the recheck from removing labels when no verdict was stored, let the campaign lookup use the tasks Message-ID index, require the Gmail address tail on the Russian and Japanese quote markers so a proposed meeting time is not cut, keep workspace question labels off notifications, and key and lock tagging question edits by id
Matthew Meszaros2026-09-24 21:21:11 -07:00
c93bf1fcca
Merge remote-tracking branch 'origin/main' into feat/compose-placement
Matthew Meszaros2026-09-24 21:20:31 -07:00
bc73fc35a9
feat: give the unibox Compose button its visible label as the accessible name (screen-reader only on phones), hide the N key hint from assistive tech, and drop the drafts row's leftover top margin
Matthew Meszaros2026-09-24 21:20:18 -07:00
6a13fd5238
feat: report the Message-ID Gmail stamps on a send and resolve a reply's campaign through the Gmail thread and In-Reply-To so campaign replies stop tagging as sales pitches (with a warmblyctl --recheck-cold-inbound backfill that clears the stale labels and a tasks thread index), let a workspace add its own yes/no and pick-one tagging questions with plain-word labels and hold/stop/task actions, and add tagging languages (44 named to the classifier; for 27, only once chosen, tagging also cuts their quoted history and reads their away and non-delivery subjects), documented in the inbox tagging guide and the OpenAPI schema
Matthew Meszaros2026-09-24 20:13:01 -07:00
74bf081d57
feat: move the unibox Compose button from the top of the folder rail into the conversation list title row (and the Scheduled view header) as a ghost sky button with an N key hint on every viewport, keeping compose drafts at the top of the rail, and update the marketing inbox mock and the unibox guide to match
Matthew Meszaros2026-09-24 20:53:37 -07:00
e5e559f5fb
Merge pull request #688 from warmbly/feature/unibox-rail-lead-pause
Matthew Meszaros2026-09-25 03:53:22 +00:00
d9fd7df42b
Merge remote-tracking branch 'origin/main' into feature/unibox-rail-lead-pause
Matthew Meszaros2026-09-24 20:39:58 -07:00
78a742e9f3
Merge pull request #689 from warmbly/fix/inbox-bulk-archive-reappearing
Matthew Meszaros2026-09-25 03:36:49 +00:00
21991ccc6b
Merge pull request #686 from warmbly/feature/contact-custom-field-inputs
Matthew Meszaros2026-09-25 03:27:34 +00:00
9b310cf0c5
feat: rebase contact custom fields key by key so a teammate's new field is kept instead of saved as a removal, lock stored field names the server refuses and check every key a save sends, keep saved fields visible across tab switches, give new-field rows stable ids, and stop Enter in a field name from submitting the New contact form
Matthew Meszaros2026-09-24 20:25:25 -07:00
5e49d16e5d
feat: animate unibox rows out in the direction of the action (archive, trash, back to inbox, snooze) with a labelled underlay and in with a fade or grow, keep the list mounted so bulk exits play and give re-entering keys a fresh presence key so a refilling list never strands archived rows, fade new pages in at full height so infinite scroll stops chaining every page, batch bulk archive/read/snooze requests under the 500-id cap, show an all-caught-up state and an animated selection bar, and page the conversation list from the last returned row so no conversation is skipped at a page boundary
Matthew Meszaros2026-09-24 20:24:31 -07:00
ed18fad2cd
feat: pause nothing from the reply composer when the lead's state cannot be re-read, keep an armed follow-up pause pointed at at least one campaign and clear it after the send, report already-held campaigns apart from ones that could not be paused, word a paused or blocked next step by its reason in the unibox contact panel, and keep Stop disabled while Resume is in flight
Matthew Meszaros2026-09-24 20:20:49 -07:00
77f0c56e72
Merge pull request #687 from warmbly/feature/automated-mail-routing-and-labels
Matthew Meszaros2026-09-25 03:19:29 +00:00
fe7f416a1e
feat: pause and resume a lead from the unibox contact panel, which now lists each campaign with the lead's status and next step or hold, add a Pause follow-ups option to the reply composer that holds the recipient's ticked campaigns once the reply is accepted (counted from a scheduled reply's send time), add Pause lead to the contact Activity tab's campaign cards, end a lead's flow on the router's exclusion and let it decide whether a reply ended it, and stop per-contact send events refetching every other contact's campaign-state preview (issue #681)
Matthew Meszaros2026-09-24 20:04:44 -07:00
ccb4a3a0cd
feat: take back a campaign pass the task queue refused so the retry that follows a failed hand-off can seed one that runs
Matthew Meszaros2026-09-24 20:12:29 -07:00
de7a7c9748
feat: take back a replayed campaign pass the task queue refused and keep its dead letter, seed the next pass on a fresh context when the one after a failed hand-off could not be written, resume a campaign whose mailboxes lack a worker at the earliest reopening, and log that wait under its own daily line
Matthew Meszaros2026-09-24 20:09:55 -07:00
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
Matthew Meszaros2026-09-24 20:08:45 -07:00
720faf3acd
feat: show every workspace custom field as its own input in the New contact dialog and the contact Details tab (collapsed after six, filterable past twelve), suggest existing fields while naming a new one or a bulk-edit key with Use it for near-matches, validate names and duplicates before saving, and send removed or cleared fields as empty so the merge-on-update endpoint actually drops them
Matthew Meszaros2026-09-24 20:01:21 -07:00
a54e9a3a2f
feat: keep a campaign's pass chain running through every failure (a pass whose hand-off to a worker fails or that errors is followed by another a minute later instead of waiting on the reconciler, retries move their slot, dead-lettered passes replay through the campaign lock), pass over mailboxes no heartbeating worker holds (worker_id now loaded with the sender pool, shown as Reconnecting in the send plan), count a hand-off failure against the lead only when it is the lead's, and try up to 200 due leads per pass with a daily activity line when all are waiting
Matthew Meszaros2026-09-24 19:56:14 -07:00
85e63208a9
feat: share one tooltip provider across the collapsed sidebar rail so tab names show after 120ms and instantly between rows, and pad the collapsed nav so the Inbox unread badge is no longer clipped at the top
Matthew Meszaros2026-09-24 19:43:47 -07:00
64627de271
feat: resume a sign-in row through a grant only when the grant lookup confirms it is usable on this instance, so a stored grant whose provider is no longer configured does not requeue its rows every minute
Matthew Meszaros2026-09-24 19:10:02 +02:00
f0861fa129
feat: make the backend drain wait for the import runner itself to stop on the shutdown deadline, resume only sign-in rows an active grant covers (decided in SQL so uncovered rows cannot crowd them out), wait for NATS consumers to close after stopping them, count rows a vendor is authorizing by provider on the import so the admin sign-in button counts and shows only Microsoft rows, keep failed and sign-in imports ahead of connecting ones in the imports menu, and base the pool banner's empty state and warming count on workspace totals only
Matthew Meszaros2026-09-24 18:57:01 +02:00
755b6155c2
Merge pull request #679 from warmbly/fix/sent-count-and-reply-optout
Matthew Meszaros2026-09-24 16:49:03 +00:00
256010725b
feat: count only email steps in every sent total (contact drawer, Leads view and statuses, campaign progress, guardrails, org conduct, verification evidence, segments, admin, advisor), keep line breaks in synced body text and strip quoted history in any shape, classify delivery failures before out-of-office and tag them as bounces, record statusless failure notices from X-Failed-Recipients as permanent bounces, limit reply and inbox-tag opt-outs to people answering our outreach (never bounces, auto-replies or list mail), and recheck earlier reply opt-outs, lifting with an audit entry only those the message that wrote them no longer supports
Matthew Meszaros2026-09-24 09:44:17 -07:00
561ba07b35
feat: send a deferred import progress event with the latest status and cancel it when a final one goes out, report a hidden import's real status instead of cancelled, rank failed and sign-in rows above authorizing ones in the imports menu and its badge, and count warming and connected mailboxes for the pool banner on the server (warming on the pool plan) rather than from the filtered, paged list
Matthew Meszaros2026-09-24 18:38:47 +02:00
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
Matthew Meszaros2026-09-24 18:31:06 +02:00
ac663093c4
feat: label the faster options on a vendor authorization by what they do, Connect all at once (admin sign-in) for the whole domain and Sign in on a row for that mailbox only
Matthew Meszaros2026-09-24 18:24:50 +02:00
babf4bff67
feat: tell a person waiting on a vendor authorization that it can take up to an hour and offer the faster ways right there (Approve as a Microsoft 365 admin with the one-click admin consent, or Sign in on a row), and connect import rows still waiting for Google or Microsoft sign-in through an administrator's grant that now covers their domain within a minute instead of requiring the import to be run again
Matthew Meszaros2026-09-24 18:20:20 +02:00
4930c578df
feat: tell the person watching a vendor authorization what to do when it waits, naming the Google Admin domain-wide delegation step with Warmbly's client ID and scopes when the vendor waits on it, and saying when the vendor has not moved a request for 20 minutes with the time and the request id to give its support
Matthew Meszaros2026-09-24 18:14:10 +02:00
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
Matthew Meszaros2026-09-24 17:46:46 +02:00
e32b4f8893
feat: let a vertical wheel over a ScrollStrip at its edge scroll the page, name the seed section consistently in the deliverability guide, and keep the warmup placement live tests to their own receipts by dating the sweep fixture decades back and checking the live-counted flag directly
Matthew Meszaros2026-09-24 05:48:26 -07:00
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
Matthew Meszaros2026-09-24 05:28:50 -07:00
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
Matthew Meszaros2026-09-24 02:19:46 -07:00
4a1bbe74d3
Merge pull request #677 from warmbly/fix/vendor-imported-mailbox-connection
Matthew Meszaros2026-09-24 10:11:41 +00:00
7557d97866
feat: run a saved mailbox's placement, events, webhook and load on their own context so an expired caller deadline cannot skip them, bound bulk connects per row instead of per batch, have the worker reconciler remember the worker a load actually placed or moved a mailbox onto, keep an ADD_EMAIL that follows a REMOVE_EMAIL while the earlier load is still dialing by running it after that load, and show an import waiting only on vendor authorization as being authorized rather than importing
Matthew Meszaros2026-09-24 11:58:49 +02:00
3eb3297b11
Merge remote-tracking branch 'origin/main' into fix/vendor-imported-mailbox-connection
Matthew Meszaros2026-09-24 11:44:58 +02:00
549fb00be6
feat: keep mailbox credential checks and imports from timing out behind a worker's command queue by loading mailboxes off the bus loop (a republish never dials twice, commands wait for an in-flight load, a failed load raises the account's auth or server error), storing Kafka offsets for background commit instead of a synchronous commit per message, reconciling moved, unplaced and dead-worker mailboxes at once while spreading the safety-net republish over 30 minutes, sending checks over each worker's Redis channel with failover in placement order, retrying unanswered import rows within the lease, finishing a connect the browser left and an import row a restart interrupted, and connecting InboxKit Google and Microsoft mailboxes with no sign-in through a vendor-authorized grant that covers only the domains the vendor account lists
Matthew Meszaros2026-09-24 11:44:58 +02:00
79b583bcae
feat: classify a campaign's parked wakeup itself as a sending tick's paced successor (IsPacedSuccessor: the preceding tick sent and completed within a minute of the park) so a reconciler re-seed or deferral recheck is pulled forward when leads arrive, skip cancelled ticks, and qualify the campaigns guide's first-send timing by mailbox window, cap and gap
Matthew Meszaros2026-09-24 01:56:23 -07:00
87a346f4ff
feat: wake a freshly seeded campaign chain (start, resume, schedule edit, reconciler re-seed) as soon as a lead is due instead of at the paced slot of the send after it, and let leads added to a waiting campaign pull its deferral recheck forward while leaving a sending tick's paced successor alone (scheduler.WakeSlot, CampaignRepository.LastTickSent)
Matthew Meszaros2026-09-24 01:43:58 -07:00
ee70b7697a
Merge remote-tracking branch 'origin/main' into fix/unibox-forward-original-message
Matthew Meszaros2026-09-23 21:48:54 -07:00
a5dfe169e4
Merge remote-tracking branch 'origin/main' into fix/unibox-forward-original-message
Matthew Meszaros2026-09-23 21:38:59 -07:00
bbd7942313
feat: unibox forward requires READ_UNIBOX alongside WRITE_UNIBOX, restores click tickets in a forwarded Warmbly send to their destinations, fills an empty-placeholder HTML note from its text, previews an empty-note forward in the Scheduled view, keeps a reply's leading blank lines, shares the stored-body read with GET /unibox/:id, and shows the Reply/Forward bar when a forward's message is no longer in the thread
Matthew Meszaros2026-09-23 21:38:59 -07:00
462df7d025
Merge pull request #673 from warmbly/feat/unibox-reply-sender-picker
Matthew Meszaros2026-09-24 04:34:30 +00:00
a544847fcb
feat: resolve a Unibox reply's Gmail thread per sending mailbox (its own copy of the conversation, or the thread its earlier reply started, and none for other providers or on a failed lookup keeps the handle), honour an API key's mailbox allowlist on scheduled list and cancel, fall back from a saved mailbox that is gone and block Send until the sender can send, fetch From candidates only when the picker opens, and fix the Unibox threading and drafts docs
Matthew Meszaros2026-09-23 21:29:24 -07:00
6c4931c28a
feat: unibox forward carries the original message, attached server-side from a new forward_message_id on POST /unibox/reply and stored on the queued task (migration 000208) so it goes out under the note and signature with its From, Date, Subject, To and Cc lines, sanitized HTML and text part; the composer allows an empty note and previews the forwarded message (#668)
Matthew Meszaros2026-09-23 21:22:17 -07:00
13b0ff85c3
feat: refuse an InboxKit key that reaches no workspace with mailbox_vendor_no_workspace, and have the per-workspace credential lookup move on only past a mailbox a workspace does not hold, reporting any other vendor failure instead of a missing mailbox
Matthew Meszaros2026-09-23 21:21:21 -07:00
f9c24cdf88
Merge pull request #672 from warmbly/fix/step-performance-canvas-order
Matthew Meszaros2026-09-24 04:18:23 +00:00
ce5eb4fd25
feat: let a Unibox reply or forward choose its sending mailbox in From (the shared MailboxPicker without Auto, kept in the draft and the undo-send), send the provider thread handle only from a mailbox that holds the thread so a switched reply threads on In-Reply-To alone, and scope scheduled sends, their cancel, count and cap to the organization whose mailboxes send them (#670)
Matthew Meszaros2026-09-23 21:18:20 -07:00
39bb5567dc
feat: order campaign Step performance by the canvas's step order (position, then created_at) instead of created_at, which the wizard writes identically for every step, number each row as its place among the email steps so it matches the canvas's Email N, label unnamed steps Email N in the dashboard, and document the steps order and position in the analytics API reference, guide and OpenAPI schema (#669)
Matthew Meszaros2026-09-23 21:12:33 -07:00
e35baa7f58
feat: connect every inbox vendor with only its API key by discovering the workspaces and organizations the key reaches (InboxKit, Zapmail, Infraforge, ScaledMail), carry the workspace in vendor mailbox and domain ids with a lookup for ids stored before, skip a workspace the key may not read, refuse a key that reaches none with mailbox_vendor_no_workspace, and add a workspace switcher to the mailbox picker that filters, counts picks and selects a whole workspace
Matthew Meszaros2026-09-23 21:12:09 -07:00