Skip to content

Releases: incredible-zetta/crm

v0.7.1 — fix x_tweet account label

Choose a tag to compare

@igun997 igun997 released this 02 Jul 09:20
6754f21

Fixes

  • x_tweet account label resolution: x_tweet (tweet detail) called TweetDetail with the raw in.Cookies field, skipping resolveCookies. Passing account=<label> (no inline cookies) failed with x_tweet: cookies required even for a stored, live account. It now resolves cookies like every other x_* tool (label precedence → CookiesForLabel, else inline blob), supporting both stored account labels and inline cookies.

Audited all x_* handlers: x_tweet was the only affected tool. x_account_save intentionally keeps the raw blob.

Full changelog: v0.7.0...v0.7.1

v0.7.0 — x.com (Twitter) MCP integration

Choose a tag to compare

@igun997 igun997 released this 02 Jul 08:02
9045a2e

Features

x.com (Twitter) MCP integration — full multi-account channel ported in-process from x-utils (cookie auth, no shell-out):

  • 13 core x_* tools: x_user, x_identify, x_post, x_delete, x_search, x_user_tweets, x_tweet, x_replies, x_followers, x_following, x_dm, plus account + watch management.
  • Account persistence + liveness (x_account_save/list/delete): accounts keyed (tenant_id, label); cookies write-only (never returned/logged); liveness cron.
  • Contact social handles: x_username / threads_username on Contact.
  • x_replies: top-level reply tweets per conversation thread, paginated.
  • Signed-webhook watches (x_watch_save/list/delete/events): per-watch webhook_url + rotatable webhook_secret + custom headers; HMAC-SHA256 X-Zetta-Signature; exported SignWebhook/VerifyWebhookSignature; poller cron.
  • x_identify: acting-account self summary.
  • threads_daily_summary MCP tool.

Fixes

  • Liveness + x_identify self-resolution: resolve the acting account's own profile via twid → UserByRestId instead of a stored screen_name + invalid from:me search fallback. Fixes functional accounts being wrongly marked dead and lets x_identify work from raw cookies.

Migrations

0011_x_accounts, 0012_contact_social_handles, 0013_x_watches.

Security

  • cookies / webhook_secret are sensitive: never logged/echoed; MCP outputs expose has_secret only.
  • Webhooks HMAC-signed; built-in headers override agent-supplied ones so security headers can't be clobbered.

Full changelog: v0.6.0...v0.7.0

v0.6.0 — Optional multi-tenancy

Choose a tag to compare

@igun997 igun997 released this 23 Jun 18:28

Optional multi-tenancy

Adds opt-in multi-tenancy controlled by the MULTI_TENANCY env flag. Default is false, which preserves the original single-tenant behavior exactly.

When enabled

  • Identity = (Authorization key, X-Session-Id). Auth key sent as today (Authorization: Bearer / X-API-Key); the tenant additionally sends a static, client-controlled X-Session-Id header.
  • Auto-provisioning, no admin. First time a (key, session_id) pair is seen, a tenant is created and an opaque, stable tenant_id is derived. Raw key never stored (only SHA-256 hash).
  • Data scoping. Every owned table has a tenant_id column; all queries filter by the tenant resolved from context. Name/natural-key uniqueness is per-tenant (email, template name, mailbox, chat, external object ids).
  • Channel config stays global. WhatsApp / Threads / IMAP gateway + tokens are shared via env; only the data is scoped.
  • Public routes (/t, /o, /export, /u, wa webhook) resolve the owning tenant from the globally-unique random code/id on the matched row.
  • Background jobs record the owning tenant per task and re-inject it into context before tenant-scoped work.

Migration

  • 0010_multi_tenancy adds the tenants table, a tenant_id column on every owned table (default 'default'), and per-tenant composite unique keys. Existing rows backfill to 'default'. Auto-applied on startup; no manual steps.

Backward compatibility

Verified on a real MySQL upgrade (v9 → 0010): legacy single-tenant data backfilled and fully reachable, multi-tenant isolation verified, full integration suite green.

Config

Variable Default Notes
MULTI_TENANCY false true scopes all data per tenant; tenants auto-provisioned from (Authorization, X-Session-Id).

PR #23.


⚠️ Security note: a stray www.threads.com_cookies.txt session file was briefly committed during merge and has been purged from history via a force-push rewrite. If you have a local clone from before this release, re-clone or hard-reset to the new master. Rotate any affected Threads/Instagram session.

v0.5.0

Choose a tag to compare

@igun997 igun997 released this 15 Jun 19:55
f914a4c

Features

  • Add Threads hybrid channel
  • Support Threads topic tags
  • Expand Threads search params and add token tools
  • Add threads_reply_tree and fix threads_history serialization

Fixes

  • Flatten threads_reply_tree output to avoid MCP schema cycle
  • Address Threads CI lint and docs

Other

  • Merge Threads hybrid channel PRs
  • Merge Threads reply tree PRs

v0.4.0

Choose a tag to compare

@igun997 igun997 released this 10 Jun 16:10
beb75d2

WhatsApp channel (two-way messaging, smart-send, delivery tracking); campaign scheduling/status/lead-stage fixes; GHCR master pre-release builds. Full changelog: v0.3.0...v0.4.0

v0.3.0

Choose a tag to compare

@igun997 igun997 released this 05 Jun 14:21

Features

  • Added self-hosted email verification: RFC syntax check, DNS MX lookup (A/AAAA fallback), and disposable/role-address heuristics. No SMTP RCPT probe (unreliable, reputation-damaging).
  • Each contact now carries email_status (valid/invalid/risky/unknown), email_reason, and email_checked_at.
  • Verification hooks: on create, on update (when email changes), on audit, and a send guard.
  • New tool email_verify — verify one contact and persist the verdict.
  • New tool email_audit — sweep a segment; async by default (returns task_id, runs via the scheduler over the whole segment), sync:true for a single inline page.
  • New env: VERIFY_EMAILS (verify on create/update), BLOCK_INVALID_SEND (refuse sending to contacts verified invalid).

Usage

{"name":"email_verify","arguments":{"id":42}}
{"name":"email_audit","arguments":{"segment":{"stage":"new"},"only_unchecked":true}}
{"name":"email_audit","arguments":{"sync":true,"limit":200}}

Notes

  • Verification is self-hosted and free; valid means deliverable-capable, not guaranteed-inbox.
  • Large audits run asynchronously through the in-process scheduler, consistent with campaign_send.

Verification

  • make check
  • staticcheck ./...

v0.2.0

Choose a tag to compare

@igun997 igun997 released this 05 Jun 13:57

Features

  • Added contact_bulk_update — apply a partial patch to many contacts by ID list (max 500 per call). Returns {matched, updated, skipped, errors}.
  • Added contact_bulk_update_by_filter — apply a partial patch to every contact matching a segment filter (stage, company, tag, q); pages internally.
  • Tag semantics are agent-friendly: add_tags / remove_tags merge without clobbering, or set_tags overwrites the whole list.
  • Partial patch fields: company, stage, notes, source, plus tags. Omitted fields are left unchanged.

Usage

{"name":"contact_bulk_update","arguments":{"ids":[1,5,9],"patch":{"stage":"qualified","add_tags":["vip"]}}}
{"name":"contact_bulk_update_by_filter","arguments":{"segment":{"stage":"proposal"},"patch":{"add_tags":["q3-push"]}}}

Notes

  • Both tools are synchronous (pure DB, no provider rate limits). Invalid stage, empty patch, or >500 ids return invalid_input. Missing contacts are skipped and reported in errors.

Verification

  • make check
  • staticcheck ./...

v0.1.4

Choose a tag to compare

@igun997 igun997 released this 05 Jun 13:28

Fixes

  • email_send now returns the underlying send failure detail in msg (e.g. SMTP auth/connection errors) instead of the generic "email send failed", matching the template_render diagnostics behavior. The error code stays send_failed.

Diagnosing send failures

  • Sync: email_send returns {error: "send_failed", msg: "send failed: <cause>"}.
  • Async campaigns: the real cause is recorded in the task last_error; inspect via task_list.

Verification

  • make check
  • staticcheck ./...

v0.1.3

Choose a tag to compare

@igun997 igun997 released this 05 Jun 13:03

Features

  • Added outbound email throttling to respect provider rate limits. Set EMAIL_RATE_MAX and EMAIL_RATE_WINDOW_SEC (e.g. 200 / 100 for Larksuite) to pace delivery.
  • The limiter is a context-aware token bucket wrapping the email sender, applied to both single email_send and campaign_send. Campaign loops now block until a slot frees instead of bursting the SMTP provider.
  • Leave the env vars unset to send without throttling (unchanged behavior).

Usage

EMAIL_RATE_MAX=200
EMAIL_RATE_WINDOW_SEC=100

Verification

  • make check
  • staticcheck ./...

v0.1.2

Choose a tag to compare

@igun997 igun997 released this 05 Jun 12:51

Features

  • campaign_send now enqueues a background task by default and returns immediately with {campaign_id, task_id, status: "queued"}, avoiding MCP request timeouts on large segments. The in-process scheduler dispatches it and flips the campaign to sent/failed.
  • Added sync: true escape hatch on campaign_send for small/test sends that wait inline and return live counts.
  • Campaigns are marked sending up front so pollers see progress; failed sends transition to failed instead of staying stuck.

Usage

  • Async (default): campaign_send {"campaign_id": 1} → poll campaign_stats or task_list.
  • Sync: campaign_send {"campaign_id": 1, "sync": true}.

Verification

  • make check
  • staticcheck ./...