lib/flapjack/gateways/sms_twilio.rb in flapjack-1.6.0 vs lib/flapjack/gateways/sms_twilio.rb in flapjack-2.0.0b1
- old
+ new
@@ -1,15 +1,20 @@
#!/usr/bin/env ruby
-require 'em-synchrony'
-require 'em-synchrony/em-http'
+require 'net/http'
+require 'uri'
+require 'uri/https'
+
require 'active_support/inflector'
-require 'flapjack/redis_pool'
+require 'flapjack/redis_proxy'
+require 'flapjack/record_queue'
+require 'flapjack/utility'
+require 'flapjack/exceptions'
require 'flapjack/data/alert'
-require 'flapjack/utility'
+require 'flapjack/data/check'
module Flapjack
module Gateways
class SmsTwilio
@@ -17,120 +22,132 @@
# --data-urlencode 'To=+61414123456' \
# --data-urlencode 'From=+61414123456' \
# --data-urlencode 'Body=Sausage' \
# -u [AccountSid]:[AuthToken]
+ TWILIO_DEFAULT_HOST = 'api.twilio.com'
+
+ attr_accessor :sent
+
include Flapjack::Utility
def initialize(opts = {})
+ @lock = opts[:lock]
+
@config = opts[:config]
- @logger = opts[:logger]
- @redis_config = opts[:redis_config] || {}
- @redis = Flapjack::RedisPool.new(:config => @redis_config, :size => 1, :logger => @logger)
- @logger.info("starting")
- @logger.debug("new sms_twilio gateway pikelet with the following options: #{@config.inspect}")
+ # TODO support for config reloading
+ @queue = Flapjack::RecordQueue.new(@config['queue'] || 'sms_twilio_notifications',
+ Flapjack::Data::Alert)
@sent = 0
- end
- def stop
- @logger.info("stopping")
- @should_quit = true
-
- redis_uri = @redis_config[:path] ||
- "redis://#{@redis_config[:host] || '127.0.0.1'}:#{@redis_config[:port] || '6379'}/#{@redis_config[:db] || '0'}"
- shutdown_redis = EM::Hiredis.connect(redis_uri)
- shutdown_redis.rpush(@config['queue'], Flapjack.dump_json('notification_type' => 'shutdown'))
+ Flapjack.logger.debug("new sms_twilio gateway pikelet with the following options: #{@config.inspect}")
end
def start
- queue = @config['queue']
+ begin
+ Zermelo.redis = Flapjack.redis
- until @should_quit
- begin
- @logger.debug("sms_twilio gateway is going into blpop mode on #{queue}")
- alert = Flapjack::Data::Alert.next(queue, :redis => @redis, :logger => @logger)
- deliver(alert) unless alert.nil?
- rescue => e
- @logger.error "Error generating or dispatching SMS Twilio message: #{e.class}: #{e.message}\n" +
- e.backtrace.join("\n")
+ loop do
+ @lock.synchronize do
+ @queue.foreach {|alert| handle_alert(alert) }
+ end
+
+ @queue.wait
end
+ ensure
+ Flapjack.redis.quit
end
end
- def deliver(alert)
+ def stop_type
+ :exception
+ end
+
+ private
+
+ def handle_alert(alert)
account_sid = @config["account_sid"]
- auth_token = @config["auth_token"]
- from = @config["from"]
- endpoint = @config["endpoint"] || "https://api.twilio.com/2010-04-01/Accounts/#{account_sid}/Messages.json"
+ auth_token = @config["auth_token"]
+ from = @config["from"]
- address = alert.address
- notification_id = alert.notification_id
- message_type = alert.rollup ? 'rollup' : 'alert'
+ endpoint_host = @config["endpoint_host"] || TWILIO_DEFAULT_HOST
+ endpoint_path = @config["endpoint_path"] || "/2010-04-01/Accounts/#{account_sid}/Messages.json"
+ address = alert.medium.address
+ notification_id = alert.id
+ message_type = alert.rollup ? 'rollup' : 'alert'
+
+ sms_dir = File.join(File.dirname(__FILE__), 'sms_twilio')
sms_template_erb, sms_template =
- load_template(@config['templates'], message_type, 'text',
- File.join(File.dirname(__FILE__), 'sms_twilio'))
+ load_template(@config['templates'], message_type, 'text', sms_dir)
- @alert = alert
- bnd = binding
+ @alert = alert
+ bnd = binding
begin
message = sms_template_erb.result(bnd).chomp
rescue => e
- @logger.error "Error while executing the ERB for an sms: " +
+ Flapjack.logger.error "Error while executing the ERB for an sms: " +
"ERB being executed: #{sms_template}"
raise
end
if @config.nil? || (@config.respond_to?(:empty?) && @config.empty?)
- @logger.error "sms_twilio config is missing"
+ Flapjack.logger.error "sms twilio config is missing"
return
end
errors = []
- safe_message = truncate(message, 159)
-
[[account_sid, "Twilio account_sid is missing"],
[auth_token, "Twilio auth_token is missing"],
- [from, "SMS from address is missing"],
- [address, "SMS address is missing"],
+ [from, "SMS from address is missing"],
+ [address, "SMS address is missing"],
[notification_id, "Notification id is missing"]].each do |val_err|
next unless val_err.first.nil? || (val_err.first.respond_to?(:empty?) && val_err.first.empty?)
errors << val_err.last
end
unless errors.empty?
- errors.each {|err| @logger.error err }
+ errors.each {|err| Flapjack.logger.error err }
return
end
- body_data = {'To' => address,
- 'From' => from,
- 'Body' => safe_message}
- @logger.debug "body_data: #{body_data.inspect}"
- @logger.debug "authorization: [#{account_sid}, #{auth_token[0..2]}...#{auth_token[-3..-1]}]"
+ body_data = {
+ 'To' => address,
+ 'From' => from,
+ 'Body' => truncate(message, 159)
+ }
- http = EM::HttpRequest.new(endpoint).post(:body => body_data, :head => {'authorization' => [account_sid, auth_token]})
+ Flapjack.logger.debug "body_data: #{body_data.inspect}"
+ Flapjack.logger.debug "authorization: [#{account_sid}, #{auth_token[0..2]}...#{auth_token[-3..-1]}]"
- @logger.debug "server response: #{http.response}"
+ req = Net::HTTP::Post.new(endpoint_path)
+ req.set_form_data(body_data)
+ req['Authorization'] = [account_sid, auth_token]
- status = (http.nil? || http.response_header.nil?) ? nil : http.response_header.status
- if (status >= 200) && (status <= 206)
+ http_response = Net::HTTP.start(endpoint_host, 443, :use_ssl => true) do |http|
+ http.request(req)
+ end
+
+ Flapjack.logger.debug "server response: #{http_response.inspect}"
+
+ status = http_response.code
+
+ if (status.to_i >= 200) && (status.to_i <= 206)
@sent += 1
- alert.record_send_success!
- @logger.debug "Sent SMS via Twilio, response status is #{status}, " +
- "notification_id: #{notification_id}"
+ Flapjack.logger.info "Sent SMS via Twilio, response status is #{status}, " +
+ "alert id: #{alert.id}"
else
- @logger.error "Failed to send SMS via Twilio, response status is #{status}, " +
- "notification_id: #{notification_id}"
+ Flapjack.logger.error "Failed to send SMS via Twilio, response status is #{status}, " +
+ "alert id: #{alert.id}"
end
rescue => e
- @logger.error "Error generating or delivering sms to #{alert.address}: #{e.class}: #{e.message}"
- @logger.error e.backtrace.join("\n")
+ Flapjack.logger.error "Error generating or delivering twilio sms to #{alert.medium.address}: #{e.class}: #{e.message}"
+ Flapjack.logger.error e.backtrace.join("\n")
raise
end
end
end