aboutsummaryrefslogtreecommitdiffstats
path: root/app/models/request_mailer.rb
blob: 817715820dccdb9586c5a8cd3e13117775682e6d (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
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
# 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.40 2008-07-14 12:06:51 francis Exp $

class RequestMailer < ApplicationMailer
    
    # Email to public body requesting info
    def initial_request(info_request, outgoing_message)
        @from = info_request.incoming_name_and_email
        @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
        @recipients = RequestMailer.name_and_email_for_followup(info_request, incoming_message_followup)
        @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
    # Separate function, so can be called from controller for logging
    def RequestMailer.name_and_email_for_followup(info_request, incoming_message_followup)
        if incoming_message_followup.nil?
            @recipients = info_request.recipient_name_and_email
        else
            @recipients = incoming_message_followup.mail.from_addrs.to_s
        end
    end

    # Incoming message arrived for a request, but new responses have been stopped.
    def stopped_responses(info_request, email)
        @from = contact_from_name_and_email
        @recipients = email.from_addrs.to_s
        @subject = "Your response to an FOI request was not delivered"
        email.setup_forward(self)
        @body = { 
            :info_request => info_request,
            :contact_email => MySociety::Config.get("CONTACT_EMAIL", 'contact@localhost')     
        }
    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 - " + info_request.title
        url = main_url(request_url(info_request))
        admin_url = request_admin_url(info_request)
        @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 the public body is late in replying
    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

    # Tell the requester that they need to say if the new response
    # contains info or not
    def new_response_reminder_alert(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 = "Did the response you got contain what you wanted? - " + info_request.title
        @body = { :incoming_message => incoming_message, :info_request => info_request, :url => url }
    end

    # Tell the requester that they need to clarify their request
    def not_clarified_alert(info_request, incoming_message)
        respond_url = show_response_url(:id => info_request.id, :incoming_message_id => incoming_message.id)
        respond_url = respond_url + "#show_response_followup" 

        post_redirect = PostRedirect.new(
            :uri => respond_url,
            :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 = "Clarify your FOI request - " + info_request.title
        @body = { :incoming_message => incoming_message, :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 = []
        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
        end

        # Nothing found, so save in holding pen
        if reply_info_requests.size == 0 
            InfoRequest.holding_pen_request.receive(email, raw_email)
            return
        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)
        end
    end

    # Send email alerts for overdue requests
    def self.alert_overdue_requests()
        #STDERR.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
            alert_event_id = info_request.last_event_forming_initial_request.id
            # 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 = ? and info_request_event_id = ?", info_request.user_id, info_request.id, alert_event_id])
                if sent_already.nil?
                    # Alert not yet sent for this user
                    #STDERR.puts "sending overdue alert to info_request " + info_request.id.to_s + " user " + info_request.user_id.to_s + " event " + alert_event_id
                    store_sent = UserInfoRequestSentAlert.new
                    store_sent.info_request = info_request
                    store_sent.user = info_request.user
                    store_sent.alert_type = 'overdue_1'
                    store_sent.info_request_event_id = alert_event_id
                    RequestMailer.deliver_overdue_alert(info_request, info_request.user)
                    store_sent.save!
                    #STDERR.puts "sent " + info_request.user.email
                end
            end
        end
    end

    # Send email alerts for new responses which haven't been classified. Goes
    # out 3 days after last update of event, then after 7.
    def self.alert_new_response_reminders
        self.alert_new_response_reminders_internal(3, 'new_response_reminder_1')
        self.alert_new_response_reminders_internal(7, 'new_response_reminder_2')
    end
    def self.alert_new_response_reminders_internal(days_since, type_code)
        #STDERR.puts "alert_new_response_reminders_internal days:" + days_since.to_s + " type: " + type_code
        info_requests = InfoRequest.find(:all, :conditions => [ "awaiting_description and info_requests.updated_at < ?", Time.now() - days_since.days ], :include => [ :user ], :order => "info_requests.id" )
        for info_request in info_requests
            alert_event_id = info_request.get_last_response_event_id
            last_response_message = info_request.get_last_response
            if alert_event_id.nil?
                raise "internal error, no last response while making alert new response reminder, request id " + info_request.id.to_s
            end
            # To the user who created the request
            sent_already = UserInfoRequestSentAlert.find(:first, :conditions => [ "alert_type = ? and user_id = ? and info_request_id = ? and info_request_event_id = ?", type_code, info_request.user_id, info_request.id, alert_event_id])
            if sent_already.nil?
                # Alert not yet sent for this user
                STDERR.puts "sending " + type_code + " alert to info_request " + info_request.url_title + " user " + info_request.user.url_name + " event " + alert_event_id.to_s
                store_sent = UserInfoRequestSentAlert.new
                store_sent.info_request = info_request
                store_sent.user = info_request.user
                store_sent.alert_type = type_code
                store_sent.info_request_event_id = alert_event_id
                # XXX uses same template for reminder 1 and reminder 2 right now. 
                RequestMailer.deliver_new_response_reminder_alert(info_request, last_response_message)
                store_sent.save!
                #STDERR.puts "sent " + info_request.user.email
            end
        end
    end

    # Send email alerts for requests which need clarification. Goes out 3 days
    # after last update of event.
    def self.alert_not_clarified_request()
        #STDERR.puts "alert_not_clarified_request"
        info_requests = InfoRequest.find(:all, :conditions => [ "not awaiting_description and described_state = 'waiting_clarification' and info_requests.updated_at < ?", Time.now() - 3.days ], :include => [ :user ], :order => "info_requests.id" )
        for info_request in info_requests
            alert_event_id = info_request.get_last_response_event_id
            last_response_message = info_request.get_last_response
            if alert_event_id.nil?
                raise "internal error, no last response while making alert not clarified reminder, request id " + info_request.id.to_s
            end
            # To the user who created the request
            sent_already = UserInfoRequestSentAlert.find(:first, :conditions => [ "alert_type = 'not_clarified_1' and user_id = ? and info_request_id = ? and info_request_event_id = ?", info_request.user_id, info_request.id, alert_event_id])
            if sent_already.nil?
                # Alert not yet sent for this user
                STDERR.puts "sending clarification reminder alert to info_request " + info_request.id.to_s + " user " + info_request.user_id.to_s + " event " + alert_event_id.to_s
                store_sent = UserInfoRequestSentAlert.new
                store_sent.info_request = info_request
                store_sent.user = info_request.user
                store_sent.alert_type = 'not_clarified_1'
                store_sent.info_request_event_id = alert_event_id
                RequestMailer.deliver_not_clarified_alert(info_request, last_response_message)
                store_sent.save!
                #STDERR.puts "sent " + info_request.user.email
            end
        end
    end

end