diff --git a/app/javascript/dashboard/components-next/whatsapp/WhatsAppTemplateParser.vue b/app/javascript/dashboard/components-next/whatsapp/WhatsAppTemplateParser.vue
index cf62a6d5d..6df06642c 100644
--- a/app/javascript/dashboard/components-next/whatsapp/WhatsAppTemplateParser.vue
+++ b/app/javascript/dashboard/components-next/whatsapp/WhatsAppTemplateParser.vue
@@ -72,6 +72,10 @@ const formatType = computed(() => {
return format ? format.charAt(0) + format.slice(1).toLowerCase() : '';
});
+const isDocumentTemplate = computed(() => {
+ return headerComponent.value?.format?.toLowerCase() === 'document';
+});
+
const hasVariables = computed(() => {
return bodyText.value?.match(/{{([^}]+)}}/g) !== null;
});
@@ -126,6 +130,11 @@ const updateMediaUrl = value => {
processedParams.value.header.media_url = value;
};
+const updateMediaName = value => {
+ processedParams.value.header ??= {};
+ processedParams.value.header.media_name = value;
+};
+
const sendMessage = () => {
v$.value.$touch();
if (v$.value.$invalid) return;
@@ -168,10 +177,12 @@ defineExpose({
processedParams,
hasVariables,
hasMediaHeader,
+ isDocumentTemplate,
headerComponent,
renderedTemplate,
v$,
updateMediaUrl,
+ updateMediaName,
sendMessage,
resetTemplate,
goBack,
@@ -225,6 +236,17 @@ defineExpose({
@update:model-value="updateMediaUrl"
/>
+
+
+
diff --git a/app/javascript/dashboard/helper/specs/templateHelper.spec.js b/app/javascript/dashboard/helper/specs/templateHelper.spec.js
index 6e0661152..375e38a2d 100644
--- a/app/javascript/dashboard/helper/specs/templateHelper.spec.js
+++ b/app/javascript/dashboard/helper/specs/templateHelper.spec.js
@@ -218,6 +218,7 @@ describe('templateHelper', () => {
expect(result.header).toEqual({
media_url: '',
media_type: 'document',
+ media_name: '',
});
expect(result.body).toEqual({
1: '',
diff --git a/app/javascript/dashboard/helper/templateHelper.js b/app/javascript/dashboard/helper/templateHelper.js
index 5c9bbff05..1fb61d760 100644
--- a/app/javascript/dashboard/helper/templateHelper.js
+++ b/app/javascript/dashboard/helper/templateHelper.js
@@ -51,6 +51,11 @@ export const buildTemplateParameters = (template, hasMediaHeaderValue) => {
if (!allVariables.header) allVariables.header = {};
allVariables.header.media_url = '';
allVariables.header.media_type = headerComponent.format.toLowerCase();
+
+ // For document templates, include media_name field for filename support
+ if (headerComponent.format.toLowerCase() === 'document') {
+ allVariables.header.media_name = '';
+ }
}
// Process button variables
diff --git a/app/javascript/dashboard/i18n/locale/en/whatsappTemplates.json b/app/javascript/dashboard/i18n/locale/en/whatsappTemplates.json
index 5f53faaa8..cf28312dc 100644
--- a/app/javascript/dashboard/i18n/locale/en/whatsappTemplates.json
+++ b/app/javascript/dashboard/i18n/locale/en/whatsappTemplates.json
@@ -40,6 +40,7 @@
"BUTTON_LABEL": "Button {index}",
"COUPON_CODE": "Enter coupon code (max 15 chars)",
"MEDIA_URL_LABEL": "Enter {type} URL",
+ "DOCUMENT_NAME_PLACEHOLDER": "Enter document filename (e.g., Invoice_2025.pdf)",
"BUTTON_PARAMETER": "Enter button parameter"
}
}
diff --git a/app/services/whatsapp/populate_template_parameters_service.rb b/app/services/whatsapp/populate_template_parameters_service.rb
index 278e52f64..3f9f64b91 100644
--- a/app/services/whatsapp/populate_template_parameters_service.rb
+++ b/app/services/whatsapp/populate_template_parameters_service.rb
@@ -30,12 +30,12 @@ class Whatsapp::PopulateTemplateParametersService
end
end
- def build_media_parameter(url, media_type)
+ def build_media_parameter(url, media_type, media_name = nil)
return nil if url.blank?
sanitized_url = sanitize_parameter(url)
validate_url(sanitized_url)
- build_media_type_parameter(sanitized_url, media_type.downcase)
+ build_media_type_parameter(sanitized_url, media_type.downcase, media_name)
end
def build_named_parameter(parameter_name, value)
@@ -89,14 +89,14 @@ class Whatsapp::PopulateTemplateParametersService
}
end
- def build_media_type_parameter(sanitized_url, media_type)
+ def build_media_type_parameter(sanitized_url, media_type, media_name = nil)
case media_type
when 'image'
build_image_parameter(sanitized_url)
when 'video'
build_video_parameter(sanitized_url)
when 'document'
- build_document_parameter(sanitized_url)
+ build_document_parameter(sanitized_url, media_name)
else
raise ArgumentError, "Unsupported media type: #{media_type}"
end
@@ -110,8 +110,11 @@ class Whatsapp::PopulateTemplateParametersService
{ type: 'video', video: { link: url } }
end
- def build_document_parameter(url)
- { type: 'document', document: { link: url } }
+ def build_document_parameter(url, media_name = nil)
+ document_params = { link: url }
+ document_params[:filename] = media_name if media_name.present?
+
+ { type: 'document', document: document_params }
end
def rich_formatting?(text)
diff --git a/app/services/whatsapp/providers/whatsapp_cloud_service.rb b/app/services/whatsapp/providers/whatsapp_cloud_service.rb
index 68e965595..124e1e5d3 100644
--- a/app/services/whatsapp/providers/whatsapp_cloud_service.rb
+++ b/app/services/whatsapp/providers/whatsapp_cloud_service.rb
@@ -141,7 +141,11 @@ class Whatsapp::Providers::WhatsappCloudService < Whatsapp::Providers::BaseServi
# {
# processed_params: {
# body: { '1': 'John', '2': '123 Main St' },
- # header: { media_url: 'https://...', media_type: 'image' },
+ # header: {
+ # media_url: 'https://...',
+ # media_type: 'image',
+ # media_name: 'filename.pdf' # Optional, for document templates only
+ # },
# buttons: [{ type: 'url', parameter: 'otp123456' }]
# }
# }
diff --git a/app/services/whatsapp/template_processor_service.rb b/app/services/whatsapp/template_processor_service.rb
index 3b12bf58b..4a89d684a 100644
--- a/app/services/whatsapp/template_processor_service.rb
+++ b/app/services/whatsapp/template_processor_service.rb
@@ -60,9 +60,10 @@ class Whatsapp::TemplateProcessorService
next if value.blank?
if media_url_with_type?(key, header_data)
- media_param = parameter_builder.build_media_parameter(value, header_data['media_type'])
+ media_name = header_data['media_name']
+ media_param = parameter_builder.build_media_parameter(value, header_data['media_type'], media_name)
header_params << media_param if media_param
- elsif key != 'media_type'
+ elsif key != 'media_type' && key != 'media_name'
header_params << parameter_builder.build_parameter(value)
end
end