Chatwoot/lib/integrations/csml/processor_service.rb

142 lines
3.7 KiB
Ruby

class Integrations::Csml::ProcessorService < Integrations::BotProcessorService
pattr_initialize [:event_name!, :event_data!, :agent_bot!]
private
def csml_client
@csml_client ||= CsmlEngine.new
end
def get_response(session_id, content)
csml_client.run(
bot_payload,
{
client: client_params(session_id),
payload: message_payload(content),
metadata: metadata_params
}
)
end
def client_params(session_id)
{
bot_id: "chatwoot-bot-#{conversation.inbox.id}",
channel_id: "chatwoot-bot-inbox-#{conversation.inbox.id}",
user_id: session_id
}
end
def message_payload(content)
{
content_type: 'text',
content: { text: content }
}
end
def metadata_params
{
conversation: conversation,
contact: conversation.contact
}
end
def bot_payload
{
id: "chatwoot-csml-bot-#{agent_bot.id}",
name: "chatwoot-csml-bot-#{agent_bot.id}",
default_flow: 'chatwoot_bot_flow',
flows: [
{
id: "chatwoot-csml-bot-flow-#{agent_bot.id}-inbox-#{conversation.inbox.id}",
name: 'chatwoot_bot_flow',
content: agent_bot.bot_config['csml_content'],
commands: []
}
]
}
end
def process_response(message, response)
csml_messages = response['messages']
has_conversation_ended = response['conversation_end']
process_action(message, 'handoff') if has_conversation_ended.present?
return if csml_messages.blank?
# We do not support wait, typing now.
csml_messages.each do |csml_message|
create_messages(csml_message, conversation)
end
end
def create_messages(message, conversation)
message_payload = message['payload']
case message_payload['content_type']
when 'text'
process_text_messages(message_payload, conversation)
when 'question'
process_question_messages(message_payload, conversation)
when 'image'
process_image_messages(message_payload, conversation)
end
end
def process_text_messages(message_payload, conversation)
conversation.messages.create(
{
message_type: :outgoing,
account_id: conversation.account_id,
inbox_id: conversation.inbox_id,
content: message_payload['content']['text'],
sender: agent_bot
}
)
end
def process_question_messages(message_payload, conversation)
buttons = message_payload['content']['buttons'].map do |button|
{ title: button['content']['title'], value: button['content']['payload'] }
end
conversation.messages.create(
{
message_type: :outgoing,
account_id: conversation.account_id,
inbox_id: conversation.inbox_id,
content: message_payload['content']['title'],
content_type: 'input_select',
content_attributes: { items: buttons },
sender: agent_bot
}
)
end
def prepare_attachment(message_payload, message, account_id)
attachment_params = { file_type: :image, account_id: account_id }
attachment_url = message_payload['content']['url']
attachment = message.attachments.new(attachment_params)
attachment_file = Down.download(attachment_url)
attachment.file.attach(
io: attachment_file,
filename: attachment_file.original_filename,
content_type: attachment_file.content_type
)
end
def process_image_messages(message_payload, conversation)
message = conversation.messages.new(
{
message_type: :outgoing,
account_id: conversation.account_id,
inbox_id: conversation.inbox_id,
content: '',
content_type: 'text',
sender: agent_bot
}
)
prepare_attachment(message_payload, message, conversation.account_id)
message.save!
end
end