Matthew Meszaros
25075fcdd8
feat: take the warmup inbox rate and its daily rolling line at Google, Microsoft and Yahoo only (small hosts ride beside it and never make the headline), and rebuild the Accounts mailbox list in the Leads style with host logos, sender and connection line, a status naming whether the mailbox is sending, warming or both, sortable Sent today, animated Warmup, Inbox and pulsing Health columns, with docs and OpenAPI updated
2026-09-27 20:40:45 -07:00
Matthew Meszaros
4587b475ca
Merge pull request #718 from warmbly/fix/warmup-mailbox-selection-cap
...
feat: page every list to the end: fix keyset cursors that dropped a row per page, load all mailboxes and campaigns in the dashboard, and stop offering unlimited limits on Settings > Limits
2026-09-27 12:26:15 +00:00
Matthew Meszaros
8590f417b8
feat: point keyset list cursors at the last row returned so mailbox, campaign, API key, API key usage, contact note, activity, deal and CRM task lists stop dropping one row at every page boundary, let campaign search report a next page, page campaigns to the end in the dashboard through a shared useAllPages hook, and hold the Settings > Limits form until the limits load
2026-09-27 05:11:24 -07:00
Matthew Meszaros
1dbbee61c6
Merge pull request #716 from warmbly/feat/localized-optout-and-unsubscribe-page
...
feat: read opt-out replies and serve the unsubscribe page in every tagging language
2026-09-27 12:10:48 +00: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
98f8841347
Merge pull request #714 from Skylinerffm97/fix/german-return-dates
...
fix(replyclassify): read German return dates after a weekday, in calendar weeks and at the end of a range
2026-09-27 11:53:31 +00:00
Matthew Meszaros
8594eda3a2
Merge pull request #713 from Skylinerffm97/fix/not-interested-is-negative
...
fix(replyclassify): read "not interested" as a negative reply
2026-09-27 11:38:24 +00:00
Matthew Meszaros
25ec1aceca
feat: keep a German "ab" date and a sentence that opens on "Bis" as two statements in ParseReturnDate by marking the capitalized sentence start before lower-casing
2026-09-27 04:37:26 -07:00
Skylinerffm97 and Claude Opus 5.5
618099d689
fix: read German return dates after a weekday with a comma ("ab Montag, 12.10.", "ab Montag, den 12.10.") for every workday instead of only "ab Montag den", read calendar weeks ("ab KW 42" as that week's Monday, "bis KW 41" and "bis KW 40/41" as the Monday after the last week, a week under way as back now), and take the end of an "ab ... bis ..." range instead of its first day unless a sentence or a return word comes between, so these out-of-office replies hold a lead until the day they name instead of the flat fallback or the start of the absence
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
2026-09-27 10:59:23 +00:00
Skylinerffm97 and Claude Opus 5.5
89b8e9790a
fix: count a German GDPR objection only when the writer objects in the first person and the same sentence goes on to what is objected to behind an article (der Verarbeitung, dem Erhalt weiterer E-Mails, jeglicher Kontaktaufnahme), so a formal disagreement like "ich widerspreche hiermit Ihrer Preisberechnung" and a signature's privacy notice ("Sie können der Verarbeitung jederzeit widersprechen") stay normal replies, while objections worded with "ausdrücklich", "gem. Art. 21 DSGVO" or a compound like "Datenverarbeitung" still opt out
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
2026-09-27 10:59:03 +00:00
Skylinerffm97 and Claude Opus 5.5
1ba3d5df9d
fix: read "not interested" and the other declined-interest replies (aren't, not really, not that, no longer, would not be, uninterested) as negative before the interest phrases, whose "interested" took them for positive replies and sent people who said no down a campaign's positive-reply branch
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
2026-09-27 10:44:38 +00:00
Skylinerffm97 and Claude Opus 5.5
fad04c5efc
feat: read German opt-out replies (bitte austragen, keine weiteren E-Mails, löschen Sie meine Daten, a GDPR objection and more) in the reply opt-out check and the lexicon layer, bind meeting-sense words like abmelden and austragen to bitte or the writer, always cut the German quote markers before reading opt-out so the sender's own German opt-out line in an Outlook, GMX/web.de or T-Online quote never opts anyone out, add GMX's date-first header block and the Original-Nachricht divider to the German rules, fold umlauts and line breaks before matching, and mention German replies in the unsubscribe guide
...
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com >
2026-09-27 10:00:47 +00:00
Matthew Meszaros
c2f8b03371
feat: word the business-only checkout notice so an untaxed sale leaves any tax due to the buyer in its own country, with the reverse charge as one example rather than the only case
2026-09-27 11:33:35 +02:00
Matthew Meszaros
4e68bb2562
feat: sell Warmbly to businesses only by requiring the buying company's legal name on the subscription and credit-pack Stripe Checkout sessions with a business-only and tax-exclusive notice beside the pay button, adding business-use and tax clauses to section 06 of the terms of service, and updating the billing guide to match
2026-09-27 11:10:46 +02:00
Matthew Meszaros
c4f0ffffc2
feat: keep a throttled warmup mailbox in the pool by stamping blocked_at only for a quarantine or block in UpdateParticipantHealth, clear it from throttled rows in migration 000222 so partner selection and the admin pool counts stop treating a throttle as a block, and run the warmup health sweep on consumer boot so a release that changes the rules re-judges every mailbox at once
2026-09-27 10:09:01 +02:00
Matthew Meszaros
8c0cb9759e
Merge pull request #708 from warmbly/fix/recent-posthog-errors
...
feat: handle the error classes recently reported to PostHog across signup, DEK creation, IMAP classification, boot migrations and the dashboard
2026-09-27 06:37:22 +00:00
Matthew Meszaros
208481f9a4
feat: answer a signup for an existing address with 409 conflict and let a concurrent SSO first sign-in resolve against the account it raced, adopt the stored organization DEK when a parallel first use stored one first, classify IMAP SERVERBUG, LIMIT, bare read-command failures and provider ALERT/EXPIRED responses as server-unreachable, throttle or credentials errors and keep the ALERT text, wait up to two minutes for a free connection slot before the boot migration gives up, guard the dashboard's DOM mutations against browser page translation, treat an aborted passkey sign-in as a cancellation, and drop posthog-js request timeouts from error tracking
2026-09-27 08:26:55 +02:00
Matthew Meszaros
49e7fec849
Merge pull request #707 from warmbly/feature/campaign-analytics-date-range
...
feat: date range filtering for campaign analytics as a send cohort
2026-09-27 06:16:54 +00: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
81c578a879
feat: keep watch and throttled mailboxes in cold rotation at their dampened volume and rest only quarantined or blocked ones, hold a watch or throttle past its line only when placement set it, fall back to the all-host headline when the major providers lack a sample without capping health on it, count a partner's junked mail through its own receipts, reset the released ledger rows' standing, and correct the resting, rolling-rate and scope docs
2026-09-26 22:26:58 -07:00
Matthew Meszaros
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
2026-09-26 22:26:58 -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
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
2026-09-26 21:28:06 -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
d95a1075de
Merge pull request #699 from warmbly/feature/contact-email-provider
...
feat: detect each contact's inbox provider from its domain's MX and SPF, show, sort and filter it across contact lists and segments, and use it for campaign ESP matching
2026-09-26 13:52:02 +00:00
Matthew Meszaros
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
2026-09-26 06:47:29 -07:00
Matthew Meszaros
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
2026-09-26 06:41:12 -07:00
Matthew Meszaros
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
2026-09-26 06:33:44 -07:00
Matthew Meszaros
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
2026-09-26 06:30:22 -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
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
2026-09-25 21:52:45 -07: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
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
2026-09-25 20:58:30 -07:00
Matthew Meszaros
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
2026-09-25 20:57:47 -07:00
Matthew Meszaros
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
2026-09-25 20:56:02 -07:00
Matthew Meszaros
d91b78458b
feat: skip placement probes from a suspended workspace the same way warmup sends are skipped
2026-09-25 20:53:52 -07:00
Matthew Meszaros
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
2026-09-25 20:52:48 -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
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
2026-09-25 20:18:26 -07:00
Matthew Meszaros
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
2026-09-25 09:44:00 -07:00
Matthew Meszaros
6b9df08f3e
Merge remote-tracking branch 'origin/main' into feature/domain-bulk-setup
2026-09-25 09:30:36 -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
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
2026-09-24 21:21:11 -07:00