aboutsummaryrefslogtreecommitdiffstats
path: root/app/models/request_mailer.rb
blob: 494beba1635b23d114ef9623899bb3e951e92bcd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# models/request_mailer.rb:
# Emails which go to public bodies on behalf of users.
#
# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved.
# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
#
# $Id: request_mailer.rb,v 1.25 2008-02-29 16:00:29 francis Exp $

class RequestMailer < ApplicationMailer
    
    # We always set Reply-To when we set Sender to be different from From,
    # since some email clients seem to erroneously use the envelope from when
    # they shouldn't, and this might help. (Have had mysterious cases of a
    # reply coming in duplicate from a public body to both From and envelope
    # from)
    
    # Email to public body requesting info
    def initial_request(info_request, outgoing_message)
        @from = info_request.incoming_name_and_email
        headers 'Sender' => info_request.envelope_name_and_email, 
                'Reply-To' => @from
        @recipients = info_request.recipient_name_and_email
        @subject    = info_request.email_subject_request
        @body       = {:info_request => info_request, :outgoing_message => outgoing_message,
            :contact_email => MySociety::Config.get("CONTACT_EMAIL", 'contact@localhost') }
    end

    # Later message to public body regarding existing request
    def followup(info_request, outgoing_message, incoming_message_followup)
        @from = info_request.incoming_name_and_email
        headers 'Sender' => info_request.envelope_name_and_email,
                'Reply-To' => @from
        if incoming_message_followup.nil?
            @recipients = info_request.recipient_name_and_email
        else
            @recipients = incoming_message_followup.mail.from_addrs.to_s
        end
        @subject    = 'Re: Freedom of Information Request - ' + info_request.title
        @subject    = info_request.email_subject_followup
        @body       = {:info_request => info_request, :outgoing_message => outgoing_message,
            :incoming_message_followup => incoming_message_followup,
            :contact_email => MySociety::Config.get("CONTACT_EMAIL", 'contact@localhost') }
    end

    # Incoming message arrived at FOI address, but hasn't got To:/CC: of valid request
    def bounced_message(email)
        @from = contact_from_name_and_email
        @recipients = @from
        @subject = "Incoming email to unknown FOI request"
        email.setup_forward(self)
    end

    # An FOI response is outside the scope of the system, and needs admin attention
    def requires_admin(info_request)
        @from = contact_from_name_and_email
        @recipients = @from
        @subject = "Unusual FOI response, requires admin attention"
        # XXX these are repeats of things in helpers/link_to_helper.rb, and shouldn't be
        url =  show_request_url(:url_title => info_request.url_title)
        admin_url =  MySociety::Config.get("ADMIN_BASE_URL", "/admin/") + 'request/show/' + info_request.id.to_s
        @body       = {:info_request => info_request, :url => url, :admin_url => admin_url }
    end

    # Tell the requester that a new response has arrived
    def new_response(info_request, incoming_message)
        post_redirect = PostRedirect.new(
            :uri => describe_state_url(:id => info_request.id),
            :user_id => info_request.user.id)
        post_redirect.save!
        url = confirm_url(:email_token => post_redirect.email_token)

        @from = contact_from_name_and_email
        @recipients = info_request.user.name_and_email
        @subject = "New response to your FOI request - " + info_request.title
        @body = { :incoming_message => incoming_message, :info_request => info_request, :url => url }
    end

    # Tell the requester that a new response has arrived
    def overdue_alert(info_request, user)
        last_response = info_request.get_last_response
        if last_response.nil?
            respond_url = show_response_no_followup_url(:id => info_request.id)
        else
            respond_url = show_response_url(:id => info_request.id, :incoming_message_id => last_response.id)
        end
        respond_url = respond_url + "#show_response_followup" 

        post_redirect = PostRedirect.new(
            :uri => respond_url,
            :user_id => user.id)
        post_redirect.save!
        url = confirm_url(:email_token => post_redirect.email_token)

        @from = contact_from_name_and_email
        @recipients = user.name_and_email
        @subject = "You're overdue a response to your FOI request - " + info_request.title
        @body = { :info_request => info_request, :url => url }
    end


    # Class function, called by script/mailin with all incoming responses.
    # [ This is a copy (Monkeypatch!) of function from action_mailer/base.rb,
    # but which additionally passes the raw_email to the member function, as we
    # want to record it. ]
    def self.receive(raw_email)
        logger.info "Received mail:\n #{raw_email}" unless logger.nil?
        mail = TMail::Mail.parse(raw_email)
        mail.base64_decode
        new.receive(mail, raw_email)
    end

    # Member function, called on the new class made in self.receive above
    def receive(email, raw_email)
        # Find which info requests the email is for
        reply_info_requests = []
        bounce_info_requests = []
        for address in (email.to || []) + (email.cc || [])
            reply_info_request = InfoRequest.find_by_incoming_email(address)
            reply_info_requests.push(reply_info_request) if reply_info_request
            bounce_info_request = InfoRequest.find_by_envelope_email(address)
            bounce_info_requests.push(bounce_info_request) if bounce_info_request
        end

        # Nothing found
        if reply_info_requests.size == 0 && bounce_info_requests.size == 0
            RequestMailer.deliver_bounced_message(email)
        end

        # Send the message to each request, to be archived with it
        for reply_info_request in reply_info_requests
            reply_info_request.receive(email, raw_email, false)
        end
        for bounce_info_request in bounce_info_requests
            bounce_info_request.receive(email, raw_email, true)
        end
    end

    # Send email alerts for overdue requests
    def self.alert_overdue_requests()
        #puts "alert_overdue_requests"
        info_requests = InfoRequest.find(:all, :conditions => [ "described_state = 'waiting_response' and not awaiting_description" ], :include => [ :user ] )
        for info_request in info_requests
            # Only overdue requests
            if info_request.calculate_status == 'waiting_response_overdue'
                # For now, just to the user who created the request
                sent_already = UserInfoRequestSentAlert.find(:first, :conditions => [ "alert_type = 'overdue_1' and user_id = ? and info_request_id = ?", info_request.user_id, info_request.id])
                if sent_already.nil?
                    # Alert not yet sent for this user
                    puts "sending overdue alert to info_request " + info_request.id.to_s + " user " + info_request.user_id.to_s
                    store_sent = UserInfoRequestSentAlert.new
                    store_sent.info_request = info_request
                    store_sent.user = info_request.user
                    store_sent.alert_type = 'overdue_1'
                    RequestMailer.deliver_overdue_alert(info_request, info_request.user)
                    store_sent.save!
                    #puts "sent " + info_request.user.email
                end
            end
        end

    end
end