feat: add global search command#23
Conversation
5d23d1c to
43d584f
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5d23d1c97f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| PortalSlug string `json:"portal_slug"` | ||
| AccountID int `json:"account_id"` | ||
| CategoryName string `json:"category_name"` | ||
| Status int `json:"status"` |
There was a problem hiding this comment.
Treat article search status as a string
Chatwoot article responses use the same enum status strings already modeled by HelpCenterArticle.Status (internal/sdk/help_center.go:66), so when /search returns an article with "status":"published" this int field makes JSON decoding fail before anything is printed and before --only can discard article results. That means otherwise valid global searches start returning failed to decode response whenever the query matches an article.
Useful? React with 👍 / 👎.
| if c.Only == "" { | ||
| return fmt.Errorf("csv output needs a single bucket; use --only=<bucket> or -o json") | ||
| } | ||
| return printSearchSection(app, resp, c.Only, false) |
There was a problem hiding this comment.
Preserve CSV format for empty search buckets
In the -o csv --only=... path, empty buckets still go through printSearchSection, whose no-result branches write prose such as No conversations found. instead of calling PrintTable with zero rows. A successful search where the selected bucket is empty therefore produces non-CSV output, breaking scripts that requested CSV; the existing row printers would emit valid headers even for empty slices.
Useful? React with 👍 / 👎.
Add `chatwoot search <query>`: a global search across conversations, contacts, messages, and help-center articles via the account-scoped /search endpoint. Supports `--only` to restrict output to a single bucket, and text, JSON, CSV, and quiet rendering (type-prefixed IDs without `--only`, plain IDs with it). The /search endpoint is not part of Chatwoot's published OpenAPI spec, so the SDK service and command are covered by httptest-based tests rather than the swagger contract harness. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
43d584f to
8a10e70
Compare
|
Thanks for the review @chatgpt-codex-connector — both points are addressed in 8a10e70:
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8a10e70d39
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| resp, err := app.Client.Search().Global(sdk.SearchOptions{ | ||
| Query: c.Query, | ||
| Page: c.Page, | ||
| }) |
There was a problem hiding this comment.
Route --only searches to bucket endpoints
When --only is provided this still calls the global /search endpoint, which Chatwoot's SearchController#index handles as search('all'); the bucket routes (/search/messages, /search/contacts, etc.) are the ones that avoid running the other searches. On large accounts, or when an unrelated bucket is slow/errors, chatwoot search --only=messages ... can time out or fail even though the requested messages search would succeed, so Only should affect the SDK request rather than just filtering the rendered payload.
Useful? React with 👍 / 👎.
|
@scmmishra @vishnu-narayanan — could I get your steer on this one before I implement it? Codex (above) suggests routing The trade-off as I see it:
One caveat either way: neither Happy to implement per-type routing if you'd prefer it — just let me know which direction you want. |
Summary
Adds
chatwoot search "<query>"— a global search across conversations, contacts, messages, and help-center articles via the account-scoped/searchendpoint, with--only=<bucket>to restrict to a single bucket. Text, JSON, CSV, and quiet output;--onlyis honored consistently across every format.Implements the proposal in #22 — happy to discuss the top-level-command-vs-flag question there before merge.
Tests
internal/sdk/search_test.goandinternal/cmd/search_test.gocover request params, four-bucket decoding,--only(text + JSON), and the text/JSON/CSV/quiet/no-result paths./searchisn't in the bundledapplication_swagger.json(only/contacts/searchis), so these usehttptestrather than the swagger contract harness — consistent with the existinginternal/cmd/*_test.go.Notes
README usage, the agent skill (command table + read-only allowlist), and CHANGELOG updated.