chatwoot-router 0.7.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.8.0] - 2026-10-08
11
+
12
+ ### Changed
13
+
14
+ - Jev sees the contact's email domain on every channel (`Contact email domain: example.net`), not only an email's
15
+ sender domain: a widget visitor who gives an address at a reserved test domain, as scripted probes do, is told
16
+ from a person, so the spam kind can end the ticket. The address and name stay redacted.
17
+
10
18
  ## [0.7.0] - 2026-10-07
11
19
 
12
20
  ### Changed
package/README.md CHANGED
@@ -12,8 +12,8 @@ is each routed account's native agent bot, connected to the inboxes it should ro
12
12
  1. A new ticket in a connected inbox is pending, so Chatwoot sends its events to the router's
13
13
  `/chatwoot/agent-bot` webhook. Each conversation is routed by a Durable Object of its own, so a slow request
14
14
  for one conversation never delays another.
15
- 2. The router reads the customer's first messages of this turn (redacted, at most three and 1,600 characters; an
16
- email's sender domain leads them)
15
+ 2. The router reads the customer's first messages of this turn (redacted, at most three and 1,600 characters; the
16
+ contact's email domain leads them)
17
17
  and asks TypeSafe's System One API (`/v1/systemone`, model `routing.model`, Jev by default; `routing.endpoint`
18
18
  may point to another deployment) for the owner, topic, kind, and whether there is a request yet.
19
19
  3. It applies the topic and kind labels, sends the kind's canned reply if it has one (at most once per
@@ -151,7 +151,7 @@ the Router DO during rollback. If its state is lost or restored to an older reco
151
151
  and isolate conversations with uncertain attempts/turns for owner review; a currently empty history does not
152
152
  prove another send is safe. Existing pending conversations are reconciled; non-pending conversations stay with people. The user token must see all relevant inboxes.
153
153
 
154
- Redaction is best effort, not anonymization: other personal information can still reach TypeSafe, and an email's
155
- sender domain is sent on purpose (never the address or name). Logs contain
154
+ Redaction is best effort, not anonymization: other personal information can still reach TypeSafe, and the
155
+ contact's email domain is sent on purpose (never the address or name). Logs contain
156
156
  ids and outcomes, never message bodies or credentials. See [SECURITY.md](https://github.com/Phala-Network/chatwoot-workers/blob/main/SECURITY.md),
157
157
  [CONTRIBUTING.md](https://github.com/Phala-Network/chatwoot-workers/blob/main/CONTRIBUTING.md) and [CHANGELOG.md](https://github.com/Phala-Network/chatwoot-workers/blob/main/packages/chatwoot-router/CHANGELOG.md). Licensed under [MIT](https://github.com/Phala-Network/chatwoot-workers/blob/main/packages/chatwoot-router/LICENSE).
@@ -836,7 +836,7 @@ async function routeConversation(ctx, accountId2, conversationId) {
836
836
  const initial = await snapshot();
837
837
  if (!initial) return;
838
838
  const identities = [initial.conversation.contact.name, initial.conversation.contact.email];
839
- const senderDomain = initial.conversation.channel === "Channel::Email" ? initial.conversation.contact.email?.split("@")[1] : void 0;
839
+ const contactDomain = initial.conversation.contact.email?.split("@")[1];
840
840
  const inputs = (messages) => {
841
841
  const texts = messages.filter(isCustomer).flatMap((message) => {
842
842
  const text3 = sanitize(
@@ -848,7 +848,7 @@ async function routeConversation(ctx, accountId2, conversationId) {
848
848
  const text2 = texts.map((entry) => entry.text).join(" ");
849
849
  return {
850
850
  key: texts.map((entry) => entry.id).join(","),
851
- text: (senderDomain ? `Email sender domain: ${senderDomain}
851
+ text: (contactDomain ? `Contact email domain: ${contactDomain}
852
852
  ${text2}` : text2).slice(0, MAX_TEXT),
853
853
  count: texts.length
854
854
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chatwoot-router",
3
- "version": "0.7.0",
3
+ "version": "0.8.0",
4
4
  "description": "Route Chatwoot conversations with TypeSafe Jev on Cloudflare Workers.",
5
5
  "keywords": [
6
6
  "chatwoot",