mirror of
https://github.com/lingble/chatwoot.git
synced 2025-10-30 18:47:51 +00:00
Added comprehensive Twilio WhatsApp content template support (Phase 1)
enabling text, media, and quick reply templates with proper parameter
conversion, sync capabilities.
**Template Types Supported**
- Basic Text Templates: Simple text with variables ({{1}}, {{2}})
- Media Templates: Image/Video/Document templates with text variables
- Quick Reply Templates: Interactive button templates
Front end changes is available via #12277
---------
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Sivin Varghese <64252451+iamsivin@users.noreply.github.com>
114 lines
2.9 KiB
Ruby
114 lines
2.9 KiB
Ruby
class Twilio::TemplateSyncService
|
|
pattr_initialize [:channel!]
|
|
|
|
def call
|
|
fetch_templates_from_twilio
|
|
update_channel_templates
|
|
mark_templates_updated
|
|
rescue Twilio::REST::TwilioError => e
|
|
Rails.logger.error("Twilio template sync failed: #{e.message}")
|
|
false
|
|
end
|
|
|
|
private
|
|
|
|
def fetch_templates_from_twilio
|
|
@templates = client.content.v1.contents.list(limit: 1000)
|
|
end
|
|
|
|
def update_channel_templates
|
|
formatted_templates = @templates.map do |template|
|
|
{
|
|
content_sid: template.sid,
|
|
friendly_name: template.friendly_name,
|
|
language: template.language,
|
|
status: derive_status(template),
|
|
template_type: derive_template_type(template),
|
|
media_type: derive_media_type(template),
|
|
variables: template.variables || {},
|
|
category: derive_category(template),
|
|
body: extract_body_content(template),
|
|
created_at: template.date_created,
|
|
updated_at: template.date_updated
|
|
}
|
|
end
|
|
|
|
channel.update!(
|
|
content_templates: { templates: formatted_templates },
|
|
content_templates_last_updated: Time.current
|
|
)
|
|
end
|
|
|
|
def mark_templates_updated
|
|
channel.update!(content_templates_last_updated: Time.current)
|
|
end
|
|
|
|
def client
|
|
@client ||= channel.send(:client)
|
|
end
|
|
|
|
def derive_status(_template)
|
|
# For now, assume all fetched templates are approved
|
|
# In the future, this could check approval status from Twilio
|
|
'approved'
|
|
end
|
|
|
|
def derive_template_type(template)
|
|
template_types = template.types.keys
|
|
|
|
if template_types.include?('twilio/media')
|
|
'media'
|
|
elsif template_types.include?('twilio/quick-reply')
|
|
'quick_reply'
|
|
elsif template_types.include?('twilio/catalog')
|
|
'catalog'
|
|
else
|
|
'text'
|
|
end
|
|
end
|
|
|
|
def derive_media_type(template)
|
|
return nil unless derive_template_type(template) == 'media'
|
|
|
|
media_content = template.types['twilio/media']
|
|
return nil unless media_content
|
|
|
|
if media_content['image']
|
|
'image'
|
|
elsif media_content['video']
|
|
'video'
|
|
elsif media_content['document']
|
|
'document'
|
|
end
|
|
end
|
|
|
|
def derive_category(template)
|
|
# Map template friendly names or other attributes to categories
|
|
# For now, use utility as default
|
|
case template.friendly_name
|
|
when /marketing|promo|offer|sale/i
|
|
'marketing'
|
|
when /auth|otp|verify|code/i
|
|
'authentication'
|
|
else
|
|
'utility'
|
|
end
|
|
end
|
|
|
|
def extract_body_content(template)
|
|
template_types = template.types
|
|
|
|
if template_types['twilio/text']
|
|
template_types['twilio/text']['body']
|
|
elsif template_types['twilio/media']
|
|
template_types['twilio/media']['body']
|
|
elsif template_types['twilio/quick-reply']
|
|
template_types['twilio/quick-reply']['body']
|
|
elsif template_types['twilio/catalog']
|
|
template_types['twilio/catalog']['body']
|
|
else
|
|
''
|
|
end
|
|
end
|
|
end
|