Skip to content

fix: normalize fileName property to handle case-insensitivity#2471

Open
enzowilliam wants to merge 2 commits intoEvolutionAPI:mainfrom
enzowilliam:fix/filename-property-inconsistency
Open

fix: normalize fileName property to handle case-insensitivity#2471
enzowilliam wants to merge 2 commits intoEvolutionAPI:mainfrom
enzowilliam:fix/filename-property-inconsistency

Conversation

@enzowilliam
Copy link

@enzowilliam enzowilliam commented Mar 11, 2026

Summary

  • Fixes the inconsistency in the /message/sendMedia/{instance} endpoint where the fileName property was case-sensitive
  • For images, only filename (lowercase) worked
  • For documents/videos, only fileName (camelCase) worked
  • Now both fileName and filename are accepted for all media types

Changes

Added property normalization at the beginning of the mediaMessage method in all three channel services:

  • src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts
  • src/api/integrations/channel/evolution/evolution.channel.service.ts
  • src/api/integrations/channel/meta/whatsapp.business.service.ts

The fix normalizes filename to fileName by using:

fileName: data.fileName || (data as any).filename,

Test plan

  • Send image with fileName property - should work
  • Send image with filename property - should work
  • Send document with fileName property - should work
  • Send document with filename property - should work
  • Send video with fileName property - should work
  • Send video with filename property - should work

Closes #2459

🤖 Generated with Claude Code

Summary by Sourcery

Normalize media message filename handling across channels and refine group mention options for message schemas and WhatsApp integration.

Bug Fixes:

  • Allow both fileName and filename properties when sending media messages across WhatsApp, Evolution, and Meta channel services.
  • Ensure mentionsEveryOne only applies when explicitly set to true in WhatsApp Baileys group messaging.

Enhancements:

  • Rename message schema property from everyOne to mentionsEveryOne for clearer and more consistent API semantics across all message types.
enzowilliam and others added 2 commits March 11, 2026 15:48
- Changed truthy check to strict equality (=== true) to properly handle string values like "false" sent by clients (e.g., n8n) - Fixed validation schema property name from 'everyOne' to 'mentionsEveryOne' to match DTO and service code Fixes EvolutionAPI#2431 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The sendMedia endpoint had an inconsistency where: - For images: only `filename` (lowercase) worked - For documents/videos: only `fileName` (camelCase) worked This was caused by the code only checking `data.fileName` without considering that users might send `filename` (lowercase) in the JSON payload. This fix normalizes the property name at the beginning of the mediaMessage method in all three channel services: - whatsapp.baileys.service.ts - evolution.channel.service.ts - whatsapp.business.service.ts Now both `fileName` and `filename` are accepted for all media types. Closes EvolutionAPI#2459 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@sourcery-ai
Copy link
Contributor

sourcery-ai bot commented Mar 11, 2026

Reviewer's Guide

Normalizes the SendMedia DTO so both fileName and filename are accepted across all WhatsApp channel integrations, and renames the everyOne mention flag to mentionsEveryOne consistently in message validation schemas and Baileys service logic.

Sequence diagram for sendMedia filename normalization

sequenceDiagram actor Client participant Api as MessageApi participant Chan as ChannelService participant WA as WhatsappProvider Client->>Api: POST /message/sendMedia/{instance}\nbody { fileName or filename } Api->>Chan: mediaMessage(data, file, isIntegration) alt data.fileName is defined Chan->>Chan: Build mediaData with fileName = data.fileName else data.fileName is undefined and data.filename is defined Chan->>Chan: Build mediaData with fileName = data.filename end Chan->>Chan: if file provided\nset mediaData.media = file buffer base64 Chan->>WA: Send normalized mediaData WA-->>Chan: Provider response Chan-->>Api: Normalized send result Api-->>Client: HTTP response 
Loading

Class diagram for updated message mention schemas

classDiagram class TextMessageSchema { +boolean mentionsEveryOne +array mentioned } class MediaMessageSchema { +boolean mentionsEveryOne +array mentioned } class PtvMessageSchema { +boolean mentionsEveryOne +array mentioned } class AudioMessageSchema { +boolean mentionsEveryOne +array mentioned } class StickerMessageSchema { +boolean mentionsEveryOne +array mentioned } class LocationMessageSchema { +boolean mentionsEveryOne +array mentioned } class PollMessageSchema { +boolean mentionsEveryOne +array mentioned } class ListMessageSchema { +boolean mentionsEveryOne +array mentioned } class ButtonsMessageSchema { +boolean mentionsEveryOne +array mentioned } TextMessageSchema <|-- MediaMessageSchema TextMessageSchema <|-- PtvMessageSchema TextMessageSchema <|-- AudioMessageSchema TextMessageSchema <|-- StickerMessageSchema TextMessageSchema <|-- LocationMessageSchema TextMessageSchema <|-- PollMessageSchema TextMessageSchema <|-- ListMessageSchema TextMessageSchema <|-- ButtonsMessageSchema 
Loading

Flow diagram for mentionsEveryOne handling in Baileys service

flowchart TD A[Start building mentions list] --> B{options.mentionsEveryOne === true} B -->|yes| C[Set mentions to all group participants ids] B -->|no| D{options.mentioned has items} D -->|yes| E[Map each mentioned value to participant id] D -->|no| F[Leave mentions empty] C --> G[Continue sending message] E --> G[Continue sending message] F --> G[Continue sending message] 
Loading

File-Level Changes

Change Details Files
Normalize media filename input to support both fileName and filename for all media types in all WhatsApp channel services.
  • Change mediaMessage construction to spread incoming data while overriding/setting fileName
  • Derive fileName from either existing data.fileName or legacy lowercase data.filename
  • Ensure file attachment buffer is still converted to base64 and assigned to media
src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts
src/api/integrations/channel/evolution/evolution.channel.service.ts
src/api/integrations/channel/meta/whatsapp.business.service.ts
Rename the broadcast-mention boolean flag from everyOne to mentionsEveryOne across message validation schemas and tighten its usage in Baileys service.
  • Update JSON schemas for all message types to use mentionsEveryOne instead of everyOne
  • Keep mentionsEveryOne typed as a boolean enum [true, false] in schemas
  • Require options.mentionsEveryOne to be strictly true before auto-mentioning all group participants
src/validate/message.schema.ts
src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts

Assessment against linked issues

Issue Objective Addressed Explanation
#2459 Fix the /message/sendMedia/{instance} endpoint so that the file name field behaves consistently across all media types (image, video, document), eliminating the bug where images only worked with filename and documents/videos only with fileName.
#2459 Standardize on a single canonical property name (fileName) in the public API contract and documentation, fully aligning the documented payload with the actual implementation. The PR changes only backend service code to normalize filename to fileName in mediaMessage methods; it does not modify any API documentation or schemas related to the documented contract, so alignment of docs/contract with the new behavior is not covered here.

Possibly linked issues


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
Contributor

@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 found 1 issue, and left some high level feedback:

  • Renaming everyOne to mentionsEveryOne across all message schemas may be a breaking API change for existing clients; consider either keeping everyOne as a deprecated alias in the schema or handling both properties during validation/normalization similar to the fileName/filename approach.
  • The mediaMessage normalization logic for fileName is duplicated in three services; consider extracting a shared helper or applying normalization at a DTO/validation layer to avoid drift between channel implementations.
  • Using fileName: data.fileName || (data as any).filename will overwrite an explicitly provided empty string fileName with filename; if that matters for your API, consider using nullish coalescing (??) instead of ||.
Prompt for AI Agents
Please address the comments from this code review: ## Overall Comments - Renaming `everyOne` to `mentionsEveryOne` across all message schemas may be a breaking API change for existing clients; consider either keeping `everyOne` as a deprecated alias in the schema or handling both properties during validation/normalization similar to the `fileName`/`filename` approach. - The `mediaMessage` normalization logic for `fileName` is duplicated in three services; consider extracting a shared helper or applying normalization at a DTO/validation layer to avoid drift between channel implementations. - Using `fileName: data.fileName || (data as any).filename` will overwrite an explicitly provided empty string `fileName` with `filename`; if that matters for your API, consider using nullish coalescing (`??`) instead of `||`. ## Individual Comments ### Comment 1 <location path="src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts" line_range="2981-2986" /> <code_context> + const mediaData: SendMediaDto = { +  ...data, +  // Normalize filename to fileName (handle case-insensitivity) +  fileName: data.fileName || (data as any).filename, + }; </code_context> <issue_to_address> **suggestion:** Overriding `fileName` after spreading may mask an existing, intentionally empty `fileName` value. If `data.fileName` is an empty string (or another falsy-but-valid value), this will incorrectly fall back to `(data as any).filename`. Prefer checking only for `undefined`, e.g. `fileName: data.fileName ?? (data as any).filename`, so intentional empty values are preserved. ```suggestion  public async mediaMessage(data: SendMediaDto, file?: any, isIntegration = false) {  const mediaData: SendMediaDto = {  ...data,  // Normalize filename to fileName (handle case-insensitivity) while preserving intentional empty values  fileName: data.fileName ?? (data as any).filename,  }; ``` </issue_to_address>

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.
Comment on lines 2981 to +2986
public async mediaMessage(data: SendMediaDto, file?: any, isIntegration = false) {
const mediaData: SendMediaDto = { ...data };
const mediaData: SendMediaDto = {
...data,
// Normalize filename to fileName (handle case-insensitivity)
fileName: data.fileName || (data as any).filename,
};
Copy link
Contributor

Choose a reason for hiding this comment

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

suggestion: Overriding fileName after spreading may mask an existing, intentionally empty fileName value.

If data.fileName is an empty string (or another falsy-but-valid value), this will incorrectly fall back to (data as any).filename. Prefer checking only for undefined, e.g. fileName: data.fileName ?? (data as any).filename, so intentional empty values are preserved.

Suggested change
public async mediaMessage(data: SendMediaDto, file?: any, isIntegration = false) {
const mediaData: SendMediaDto = { ...data };
const mediaData: SendMediaDto = {
...data,
// Normalize filename to fileName (handle case-insensitivity)
fileName: data.fileName || (data as any).filename,
};
public async mediaMessage(data: SendMediaDto, file?: any, isIntegration = false) {
const mediaData: SendMediaDto = {
...data,
// Normalize filename to fileName (handle case-insensitivity) while preserving intentional empty values
fileName: data.fileName ?? (data as any).filename,
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

1 participant