mirror of
				https://github.com/lingble/chatwoot.git
				synced 2025-10-29 10:12:34 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			122 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
			
		
		
	
	
			122 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
| # Find the various telegram payload samples here: https://core.telegram.org/bots/webhooks#testing-your-bot-with-updates
 | |
| # https://core.telegram.org/bots/api#available-types
 | |
| 
 | |
| class Telegram::IncomingMessageService
 | |
|   include ::FileTypeHelper
 | |
|   pattr_initialize [:inbox!, :params!]
 | |
| 
 | |
|   def perform
 | |
|     # chatwoot doesn't support group conversations at the moment
 | |
|     return unless private_message?
 | |
| 
 | |
|     set_contact
 | |
|     update_contact_avatar
 | |
|     set_conversation
 | |
|     @message = @conversation.messages.build(
 | |
|       content: params[:message][:text].presence || params[:message][:caption],
 | |
|       account_id: @inbox.account_id,
 | |
|       inbox_id: @inbox.id,
 | |
|       message_type: :incoming,
 | |
|       sender: @contact,
 | |
|       source_id: (params[:message][:message_id]).to_s
 | |
|     )
 | |
|     attach_files
 | |
|     @message.save!
 | |
|   end
 | |
| 
 | |
|   private
 | |
| 
 | |
|   def private_message?
 | |
|     params.dig(:message, :chat, :type) == 'private'
 | |
|   end
 | |
| 
 | |
|   def set_contact
 | |
|     contact_inbox = ::ContactInboxWithContactBuilder.new(
 | |
|       source_id: params[:message][:from][:id],
 | |
|       inbox: inbox,
 | |
|       contact_attributes: contact_attributes
 | |
|     ).perform
 | |
| 
 | |
|     @contact_inbox = contact_inbox
 | |
|     @contact = contact_inbox.contact
 | |
|   end
 | |
| 
 | |
|   def update_contact_avatar
 | |
|     return if @contact.avatar.attached?
 | |
| 
 | |
|     avatar_url = inbox.channel.get_telegram_profile_image(params[:message][:from][:id])
 | |
|     ::Avatar::AvatarFromUrlJob.perform_later(@contact, avatar_url) if avatar_url
 | |
|   end
 | |
| 
 | |
|   def conversation_params
 | |
|     {
 | |
|       account_id: @inbox.account_id,
 | |
|       inbox_id: @inbox.id,
 | |
|       contact_id: @contact.id,
 | |
|       contact_inbox_id: @contact_inbox.id,
 | |
|       additional_attributes: conversation_additional_attributes
 | |
|     }
 | |
|   end
 | |
| 
 | |
|   def set_conversation
 | |
|     @conversation = @contact_inbox.conversations.first
 | |
|     return if @conversation
 | |
| 
 | |
|     @conversation = ::Conversation.create!(conversation_params)
 | |
|   end
 | |
| 
 | |
|   def contact_attributes
 | |
|     {
 | |
|       name: "#{params[:message][:from][:first_name]} #{params[:message][:from][:last_name]}",
 | |
|       additional_attributes: additional_attributes
 | |
|     }
 | |
|   end
 | |
| 
 | |
|   def additional_attributes
 | |
|     {
 | |
|       username: params[:message][:from][:username],
 | |
|       language_code: params[:message][:from][:language_code]
 | |
|     }
 | |
|   end
 | |
| 
 | |
|   def conversation_additional_attributes
 | |
|     {
 | |
|       chat_id: params[:message][:chat][:id]
 | |
|     }
 | |
|   end
 | |
| 
 | |
|   def file_content_type
 | |
|     return :image if params[:message][:photo].present? || params.dig(:message, :sticker, :thumb).present?
 | |
|     return :audio if params[:message][:voice].present? || params[:message][:audio].present?
 | |
|     return :video if params[:message][:video].present?
 | |
| 
 | |
|     file_type(params[:message][:document][:mime_type])
 | |
|   end
 | |
| 
 | |
|   def attach_files
 | |
|     return unless file
 | |
| 
 | |
|     attachment_file = Down.download(
 | |
|       inbox.channel.get_telegram_file_path(file[:file_id])
 | |
|     )
 | |
| 
 | |
|     @message.attachments.new(
 | |
|       account_id: @message.account_id,
 | |
|       file_type: file_content_type,
 | |
|       file: {
 | |
|         io: attachment_file,
 | |
|         filename: attachment_file.original_filename,
 | |
|         content_type: attachment_file.content_type
 | |
|       }
 | |
|     )
 | |
|   end
 | |
| 
 | |
|   def file
 | |
|     @file ||= visual_media_params || params[:message][:voice].presence || params[:message][:audio].presence || params[:message][:document].presence
 | |
|   end
 | |
| 
 | |
|   def visual_media_params
 | |
|     params[:message][:photo].presence&.last || params.dig(:message, :sticker, :thumb).presence || params[:message][:video].presence
 | |
|   end
 | |
| end
 | 
