Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4a3b771e98 | ||
|
|
5b5b1b42e3 | ||
|
|
77ff49a96c | ||
|
|
9f35f984cc | ||
|
|
15f85cfcdb | ||
|
|
2a6bae2c6f | ||
|
|
f94f436d0b | ||
|
|
5ecf39a3a7 |
@@ -126,6 +126,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;
|
||||
@@ -172,6 +177,7 @@ defineExpose({
|
||||
renderedTemplate,
|
||||
v$,
|
||||
updateMediaUrl,
|
||||
updateMediaName,
|
||||
sendMessage,
|
||||
resetTemplate,
|
||||
goBack,
|
||||
@@ -225,6 +231,21 @@ defineExpose({
|
||||
@update:model-value="updateMediaUrl"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
v-if="headerComponent?.format === 'DOCUMENT'"
|
||||
class="flex items-center mb-2.5"
|
||||
>
|
||||
<Input
|
||||
:model-value="processedParams.header?.media_name || ''"
|
||||
type="text"
|
||||
class="flex-1"
|
||||
:placeholder="
|
||||
t('WHATSAPP_TEMPLATES.PARSER.MEDIA_NAME_PLACEHOLDER') ||
|
||||
'Enter custom filename (optional)'
|
||||
"
|
||||
@update:model-value="updateMediaName"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Body Variables Section -->
|
||||
|
||||
@@ -51,6 +51,9 @@ export const buildTemplateParameters = (template, hasMediaHeaderValue) => {
|
||||
if (!allVariables.header) allVariables.header = {};
|
||||
allVariables.header.media_url = '';
|
||||
allVariables.header.media_type = headerComponent.format.toLowerCase();
|
||||
if (headerComponent.format === 'DOCUMENT') {
|
||||
allVariables.header.media_name = '';
|
||||
}
|
||||
}
|
||||
|
||||
// Process button variables
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
"BUTTON_LABEL": "Button {index}",
|
||||
"COUPON_CODE": "Enter coupon code (max 15 chars)",
|
||||
"MEDIA_URL_LABEL": "Enter {type} URL",
|
||||
"MEDIA_NAME_PLACEHOLDER": "Enter custom filename",
|
||||
"BUTTON_PARAMETER": "Enter button parameter"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,15 @@ 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)
|
||||
filename = (media_name.presence || extract_filename_from_url(sanitized_url))
|
||||
build_document_parameter(sanitized_url, filename)
|
||||
else
|
||||
raise ArgumentError, "Unsupported media type: #{media_type}"
|
||||
end
|
||||
@@ -110,8 +111,10 @@ class Whatsapp::PopulateTemplateParametersService
|
||||
{ type: 'video', video: { link: url } }
|
||||
end
|
||||
|
||||
def build_document_parameter(url)
|
||||
{ type: 'document', document: { link: url } }
|
||||
def build_document_parameter(url, filename = nil)
|
||||
document_param = { link: url }
|
||||
document_param[:filename] = filename if filename.present?
|
||||
{ type: 'document', document: document_param }
|
||||
end
|
||||
|
||||
def rich_formatting?(text)
|
||||
@@ -145,4 +148,19 @@ class Whatsapp::PopulateTemplateParametersService
|
||||
rescue URI::InvalidURIError => e
|
||||
raise ArgumentError, "Invalid URL format: #{e.message}. Please enter a valid URL like https://example.com/document.pdf"
|
||||
end
|
||||
|
||||
def extract_filename_from_url(url)
|
||||
return nil if url.blank?
|
||||
|
||||
begin
|
||||
uri = URI.parse(url)
|
||||
path = uri.path
|
||||
filename = File.basename(path)
|
||||
|
||||
# Return filename only if it has an extension, otherwise return nil
|
||||
filename.include?('.') ? filename : nil
|
||||
rescue URI::InvalidURIError
|
||||
nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -60,9 +60,9 @@ 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_param = parameter_builder.build_media_parameter(value, header_data['media_type'], header_data['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
|
||||
|
||||
@@ -182,6 +182,50 @@ describe Whatsapp::SendOnWhatsappService do
|
||||
expect(message.reload.source_id).to eq('123456789')
|
||||
end
|
||||
|
||||
it 'handles template with document header parameters and extracts filename' do
|
||||
processed_params = {
|
||||
'body' => { '1' => 'Order123' },
|
||||
'header' => { 'media_url' => 'https://example.com/documents/receipt.pdf', 'media_type' => 'document' }
|
||||
}
|
||||
document_template_params = build_sample_template_params(processed_params)
|
||||
message = create_message_with_template('', document_template_params)
|
||||
|
||||
components = [
|
||||
{ type: 'header',
|
||||
parameters: [{ type: 'document', document: { link: 'https://example.com/documents/receipt.pdf', filename: 'receipt.pdf' } }] },
|
||||
{ type: 'body', parameters: [{ type: 'text', text: 'Order123' }] }
|
||||
]
|
||||
stub_sample_template_request(components)
|
||||
|
||||
described_class.new(message: message).perform
|
||||
expect(message.reload.source_id).to eq('123456789')
|
||||
end
|
||||
|
||||
it 'handles template with document header parameters and custom media_name' do
|
||||
processed_params = {
|
||||
'body' => { '1' => 'Order456' },
|
||||
'header' => {
|
||||
'media_url' => 'https://baserow.example.com/media/user_files/lBWKm8sZ24l7JLkz5V253Yt0RWG4ypfu_e5a8419c8e6f9a3e58d868bd065f4a4d7cea6a30b4716c380a9b0e1628596d9f.pdf',
|
||||
'media_type' => 'document',
|
||||
'media_name' => 'customer_charge.pdf'
|
||||
}
|
||||
}
|
||||
custom_name_template_params = build_sample_template_params(processed_params)
|
||||
message = create_message_with_template('', custom_name_template_params)
|
||||
|
||||
components = [
|
||||
{ type: 'header',
|
||||
parameters: [{ type: 'document',
|
||||
document: { link: 'https://baserow.example.com/media/user_files/lBWKm8sZ24l7JLkz5V253Yt0RWG4ypfu_e5a8419c8e6f9a3e58d868bd065f4a4d7cea6a30b4716c380a9b0e1628596d9f.pdf',
|
||||
filename: 'customer_charge.pdf' } }] },
|
||||
{ type: 'body', parameters: [{ type: 'text', text: 'Order456' }] }
|
||||
]
|
||||
stub_sample_template_request(components)
|
||||
|
||||
described_class.new(message: message).perform
|
||||
expect(message.reload.source_id).to eq('123456789')
|
||||
end
|
||||
|
||||
it 'handles empty processed_params gracefully' do
|
||||
empty_template_params = {
|
||||
name: 'sample_shipping_confirmation',
|
||||
|
||||
Reference in New Issue
Block a user