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
|
# File 'lib/ses_proxy/sns_endpoint.rb', line 19
def call(env)
req = Rack::Request.new(env)
res = []
if not req.post? or not check_message_type(env) or not check_topic(env)
return make_error
end
json_string = req.body.read
sns_obj = nil
begin
if json_string and not json_string.strip.eql?""
sns_obj = JSON.parse json_string
end
if sns_obj
unless check_message_signature(sns_obj)
puts "Error in message signature"
return make_error
end
if env["HTTP_X_AMZ_SNS_MESSAGE_TYPE"].eql?"Notification"
message = JSON.parse sns_obj["Message"]
unless message
return make_error
end
if message["notificationType"].eql? "Bounce"
message["bounce"]["bouncedRecipients"].each do |recipient|
if record = Bounce.where(:email => recipient["emailAddress"]).first
record.count ||= 0
record.count += 1
if record.count >= 2
record.retry_at ||= Time.now
record.retry_at = record.retry_at.to_time + ((2 ** (record.count - 2)) * 7).days
end
record.updated_at = Time.now
record.save!
else
record = Bounce.new({
:email => recipient["emailAddress"],
:type => message["bounce"]["bounceType"],
:desc => recipient["diagnosticCode"],
:count => 1,
:created_at => Time.now,
:updated_at => Time.now
})
record.save!
end
end
elsif message["notificationType"].eql? "Complaint"
message["complaint"]["complainedRecipients"].each do |recipient|
if record = Complaint.where(:email => recipient["emailAddress"]).first
record.updated_at = Time.now
record.save!
else
record = Complaint.new({
:email=>recipient["emailAddress"],
:type=>message["complaint"]["complaintFeedbackType"],
:created_at=>Time.now,
:updated_at=>Time.now
})
record.save!
end
end
end
elsif env["HTTP_X_AMZ_SNS_MESSAGE_TYPE"].eql?"SubscriptionConfirmation" and sns_obj["Type"].eql? "SubscriptionConfirmation"
sns.confirm_subscription :topic_arn=>sns_obj["TopicArn"], :token=>sns_obj["Token"], :authenticate_on_unsubscribe=>"true"
end
[200, {'Content-Type' => 'text/html'}, res]
else
puts "SNS Object is nil"
return make_error
end
rescue Exception => e
print "Error! "
puts e.message
return make_error
end
end
|