diff --git a/app/models/channel/filter/auto_response_check.rb b/app/models/channel/filter/auto_response_check.rb index ef12d599e..139be7865 100644 --- a/app/models/channel/filter/auto_response_check.rb +++ b/app/models/channel/filter/auto_response_check.rb @@ -8,6 +8,12 @@ module Channel::Filter::AutoResponseCheck mail[ 'x-zammad-send-auto-response'.to_sym ] = false mail[ 'x-zammad-is-auto-response'.to_sym ] = true + if !mail[ 'x-zammad-article-preferences'.to_sym ] + mail[ 'x-zammad-article-preferences'.to_sym ] = {} + end + mail[ 'x-zammad-article-preferences'.to_sym ]['send-auto-response'] = false + mail[ 'x-zammad-article-preferences'.to_sym ]['is-auto-response'] = true + return if mail[ 'x-loop'.to_sym ] && mail[ 'x-loop'.to_sym ] =~ /(yes|true)/i return if mail[ 'precedence'.to_sym ] && mail[ 'precedence'.to_sym ] =~ /bulk/i return if mail[ 'auto-submitted'.to_sym ] && mail[ 'auto-submitted'.to_sym ] =~ /auto-(generated|replied)/i @@ -16,5 +22,8 @@ module Channel::Filter::AutoResponseCheck mail[ 'x-zammad-send-auto-response'.to_sym ] = true mail[ 'x-zammad-is-auto-response'.to_sym ] = false + mail[ 'x-zammad-article-preferences'.to_sym ]['send-auto-response'] = true + mail[ 'x-zammad-article-preferences'.to_sym ]['is-auto-response'] = false + end end diff --git a/app/models/ticket.rb b/app/models/ticket.rb index b544d68b3..c456fa36f 100644 --- a/app/models/ticket.rb +++ b/app/models/ticket.rb @@ -697,6 +697,15 @@ perform changes on ticket next if user.email =~ /(mailer-daemon|postmaster|abuse|root)@.+?\..+?/i end + # check if notification should be send because of customer emails + if item && item[:article_id] + article = Ticket::Article.lookup(id: item[:article_id]) + if article && article.preferences['is-auto-response'] == true && article.from && article.from =~ /#{Regexp.quote(user.email)}/i + logger.info "Send not trigger based notification to #{user.email} because of auto response tagged incoming email" + next + end + end + email = user.email.downcase.strip next if recipient_already[email] recipient_already[email] = true @@ -712,39 +721,6 @@ perform changes on ticket next if !email_address next if !email_address.channel_id - # check if notification should be send because of customer emails - if item && item[:article_id] - article = Ticket::Article.lookup(id: item[:article_id]) - if article - type = Ticket::Article::Type.lookup(id: article.type_id) - sender = Ticket::Article::Sender.lookup(id: article.sender_id) - if sender && sender.name == 'Customer' && type && type.name == 'email' - - # get attachment - list = Store.list( - object: 'Ticket::Article::Mail', - o_id: article.id, - ) - if list && list[0] - file = Store.find(list[0].id) - if file - content = file.content - if content - parser = Channel::EmailParser.new - mail = parser.parse(content) - - # check headers - next if mail['x-loop'.to_sym] =~ /yes/i - next if mail['precedence'.to_sym] =~ /bulk/i - next if mail['auto-submitted'.to_sym] =~ /auto-generated/i - next if mail['x-auto-response-suppress'.to_sym] =~ /yes/i - end - end - end - end - end - end - objects = { ticket: self, article: articles.last, diff --git a/test/unit/email_process_auto_response_test.rb b/test/unit/email_process_auto_response_test.rb index 1dcd35869..a0b37e928 100644 --- a/test/unit/email_process_auto_response_test.rb +++ b/test/unit/email_process_auto_response_test.rb @@ -3,7 +3,49 @@ require 'test_helper' class EmailProcessAutoResponseTest < ActiveSupport::TestCase - test 'process with out of office check' do + test 'process auto reply check' do + + roles = Role.where(name: 'Agent') + agent1 = User.create_or_update( + login: 'ticket-auto-responder-agent1@example.com', + firstname: 'AutoReponder', + lastname: 'Agent1', + email: 'ticket-auto-responder-agent1@example.com', + password: 'agentpw', + active: true, + roles: roles, + groups: Group.all, + updated_by_id: 1, + created_by_id: 1, + ) + + Trigger.create_or_update( + name: 'auto reply', + condition: { + 'ticket.state_id' => { + 'operator' => 'is', + 'value' => Ticket::State.lookup(name: 'new').id.to_s, + } + }, + perform: { + 'notification.email' => { + 'body' => 'some text
#{ticket.customer.lastname}
#{ticket.title}', + 'recipient' => 'ticket_customer', + 'subject' => 'Thanks for your inquiry (#{ticket.title})!', + }, + 'ticket.priority_id' => { + 'value' => Ticket::Priority.lookup(name: '3 high').id.to_s, + }, + 'ticket.tags' => { + 'operator' => 'add', + 'value' => 'aa, kk', + }, + }, + disable_notification: true, + active: true, + created_by_id: 1, + updated_by_id: 1, + ) email_raw_string = "From: me@example.com To: customer@example.com @@ -13,6 +55,8 @@ Some Text" ticket_p, article_p, user_p, mail = Channel::EmailParser.new.process({}, email_raw_string) assert_equal(true, mail['x-zammad-send-auto-response'.to_sym]) + Scheduler.worker(true) + assert_equal(2, article_p.ticket.articles.count) email_raw_string = "From: me@example.com To: customer@example.com @@ -23,6 +67,8 @@ Some Text" ticket_p, article_p, user_p, mail = Channel::EmailParser.new.process({}, email_raw_string) assert_equal(false, mail['x-zammad-send-auto-response'.to_sym]) + Scheduler.worker(true) + assert_equal(1, article_p.ticket.articles.count) email_raw_string = "From: me@example.com To: customer@example.com @@ -40,6 +86,8 @@ Subject: some new subject Auto-Submitted: auto-generated Some Text" + Scheduler.worker(true) + assert_equal(1, article_p.ticket.articles.count) ticket_p, article_p, user_p, mail = Channel::EmailParser.new.process({}, email_raw_string) assert_equal(false, mail['x-zammad-send-auto-response'.to_sym]) @@ -54,6 +102,112 @@ Some Text" ticket_p, article_p, user_p, mail = Channel::EmailParser.new.process({}, email_raw_string) assert_equal(false, mail['x-zammad-send-auto-response'.to_sym]) + Scheduler.worker(true) + assert_equal(1, article_p.ticket.articles.count) + + email_raw_string = "Return-Path: +X-Original-To: sales@znuny.com +Received: from mail-qk0-f170.example.com (mail-qk0-f170.example.com [209.1.1.1]) + by arber.znuny.com (Postfix) with ESMTPS id C3AED5FE2E + for ; Mon, 22 Aug 2016 19:03:15 +0200 (CEST) +Received: by mail-qk0-f170.example.com with SMTP id t7so87721720qkh.1 + for ; Mon, 22 Aug 2016 10:03:15 -0700 (PDT) +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=XX.XX; s=example; + h=to:from:date:message-id:subject:mime-version:precedence + :auto-submitted:content-transfer-encoding:content-disposition; + bh=SL5tTVvGdxsKjLic38irxzlP439P3jixJH0QTG1HJ5I=; + b=CIk3PLELgjOCagyiFFbd6rlb8ZRDGYRUrg5Dntxa7e5X+PT4cgL+IE13N9TFkK8ZUJ + GohlaPLGiBymIYLTtYMKUpcf22oiX8ZgGiSu1aEMC1Gsa1ZDf+vpy4kd4+7EecRT3IWF + 4RafQxeaqe67budhQpO1Z6UAel6BdJj0xguKM= +X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=1e100.net; s=20130820; + h=x-gm-message-state:to:from:date:message-id:subject:mime-version + :precedence:auto-submitted:content-transfer-encoding + :content-disposition; + bh=SL5tTVvGdxsKjLic38irxzlP439P3jixJH0QTG1HJ5I=; + b=PYULo3xigc4O/cuNZ79OathQ5HDMFWWIwUxz6CHbpXDQR5k3EPy/skJU1992hVz9Rl + xiGwScBCkMqOjlxHjQSWhFJIxNtdvMk4m0bixBZ79IEvRuQa9cEbqjf6efnV58br5ftQ + 2osHrtQczoSqLE/d61/o102RfQ0avVyX8XNJik0iepg8MiCY7LTOE9hrbnuDDLxgQecH + rMEfkR7bafcUj1YEto5Vd7uV11cVZYx8UIQqVAVbfygv8dTSFeOzz3NyM0M41rRexfYH + 79Yi5i7z/Wk6q2427wkJ3FIR1B7VQVQEmcq/Texbch+gAXPGBNPUHdg2WHt7NXGktrHL + d3DA== +X-Gm-Message-State: AE9vXwMCTnihGiG/tc7xNNlhFLcEK6DPp7otypJg5e4alD3xGK2R707BP29druIi/mcdNyaHg1vP5lSZ8EvrwvOF8iA0HNFhECGjBTJ40YrSJAR8E89xVwxFv/er+U3vEpqmPmt+hL4QhxK/+D2gKOcHSxku +X-Received: by 10.1.1.1 with SMTP id 17mr25015996qkf.279.1471885393931; + Mon, 22 Aug 2016 10:03:13 -0700 (PDT) +To: sales@znuny.com +From: \"XXX\" +Date: Mon, 22 Aug 2016 10:03:13 -0700 +Message-ID: +Subject: XX PieroXXway - vacation response RE: Callback Request: XX XX [Ticket#1118974] +MIME-Version: 1.0 +Precedence: bulk +X-Autoreply: yes +Auto-Submitted: auto-replied +Content-Type: text/html; charset=UTF-8 +Content-Transfer-Encoding: quoted-printable +Content-Disposition: inline + +test" + + ticket_p, article_p, user_p, mail = Channel::EmailParser.new.process({}, email_raw_string) + assert_equal(false, mail['x-zammad-send-auto-response'.to_sym]) + Scheduler.worker(true) + assert_equal(1, article_p.ticket.articles.count) + + # add an agent notification + Trigger.create_or_update( + name: 'additional agent notification', + condition: { + 'ticket.state_id' => { + 'operator' => 'is', + 'value' => Ticket::State.lookup(name: 'new').id.to_s, + } + }, + perform: { + 'notification.email' => { + 'body' => 'some text
#{ticket.customer.lastname}
#{ticket.title}', + 'recipient' => 'ticket_agents', + 'subject' => 'New Ticket add. info (#{ticket.title})!', + }, + 'ticket.priority_id' => { + 'value' => Ticket::Priority.lookup(name: '3 high').id.to_s, + }, + 'ticket.tags' => { + 'operator' => 'add', + 'value' => 'aa, kk', + }, + }, + disable_notification: true, + active: true, + created_by_id: 1, + updated_by_id: 1, + ) + + email_raw_string = "From: me@example.com +To: customer@example.com +Subject: some new subject +X-Loop: yes + +Some Text" + + ticket_p, article_p, user_p, mail = Channel::EmailParser.new.process({}, email_raw_string) + assert_equal(false, mail['x-zammad-send-auto-response'.to_sym]) + Scheduler.worker(true) + assert_equal(2, article_p.ticket.articles.count) + article_customer = article_p.ticket.articles.first + assert_equal('me@example.com', article_customer.from) + assert_equal('customer@example.com', article_customer.to) + assert_equal('Customer', article_customer.sender.name) + assert_equal('email', article_customer.type.name) + article_notification = article_p.ticket.articles.last + assert_match(/New Ticket add. info/, article_notification.subject) + assert_no_match(/me@example.com/, article_notification.to) + assert_match(/#{agent1.email}/, article_notification.to) + assert_equal('System', article_notification.sender.name) + assert_equal('email', article_notification.type.name) + + Trigger.destroy_all end