Commit Graph
14 Commits
Author SHA1 Message Date
d43a87c9dc feat: Add labels to contact import/export (#13313)
Adds label support to contact import and export so teams can carry
approved contact labels through CSV workflows. Imports accept a `labels`
column with labels that already exist in the account; multiple labels
should be entered as a quoted comma-separated CSV value, for example
`"customer,vip"`.

Imports are additive: they add labels to contacts and do not remove
labels already on a contact. Removing a label from the CSV row or
leaving the `labels` cell blank will not clear existing contact labels.
To remove a label, edit the contact directly.

## Closes

- Closes #8535

## How to test

1. Create a few contact labels in the account, such as `customer`,
`vip`, and `lead`.
2. Go to Contacts -> Import contacts and download the sample CSV.
3. Import contacts with a `labels` column. Use a single label like
`lead`, or quote multiple labels like `"customer,vip"`.
4. Confirm imported contacts are created with the expected labels.
5. Re-import an existing contact with a new label and confirm the new
label is added without removing existing labels.
6. Try a row with an unknown label, such as `"vip,unknown_label"`, and
confirm only that row is rejected in the failed records CSV while the
other valid rows are imported.
7. Export contacts and confirm the CSV includes a `labels` column with
comma-separated approved labels.

## What changed

- Contact exports include approved `labels` in the default CSV columns.
This adds a new default export column for CSV consumers.
- Contact imports parse `labels` as comma-separated values inside the
CSV cell.
- Imported labels are validated against labels that already exist in the
account.
- Rows with unknown labels are rejected with an `Unknown labels: ...`
error; valid rows in the same import continue to process.
- Imported labels are additive and do not remove existing contact
labels.
- Label application during import does not dispatch an additional
per-contact update event.
- The sample CSV includes an import-safe `labels` column. The modal
keeps the existing generic CSV import copy.

---------

Co-authored-by: Sojan Jose <sojan@pepalo.com>
2026-05-06 18:46:36 +05:30
16b8693e1b fix: standardize contact company field on company_name (#14099)
Standardizes the contact company import/filter/automation contract on
`company_name`.

Closes #14096
Revives #9907

## Why

Contact company is read across the current CRM/contact UI from
`additional_attributes['company_name']`, but CSV import and a few
backend filter/automation paths still used the older `company` key. That
meant imported company values could be saved in a place the dashboard,
sorting, filters, and automation conditions did not consistently read
from.

Based on the production data check, the legacy `company` automation
configuration is effectively dead: the affected account did not have
contacts populated with `additional_attributes['company']`. So this PR
intentionally avoids adding long-term fallback behavior and uses
`company_name` as the single key going forward.

## What changed

- Contact CSV import now writes only `company_name` into
`additional_attributes['company_name']`.
- The example contact import CSV now uses the `company_name` header.
- Contact company sorting/filter config now uses `company_name`.
- Automation condition config now uses `company_name`.
- Existing standard automation conditions with `attribute_key:
'company'` are migrated to `company_name`.
- Existing saved contact filters with standard `attribute_key:
'company'` are migrated to `company_name`.
- Custom attributes named `company` are preserved and are not rewritten
by the migration.

## How to test

- Import a contact CSV with a `company_name` column and confirm the
Contact Company field is populated.
- Sort contacts by Company and confirm imported contacts are ordered
correctly.
- Create/edit an automation with Company as a condition and confirm it
saves with `company_name`.
- Verify existing saved contact filters and automation rules using the
old standard `company` key are migrated to `company_name`.

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Sojan Jose <sojan@pepalo.com>
2026-04-27 18:43:26 +05:30
Kenta IshizakiandGitHub 9a89e1f522 fix: Strip UTF-8 BOM in DataImportJob#csv_reader before parsing CSV (#14126)
## Description

`DataImportJob#csv_reader` reads CSV data with `force_encoding('UTF-8')`
but does not strip the UTF-8 Byte Order Mark (`EF BB BF`). If a CSV file
containing a BOM is imported, the first header key is prefixed with
`\uFEFF`, which causes key mismatches in `DataImport::ContactManager`
when the first column is one of the recognized keys (`:email`,
`:identifier`, `:phone_number`, `:name`).

This was identified during review of #14123 (see #14124 for the tracking
issue).

Fixes #14124

## Type of change

- [x] Bug fix (non-breaking change which fixes an issue)

## How Has This Been Tested?

- Added a new fixture (`spec/fixtures/data_import/with_bom.csv`)
containing a UTF-8 BOM followed by valid contact data.
- Added a new spec (`will strip UTF-8 BOM and import contacts
correctly`) that imports the BOM fixture and verifies that `name`,
`email`, and `phone_number` are all correctly parsed.
- All existing examples in `spec/jobs/data_import_job_spec.rb` continue
to pass.

## Checklist:

- [x] My code follows the style guidelines of this project
- [x] I have performed a self-review of my code
- [x] I have commented on my code, particularly in hard-to-understand
areas
- [x] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] New and existing unit tests pass locally with my changes
- [x] Any dependent changes have been merged and published in downstream
modules
2026-04-24 17:03:03 +05:30
Sojan JoseandGitHub cc86b8c7f1 fix: stream attachment handling in workers (#12870)
We’ve been watching Sidekiq workers climb from ~600 MB at boot to
1.4–1.5 GB after an hour whenever attachment-heavy jobs run. This PR is
an experiment to curb that growth by streaming attachments instead of
loading the whole blob into Ruby: reply-mailer inline attachments,
Telegram uploads, and audio transcriptions now read/write in chunks. If
this keeps RSS stable in production we’ll keep it; otherwise we’ll roll
it back and keep digging
2025-12-05 13:02:53 -08:00
Shivam MishraandGitHub c031cb19d2 fix: downcase email before finding (#8921)
* fix: downcase email when finding

* feat: add `from_email` class

* refactor: use `from_email`

* feat: add rule to disallow find_by email directly

* chore:  remove redundant test

Since the previous imlpmentation didn't do a case-insentive search, a new user would be created, and the error would be raised at the DB layer. With the new changes, this test case is redundant

* refactor: use from_email
2024-02-21 18:51:00 +05:30
Muhsin KelothandGitHub c899cc825d fix: Handle Contact import MalformedCSVError (#8706) 2024-01-18 13:05:58 +05:30
Sojan JoseandGitHub 6a73953003 chore: Add delay before running dataimport job (#8039)
- We have observed some failures for data import jobs in the cloud due to race conditions with job executions and active storage file uploading. This PR adds delays and retries to accommodate that.
2023-10-03 22:18:57 -07:00
Sojan JoseandGitHub 64ae9f625a chore: Persist emojis in Contact Import (#7803)
The previous fix would remove emojis in contact data. This change ensures they are persisited

ref: #7787
2023-08-24 14:04:52 -07:00
Sojan JoseandGitHub acb7debd3f chore: Contact import improvements (#7787)
- Ensure existing contact information is updated on data import
- Refactor the existing job to make it more readable
- Fixes issues with import files in the wrong encoding
fixes: #7307
2023-08-23 23:24:47 -07:00
Sojan JoseandGitHub 7ab7bac6bf chore: Enable the new Rubocop rules (#7122)
fixes: https://linear.app/chatwoot/issue/CW-1574/renable-the-disabled-rubocop-rules
2023-05-19 14:37:10 +05:30
905e77048f chore: Contact import improvements (CW-1362) (#6747)
Fixes: https://linear.app/chatwoot/issue/CW-1362/csv-imports-are-not-working-properly
Fixes: #3462

---------

Co-authored-by: Sojan <sojan@pepalo.com>
2023-04-18 00:40:55 +05:30
Tejaswini ChileandGitHub d2d6d271c3 CW-1399 Phone number import (#6815) 2023-04-03 13:53:59 +05:30
Sojan JoseandGitHub 615a575bdd fix: Agent typing indicator for website widget (#4495)
When we migrated the pubsub tokens from contact to contact inboxes, we missed out on doing this update for the typing indicator events. Hence the agent typing events weren't visible on the widget side. This change fixes that and removes the necessary column contact pubsub token from the model.

fixes: #4476
2022-04-18 19:05:45 +05:30
Sojan JoseandGitHub c61edff189 feat: Add bulk imports API for contacts (#1724) 2021-02-03 19:24:51 +05:30