Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 14 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,10 +189,19 @@ inbound calls only.
libphonenumber) to determine country and timezone
5. For US/CA numbers, uses the 3-digit area code to narrow to a specific
timezone
6. Creates an internal note on the contact with timezone details (visible in
all Inbox views)
7. Sets an `inferred_timezone` custom attribute on the contact (filterable,
usable in reports)
6. Creates an internal note on the contact with timezone details and a stable
receipt derived from the Intercom call ID (visible in all Inbox views)
7. On Intercom's one-minute webhook retry, reads the conversation and skips the
note write when that call receipt already exists
8. Sets an `inferred_timezone` custom attribute on the contact (filterable,
usable in reports). The note and attribute writes run concurrently so the
normal webhook path can acknowledge within Intercom's five-second deadline.

If a note request has an ambiguous outcome, the handler reads the conversation
and treats an existing exact call receipt as success. If the receipt cannot be
proved, or the contact attribute update fails, it returns an error so Intercom's
single retry can safely finish the work. A missing/invalid call ID suppresses
the note rather than performing a write that cannot be deduplicated.

## Project Structure

Expand Down Expand Up @@ -283,7 +292,7 @@ repository-root `.env` used by `doctl serverless deploy . --remote-build --env
| `WEBHOOK_SECRET` | Intercom app client secret |
| `LEAD_TO_USER_CONVERSION_ENABLED` | Optional. Set to `true` to enable server-side lead→user merge. **Off by default** because the merge breaks live Messenger sessions (see Lead-to-User section). |
| `INTERCOM_DRAFT_BRIDGE_SECRET` | Random bearer secret required by the draft bridge. |
| `INTERCOM_ARTICLE_AUTHOR_ID` | Intercom teammate/admin ID used as the article author. |
| `INTERCOM_ARTICLE_AUTHOR_ID` | Pinned full-seat Intercom teammate/admin ID used as the article author and, through a function-local alias, the call-location note author. |

### Intercom Webhook Setup

Expand Down
5 changes: 5 additions & 0 deletions packages/intercom/tests/serve_local.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,11 @@ def run(port=8080):
missing.append("INTERCOM_ACCESS_TOKEN")
if not os.environ.get("WEBHOOK_SECRET"):
missing.append("WEBHOOK_SECRET")
if not (
os.environ.get("INTERCOM_WEBHOOK_ADMIN_ID")
or os.environ.get("INTERCOM_ARTICLE_AUTHOR_ID")
):
missing.append("INTERCOM_ARTICLE_AUTHOR_ID")
if missing:
print(f"ERROR: Missing environment variables: {', '.join(missing)}")
print("Copy .env.example to .env and fill in your real values.")
Expand Down
Loading