Skip to content

docs: add HubSpot, Salesforce, Freshdesk, and Intercom integration guides#254

Merged
chris-absmartly merged 5 commits intomasterfrom
docs/zendesk-integration
Mar 10, 2026
Merged

docs: add HubSpot, Salesforce, Freshdesk, and Intercom integration guides#254
chris-absmartly merged 5 commits intomasterfrom
docs/zendesk-integration

Conversation

@joalves
Copy link
Collaborator

@joalves joalves commented Mar 9, 2026

Summary

  • Adds four new integration documentation pages for sending CRM/support events as ABsmartly goal events:
    • HubSpot — via Workflow webhook actions (notes middleware needed for PUT)
    • Salesforce — via Flow HTTP Callouts with Named Credentials
    • Freshdesk — via Automation Rules with webhooks (notes middleware needed for PUT)
    • Intercom — via Series webhooks
  • Follows the same structure as the existing Zendesk integration doc

Summary by CodeRabbit

  • Documentation
    • Added integration guides for Freshdesk, HubSpot, Intercom and Salesforce. Each guide includes prerequisites, step‑by‑step setup for sending events as ABsmartly goals, webhook/workflow configuration and example payloads/headers, mapping and environment/app guidance, middleware notes where applicable, verification and testing steps, operational considerations (rate limits, retries) and examples for tracking multiple events.

…ides

Add documentation for sending CRM and support events as goal events
to the ABsmartly Collector API using each platform's webhook/automation
capabilities.
@coderabbitai
Copy link

coderabbitai bot commented Mar 9, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Four new documentation files were added under docs/Third-party-integrations: Freshdesk-Integration.mdx, HubSpot-Integration.mdx, Intercom-Integration.mdx and Salesforce-Integration.mdx. Each file explains prerequisites and step-by-step configuration to forward platform events to ABsmartly (via webhooks or Salesforce HTTP callouts), provides required headers and JSON payload templates, notes on environment/app/unit mappings and placeholders, and includes testing/verification steps and cautions (rate limits, middleware, compatibility).

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Suggested reviewers

  • bmsilva
  • mario-silva
  • marcio-absmartly

Poem

🐰 I hopped through docs with a nib so bright,
Freshdesk, HubSpot, Intercom — Salesforce took flight,
Webhooks and payloads stitched neat in a row,
Goals counted, units shared, off to testing we go,
The burrow cheers as integrations glow!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarises the main change: adding four new integration documentation guides (HubSpot, Salesforce, Freshdesk, Intercom).
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch docs/zendesk-integration

Comment @coderabbitai help to get the list of available commands and usage tips.

@netlify
Copy link

netlify bot commented Mar 9, 2026

Deploy Preview for absmartly-docs ready!

Name Link
🔨 Latest commit 533be9d
🔍 Latest deploy log https://app.netlify.com/projects/absmartly-docs/deploys/69aedad6e9b9810008df0bd4
😎 Deploy Preview https://deploy-preview-254--absmartly-docs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

The Collector already supports POST on /v1/context/publish as an alias
for PUT /v1/context, so no middleware is needed for POST-only platforms.
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (1)
docs/Third-party-integrations/Intercom-Integration.mdx (1)

50-50: Avoid fixed timestamps in the payload example.

Line 50 and Line 60 hard-code a single epoch value; if copied as-is, all events appear to happen at the same time. Prefer dynamic timestamp attributes and note the expected format (epoch ms or ISO-8601).

Also applies to: 60-60

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/Third-party-integrations/Intercom-Integration.mdx` at line 50, Replace
the hard-coded epoch values for timestamp fields (e.g., the "publishedAt"
property shown in the payload example) with dynamic placeholders and a short
note about accepted formats; specifically, update the "publishedAt" occurrences
to use a variable or template (e.g., {{timestamp}} or Date.now()) and add a
parenthetical that the service accepts epoch milliseconds or ISO-8601 strings so
readers know how to generate timestamps instead of copying a fixed epoch.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/Third-party-integrations/Freshdesk-Integration.mdx`:
- Line 59: The JSON example contains unquoted Freshdesk template placeholders
(e.g., the token publishedAt: {{ticket.created_at_with_timestamp}}) which
produces invalid JSON; update the example so all placeholder values are wrapped
in double quotes (for instance change publishedAt:
{{ticket.created_at_with_timestamp}} to use a quoted placeholder) and verify the
surrounding lines (other placeholders) are similarly quoted so the snippet is
valid JSON.

In `@docs/Third-party-integrations/HubSpot-Integration.mdx`:
- Line 49: The docs present conflicting approaches: the "Customize request body"
direct payload example and the later statement that full payload control
requires middleware; update the HubSpot Integration doc so middleware is the
primary, recommended implementation and the direct webhook example is explicitly
labeled as a minimal/limited shortcut that cannot supply full payload control.
Specifically, revise the "Customize request body" section to: (1) state clearly
that full payload customization requires using middleware (link to the
middleware section); (2) keep the direct webhook/static-properties snippet as a
brief, constrained example and add a prominent caveat that it is limited and may
break integrations needing full payloads; and (3) remove or reword the
contradictory lines in the 57–62 area to align with the middleware-first
guidance.
- Around line 99-108: The headers table for the middleware forwarding to
ABsmartly is missing Content-Type; update the table so it includes a row for
Content-Type with value application/json alongside the existing headers
(X-API-Key, X-Application, X-Application-Version, X-Environment, X-Agent) so the
middleware explicitly documents sending Content-Type: application/json when
forwarding requests.

In `@docs/Third-party-integrations/Salesforce-Integration.mdx`:
- Line 55: The JSON example uses raw Flow expressions like
{!$Flow.CurrentDateTime} which produce invalid JSON; update both occurrences
(e.g., the "publishedAt" fields) to be string values by wrapping the expression
in TEXT() and quoting it so the JSON contains "publishedAt":
"TEXT({!$Flow.CurrentDateTime})" (apply the same change to the second timestamp
occurrence).

---

Nitpick comments:
In `@docs/Third-party-integrations/Intercom-Integration.mdx`:
- Line 50: Replace the hard-coded epoch values for timestamp fields (e.g., the
"publishedAt" property shown in the payload example) with dynamic placeholders
and a short note about accepted formats; specifically, update the "publishedAt"
occurrences to use a variable or template (e.g., {{timestamp}} or Date.now())
and add a parenthetical that the service accepts epoch milliseconds or ISO-8601
strings so readers know how to generate timestamps instead of copying a fixed
epoch.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 472ac1cb-08cb-4580-b56d-d7867d43b264

📥 Commits

Reviewing files that changed from the base of the PR and between af899dc and 81a03dd.

📒 Files selected for processing (4)
  • docs/Third-party-integrations/Freshdesk-Integration.mdx
  • docs/Third-party-integrations/HubSpot-Integration.mdx
  • docs/Third-party-integrations/Intercom-Integration.mdx
  • docs/Third-party-integrations/Salesforce-Integration.mdx

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
docs/Third-party-integrations/Freshdesk-Integration.mdx (1)

48-70: ⚠️ Potential issue | 🟡 Minor

Quote or clarify the timestamp placeholders in the JSON example.

Lines 50 and 60 contain unquoted Freshdesk placeholders ({{ticket.created_at_with_timestamp}}), which makes the JSON snippet syntactically invalid as displayed. If created_at_with_timestamp returns a Unix timestamp (number), the runtime JSON will be valid, but readers may be confused by the example.

Consider either quoting the placeholders (if Freshdesk returns ISO strings) or adding a brief note explaining that Freshdesk substitutes these with numeric timestamps before sending.

Option 1: Quote the placeholders
 {
-  "publishedAt": {{ticket.created_at_with_timestamp}},
+  "publishedAt": "{{ticket.created_at_with_timestamp}}",
   "units": [
     {
       "type": "email",
       "uid": "{{ticket.contact.email}}"
     }
   ],
   "goals": [
     {
       "name": "freshdesk_ticket_created",
-      "achievedAt": {{ticket.created_at_with_timestamp}},
+      "achievedAt": "{{ticket.created_at_with_timestamp}}",
       "properties": {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/Third-party-integrations/Freshdesk-Integration.mdx` around lines 48 -
70, The JSON example uses unquoted Freshdesk placeholders (e.g.,
{{ticket.created_at_with_timestamp}}) for the publishedAt and achievedAt fields
which renders the snippet syntactically ambiguous; update the example by either
quoting those placeholders (e.g., "publishedAt":
"{{ticket.created_at_with_timestamp}}", "achievedAt":
"{{ticket.created_at_with_timestamp}}") if Freshdesk returns ISO strings, or add
a one-line note next to the publishedAt/achievedAt examples clarifying that
Freshdesk substitutes those placeholders with numeric Unix timestamps so readers
know whether quotes are required; reference the JSON keys publishedAt and
goals[0].achievedAt and the placeholder {{ticket.created_at_with_timestamp}}
when making the change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@docs/Third-party-integrations/Freshdesk-Integration.mdx`:
- Around line 48-70: The JSON example uses unquoted Freshdesk placeholders
(e.g., {{ticket.created_at_with_timestamp}}) for the publishedAt and achievedAt
fields which renders the snippet syntactically ambiguous; update the example by
either quoting those placeholders (e.g., "publishedAt":
"{{ticket.created_at_with_timestamp}}", "achievedAt":
"{{ticket.created_at_with_timestamp}}") if Freshdesk returns ISO strings, or add
a one-line note next to the publishedAt/achievedAt examples clarifying that
Freshdesk substitutes those placeholders with numeric Unix timestamps so readers
know whether quotes are required; reference the JSON keys publishedAt and
goals[0].achievedAt and the placeholder {{ticket.created_at_with_timestamp}}
when making the change.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6d42a055-9565-42a0-bc77-f4385d228512

📥 Commits

Reviewing files that changed from the base of the PR and between 81a03dd and 2da86ee.

📒 Files selected for processing (2)
  • docs/Third-party-integrations/Freshdesk-Integration.mdx
  • docs/Third-party-integrations/HubSpot-Integration.mdx

HubSpot's built-in webhook action only supports flat key-value JSON,
which can't represent the nested units/goals structure the ABsmartly
Collector API requires. Replaced with a Custom Code Action using axios
to make a properly structured HTTP request with dynamic HubSpot
properties.
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
docs/Third-party-integrations/HubSpot-Integration.mdx (1)

141-145: Document the retry caveat if readers add try/catch.

HubSpot does retry custom code actions for axios 429/5xx failures, and the 20-second / 128 MB limits here are correct. But HubSpot’s own docs also note that, once you introduce a catch block, you need to re-throw the error for that retry behaviour to happen. A short sentence here would stop readers from adding logging and accidentally disabling retries. (developers.hubspot.com)

Suggested doc fix
 <Admonition type="info">
 Custom code actions must complete within <strong>20 seconds</strong> and use a maximum
 of <strong>128 MB</strong> of memory. Failed requests due to rate limiting (429) or
 server errors (5xx) are automatically retried by HubSpot for up to three days.
+If you wrap the request in a <code>try/catch</code> block, re-throw the error after
+logging it so HubSpot can still retry the action.
 </Admonition>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/Third-party-integrations/HubSpot-Integration.mdx` around lines 141 -
145, Update the Admonition that begins "Custom code actions must complete within
20 seconds..." to add a short caveat that if readers add a try/catch around
axios (or other) calls they must re-throw the error for HubSpot to retry on
429/5xx; explicitly mention "re-throw the caught error" so logging in a catch
block doesn't disable HubSpot's automatic retry behavior for axios 429 and 5xx
failures (per HubSpot docs).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/Third-party-integrations/HubSpot-Integration.mdx`:
- Around line 57-73: The sample handler exports.main currently uses
event.inputFields["email"] as the unit uid without validating it; add a guard at
the start of exports.main to check that email (or whichever chosen HubSpot
field) is present and non-empty and fail fast (throw an error or return a 4xx
response) before calling axios.put, so you never send a context with an invalid
uid; reference the exported function exports.main and the email variable and the
axios.put call to locate where to add this validation and the early
return/throw.

---

Nitpick comments:
In `@docs/Third-party-integrations/HubSpot-Integration.mdx`:
- Around line 141-145: Update the Admonition that begins "Custom code actions
must complete within 20 seconds..." to add a short caveat that if readers add a
try/catch around axios (or other) calls they must re-throw the error for HubSpot
to retry on 429/5xx; explicitly mention "re-throw the caught error" so logging
in a catch block doesn't disable HubSpot's automatic retry behavior for axios
429 and 5xx failures (per HubSpot docs).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 27770d9e-a3f5-477a-8cbc-08705610a4ec

📥 Commits

Reviewing files that changed from the base of the PR and between 2da86ee and 3975f23.

📒 Files selected for processing (1)
  • docs/Third-party-integrations/HubSpot-Integration.mdx

joalves added 2 commits March 9, 2026 14:33
Use hs_enrollment_trigger property to determine which trigger enrolled
the record and map it to the appropriate goal name. A single workflow
can now handle multiple triggers within the same object type.
- Quote Freshdesk timestamp placeholders for valid JSON display
- Wrap Salesforce Flow expressions in TEXT() and quote them
- Replace hardcoded Intercom timestamps with dynamic placeholders
- Add try/catch retry caveat to HubSpot admonition
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
docs/Third-party-integrations/HubSpot-Integration.mdx (1)

98-102: Properties may be undefined if fields are not included in the workflow.

If the workflow doesn't include dealname, dealstage, or pipeline as input properties, these will be undefined in the payload. This is likely intentional, but it may be worth noting in the documentation that users should ensure all referenced properties are added in Step 2.5.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/Third-party-integrations/HubSpot-Integration.mdx` around lines 98 - 102,
The doc snippet assigns properties (deal_name, deal_stage, pipeline) from
event.inputFields["dealname"], event.inputFields["dealstage"], and
event.inputFields["pipeline"] but doesn't warn these can be undefined if those
inputFields aren't included in the workflow; update the documentation around the
properties block to note that deal_name / deal_stage / pipeline may be undefined
unless the corresponding input fields are added in the workflow (reference Step
2.5), and advise users to ensure those fields are included or to provide
fallback handling when consuming these properties.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@docs/Third-party-integrations/HubSpot-Integration.mdx`:
- Around line 98-102: The doc snippet assigns properties (deal_name, deal_stage,
pipeline) from event.inputFields["dealname"], event.inputFields["dealstage"],
and event.inputFields["pipeline"] but doesn't warn these can be undefined if
those inputFields aren't included in the workflow; update the documentation
around the properties block to note that deal_name / deal_stage / pipeline may
be undefined unless the corresponding input fields are added in the workflow
(reference Step 2.5), and advise users to ensure those fields are included or to
provide fallback handling when consuming these properties.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 2b964932-f9a1-43d9-aa8f-a9fb95b31748

📥 Commits

Reviewing files that changed from the base of the PR and between 3975f23 and 7bdbfd4.

📒 Files selected for processing (1)
  • docs/Third-party-integrations/HubSpot-Integration.mdx

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
docs/Third-party-integrations/Intercom-Integration.mdx (1)

37-44: Add Content-Type header to the table for consistency.

The headers table doesn't include Content-Type, though Line 34 mentions setting Content-Type to JSON in the Intercom UI. For consistency with the other integration docs and explicit documentation, consider adding it to the table.

📝 Suggested addition
 | `X-Agent` | `intercom-webhook` |
+| `Content-Type` | `application/json` |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/Third-party-integrations/Intercom-Integration.mdx` around lines 37 - 44,
The headers table is missing the Content-Type header; update the table in
Intercom-Integration.mdx next to the existing rows (e.g., `X-API-Key`,
`X-Application`, `X-Environment`, `X-Agent`) by adding a `Content-Type` row with
the value `application/json` so the doc matches the mention on Line 34 and other
integration docs.
docs/Third-party-integrations/Freshdesk-Integration.mdx (1)

35-43: Clarify authentication configuration.

Line 35 instructs users to toggle on "Requires authentication" and enter the API key, but lines 38-42 also add X-API-Key as a custom header. This may result in duplicate authentication or confusion. Please clarify whether both are required or if users should choose one approach.

📝 Suggested clarification
-   - **Requires authentication**: Toggle on, and enter your ABsmartly SDK API Key.
+   - **Requires authentication**: Leave off (authentication is handled via the `X-API-Key` custom header below).

Alternatively, if Freshdesk's "Requires authentication" uses a different mechanism (e.g., Basic Auth), clarify that ABsmartly uses header-based authentication instead.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/Third-party-integrations/Freshdesk-Integration.mdx` around lines 35 -
43, The doc currently tells users to both toggle "Requires authentication" and
also add an X-API-Key custom header (the "Requires authentication" toggle and
the Custom Headers block containing "X-API-Key: YOUR_ABSMARTLY_API_KEY"), which
is confusing; update the text to clarify that users should either enable
Freshdesk's "Requires authentication" and enter the ABsmartly API key there OR
leave that off and add the API key via the Custom Headers (X-API-Key) — and add
a note explaining that if Freshdesk's "Requires authentication" implements Basic
Auth, ABsmartly uses header-based API key auth so the header approach is
required instead. Ensure the doc explicitly states which method Freshdesk will
use and give the single recommended option for ABsmartly (header-based
X-API-Key) if applicable.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/Third-party-integrations/HubSpot-Integration.mdx`:
- Around line 84-85: Update the Freshdesk integration example to call the
standard ABsmartly Collector API endpoint with a PUT to /v1/context instead of
POST to /v1/context/publish; locate the axios call (e.g., the axios.post(...) or
axios.post(".../v1/context/publish")) in the Freshdesk example and change it to
use axios.put with the URL "https://your-subdomain.absmartly.io/v1/context" so
it matches the HubSpot/Salesforce/Intercom examples and the Collector API
specification.

In `@docs/Third-party-integrations/Intercom-Integration.mdx`:
- Around line 48-69: The JSON example uses a non-existent Series webhook
attribute "{timestamp_ms}" for publishedAt and achievedAt; update those fields
to use a valid Intercom attribute such as "{created_at}" (or another configured
Series attribute from the attribute picker) and document that "{created_at}" is
Unix seconds so callers must convert/format it as needed; specifically change
the publishedAt and goals[].achievedAt placeholders and add a brief note that
the attribute must be selected in the Intercom Series webhook picker and
converted to milliseconds/ISO if your integration expects that format.

---

Nitpick comments:
In `@docs/Third-party-integrations/Freshdesk-Integration.mdx`:
- Around line 35-43: The doc currently tells users to both toggle "Requires
authentication" and also add an X-API-Key custom header (the "Requires
authentication" toggle and the Custom Headers block containing "X-API-Key:
YOUR_ABSMARTLY_API_KEY"), which is confusing; update the text to clarify that
users should either enable Freshdesk's "Requires authentication" and enter the
ABsmartly API key there OR leave that off and add the API key via the Custom
Headers (X-API-Key) — and add a note explaining that if Freshdesk's "Requires
authentication" implements Basic Auth, ABsmartly uses header-based API key auth
so the header approach is required instead. Ensure the doc explicitly states
which method Freshdesk will use and give the single recommended option for
ABsmartly (header-based X-API-Key) if applicable.

In `@docs/Third-party-integrations/Intercom-Integration.mdx`:
- Around line 37-44: The headers table is missing the Content-Type header;
update the table in Intercom-Integration.mdx next to the existing rows (e.g.,
`X-API-Key`, `X-Application`, `X-Environment`, `X-Agent`) by adding a
`Content-Type` row with the value `application/json` so the doc matches the
mention on Line 34 and other integration docs.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c710cefe-0a3b-4dc0-834e-841cd08b4acd

📥 Commits

Reviewing files that changed from the base of the PR and between 7bdbfd4 and 533be9d.

📒 Files selected for processing (4)
  • docs/Third-party-integrations/Freshdesk-Integration.mdx
  • docs/Third-party-integrations/HubSpot-Integration.mdx
  • docs/Third-party-integrations/Intercom-Integration.mdx
  • docs/Third-party-integrations/Salesforce-Integration.mdx

Comment on lines +84 to +85
await axios.put(
"https://your-subdomain.absmartly.io/v1/context",
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

ABsmartly Collector API context endpoint PUT vs POST

💡 Result:

In the ABsmartly Collector API, /context supports both POST and PUT, but for different operations (not interchangeable):

  • POST /context = “Create a Context” (creates a new context and returns variant assignments for the provided units). [1]
  • PUT /context = “Publish Experiment Events” (publishes exposures, goals, and attributes for a context). [2]
    • For multiple contexts in one call, use PUT /context/batch. [2]

So: use POST to get/initialize a context with assignments; use PUT later to send tracking/events for that context. [1][2]


🏁 Script executed:

find . -type f -name "*.mdx" -o -name "*.md" | xargs grep -l "Freshdesk\|Salesforce\|Intercom" | head -20

Repository: absmartly/docs

Length of output: 716


🏁 Script executed:

find . -path "*/Third-party-integrations/*" -type f \( -name "*.mdx" -o -name "*.md" \) | sort

Repository: absmartly/docs

Length of output: 683


🏁 Script executed:

grep -n "axios\|fetch\|POST\|PUT\|/context\|/v1" ./docs/Third-party-integrations/Freshdesk-Integration.mdx | head -30

Repository: absmartly/docs

Length of output: 251


🏁 Script executed:

grep -n "axios\|fetch\|POST\|PUT\|/context\|/v1" ./docs/Third-party-integrations/Salesforce-Integration.mdx | head -30

Repository: absmartly/docs

Length of output: 222


🏁 Script executed:

grep -n "axios\|fetch\|POST\|PUT\|/context\|/v1" ./docs/Third-party-integrations/Intercom-Integration.mdx | head -30

Repository: absmartly/docs

Length of output: 228


Align Freshdesk integration to use standard endpoint.

Freshdesk currently uses POST to /v1/context/publish, whilst HubSpot, Salesforce, and Intercom all use PUT to /v1/context. According to the ABsmartly Collector API, the standard endpoint for publishing experiment events is PUT /context, not POST /context/publish. Update the Freshdesk integration to use PUT to /v1/context for consistency with the other integration examples and the API specification.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/Third-party-integrations/HubSpot-Integration.mdx` around lines 84 - 85,
Update the Freshdesk integration example to call the standard ABsmartly
Collector API endpoint with a PUT to /v1/context instead of POST to
/v1/context/publish; locate the axios call (e.g., the axios.post(...) or
axios.post(".../v1/context/publish")) in the Freshdesk example and change it to
use axios.put with the URL "https://your-subdomain.absmartly.io/v1/context" so
it matches the HubSpot/Salesforce/Intercom examples and the Collector API
specification.

Comment on lines +48 to +69
```json
{
"publishedAt": "{timestamp_ms}",
"units": [
{
"type": "user_id",
"uid": "{user_id}"
}
],
"goals": [
{
"name": "intercom_conversation_started",
"achievedAt": "{timestamp_ms}",
"properties": {
"user_email": "{email}",
"user_name": "{name}",
"company": "{company.name}"
}
}
]
}
```
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🌐 Web query:

Intercom Series webhook timestamp_ms attribute

💡 Result:

  • Series webhooks: there isn’t a built-in timestamp_ms attribute that Intercom automatically adds to a Series webhook payload. Series webhooks send whatever key/value pairs you configure in the webhook block (typically Intercom attributes you pick from the {...} menu). [1]
  • Intercom “Developer Hub” webhooks (API webhooks): Intercom’s webhook notification envelopes use fields like created_at, first_sent_at, etc., which are Unix timestamps in seconds (not milliseconds) in the examples shown. [2]
  • Where timestamp_ms does exist in Intercom docs: in the Fin Agent webhook context, message.timestamp_ms is an ISO-8601 datetime with millisecond precision, and is noted as only present in certain webhook event responses (e.g. fin_replied). [3]

Sources:
[1] (intercom.com)
[2] (developers.intercom.com)
[3] (developers.intercom.com)

Citations:


Update Intercom timestamp placeholder to a valid Series webhook attribute.

The payload uses {timestamp_ms} for both publishedAt and achievedAt, but this is not a built-in Intercom Series webhook attribute. Intercom Series webhooks only transmit attributes you explicitly configure from the attribute picker {...}, and timestamp_ms is not available in the standard Series webhook editor. Standard Intercom webhook timestamps use created_at (Unix seconds). Either use a valid Intercom attribute name (e.g., {created_at} with appropriate format handling) or clarify in the documentation which specific Intercom attribute should be selected for this field.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/Third-party-integrations/Intercom-Integration.mdx` around lines 48 - 69,
The JSON example uses a non-existent Series webhook attribute "{timestamp_ms}"
for publishedAt and achievedAt; update those fields to use a valid Intercom
attribute such as "{created_at}" (or another configured Series attribute from
the attribute picker) and document that "{created_at}" is Unix seconds so
callers must convert/format it as needed; specifically change the publishedAt
and goals[].achievedAt placeholders and add a brief note that the attribute must
be selected in the Intercom Series webhook picker and converted to
milliseconds/ISO if your integration expects that format.

@chris-absmartly chris-absmartly merged commit a283a39 into master Mar 10, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants