sendWhatsAppAudio (WHATSAPP-BUSINESS/Meta Cloud API): hardcoded .mp3/audio-mpeg mimetype silently breaks delivery, no voice:true support
Nobody has claimed this yet.
Assessment
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Newbie friendliness
- 70/100
- Issue type
- Bug
- Clarity
- Mostly clear
- Activity status
- Active
- Tech stack
- typescript
Research direction
Start in src/api/integrations/channel/meta/whatsapp.business.service.ts, reading processAudio() and audioWhatsapp() and comparing them with the generic sendMedia path. Reproduce the base64 Ogg/Opus case without AUDIO_CONVERTER.API_URL, then verify that the uploaded media metadata reflects the actual audio and that Meta receives voice-note handling. Done means the message delivers visibly and no longer reports a successful 201 while silently failing.
Written by the indexing model from the issue text.
Description
Welcome
Searched the tracker first, didn't find this exact combination reported.
What did you do?
Sent an outgoing voice note through a WHATSAPP-BUSINESS (Meta Cloud API) instance via POST /message/sendWhatsAppAudio/{instance}, base64 body, no file/URL: {"number": "...", "audio": "<base64>"}. The audio was a real, valid Ogg container with an Opus stream (48kHz, mono).
It kept silently failing to deliver, so I went and read processAudio() / audioWhatsapp() in src/api/integrations/channel/meta/whatsapp.business.service.ts:
public async processAudio(audio: string, number: string, file: any) {
...
} else {
let mimetype: string | false;
const prepareMedia: any = {
fileName: `${hash}.mp3`, // always ".mp3", no matter what you actually sent
mediaType: 'audio',
media: audio,
};
...
} else if (audio && !file) {
mimetype = mimeTypes.lookup(prepareMedia.fileName); // derived from that fake ".mp3" name
const id = await this.getIdMedia(prepareMedia);
...
}
prepareMedia.mimetype = mimetype;
return prepareMedia;
}
}
When AUDIO_CONVERTER.API_URL isn't set, fileName is always "{number}-{timestamp}.mp3", and the mimetype gets looked up from that made-up filename — so it's always audio/mpeg, regardless of what's actually in the buffer. Real Ogg/Opus bytes end up uploaded to Meta declared as audio/mpeg.
What did you expect?
For the mimetype to match the actual content (sniff it, or at least let it be passed in), or failing that, some kind of visible error instead of a 201 that goes nowhere.
What did you observe instead?
201 Created, a realkey.id(wamid...) — looks exactly like a normal successful send.- Shows up fine in Evolution's own
POST /chat/findMessages,messageType: "audioMessage". - Then just stops.
MessageUpdatestays[]forever — no SERVER_ACK, no DELIVERED, no READ, no failed. Nothing. No webhook fires for it ever again. - Same exact audio bytes, sent instead through
POST /message/sendMedia/{instance}withmediatype: "audio"(needs an explicitfileNameor that one 500s) — comes back correctly asmimetype: "audio/ogg"and actually delivers, READ within seconds.
Tried this 4 times, with and without encoding: false on the sendWhatsAppAudio payload — no difference, because that flag only touches whether the audio bytes get re-encoded, not the fake filename/mimetype used for the upload.
One more thing while I was in there: neither processAudio() nor the generic media path ever sets "voice": true on the outgoing type: "audio" message to Meta. That flag is what actually makes WhatsApp render it as a real voice note (mic icon, auto-download, waveform/duration) instead of a plain audio attachment. So even with the mimetype bug fixed, sendWhatsAppAudio still wouldn't produce a real voice-note bubble.
Screenshots/Videos
None, this was all API-level, no UI on our side involved.
Which version of the API are you using?
2.3.7
What is your environment?
Docker
Other environment specifications
Self-hosted, WHATSAPP-BUSINESS channel (Meta Cloud API). No AUDIO_CONVERTER.API_URL configured.
If applicable, paste the log output
Nothing to paste — that's the problem, there's no error anywhere. It just returns 201 and dies silently.
Additional Notes
Workaround we're using for now: send outgoing audio through sendMedia with mediatype: "audio" instead of sendWhatsAppAudio. Delivers fine, just loses the native voice-note look (which, per above, wasn't happening anyway).
Can put together a minimal curl repro with a synthetic tone if that helps.
- Dominant language
- TypeScript
- Stars
- 9.6k
- Forks
- 7.3k
- PR merge metrics
- No merged PRs in 30d
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from evolution-foundation/evolution-api
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
Difficulty 1/5 1-3 hours Newbie friendliness 88/100
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
-
Difficulty 1/5 Under an hour Newbie friendliness 88/100
evolution-foundation/evolution-api#2700 · 1 comment ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
All issues in evolution-foundation/evolution-api
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 65/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
-
bug v2
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
modelcontextprotocol/inspector#2458 · 1 comment ·
-
Difficulty 1/5 Under an hour Newbie friendliness 75/100
railmapgen/rmp-gallery#4068 ·
-
Mend: dependency security vulnerability status: needs triage 🕵️♀️
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
carbon-design-system/ibm-products#9907 ·