diff --git a/app/javascript/dashboard/components/widgets/conversation/ReplyBox.vue b/app/javascript/dashboard/components/widgets/conversation/ReplyBox.vue index ff831281b..0d3c35cde 100644 --- a/app/javascript/dashboard/components/widgets/conversation/ReplyBox.vue +++ b/app/javascript/dashboard/components/widgets/conversation/ReplyBox.vue @@ -223,7 +223,8 @@ export default { this.isATwilioWhatsappChannel || this.isAPIInbox || this.isAnEmailChannel || - this.isATwilioSMSChannel + this.isATwilioSMSChannel || + this.isATelegramChannel ); }, replyButtonLabel() { diff --git a/app/javascript/shared/mixins/inboxMixin.js b/app/javascript/shared/mixins/inboxMixin.js index 5ff8509fe..5ec1aeb14 100644 --- a/app/javascript/shared/mixins/inboxMixin.js +++ b/app/javascript/shared/mixins/inboxMixin.js @@ -35,6 +35,9 @@ export default { isAnEmailChannel() { return this.channelType === INBOX_TYPES.EMAIL; }, + isATelegramChannel() { + return this.channelType === INBOX_TYPES.TELEGRAM; + }, isATwilioSMSChannel() { const { medium: medium = '' } = this.inbox; return this.isATwilioChannel && medium === 'sms'; diff --git a/app/models/channel/telegram.rb b/app/models/channel/telegram.rb index e0d020f2f..16e6427e3 100644 --- a/app/models/channel/telegram.rb +++ b/app/models/channel/telegram.rb @@ -32,14 +32,10 @@ class Channel::Telegram < ApplicationRecord "https://api.telegram.org/bot#{bot_token}" end - def send_message_on_telegram(message, chat_id) - response = HTTParty.post("#{telegram_api_url}/sendMessage", - body: { - chat_id: chat_id, - text: message - }) + def send_message_on_telegram(message) + return send_message(message) if message.attachments.empty? - response.parsed_response['result']['message_id'] if response.success? + send_attachments(message) end def get_telegram_profile_image(user_id) @@ -80,4 +76,46 @@ class Channel::Telegram < ApplicationRecord }) errors.add(:bot_token, 'error setting up the webook') unless response.success? end + + def send_message(message) + response = message_request(message.conversation[:additional_attributes]['chat_id'], message.content) + response.parsed_response['result']['message_id'] if response.success? + end + + def send_attachments(message) + send_message(message) unless message.content.nil? + + telegram_attachments = [] + message.attachments.each do |attachment| + telegram_attachment = {} + + case attachment[:file_type] + when 'image' + telegram_attachment[:type] = 'photo' + when 'file' + telegram_attachment[:type] = 'document' + end + telegram_attachment[:media] = attachment.file_url + telegram_attachments << telegram_attachment + end + + response = attachments_request(message.conversation[:additional_attributes]['chat_id'], telegram_attachments) + response.parsed_response['result'].first['message_id'] if response.success? + end + + def attachments_request(chat_id, attachments) + HTTParty.post("#{telegram_api_url}/sendMediaGroup", + body: { + chat_id: chat_id, + media: attachments.to_json + }) + end + + def message_request(chat_id, text) + HTTParty.post("#{telegram_api_url}/sendMessage", + body: { + chat_id: chat_id, + text: text + }) + end end diff --git a/app/services/telegram/send_on_telegram_service.rb b/app/services/telegram/send_on_telegram_service.rb index e6e98ff39..c4b27bc4f 100644 --- a/app/services/telegram/send_on_telegram_service.rb +++ b/app/services/telegram/send_on_telegram_service.rb @@ -8,7 +8,7 @@ class Telegram::SendOnTelegramService < Base::SendOnChannelService def perform_reply ## send reply to telegram message api # https://core.telegram.org/bots/api#sendmessage - message_id = channel.send_message_on_telegram(message.content, conversation[:additional_attributes]['chat_id']) + message_id = channel.send_message_on_telegram(message) message.update!(source_id: message_id) if message_id.present? end diff --git a/spec/assets/attachment.pdf b/spec/assets/attachment.pdf new file mode 100644 index 000000000..e69de29bb diff --git a/spec/models/channel/telegram_spec.rb b/spec/models/channel/telegram_spec.rb new file mode 100644 index 000000000..de174d89c --- /dev/null +++ b/spec/models/channel/telegram_spec.rb @@ -0,0 +1,70 @@ +require 'rails_helper' + +RSpec.describe Channel::Telegram do + let(:telegram_channel) { create(:channel_telegram) } + + context 'when a valid message and empty attachments' do + it 'send message' do + message = create(:message, message_type: :outgoing, content: 'test', + conversation: create(:conversation, inbox: telegram_channel.inbox, additional_attributes: { 'chat_id' => '123' })) + + telegram_message_response = double + + allow(telegram_message_response).to receive(:success?).and_return(true) + allow(telegram_message_response).to receive(:parsed_response).and_return({ 'result' => { 'message_id' => 'telegram_123' } }) + allow(telegram_channel).to receive(:message_request).and_return(telegram_message_response) + expect(telegram_channel.send_message_on_telegram(message)).to eq('telegram_123') + end + end + + context 'when a empty message and valid attachments' do + let(:message) do + create(:message, message_type: :outgoing, content: nil, + conversation: create(:conversation, inbox: telegram_channel.inbox, additional_attributes: { 'chat_id' => '123' })) + end + + it 'send image' do + telegram_attachment_response = double + attachment = message.attachments.new(account_id: message.account_id, file_type: :image) + attachment.file.attach(io: File.open(Rails.root.join('spec/assets/avatar.png')), filename: 'avatar.png', content_type: 'image/png') + + allow(telegram_attachment_response).to receive(:success?).and_return(true) + allow(telegram_attachment_response).to receive(:parsed_response).and_return({ 'result' => [{ 'message_id' => 'telegram_456' }] }) + allow(telegram_channel).to receive(:attachments_request).and_return(telegram_attachment_response) + expect(telegram_channel.send_message_on_telegram(message)).to eq('telegram_456') + end + + it 'send document' do + telegram_attachment_response = double + attachment = message.attachments.new(account_id: message.account_id, file_type: :file) + attachment.file.attach(io: File.open(Rails.root.join('spec/assets/attachment.pdf')), filename: 'attachment.pdf', + content_type: 'application/pdf') + + allow(telegram_attachment_response).to receive(:success?).and_return(true) + allow(telegram_attachment_response).to receive(:parsed_response).and_return({ 'result' => [{ 'message_id' => 'telegram_456' }] }) + allow(telegram_channel).to receive(:attachments_request).and_return(telegram_attachment_response) + expect(telegram_channel.send_message_on_telegram(message)).to eq('telegram_456') + end + end + + context 'when a valid message and valid attachment' do + it 'send both message and attachment' do + message = create(:message, message_type: :outgoing, content: 'test', + conversation: create(:conversation, inbox: telegram_channel.inbox, additional_attributes: { 'chat_id' => '123' })) + + telegram_message_response = double + telegram_attachment_response = double + attachment = message.attachments.new(account_id: message.account_id, file_type: :image) + attachment.file.attach(io: File.open(Rails.root.join('spec/assets/avatar.png')), filename: 'avatar.png', content_type: 'image/png') + + allow(telegram_message_response).to receive(:success?).and_return(true) + allow(telegram_message_response).to receive(:parsed_response).and_return({ 'result' => { 'message_id' => 'telegram_456' } }) + allow(telegram_attachment_response).to receive(:success?).and_return(true) + allow(telegram_attachment_response).to receive(:parsed_response).and_return({ 'result' => [{ 'message_id' => 'telegram_789' }] }) + + allow(telegram_channel).to receive(:message_request).and_return(telegram_message_response) + allow(telegram_channel).to receive(:attachments_request).and_return(telegram_attachment_response) + expect(telegram_channel.send_message_on_telegram(message)).to eq('telegram_789') + end + end +end