177 Commits
Author SHA1 Message Date
Eric f145c778b8 Website: log number of android enterprise requests in the past minute (#50780)
Related to: https://github.com/fleetdm/fleet/issues/49212

Changes:
- Updated the custom hook to create `sails.androidProxyApiRequestCount`,
and to log and reset the value every minute
- Updated android proxy endpoints to increment
`sails.androidProxyApiRequestCount` every time a request to the Android
management API is sent

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Monitoring**
* Added comprehensive tracking for Android Management API requests
across enrollment, enterprise, device, application, policy, and command
operations.
* Added periodic request-count logging and automatic resets when Android
Enterprise credentials are configured.
* Improved reporting alignment with minute-based API limits while
keeping logs quiet during periods without requests.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-07 11:58:35 -05:00
Eric 1563aeb70c Website: improve speed of deliver-talk-to-us-form-submission action (#50593)
Changes:
- Updated the model used in the prompt helper calls in the
deliver-talk-to-us-form-submission action and the get-enriched helper to
improve the speed of routing users booking a demo.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Improvements**
* Updated location and address enrichment to use an updated language
model, improving the processing of submitted information while
preserving existing form behavior.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-05 11:42:13 -05:00
Eric 85692f8238 Website: set historical event source (#50546)
Changes:
- Updated the website's createHistoricalEvent helper to accept an
eventSource input that is used to set the historical event source on
created records.
- Updated places where we create historical events to set a historical
event source
- Updated the accepted contact sources values in the receive-from-clay
webhook
- Updated the deliver-gitops-workshop-request action to log a warning
when a campaign member record cannot be created

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **Improvements**
- Improved activity tracking for newsletter subscriptions, signups,
contact forms, workshop requests, webinars, gated content, and page
views.
- Added clearer source details to records for more accurate attribution.
- Expanded support for website, webinar, event, LinkedIn, prospecting,
and GitHub activity sources.
- **Bug Fixes**
- Workshop requests now continue successfully if campaign updates
encounter an error.
- Corrected warning messages and preserved relevant submission details
for troubleshooting.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-04 18:26:14 -05:00
Allen HouchinsandEric 19af21dd1a Upgrade query-generator SQL step to Claude Sonnet 5 (#49187)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** N/A

## What this does

The `/query-generator` page's osquery-SQL-generation step
([get-llm-generated-sql.js](website/api/controllers/query-generator/get-llm-generated-sql.js))
was on `claude-sonnet-4-6`, which is now one generation behind. This PR:

- Bumps that call to `claude-sonnet-5`. The schema-filtration step stays
on `claude-haiku-4-5`, which is already the latest Haiku release, so no
change needed there.
- Adds `effort` support to the shared [`ai.prompt`
helper](website/api/helpers/ai/prompt.js), forwarded as
`output_config.effort` on Anthropic requests, and sets it to `"low"` for
the SQL-generation call. Effort controls how much the model deliberates
(and how many tokens/how much latency that costs). `"low"` was chosen
because the Haiku pre-filtering step already narrows the osquery schema
down to relevant tables, so the Sonnet step isn't starting from scratch
and doesn't need to spend much effort re-deriving that context.
- Bumps `max_tokens` in the Anthropic branch of the helper from 4096 to
8192. Claude Sonnet 5 turns on adaptive thinking by default when the
`thinking` param is omitted (which this helper does), and `max_tokens`
is a hard cap on *total* output including thinking tokens — at 4096
there was a real risk of thinking tokens eating into the budget and
truncating the JSON response the SQL step needs to return.
- **Fixes a pre-existing bug found while making the above changes:** the
`sqlReport` call passed the system prompt as a bare object-shorthand key
named `systemPromptForQueryGeneration`, but the `ai.prompt` helper's
declared input is `systemPrompt`. Sails silently drops unrecognized keys
passed to `.with(...)`, so the "Return ONLY a raw JSON object..." system
prompt was never actually reaching the model for this call. This has
been broken since the query generator was switched to Anthropic
(`f7c20c4731`); the sibling `filteredTables` call above it was
unaffected since it passes `systemPrompt` positionally. Now fixed to
`systemPrompt: systemPromptForQueryGeneration`.

## Why

Claude Sonnet 5 follows structured/constrained instructions (don't alias
tables, use `LIKE` with wildcards, only reference documented columns,
etc.) more literally than 4.6, which should make the generated SQL more
reliable. It's priced the same or cheaper than 4.6 during the current
introductory period.

## Trade-offs called out for review

- Thinking being on by default adds some latency versus the old
(thinking-off) behavior on 4.6. This call is not currently streamed
(`sails.helpers.http.post`, single blocking call over a socket), so any
added thinking time is invisible wait time for the user rather than a
visible "thinking" indicator. `effort: "low"` should keep this modest,
but worth confirming with a manual QA pass on a few representative
questions before merging.
- Only the SQL-generation call was migrated. The schema-filtration call
also runs on an Anthropic model, but Haiku 4.5 doesn't support
`output_config.effort` (added `effort` is a no-op if passed to it), so
it was left as-is.

# Checklist for submitter

If some of the following don't apply, delete the relevant line.

- [ ] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
See [Changes
files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files)
for more information.

- [x] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented (using placeholders for values in statements), JS
inline code is prevented especially for url redirects, and untrusted
data interpolated into shell scripts/commands is validated against shell
metacharacters.
- [x] Timeouts are implemented and retries are limited to avoid infinite
loops
- [ ] If paths of existing endpoints are modified without backwards
compatibility, checked the frontend/CLI for any necessary changes

## Testing

- [ ] Added/updated automated tests
- [ ] Where appropriate, [automated tests simulate multiple hosts and
test for host
isolation](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/reference/patterns-backend.md#unit-testing)
(updates to one hosts's records do not affect another)

- [ ] QA'd all new/changed functionality manually


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Improvements**
  * Improved AI-generated SQL responses with an updated language model.
  * Added adaptive effort controls for supported AI requests.
* Increased response capacity to support more detailed generated
results.
* Improved handling of AI responses to provide more reliable results
when content includes different response formats.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Eric <eashaw@sailsjs.com>
2026-08-03 21:39:40 -05:00
Eric ba7168f54b Website: update contact source (#50356)
Changes:
- Updated the contact source used for contacts created by the
deliver-webinar-access-request action (Webinar » Website - Gated video)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **Bug Fixes**
- Webinar access requests are now categorized as “Website - Gated video”
in Salesforce.
- Updated contact and account records use the new source label
consistently.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-31 17:20:40 -05:00
Eric 58642183c6 Website: update contact source for workshop requests (#50072)
Changes:
- Updated the contact source used for contacts created from workshop
requests

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Bug Fixes**
* Workshop requests are now correctly identified as “Website - Workshop
request” in CRM records, improving source tracking and reporting.
* Workshop request contacts are treated as form-based, ensuring the most
recent campaign member status is set to **Registered**.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-30 08:13:01 -05:00
Eric f25b1ec58d Website: update territory routing for talk to us submissions (#50101)
https://github.com/fleetdm/confidential/issues/16947

Changes:
- Updated the get-territory-user-id helper to accept `website` and
`numberOfEmployees` inputs
- Updated the deliver-talk-to-us-form-submission action to send website
and number of employees to the get-territory-user-id helper, and updated
the `bookingUrlByUserId` dictionary.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Improved territory routing for “Talk to us” submissions by using
employee count, city, and website details.
* Updated routing logic to direct submissions to the appropriate
Calendly booking link.
* Preserved existing validation and error handling for incomplete or
unexpected territory lookup results.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-29 13:48:08 -05:00
Eric 632b4d924b Website: use shared Google API auth client in android proxy endpoints. (#47810)
Closes: https://github.com/fleetdm/fleet/issues/46496

Changes:
- Updated the website's custom hook to create a Google API auth client
and make it available at `sails.googleAuthClient`
- Updated Android proxy endpoints to use the shared Google API auth
client.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Refactor**
* Optimized Google API authentication handling for Android management
features to improve system performance and reliability.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-20 18:38:55 -05:00
Sam Pfluger d514466833 Add contactSource "Event - 2026-07 PSU MacAdmins" (#49323)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added support for contacts associated with the “Event - 2026-07 PSU
MacAdmins” source.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-15 00:23:24 -05:00
Eric a7a98d6c6a Website: update get-enriched helper (#47688)
Changes:
- Updated the get-enriched helper to not use deleted locations returned
from Coresignal when including information about a company's
headquarters.
2026-06-16 13:25:46 -05:00
Eric 6f8251cadd Website: Update get-territory-user-id helper (#47630)
Changes:
- Updated the get-territory-user-id helper to not require a country
input, but to throw an error if one is not provided. This is done to
replace the default usageError that is thrown by helpers with an error
that provides more information about the provided inputs

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Refactor**
* Improved input validation error handling for territory lookups to
provide clearer error messages during runtime.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-15 15:03:28 -05:00
Eric fee63bba51 Website: Update user routing in deliver-talk-to-us-submission action (#47457)
Related to: https://github.com/fleetdm/confidential/issues/16303

Changes:
- Added a new Salesforce helper: getTerritoryUserId, a helper that
returns the ID of the Salesforce user associated with a provided
location (state, country, city)
- Updated the deliver-talk-to-us-form-submission action to send ICP
users to one of five different Calendly events based on their company's
headquarters location.
- Updated the get-enriched helper to include company headquarters
information when enriching a user.
2026-06-11 16:37:37 -05:00
johnjeremiah 45a7ad25e0 Add Organic AI referrer attribution (#46182)
Detect AI/LLM referrers and classify them as an "Organic AI (AI)"
source. Adds a REFERRER_DOMAINS_FOR_ORGANIC_AI list and branching logic
to set attributionDetails.sourceChannelDetails and
attributionDetails.campaign based on the referring AI platform (ChatGPT,
Claude, Gemini, or Other) in
website/api/helpers/salesforce/update-or-create-contact-and-account.js.

<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** 
resolves fleetdm/confidential#16034
 



<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Improved contact attribution: traffic from AI/LLM platforms (ChatGPT,
Claude, Gemini, etc.) is now labeled "Organic AI (AI)" and assigned
platform-specific default campaigns.
* Refined organic search detection to better identify Bing search
referrals.
* Other non-digital/non-event referrers now default to "Web referral
(WR)".

<!-- review_stack_entry_start -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/46182?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)

<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-29 18:38:59 -04:00
johnjeremiahandEric cc2cb0a204 Add mostRecentCampaign to event records (#45750)
Following the pattern we have for Clay updating historical events with
the campaign name, this updates the historical event to include the
campaign name for website events.

After the contact is created/updated, we now include the campaign name
as a parameter for the historical event to update/populate the existing
field on the sfdc historical event object.




<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Historical events for signups, newsletter subscriptions, contact/quote
requests, whitepaper downloads, workshop requests, and page views now
include campaign association to improve marketing analytics.
* **Bug Fixes / Reliability**
* Webhooks now fall back to the most recent campaign when none is
provided.
* **Chores**
* Backend responses now expose a mostRecentCampaign field to support
campaign attribution.

<!-- review_stack_entry_start -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/45750?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)

<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Eric <eashaw@sailsjs.com>
2026-05-22 22:38:29 -04:00
365f80558c using attributionDetails to store referrer (#46096)
Not seeing referrer data in SFDC, making this code consistent to
troubleshoot


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Refactor**
* Standardized referrer attribution so referrer URLs are consistently
captured from attribution data and applied for both new and existing
contacts in the Salesforce integration, improving accuracy of marketing
attribution and recent referrer tracking.

<!-- review_stack_entry_start -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/46096?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)

<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
Co-authored-by: Eric <eashaw@sailsjs.com>
2026-05-22 22:37:33 -04:00
johnjeremiah 66f5b46903 Improve referrer matching and add domains (#45803)
A small bug in our attribution logic. R

Replace exact equality checks with startsWith() (via Array.some). 

The classification uses Array.includes(), which requires an **exact
string match**.
The lists contain bare root domains:  for example

> 'https://www.linkedin.com/'
> 'https://www.reddit.com/'
> 'https://x.com/'

The stored referrer is always the full URL of the specific page the
visitor came from, including path.

So - if an Organic Social URL was https://www.linkedin.com/feed/ 
It does not equal https://www.linkedin.com/ 
and 
The match fails, and the visit falls through to Web Referral. (this
would be incorrect)


Also - Expand search engine list (generalized Google domain, added
Startpage, Brave, Kagi, Yandex entries) and significantly extend social
referrer list (LinkedIn variants, lnkd.in, Hacker News, X/Twitter
variants, Facebook mobile/l.facebook, Instagram, Threads, Bsky, Mastodon
instances, YouTube, Reddit variants, Pinterest, Quora, etc.).

These changes make Organic search/social detection more accurate across
country TLDs, subdomains and shortened links.




<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Bug Fixes**
* Improved Salesforce traffic attribution by expanding organic referrer
allowlists and enhancing matching to better detect organic search and
social sources.
* Normalized referrer values when absent or malformed to prevent
misclassification, yielding more accurate traffic categorization and
attribution reporting.

<!-- review_stack_entry_start -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/45803?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)

<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-22 09:00:16 -04:00
johnjeremiah 04e0befd79 Populate referrer fields from marketing cookie (#45807)
Set Salesforce contact referrer fields from
marketingAttributionCookie.referrer. Adds Source_referrer_url__c and
Most_recent_referrer_url__c assignments in the initial attribution block
and an additional Most_recent_referrer_url__c assignment in the later
block so referrer data is persisted when creating/updating contacts.




<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Enhanced Salesforce integration with improved contact attribution
tracking. Referrer information is now automatically captured and stored
in designated attribution fields for both newly created and updated
contact records, enabling more comprehensive tracking of customer
acquisition sources and marketing engagement paths throughout the user
journey.

<!-- review_stack_entry_start -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/45807?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)

<!-- review_stack_entry_end -->

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-22 08:18:47 -04:00
johnjeremiah e8ff0b1a42 Set campaign member status for form-based contacts (#45427)
Add a list of form-based contact sources and set
Most_recent_campaign_member_status__c to 'Registered' when contactSource
matches any of them. This marks contacts originating from website
contact forms, webinars, gated docs, and related sources as registered.
The change includes an eslint-disable-line camelcase comment for the
Salesforce field name.




<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Enhanced contact registration tracking to automatically set
appropriate campaign status when contacts are registered through
form-based sources such as webinars.

<!-- review_stack_entry_start -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/45427)

<!-- review_stack_entry_end -->

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-18 10:52:39 -04:00
Sam Pfluger 8b64d27f35 Add "Requested Fleet SWAG" to intent signals (#45443)
@eashaw, I also updated the intent signals for the receive-from-clay.js
to match create-historical-event.js



<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

## Release Notes

* **Improvements**
* Expanded system support for tracking additional customer interaction
types, including training attendance, meetings, forms, account updates,
and marketing activities.
  * Added new event type for swag requests.

<!-- review_stack_entry_start -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/45443)

<!-- review_stack_entry_end -->

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-13 19:52:28 -05:00
Eric d55b60d320 Website: update CRM helper (#44081)
Closes: https://github.com/fleetdm/fleet/issues/44066

Changes:
- updated the `update-or-create-contact-and-account` helper to:
- Save potential duplicate contacts with placeholder name values (`?
?`).
- Use the firstName and lastName values returned by the get-enriched
helper if a name is not provided.
   - Update contacts with placeholder name values if a name is provided.
 - Removed a domain from the lists of banned email domains.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Enhanced Salesforce contact creation with automatic name derivation
from enrichment data.
* Improved duplicate detection allowing new contacts to be created with
flexible matching rules.
* Automatic replacement of placeholder names with verified data during
contact updates.

* **Chores**
  * Updated email domain blocklists configuration.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-04-23 15:26:02 -05:00
johnjeremiah 087ba3ff80 Contact source change for webinar and gated doc (#43838)
Updating the contact source value for webinars and gated docs to match
the new sfdc values



<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Bug Fixes**
* Corrected CRM contact-source classification so webinar access requests
and whitepaper downloads are categorized separately from general contact
form submissions.

* **Chores**
* Expanded accepted contact-source values in the CRM integration to
include distinct labels for webinars and gated documents.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-04-21 17:03:41 -05:00
EricandCopilot be14f7c10d Website: Add webinar article template page. (#43627)
Changes:
- Added support for a new article category: `webinar`.
- Added a template page for webinar articles.
- Added an additional route for webinar articles that users are taken to
to watch the webinar recording.
- Added `deliver-webinar-access-request`, an action that updates CRM
records when users fill out the form on the webinar template page.
- Updated the accepted `intentSignal` values in the
create-historical-event helper.
- Added an article for the "Beyond the hype, practical AI for device
management" webinar.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Public webinar pages (/webinars/:slug and /watch) with optional
embedded video and a new page template, script, and styles.
* Sidebar signup form (first name, last name, work email) with prefill
for signed-in users and improved scroll behavior.
* POST API to request webinar access: validates email domain, records a
webinar-request event, triggers background CRM sync, and returns a watch
view on success.
* Static-site build now recognizes webinar articles and enforces
embedded-video URL validation.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-16 09:14:28 -05:00
johnjeremiah 27bfa6b20e Adding cpc for paid search (#43274)
Adding the code cpc - for paid search so that we get attribution
correct.
2026-04-10 09:18:54 -04:00
f47c0e5670 Add event UTM medium codes to source channel attribution (#43150)
## Summary

- Adds 9 event-related UTM medium codes (`mc`, `rc`, `le`, `ec`, `fe`,
`pe`, `se`, `wh`, `ws`) to the marketing attribution logic in
`update-or-create-contact-and-account.js`
- Maps these codes to the `'Event'` source channel, following the same
pattern used for Digital and Organic channels
- Adds friendly name mappings for each event code (e.g., `mc` → "Major
conference (MC)", `wh` → "Fleet hosted webinar (WH)")

### UTM Medium → Source Channel Mapping

| Code | Description | Source Channel |
|------|-------------|---------------|
| `mc` | Major conference | Event |
| `rc` | Regional conference | Event |
| `le` | Local event/meetup | Event |
| `ec` | Executive community | Event |
| `fe` | Field event/workshop | Event |
| `pe` | Partner event | Event |
| `se` | Speaking engagement | Event |
| `wh` | Fleet hosted webinar | Event |
| `ws` | Sponsored webinar | Event |

### Changes

The source channel determination logic now has three branches:
1. **Digital** — `ps`, `so`, `pm`, `cs`, `em` (unchanged)
2. **Event** — `mc`, `rc`, `le`, `ec`, `fe`, `pe`, `se`, `wh`, `ws`
(new)
3. **Organic** — everything else / no UTM medium (unchanged, remains the
default fallback)

Built for [John
Jeremiah](https://fleetdm.slack.com/archives/D0AGMBRKRR9/p1775584746996929)
by [Kilo for Slack](https://kilo.ai/features/slack-integration)

---------

Co-authored-by: kiloconnect[bot] <240665456+kiloconnect[bot]@users.noreply.github.com>
Co-authored-by: Eric <eashaw@sailsjs.com>
2026-04-07 18:11:38 -05:00
Eric eed4fe1357 Website: Update CRM helper to set values on account (#42989)
Closes: https://github.com/fleetdm/confidential/issues/14516

Changes:
- Updated update-or-create-contact-and-account to set the number of
hosts on account records if it is provided.
- Updated the create-quote action to send details about the number of
hosts to the update-or-create-contact-and-account helper
2026-04-03 12:30:21 -05:00
Eric addabc28bb Website: Update self-service Fleet premium license form (#42488)
Closes: https://github.com/fleetdm/confidential/issues/14516 

Changes:
- Added inputs for individual platforms to the license form on
/new-license
- Updated contact descriptions set by the receive-from-stripe webhook
- Updated supported intentSignal values in the createHistoricalEvent
helper
- Updated the create-quote action to update contact descriptions and
create a historical event
2026-03-26 14:23:05 -05:00
Eric 7eb07b4d87 Website: Update accepted contactSource values in CRM helpers. (#41808)
Changes:
- Updated the accepted `contactSource` values in the
updateOrCreateContactAndAccount and
updateOrCreateContactAndAccountAndCreateLead helpers
2026-03-20 10:06:31 -05:00
Eric 80eec816b7 Website: Update descriptions set by CRM helper (#41917)
Closes: https://github.com/fleetdm/fleet/issues/41797

Changes:
- Updated the `updateOrCreateContactAndAccount` helper to include a date
timestamp (YYYY-MM-DD) and prepend updates to contact descriptions to
the existing description value.
2026-03-18 17:28:23 -05:00
05f2daad4b Add 'Registered for a conference' intent signal (#41919)
## Summary

- Adds `'Registered for a conference'` to the `intentSignal` `isIn`
array in three files:
- `website/api/helpers/salesforce/create-historical-event.js` — between
`'Signed up for Fleet event'` and `'Engaged with Fleetie at event'`
- `website/api/controllers/webhooks/receive-from-clay.js` — between
`'Signed up for Fleet event'` and `'Engaged with Fleetie at event'`
-
`website/api/helpers/salesforce/update-or-create-contact-and-account.js`
— added to the `isIn` array
- This replaces the incorrect approach in PR #41918, which added the
signal to the handbook markdown table instead of the code where intent
signals are validated.

---

Built for [Sam
Pfluger](https://fleetdm.slack.com/archives/D0AF8QFBVHB/p1773789580384389?thread_ts=1773788922.891409&cid=D0AF8QFBVHB)
by [Kilo for Slack](https://kilo.ai/features/slack-integration)

---------

Co-authored-by: kiloconnect[bot] <240665456+kiloconnect[bot]@users.noreply.github.com>
Co-authored-by: Sam Pfluger <108141731+Sampfluger88@users.noreply.github.com>
2026-03-18 08:21:50 -05:00
Eric b4cd1d0425 Website: Update accepted intentSignal values in createHistoricalEvent helper (#41884)
Changes:
- updated the accepted `intentSignal` values in the
createHistoricalEvent helper
2026-03-17 14:32:11 -05:00
f7c20c4731 Switch query generator to use Anthropic Sonnet on the backend (#41521)
## Summary

Closes #41466

- Adds Anthropic Claude API support to the `prompt.js` AI helper,
detecting `claude-*` model names and routing to the Anthropic Messages
API (`https://api.anthropic.com/v1/messages`) with proper authentication
headers
- Switches both LLM calls in the query generator
(`get-llm-generated-sql.js`) from OpenAI models
(`gpt-4o-mini-2024-07-18` for schema filtration, `o3-mini-2025-01-31`
for SQL generation) to `claude-sonnet-4-6-20260218`
- Adds `anthropicSecret` config placeholder in `custom.js` (set via
`sails_custom__anthropicSecret` env var in production)
- Updates the query generator UI to reference "Anthropic" instead of
"OpenAI"

### Changes

| File | What changed |
|------|-------------|
| `website/api/helpers/ai/prompt.js` | Added Anthropic API branch
alongside existing OpenAI logic; system prompts use Anthropic's
top-level `system` parameter |
| `website/api/controllers/query-generator/get-llm-generated-sql.js` |
Both model references changed to `claude-sonnet-4-6-20260218` |
| `website/config/custom.js` | Added `anthropicSecret` config
placeholder |
| `website/views/pages/admin/query-generator.ejs` | Updated copy from
"OpenAI" to "Anthropic" |

### Deployment notes

The `sails_custom__anthropicSecret` environment variable must be set
with an Anthropic API key before deploying this change.

---

Built for
[mikermcneil](https://fleetdm.slack.com/archives/D0AFASLRHNU/p1773278374183489?thread_ts=1773271495.702919&cid=D0AFASLRHNU)
by [Kilo for Slack](https://kilo.ai/features/slack-integration)

---------

Co-authored-by: kiloconnect[bot] <240665456+kiloconnect[bot]@users.noreply.github.com>
Co-authored-by: Eric <eashaw@sailsjs.com>
2026-03-16 11:48:33 -05:00
Eric 46bc7dc880 Website: add whitepaper article template page (#41405)
Changes:
- Updated `build-static-content` to support a new article category:
`whitepaper`
- Added a new article template page: `basic-whitepaper.ejs`.
- Added `deliver-whitepaper-download-request`, an action that
creates/updates a contact and account in the CRM and creates a
historical event when a user submits a form to download a whitepaper.
- Updated the "News" link in the website's header navigation to be
"Resources / Blog", and changed the link to /articles
- Added a link to the whitepapers category page (/whitepapers) to the
side bar navigation on article category pages
- Added a whitepaper article: "Modern endpoint management: Managing
devices as code"
2026-03-11 12:37:23 -05:00
Eric 68617804b2 Website: add script to report Render trial usage (#40830)
Closes: https://github.com/fleetdm/confidential/issues/13687

Changes:
- Added a new script: `send-trial-usage-information-to-crm`, A script
that reports the latest usage information for Render trial Fleet
instances created and assigned to users by the website.
- Updated the updateOrCreateContactAndAccount helper to accept a
`trialInstanceUsageDetails` input and set provided values on contact
records.
2026-03-03 12:10:28 -06:00
Eric 0693041f13 Website: Update attribution cookie (#40532)
Closes: https://github.com/fleetdm/confidential/issues/14391

Changes:
- Updated the attribution cookie set in the website's custom hook to
include the value of a user's `gclid` query parameter (if it is set)
- Updated the updateOrCreateContactAndAccount helper to set this value
on created Contact records.
2026-02-25 15:18:14 -06:00
Eric be54839d3c Website: upgrade jsforce dependency (#39999)
Changes:
- upgraded the version of jsforce used by the website (`1.11.1` »
`3.10.14`)
- Updated the error handling in the updateOrCreateContactAndAccount
helper to work with the updated version of jsforce
2026-02-17 17:17:24 -06:00
Eric 9cb420b77c Website: Update accepted contact source values (#39697)
Changes:
- Updated the accepted `contactSource` values in the
updateOrCreateContactAndAccount helper
2026-02-11 13:18:09 -06:00
Eric 358d61192b Website: Create historical events for signups (#39429)
Closes: https://github.com/fleetdm/fleet/issues/38375

Changes:
- Added a new intent signal value to the create-historical-event helper
- Updated the signup action to create a historical event when new users
sign up.
2026-02-05 15:26:31 -06:00
Eric 2726843403 Website: Update deliver-gitops-workshop-request (#39333)
Closes: https://github.com/fleetdm/confidential/issues/13968

Changes:
- Updated the `deliver-gitops-workshop-request` action to create a
historical event record
- Added a new intent signal to the create historical event helper
2026-02-05 15:08:50 -06:00
Eric df3ba51dab Website: Update get-enriched helper (#39347)
Closes: https://github.com/fleetdm/fleet/issues/39332

Changes:
- Updated the get-enriched helper to not use a provided email address if
the domain is included in the `bannedEmailDomainsForWebsiteSubmissions`
config value, and to not attempt to parse `null` website values returned
from coresignal
2026-02-04 14:53:41 -06:00
Eric cf8b461e5d Website: add GitOps workshop landing page. (#38812)
Changes:
- Added a landing page that has links to upcoming citops workshops, and
a link to a form where users can request a GitOps workshop.
- Updated the contact page to display a GitOps workshop request form for
users who are linked to it from the GitOps workshop landing page.
- Added `deliver-gitops-workshop-request`, an action that sends details
of GitOps workshop request submissions to Salesforce.
- Added a new helper that creates campaign member objects in Salesforce.
- Added two new config variables used to get event details from the
Eventbrite API.
2026-01-27 22:18:46 +09:00
Eric c4f8ded657 Website: Update values to match CRM picklist values (#38734)
Changes:
- Updated the accepted `intentSingal` values in the receive-from-clay
webhook and the createHistoricalEvent helper to match the picklist
values in Salesforce
- updated a "most recent/source channel details" value set in the
updateOrCreateContactAndAccount helper to match the picklist value in
Salesforce.
2026-01-23 15:35:33 -06:00
Eric 65f313d153 Website: update clay webhook inputs and historical event helper (#38601)
Closes: https://github.com/fleetdm/fleet/issues/38500

Changes:
- Added support for a `relatedCampaign` input to the receive-from-clay
webhook.
- Updated the `create-historical-event` helper to set `relatedCampaign`
on new historical event records (if provided)
2026-01-21 16:11:57 -06:00
Eric 7759fa71f7 Website: Update values set in CRM helper (#38559)
Changes:
- Updated the "Source channel detail" and "Most recent channel detail"
values set in the update-or-create-contact-and-account helper to match
the updated accepted values
2026-01-20 18:47:18 -06:00
Sam Pfluger b32681937c Consolidate event types in Salesforce integration (#38466) 2026-01-17 21:44:11 -06:00
Eric 92c89f37d7 Website: Update CRM helper (#38374)
Changes:
- Updated a variable name to be correct in the
update-or-create-contact-and-account helper
2026-01-15 09:51:10 -06:00
Eric 8ca9abc5a0 Website: add attribution cookie and update CRM helper (#38324)
https://github.com/fleetdm/confidential/issues/13605

Changes:
- Updated the website's custom hook to set a `marketingAttribution`
cookie.
- Updated places where we use the update-or-create-contact-and-account
helper to pass in a requesting user's marketingAttribution cookie.
- Updated the update-or-create-contact-and-account helper to process
values from the marketingAttribution cookie.
2026-01-14 18:14:55 -06:00
Mike McNeilandEric 0b0a81c2e6 Differentiate job applicants etc from demo requests (#38132)
Co-authored-by: Eric <eashaw@sailsjs.com>
2026-01-09 16:14:34 -06:00
Sam Pfluger fc6da5c233 Fix sentence case (#34979) 2025-10-29 22:43:58 -05:00
Eric b04ba96929 Website: Update enrichment helper queries when organization is provided. (#34949)
Changes:
- Updated the get-enriched helper to only send a single query for
organization name (if `organization` is provided).
2025-10-29 14:10:44 -05:00
Eric 11984cdf6f Website: Improve results returned by get-enriched helper (#34896)
Closes: https://github.com/fleetdm/confidential/issues/12790

Changes:
- Updated the get-enriched helper to use a different Coresignal API to
search for company information.
2025-10-28 16:23:30 -05:00