* feat: add audio transcoding support for WhatsApp Cloud API - Introduced `Audio::TranscodeService` to handle audio transcoding to OGG/Opus format. - Updated `Messages::MessageBuilder` to transcode audio attachments based on `transcode_audio` parameter. - Enhanced `WhatsappCloudService` to normalize audio content types and send voice flag for recorded audio in OGG format. - Added utility functions for audio conversion in JavaScript. - Updated Dockerfile to include FFmpeg for audio processing. - Added tests for audio transcoding and WhatsApp Cloud service interactions. * feat: enhance audio handling with transcoding support and error management * feat: improve audio transcoding error handling and enhance audio recording features * feat: enhance audio transcoding process and error handling for better reliability * feat: update recorded audio handling to support boolean and array formats
131 lines
3.0 KiB
JavaScript
131 lines
3.0 KiB
JavaScript
/* eslint no-console: 0 */
|
|
/* global axios */
|
|
import ApiClient from '../ApiClient';
|
|
|
|
export const buildCreatePayload = ({
|
|
message,
|
|
isPrivate,
|
|
contentAttributes,
|
|
echoId,
|
|
files,
|
|
isRecordedAudio,
|
|
ccEmails = '',
|
|
bccEmails = '',
|
|
toEmails = '',
|
|
templateParams,
|
|
}) => {
|
|
let payload;
|
|
if (files && files.length !== 0) {
|
|
payload = new FormData();
|
|
if (message) {
|
|
payload.append('content', message);
|
|
}
|
|
files.forEach(file => {
|
|
payload.append('attachments[]', file);
|
|
});
|
|
if (isRecordedAudio === true) {
|
|
payload.append('is_recorded_audio', true);
|
|
} else if (Array.isArray(isRecordedAudio)) {
|
|
isRecordedAudio.forEach(filename => {
|
|
payload.append('is_recorded_audio[]', filename);
|
|
});
|
|
}
|
|
payload.append('private', isPrivate);
|
|
payload.append('echo_id', echoId);
|
|
payload.append('cc_emails', ccEmails);
|
|
payload.append('bcc_emails', bccEmails);
|
|
|
|
if (toEmails) {
|
|
payload.append('to_emails', toEmails);
|
|
}
|
|
if (contentAttributes) {
|
|
payload.append('content_attributes', JSON.stringify(contentAttributes));
|
|
}
|
|
} else {
|
|
payload = {
|
|
content: message,
|
|
private: isPrivate,
|
|
echo_id: echoId,
|
|
content_attributes: contentAttributes,
|
|
cc_emails: ccEmails,
|
|
bcc_emails: bccEmails,
|
|
to_emails: toEmails,
|
|
template_params: templateParams,
|
|
};
|
|
}
|
|
return payload;
|
|
};
|
|
|
|
class MessageApi extends ApiClient {
|
|
constructor() {
|
|
super('conversations', { accountScoped: true });
|
|
}
|
|
|
|
create({
|
|
conversationId,
|
|
message,
|
|
private: isPrivate,
|
|
contentAttributes,
|
|
echo_id: echoId,
|
|
files,
|
|
isRecordedAudio,
|
|
ccEmails = '',
|
|
bccEmails = '',
|
|
toEmails = '',
|
|
templateParams,
|
|
}) {
|
|
return axios({
|
|
method: 'post',
|
|
url: `${this.url}/${conversationId}/messages`,
|
|
data: buildCreatePayload({
|
|
message,
|
|
isPrivate,
|
|
contentAttributes,
|
|
echoId,
|
|
files,
|
|
isRecordedAudio,
|
|
ccEmails,
|
|
bccEmails,
|
|
toEmails,
|
|
templateParams,
|
|
}),
|
|
});
|
|
}
|
|
|
|
delete(conversationID, messageId) {
|
|
return axios.delete(`${this.url}/${conversationID}/messages/${messageId}`);
|
|
}
|
|
|
|
editContent(conversationID, messageId, content) {
|
|
return axios.patch(
|
|
`${this.url}/${conversationID}/messages/${messageId}/edit_content`,
|
|
{ content }
|
|
);
|
|
}
|
|
|
|
retry(conversationID, messageId) {
|
|
return axios.post(
|
|
`${this.url}/${conversationID}/messages/${messageId}/retry`
|
|
);
|
|
}
|
|
|
|
getPreviousMessages({ conversationId, after, before }) {
|
|
const params = { before };
|
|
if (after && Number(after) !== Number(before)) {
|
|
params.after = after;
|
|
}
|
|
return axios.get(`${this.url}/${conversationId}/messages`, { params });
|
|
}
|
|
|
|
translateMessage(conversationId, messageId, targetLanguage) {
|
|
return axios.post(
|
|
`${this.url}/${conversationId}/messages/${messageId}/translate`,
|
|
{
|
|
target_language: targetLanguage,
|
|
}
|
|
);
|
|
}
|
|
}
|
|
|
|
export default new MessageApi();
|