WP Manifestindependent plugin directory
manifest / ai / fluentcrm-contact-enrichment

FluentCRM Contact Enrichment

Enriches FluentCRM company records using the Claude API. Researches the organization, writes structured org-profile fields to all linked contacts, and stores a narrative research note on the company.

by Make Good · github.com/wemakegood/fluentcrm-contact-enrichment · website

★ 0stars
0forks

Install

No release zip yet. The repository archive installs, but the folder name will carry the branch suffix and updates will not flow:

wp plugin install https://github.com/wemakegood/fluentcrm-contact-enrichment/archive/refs/heads/main.zip

A WordPress plugin that adds AI-powered research surfaces to FluentCRM, using the Anthropic Claude API with web search.

Two parallel research paths:

  • Company research — Click "Enrich" on a FluentCRM company profile. The plugin researches the organization, returns structured fields (org type, sector, employees, revenue, geographic scope, focus areas, partnership models, alignment score), fills FluentCRM's native company columns (industry, description, address, social URLs) when empty, and writes a four-section narrative note. The structured fields mirror onto every contact whose primary company is that company, so they're filterable in FluentCRM's contact segment builder.
  • Individual contact research — Click "Enrich" on a contact profile. The plugin researches the person (career, philanthropic / leadership / decision-making background per use case, alignment with the requesting org's mission), returns 5 structured fields plus a four-section narrative note. Grounded in Apra's professional ethics standards with a per-contact opt-out flag.

The plugin is general-purpose. Use cases are framed by admin-configurable Markdown context modules that ground each research surface in the organization's priorities. A nonprofit's modules describe donor research; a leadership-development program's would describe cohort prep; a B2B sales team's would describe stakeholder research. The plugin doesn't bake in a single use case.

Status

Active development. The plugin runs in production on at least one site, has been validated against real enrichment workloads, and follows semantic versioning. See the Changelog section in readme.txt for release-by-release detail.

Installation

As a WordPress plugin

cd wp-content/plugins
git clone https://github.com/WeMakeGood/fluentcrm-contact-enrichment.git

Then activate via the WordPress plugin admin. The plugin bundles its only Composer dependency (Parsedown) in vendor/, so you don't need to run composer install for end-user installations.

Prerequisites

Development setup

git clone https://github.com/WeMakeGood/fluentcrm-contact-enrichment.git
cd fluentcrm-contact-enrichment
composer install   # installs Parsedown + dev dependencies

The plugin loads cleanly without composer install because vendor/ is committed; running install is only needed if you want the dev dependencies (wp-cli/i18n-command for i18n tooling).

Architecture

Components

fluentcrm-contact-enrichment/
├── fluentcrm-contact-enrichment.php   bootstrap, constants, hook wiring
├── includes/
│   ├── class-field-registrar.php      auto-create + heal field definitions
│   ├── class-context-modules.php      Company + Contact context module storage
│   ├── class-claude-client.php        Anthropic Messages API HTTP client
│   ├── class-data-mapper.php          JSON extraction + value validation
│   ├── class-lookup-fields.php        inject FluentCRM custom-field values into prompts
│   ├── class-contact-sync.php         push company-cached values to contacts
│   ├── class-enrichment-job.php       WP-Cron handlers for both surfaces
│   ├── class-admin-settings.php       FluentCRM → Contact Enrichment admin page wiring (Vue mount)
│   ├── class-rest-controller.php      REST API surface (fce/v1) for the Vue admin UI
│   ├── class-company-section.php      company profile section + Enrich button
│   └── class-contact-section.php      contact profile section + Enrich button
├── docs/
│   ├── fluentcrm-enrichment-research.md   pre-build recon, design decisions, deferred features
│   └── fields-reference.md                operational reference for all custom fields
├── readme.txt    WordPress.org-format readme (admin-facing)
├── CLAUDE.md     engineering context for future maintainer / AI sessions
└── README.md     this file

Data flow

[Admin clicks Enrich on a company or contact]
    ↓
[admin-ajax.php — capability + nonce checks, status flip, schedule cron]
    ↓
[WP-Cron fires fce_run_enrichment_job (companies) or fce_run_contact_enrichment_job (contacts)]
    ↓
[Build system prompt: research discipline + admin's active context modules + schema]
    ↓
[POST https://api.anthropic.com/v1/messages with web_search_20250305 tool enabled]
    ↓
[Parse JSON from response, validate against allowed-options lists]
    ↓
[Write structured fields + create narrative note (CompanyNote for orgs, SubscriberNote for contacts)]
    ↓
[For company enrichment: mirror values onto every contact where company_id matches]

The contact research path adds an extra step at the top: individual_research_consent is checked before any other work. If the contact has consent set to "Restricted," the cron handler short-circuits and no API call is made.

Key integration points

The plugin exposes one extension hook of its own and integrates cleanly with one external hook in the sister plugin:

  • fcr_excluded_field_slugs (filter, defined in fluentcrm-company-rollups, hooked here) — the plugin contributes its 17 plugin-managed contact field slugs so they're excluded from rollup configuration. The values are intrinsic to each person or mirrored from companies; rolling them up across contacts always returns the same value and is meaningless.
  • fluent_crm/admin_vars (FluentCRM's filter) — the plugin filters out the 3 company-side enrichment status fields from FluentCRM's profile sidebar to avoid duplication with the plugin's own profile section. The 14 other plugin-managed fields are deliberately left visible because they're useful in FluentCRM's segment builder, list-view filter chips, and custom column dropdown.
  • WP-Cron hooks — fce_run_enrichment_job (company) and fce_run_contact_enrichment_job (contact) are the cron entry points. Other plugins or custom code can dispatch them directly via do_action() if you need to trigger enrichment programmatically.

Custom fields

The plugin creates and manages custom fields in FluentCRM. See docs/fields-reference.md for the full operational reference (slugs, types, allowed values, fallbacks, storage paths, segmenting guidance). Quick map:

Surface Slugs Group
Company status enrichment_status, enrichment_date, enrichment_confidence Enrichment
Company-side org cache (mirrored to contacts) org_type, org_sector, org_employees, org_revenue, org_geo_scope, org_focus_areas, org_partnership_models, org_alignment_score Enrichment — Org Profile / — Alignment
Contact-side individual research individual_capacity_tier, individual_alignment, individual_engagement_readiness, individual_prior_relationship, individual_relevant_signals_present Enrichment — Individual
Contact-side individual status individual_enrichment_status, individual_enrichment_date, individual_enrichment_confidence, individual_research_consent Enrichment — Individual Status

Field definitions are auto-created on activation and idempotent on re-activation. A heal pass migrates existing data when field shapes change between releases.

Configuration

All admin configuration lives in FluentCRM → Contact Enrichment (a Vue 3 admin app under FluentCRM's submenu). Six tabs:

  • Dashboard — plugin orientation, your current configured state (provider, web search, company module), Make Good attribution
  • Contact Context — split into two subtabs:
    • Modules — Markdown context modules with a Markdown editor (md-editor-v3), list+detail layout, drag-to-reorder, starter examples for common use cases (donor prospecting, cohort prep, B2B sales/partnership), and a click-to-copy meta-prompt for generating modules via your own LLM
    • Lookup Fields — grouped, collapsible picker for FluentCRM custom fields whose values are injected into the enrichment prompt as "existing data on file" (giving history, WooCommerce orders, course completions, internal scoring)
  • Company Context — same two-subtab pattern, surface-specific copy (visible only when FluentCRM's Company module is enabled)
  • Focus Areas — drag-to-reorder vocabulary for the org_focus_areas multi-select field
  • Capacity Tiers — drag-to-reorder vocabulary for the individual_capacity_tier field, with a "restore donor-flavored defaults" affordance
  • Danger Zone — bulk "Resync all contacts" with typed-confirm gate (visible only when the Company module is enabled)

The API key, model, and provider configuration come from FluentCRM → Settings → AI Configuration — the plugin reads FluentCRM's existing AI credentials rather than managing its own. The Dashboard tab shows the current configured state with links into FluentCRM's settings if anything needs adjustment.

Privacy and ethics

Individual research is grounded in Apra's Statement of Ethics:

  • Source provenance. Public sources only. Inline citation of every claim with Markdown links to source URLs.
  • Relevance. Research restricted to information bearing on the use case the admin's context modules define. Personal-life details, family information, and aggregator-site data are out of scope by prompt design — even if findable.
  • Confidentiality. Per-contact individual_research_consent field gates research at the cron-job level. Restricted contacts cannot be researched even if an admin clicks Enrich.
  • Honest uncertainty. "Unknown" is the expected answer for non-public-figure subjects. Confidence values are calibrated low by design.

The privacy posture is documented at length in docs/fluentcrm-enrichment-research.md.

Cost

Each enrichment makes one Anthropic Messages API call with web search enabled.

  • Web search: $10 per 1,000 searches. Typical company-research call: 6–10 searches. Typical contact-research call: 5–8.
  • Tokens: Sonnet 4.6 default at $3/MTok input + $15/MTok output. A typical enrichment with a moderate-sized context module runs ~$0.05–$0.15 total (search + tokens).

The plugin's deferred-feature analysis covers prompt caching as a potential cost optimization. See docs/fluentcrm-enrichment-research.md.

Development

Coding conventions

  • WordPress core style (snakecase methods, `wp*` for utilities), not PSR
  • Function and constant prefix FCE_* / fce_*
  • Capability check + nonce check on every form post and AJAX handler
  • Sanitize on save, escape on render
  • All FluentCRM data writes go through public APIs (FluentCrmApi('companies')->createOrUpdate, Subscriber::syncCustomFieldValues, model ::create()) — no direct wpdb writes to FluentCRM tables

Testing

The plugin has been verified live throughout its development against a real WordPress + FluentCRM installation. Each release commit's message documents what was verified. There's no automated test suite; verification is manual and tied to release commits.

Engineering documentation

  • CLAUDE.md — engineering context for future maintainers (and AI assistants) working on the plugin. Documents non-obvious decisions, FluentCRM API quirks, and the rationale behind specific design choices.
  • docs/fluentcrm-enrichment-research.md — pre-build reconnaissance, decisions made during the build, deferred features (prompt caching, Files API), and the research-doc record for individual contact research.
  • docs/fields-reference.md — operational reference for all custom fields the plugin creates and manages.

FluentCRM developer documentation

Filter and action hook names, parameter signatures, and FluentCRM's documented extension surfaces live in a separate repository, not in the FluentCRM source. For substantive work on FluentCRM integration code, clone the docs locally:

git clone --depth 1 https://github.com/fluentcrm/fluent-crm-developers-docs.git /tmp/fluent-crm-developers-docs

Refresh with git -C /tmp/fluent-crm-developers-docs pull before significant work — FluentCRM updates the docs as their platform evolves.

Contributing

Issues and pull requests welcome on GitHub. Substantive PRs benefit from a brief discussion in an issue first so we can align on approach.

License

GPL-2.0-or-later. See LICENSE for the full text. Bundled dependency:

Repository