Skip to content

fix(crm): Notificame fallback_title uses content[:fileName] (EVO-1130)#69

Merged
dpaes merged 1 commit into
developfrom
fix/EVO-1130
May 15, 2026
Merged

fix(crm): Notificame fallback_title uses content[:fileName] (EVO-1130)#69
dpaes merged 1 commit into
developfrom
fix/EVO-1130

Conversation

@nickoliveira23
Copy link
Copy Markdown
Contributor

@nickoliveira23 nickoliveira23 commented May 15, 2026

Summary

  • Whatsapp::IncomingMessageNotificameService#attach_file now prefers content[:fileName] for fallback_title, falling back to URL basename when absent or blank.
  • Mirrors the Notificame outbound serializer (providers/notificame_service.rb:63,431) and the Z-API inbound handler (incoming_message_zapi_service.rb:209), which already consume the same :fileName camelCase key.
  • Adds the first spec for attach_file, covering the three branches of the resolution (fileName present, absent, blank).

Changed Files

  • app/services/whatsapp/incoming_message_notificame_service.rb — single-line change at the fallback_title assignment
  • spec/services/whatsapp/incoming_message_notificame_service_spec.rb — new file, 3 examples

Validation

  • ruby -c app/services/whatsapp/incoming_message_notificame_service.rb → Syntax OK
  • ruby -c spec/services/whatsapp/incoming_message_notificame_service_spec.rb → Syntax OK
  • bundle exec rspec spec/services/whatsapp/incoming_message_notificame_service_spec.rb → 3 examples, 0 failures

Notes

  • The inbound :fileName convention is inferred from API symmetry and corroborated by the Z-API sibling handler. Capturing a real Notificame document webhook in production logs would close the loop — non-blocking, but worth checking once a real document message lands.

Linked Issue

🤖 Generated with Claude Code

Summary by Sourcery

Prefer Notificame payload fileName for WhatsApp incoming attachment fallback titles, with URL basename as a secondary fallback.

Bug Fixes:

  • Ensure WhatsApp Notificame incoming attachments use the provided fileName field when available for fallback_title instead of always deriving it from the file URL.

Tests:

  • Add service specs for Whatsapp::IncomingMessageNotificameService#attach_file covering fileName present, missing, and blank cases for fallback_title resolution.

…k_title (EVO-1130)

Inbound Notificame webhook delivers the real filename in `content[:fileName]`
(mirrors the outbound serializer and the Z-API inbound handler). Falling
back to URL basename produced opaque hashes for proxied/signed URLs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@sourcery-ai
Copy link
Copy Markdown

sourcery-ai Bot commented May 15, 2026

Reviewer's Guide

Adjusts Notificame WhatsApp inbound file attachment handling to prefer the provided fileName for fallback_title and adds targeted specs for the new behavior.

Sequence diagram for updated Notificame inbound file fallback_title resolution

sequenceDiagram
  participant NotificameWebhook
  participant IncomingMessageNotificameService
  participant Message
  participant Attachment

  NotificameWebhook ->> IncomingMessageNotificameService: attach_file(message, content)
  IncomingMessageNotificameService ->> Message: attachments
  activate Message
  Message ->> Attachment: new(file_type, fallback_title, file)
  deactivate Message

  rect rgb(230,230,230)
    IncomingMessageNotificameService ->> IncomingMessageNotificameService: [content[:fileName].present?]
    Note over IncomingMessageNotificameService: fallback_title = content[:fileName]
  end

  rect rgb(230,230,230)
    IncomingMessageNotificameService ->> IncomingMessageNotificameService: [content[:fileName] blank]
    IncomingMessageNotificameService ->> IncomingMessageNotificameService: URI.parse(content[:fileUrl])
    Note over IncomingMessageNotificameService: fallback_title = basename from content[:fileUrl]
  end
Loading

File-Level Changes

Change Details Files
Update fallback_title resolution for Notificame inbound file attachments to prioritize content[:fileName] with a URL-based fallback.
  • Change attach_file to use content[:fileName].presence before deriving a filename from content[:fileUrl].
  • Retain existing URL basename extraction via URI.parse with a rescue-based fallback when fileName is missing or blank.
  • Keep existing file attachment attributes (file_type, file IO, filename, mime type) unchanged aside from fallback_title logic.
app/services/whatsapp/incoming_message_notificame_service.rb
Add specs covering attach_file fallback_title behavior for Notificame inbound messages.
  • Introduce a service spec scaffold that gracefully skips when rails_helper is unavailable in lightweight environments.
  • Mock provider_service.download_media, message.attachments, and file_content_type to isolate attach_file behavior.
  • Add three examples asserting fallback_title resolution when fileName is present, missing, or blank, including basic assertions on file payload structure.
spec/services/whatsapp/incoming_message_notificame_service_spec.rb

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've left some high level feedback:

  • The fallback_title expression is getting a bit dense with the presence checks and rescue; consider extracting this into a small helper method (e.g. resolved_fallback_title(content)) to improve readability and make the error handling more explicit.
  • The inline rescue in the fallback_title URL basename logic will catch all exceptions from URI.parse; it might be safer to rescue only the expected parsing errors or handle invalid URLs earlier to avoid silently swallowing unexpected issues.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The `fallback_title` expression is getting a bit dense with the `presence` checks and `rescue`; consider extracting this into a small helper method (e.g. `resolved_fallback_title(content)`) to improve readability and make the error handling more explicit.
- The inline `rescue` in the `fallback_title` URL basename logic will catch all exceptions from `URI.parse`; it might be safer to rescue only the expected parsing errors or handle invalid URLs earlier to avoid silently swallowing unexpected issues.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Copy link
Copy Markdown

@dpaes dpaes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved.

ACs validated against the diff:

  • fallback_title now prefers content[:fileName] (line 308)
  • URL basename retained as second-level fallback via || chain
  • New spec covers fileName present / missing / blank (3 examples)

Convention corroborated by Z-API inbound handler (incoming_message_zapi_service.rb:209) and Notificame outbound serializer (providers/notificame_service.rb:63, 431). Cross-gateway symmetry is strong evidence.

One Medium observation logged on the Linear card (EVO-1130) about the spec scaffold's rescue LoadError + return unless defined?(Rails) guards — non-blocking, capped Medium by project convention since specs aren't blockers.

Sourcery's helper-extraction and rescue-scoping points are valid but pre-existing / out of scope for this single-line fix.

Real Notificame document webhook payload still worth capturing in production logs to close the inference loop — already flagged in the PR body as non-blocking.

@dpaes dpaes merged commit b013399 into develop May 15, 2026
1 check passed
@dpaes dpaes deleted the fix/EVO-1130 branch May 15, 2026 18:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants