Created
January 22, 2015 13:20
-
-
Save akinsgre/94c2d22b64d801d8bd96 to your computer and use it in GitHub Desktop.
Revisions
-
akinsgre created this gist
Jan 22, 2015 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,117 @@ class Contact < ActiveRecord::Base has_many :groups, :through => :group_contacts has_many :group_contacts has_many :messages belongs_to :user validates_presence_of :entry require_dependency 'phone' require_dependency 'sms' require_dependency 'email' require_dependency 'fb_group' #GAK 11/4/2011 # Email is a virtual attribute so it can be captured in a form_for but then assigned to the User to whom the contact belongs # rather than being saved on the Contact record (which breaks for those contacts created by group_owners and not associated # with a user account.. Got to think about this some. def email @email end def email=(email) @email = email end def self.hide?(user,group) false end def self.select_options(user, group) Rails.logger.debug "##### User owns group (#{user.id} == #{group.user.id}) #{user == group.user}" unless user.nil? descendants.reject { |d| d.hide?(user, group ) }.collect { |d| [d.identify,d.to_s] } end def to_s "Contact => #{self.name}, #{self.entry}" end def self.determine_type(params) contact = nil contactType = params[:contact][:type] normalized_entry = Phone.normalize_number(params[:contact][:entry], :default_country_number => '01') contactExists = Contact.exists?(params[:id]) || ( !normalized_entry.nil? && Contact.exists?(:normalized_entry => normalized_entry, :type => contactType) ) || Contact.exists?(:entry => params[:contact][:entry], :type => contactType) if contactExists Rails.logger.info "###### Contact Exists" ActiveRecord::Base.transaction do contact = Contact.find(params[:id]) unless params[:id].nil? Rails.logger.info "###### Contact found by ID is #{contact.inspect}" contact ||= Contact.find_by(:normalized_entry => normalized_entry, :type => contactType) unless normalized_entry.nil? Rails.logger.info "###### Contact found by normalized_entry is #{contact.inspect}" contact ||= Contact.find_by(:entry => params[:contact][:entry], :type => contactType) unless params[:contact][:entry].empty? Rails.logger.info "###### Contact found by entry is #{contact.inspect}" Rails.logger.info "###### Contact is #{contact.inspect}" if contact.type != contactType contact.type = contactType contact.save end Rails.logger.info "###### After setting contact type Contact is #{contact.inspect}" case contactType when 'Phone' contact = contact.becomes(Phone) when 'Sms' contact = contact.becomes(Sms) when 'Email' contact = contact.becomes(Email) when 'FbGroup' contact = contact.becomes(FbGroup) else raise "Not a supported type" end Rails.logger.info "###### After become Contact is #{contact.inspect}" contact = Contact.find(contact.id) unless contact.update_attributes(params[:contact].permit(:name, :user_id, :entry)) Rails.logger.error "##### Had to rollback transaction because #{contact.errors.full_messages}" raise ActiveRecord::Rollback end Rails.logger.info "###### Completed contact modification #{contact.inspect}" end else puts "##### The contact does not exist" case contactType when'Phone' contact = Phone.new(params[:contact].permit(:name, :user_id, :entry, :type)) when 'Sms' contact = Sms.new(params[:contact].permit(:name, :user_id, :entry, :type)) when 'Email' contact = Email.new(params[:contact].permit(:name, :user_id, :entry, :type)) when 'FbGroup' contact = FbGroup.new(params[:contact].permit(:name, :user_id, :entry, :type)) else raise "Not a supported type" end contact.save end Rails.logger.info "##### Returning contact #{contact.inspect}" return contact end end # == Schema Information # # Table name: contacts # # id :integer not null, primary key # name :string(255) # created_at :datetime # updated_at :datetime # user_id :integer # type :string(255) # entry :string(255) # identifier :string(255) # normalized_entry :text # This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,37 @@ class Email < Contact include ActiveModel::Naming validates :entry, :email => { :message => I18n.t('validations.errors.models.email.invalid_email')} def self.identify "Email" end def identify "Email" end def self.long_description "Valid email address" end def deliver(contact, message, advertisement, options = {}) MessageMailer.send_message(contact,message, advertisement).deliver sent_message = advertisement.html_message rescue => e Rails.logger.error "####### There was a problem #{e.message} " raise e end end # == Schema Information # # Table name: contacts # # id :integer not null, primary key # name :string(255) # created_at :datetime # updated_at :datetime # user_id :integer # type :string(255) # entry :string(255) # identifier :string(255) # normalized_entry :text # This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,61 @@ require 'twilio-ruby' class MessagesController < ApplicationController include MessageHelper def new @message = Message.new @group = Group.find(params[:group_id]) @message.group = @group end def deliver @message = Message.new(params[:message].permit(:message, :group_id, :phone_message)) @contacts = Group.find(@message.group_id).contacts @group = Group.find(@message.group_id) if @contacts.size == 0 flash[:alert] = "The message was not sent because the group doesn't have any contacts." redirect_to @group and return end render(:file => File.join(Rails.root, 'public/404'), :status => 404, :layout => false, content_type: "text/html" ) and return if @group.nil? @account_sid = ENV['TW_SID'] @auth_token = ENV['TW_TOKEN'] Rails.logger.debug "##### Set up a client to talk to the Twilio REST API using Twilio gem with #{@account_sid} #{@auth_token}" @client = Twilio::REST::Client.new(@account_sid, @auth_token) @message.group = @group if @group.exceed_messages? flash[:alert] = "The message cannot be sent because you have already sent #{@group.membership_level.allowed_messages} this month. You must upgrade to a 'Premium' or 'Sponsored' level to be able to send additional messages." redirect_to @group and return end if @message.save Rails.logger.info "##### Sending #{@message.inspect} to each contact" # Check membership, on Group model (ie., Group.messages_exceeded?) level before sending message # abort if number of messages exceeds threshhold errors = 0 # because localhost can't host the Twilio services if Rails.env.development? app_url = "http://nmc-demo.herokuapp.com" else app_url = "#{request.protocol + request.host_with_port}" end @contacts.each do |c| advertisement = Sponsor.getAd sent_message = c.deliver(c, @message, advertisement, {:client => @client, :group => @group, :app_url => app_url}) record_message(sent_message, @group, c, advertisement ) unless c.type == "FbGroup" end flash.now[:notice] = "Message sent successfully to #{@contacts.size - errors } contacts." render "groups/show", id: @group.id end rescue => e Rails.logger.warn "##### There was a problem sending this message. #{e.message}" flash.now[:alert] = "There was a problem sending this message. #{e.message}" render "groups/show", id: @group.id end end This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,69 @@ class Phone < Contact include ActiveModel::Naming phony_normalize :entry, as: :normalized_entry, :default_country_code => 'US' validates_plausible_phone :entry, :normalized_country_code => 'US', :message => I18n.t('validations.errors.models.phone.invalid_number') def self.identify "Phone" end def identify "Phone" end def self.long_description "Phone number (10 digit)" end def self.normalize_number(number, options = {}) return if number.nil? number = number.clone # Just to be sure, we don't want to change the original. number.gsub!(/[^\d\+]/, '') # Strips weird stuff from the number return if number.blank? if default_country_number = options[:default_country_number] # Add default_country_number if missing number = "#{default_country_number}#{number}" if not number =~ /\A(00|\+|#{default_country_number})/ end Phony.normalize(number) rescue => e number # If all goes wrong .. we still return the original input. end def deliver(contact, message, advertisement, options = {}) client = options[:client] group = options[:group] sponsor_msg = Rack::Utils.escape(advertisement.phone_message) if message.phone_message.blank? message = Rack::Utils.escape(message.message) else message = Rack::Utils.escape(message.phone_message) end sent_message = sponsor_msg group_name = Rack::Utils.escape(group.name) url = "#{options[:app_url]}/twiml/say.xml?secret=#{ ENV['NMC_API_KEY'] }&IfMachine=Continue&message=#{message}&sponsor_msg=#{sponsor_msg}&group=#{group_name}" @call = client.account.calls.create( :from => group.twilio_number, :to => contact.entry, :url => url, :method => 'GET' ) rescue => e Rails.logger.info "####### An error occurred #{e.message}" end end # == Schema Information # # Table name: contacts # # id :integer not null, primary key # name :string(255) # created_at :datetime # updated_at :datetime # user_id :integer # type :string(255) # entry :string(255) # identifier :string(255) # normalized_entry :text #