Problem/Motivation

The MondayCreateItemWebformHandler calls create_item on every completed submission. When several submissions carry the same email address — the same form submitted twice, or two different forms that each populate a different subset of columns — each one produces a separate Monday item. The result is duplicate rows in the board and lost consolidation of a single contact's data.

A blind overwrite is not acceptable either: a board may have many columns populated by different forms (or by a prior CSV import), so re-writing the whole item on each submission would erase columns set by earlier submissions.

Steps to reproduce

  1. Configure the handler on a board with an email column, mapping a Webform email field to it.
  2. Submit the form with a@example.com.
  3. Submit again with the same email (same or a different form / field set).
  4. Observe two separate items on the board instead of one merged item.

Proposed resolution

Add an opt-in, email-keyed upsert to the handler:

  • New per-handler config dedup_email_column_id. Empty ⇒ current create-only behavior (fully backward-compatible). Set to a Monday column ID ⇒ upsert enabled.
  • On submission with dedup enabled, look up existing items by the email column value via a single server-side filter
    (items_page_by_column_values):
    • No match ⇒ create_item (current behavior).
    • One match ⇒ change_multiple_column_values writing only the columns present in this submission; all other columns are left untouched (partial-field merge). Empty submitted fields are skipped, so they never overwrite existing values.
    • Multiple matches (legacy / imported duplicates) ⇒ merge into the oldest item (lowest item ID) and log a warning listing the other matches IDs.
  • Item name, the lead-source column, and the target group are written on create only — never on merge — so a merge does not churn the identity column, overwrite lead provenance, or move the item between pipeline groups.
  • Email matching relies on Monday's exact column match; no address normalization is applied.
  • If the lookup call fails, the relay aborts through the existing failure path (logged; configurable user-facing message; local submission preserved) rather than falling back to a create, to avoid re-introducing duplicates during an API outage.

Remaining tasks

  • Add findItemsByColumnValue() and changeColumnValues() to MondayClientInterface /
    MondayClient.
  • Refactor buildColumnValues() so the lead-source column is appended on the create path only.
  • Rewrite relay() as the upsert described above.
  • Add dedup_email_column_id to the config form and config/schema/monday_crm_integration.schema.yml.
  • Unit tests: new client methods (0 / 1 / many results, error paths); handler matrix (dedup off; 0 / 1 / many matches; missing-email;
    empty-field-no-overwrite on merge; lookup-failure abort; assert name / group / lead-source are not sent on merge).
  • Update README.
  • Manual verification of the cross-form merge against a real board.

User interface changes

One new optional field, "Dedup email column ID," on the handler configuration form. No change when left empty.

API changes

Two new methods on MondayClientInterface: findItemsByColumnValue(int $boardId, string $columnId, string $value): array and
changeColumnValues(int $boardId, int $itemId, array $columnValues): array. Additive — no existing signatures change.

Data model changes

One new handler config key dedup_email_column_id (string, default empty). No update hook required; existing handlers default to empty and
keep current behavior.

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

das.gautam created an issue. See original summary.

  • das.gautam committed 732a5caf on 1.0.x
    Issue #3616294 by das.gautam: Deduplicate on email — upsert with partial...
das.gautam’s picture

Status: Active » Fixed

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.