require "email_reply_trimmer" class MessagesMailReceiver def self.regexp /(?\d+)\.(?\d+)\.(?\w+)/ end def initialize(match) @message = Message.find_by_id(match[:message_id]) @user = User.find_by_id(match[:user_id]) raise "Message could not be found" if @message.nil? raise "User could not be found" if @user.nil? hash = @message.mail_hash_for_user(@user) raise "Hash does not match expectations" unless hash.casecmp(match[:hash]) == 0 end def received(data) mail = Mail.new data mail_part = get_mail_part(mail) raise "No valid content could be found" if mail_part.nil? body = mail_part.body.decoded unless mail_part.content_type_parameters.nil? body = body.force_encoding mail_part.content_type_parameters[:charset] end if MIME::Type.simplified(mail_part.content_type) == "text/html" body = Nokogiri::HTML(body).text end body.encode!(Encoding::default_internal) body = EmailReplyTrimmer.trim(body) raise BlankBodyException if body.empty? message = @user.send_messages.new body: body, group: @message.group, private: @message.private, received_email: data if @message.reply_to message.reply_to_message = @message.reply_to_message else message.reply_to_message = @message end if mail.subject message.subject = mail.subject.gsub("[#{FoodsoftConfig[:name]}] ", "") else message.subject = I18n.t('messages.model.reply_subject', subject: message.reply_to_message.subject) end message.add_recipients [@message.sender_id] message.save! DeliverMessageJob.perform_later(message) end private def get_mail_part(mail) return mail unless mail.multipart? mail_part = nil for part in mail.parts part = get_mail_part(part) content_type = MIME::Type.simplified(part.content_type) if content_type == "text/plain" || !mail_part && content_type == "text/html" mail_part = part end end mail_part end class BlankBodyException < MidiSmtpServer::SmtpdException def initialize(msg = nil) super msg, 541, 'The recipient address rejected your message because of a blank plain body' end end end