code9ty/website

View on GitHub
lib/assets/AfricasTalkingGateway.rb

Summary

Maintainability
C
1 day
Test Coverage
require 'rubygems'
require 'net/http'
require 'uri'
require 'json'

class AfricasTalkingGatewayException < Exception
end

class SMSMessages
    attr_accessor :id, :text, :from, :to, :linkId, :date

    def initialize(id_, text_, from_, to_, linkId_, date_)
        @id     = id_
        @text   = text_
        @from   = from_
        @to     = to_
        @linkId = linkId_
        @date   = date_
    end
end

class StatusReport
    attr_accessor :number, :status, :cost, :messageId

    def initialize(number_, status_, cost_,messageId_)
        @number = number_
        @status = status_
        @cost   = cost_
        @messageId = messageId_
    end
end

class PremiumSubscriptionNumbers
    attr_accessor :phoneNumber, :id

    def initialize(number_, id_)
        @phoneNumber = number_
        @id     = id_
    end
end

class AirtimeResult
    attr_accessor :amount, :phoneNumber, :requestId, :status, :errorMessage, :discount

    def initialize(status_, number_, amount_, requestId_, errorMessage_, discount_)
        @status       = status_
        @phoneNumber  = number_
        @amount       = amount_
        @requestId    = requestId_
        @errorMessage = errorMessage_
        @discount     = discount_
    end
end

class CallResponse
    attr_accessor :phoneNumber, :status

    def initialize(status_, number_)
        @status      = status_
        @phoneNumber = number_
    end
end

class QueuedCalls
    attr_accessor :numCalls, :phoneNumber, :queueName
    
    def initialize(number_, numCalls_, queueName_)
        @phoneNumber = number_
        @numCalls    = numCalls_
        @queueName   = queueName_
    end
end

class AfricasTalkingGateway

    SMS_URL          = 'https://api.africastalking.com/version1/messaging'
    VOICE_URL        = 'https://voice.africastalking.com'
    SUBSCRIPTION_URL = 'https://api.africastalking.com/version1/subscription'
    USERDATA_URL     = 'https://api.africastalking.com/version1/user'
    AIRTIME_URL      = 'https://api.africastalking.com/version1/airtime'

    HTTP_CREATED     = 201
    HTTP_OK          = 200

    #Set debug flag to to true to view response body
    DEBUG            = false
  

    def initialize(user_name,api_key)
        @user_name    = user_name
        @api_key      = api_key

        @response_code = nil
    end

    def sendMessage(recipients_, message_, from_ = nil, bulkSMSMode_ = 1, enqueue_ = 0, keyword_ = nil, linkId_ = nil, retryDurationInHours_ = nil)
        post_body = {
                        'username'    => @user_name, 
                        'message'     => message_, 
                        'to'          => recipients_, 
                        'bulkSMSMode' => bulkSMSMode_ 
                    }
        if (from_ != nil)
            post_body['from'] = from_
        end

        if (enqueue_ > 0)
            post_body['enqueue'] = enqueue_
        end

        if (keyword_ != nil)
            post_body['keyword'] = keyword_
        end

        if (linkId_ != nil)
            post_body['linkId'] = linkId_
        end

        if (retryDurationInHours_ != nil)
            post_body['retryDurationInHours'] = retryDurationInHours_
        end

        response = executePost(SMS_URL, post_body)
        if @response_code == HTTP_CREATED
            messageData = JSON.parse(response,:quirks_mode=>true)["SMSMessageData"]
            recipients = messageData["Recipients"]
            
            if recipients.length > 0
                reports = recipients.collect { |entry|
                    StatusReport.new entry["number"], entry["status"], entry["cost"], entry["messageId"]
                }
                return reports
            end
            
            raise AfricasTalkingGatewayException, messageData["Message"]
            
        else
              raise AfricasTalkingGatewayException, response
        end
     end

    def fetchMessages(last_received_id_)
        url = "#{SMS_URL}?username=#{@user_name}&lastReceivedId=#{last_received_id_}"
        response = executePost(url)
        if @response_code == HTTP_OK
            messages = JSON.parse(response, :quirky_mode => true)["SMSMessageData"]["Messages"].collect { |msg|
                SMSMessage.new msg["id"], msg["text"], msg["from"] , msg["to"], msg["linkId"], msg["date"]
            }
            return messages
        else
            raise AfricasTalkingGatewayException, response
        end
    end

    def createSubcription(phone_number_, short_code_, keyword_)
        if(phone_number_.length == 0 || short_code.length == 0 || keyword_.length == 0)
            raise AfricasTalkingGatewayException, "Please supply phone number, short code and keyword"
        end
        
        post_body = {
                        'username'    => @user_name,
                        'phoneNumber' => phone_number_,
                        'shortCode'   => short_code_,
                        'keyword'     => keyword_
                    }
        url      = "#{SUBSCRIPTION_URL}/create"
        response = executePost(url, post_body)
        if(@response_code == HTTP_CREATED)
            return JSON.parse(response, :quirky_mode => true)
        else
            raise AfricasTalkingGatewayException, response
        end
    end

    def deleteSubcription(phone_number_, short_code_, keyword_)
        if(phone_number_.length == 0 || short_code.length == 0 || keyword_.length == 0)
            raise AfricasTalkingGatewayException, "Please supply phone number, short code and keyword"
        end
        
        post_body = {
                        'username'    => @user_name,
                        'phoneNumber' => phone_number_,
                        'shortCode'   => short_code_,
                        'keyword'     => keyword_
                    }
        url = "#{SUBSCRIPTION_URL}/delete"

        response = executePost(url, post_body)

        if(@response_code == HTTP_CREATED)
            return JSON.parse(response, :quirky_mode => true)
        else
            raise AfricasTalkingGatewayException, response
        end
    end

    def fetchPremiumSubscriptions(short_code_, keyword_, last_received_id_ = 0)
        if(short_code_.length == 0 || keyword_.length == 0)
            raise AfricasTalkingGatewayException, "Please supply the short code and keyword"
        end

        url = "#{SUBSCRIPTION_URL}?username=#{@user_name}&shortCode=#{short_code_}&keyword=#{keyword_}&lastReceivedId=#{last_received_id_}"

        response = executePost(url)

        if(@response_code == HTTP_OK)
            subscriptions = JSON.parse(response)['responses'].collect{ |subscriber|
                PremiumSubscriptionNumbers.new subscriber['phoneNumber'], subscriber['id']
            }
            return subscriptions
        else
            raise AfricasTalkingGatewayException, response
        end
    end

    def call(from_, to_)
        post_body = {
                        'username' => @user_name, 
                        'from'     => from_, 
                        'to'       => to_ 
                    }
        response = executePost("#{VOICE_URL}/call", post_body)
        if(@response_code == HTTP_OK || @response_code == HTTP_CREATED)
            jObject = JSON.parse(response, :quirky_mode => true)

            if (jObject['errorMessage'] == "None")
                results = jObject['entries'].collect{|result|
                    CallResponse.new result['status'], result['phoneNumber']
                }
                return results
            end

            raise AfricasTalkingGatewayException, jObject['errorMessage']
        end

        raise AfricasTalkingGatewayException, response
    end

    def getNumQueuedCalls(phone_number_, queue_name_ = nil)
        post_body = {
                        'username'    => @user_name,
                        'phoneNumbers' => phone_number_,
                    }
        if (queue_name_ != nil)
            post_body['queueName'] = queue_name_
        end
        url = "#{VOICE_URL}/queueStatus"
        response = executePost(url, post_body)

        jsObject = JSON.parse(response, :quirky_mode => true)
        
        if(@response_code == HTTP_OK || @response_code == HTTP_CREATED)
            if (jsObject['errorMessage'] == "None")
                results = jsObject['entries'].collect{|result|
                    QueuedCalls.new result['phoneNumber'], result['numCalls'], result['queueName']
                }
                return results
            end

            raise AfricasTalkingGatewayException, jsObject['errorMessage']
        end
        
        raise AfricasTalkingGatewayException, response
    end

    def uploadMediaFile(url_string_)
        post_body = {
                        'username' => @user_name,
                        'url'      => url_string_
                    }
        url      = "#{VOICE_URL}/mediaUpload"
        response = executePost(url, post_body)

        jsObject = JSON.parse(response, :quirky_mode => true)

        raise AfricasTalkingGatewayException, jsObject['errorMessage'] if jsObject['errorMessage'] != "None"
    end

    def sendAirtime(recipients_)
        recipients = recipients_.to_json
        post_body = {
                        'username'   => @user_name,
                        'recipients' => recipients
                    }
        url      = "#{AIRTIME_URL}/send"
        response = executePost(url, post_body)
        if (@response_code == HTTP_CREATED)
            responses = JSON.parse(response)['responses']
            if (responses.length > 0)
                results = responses.collect{ |result|
                    AirtimeResult.new result['status'], result['phoneNumber'],result['amount'],result['requestId'], result['errorMessage'], result['discount']
                }
                return results
            else
                raise AfricasTalkingGatewayException, response['errorMessage']
            end
        else
            raise AfricasTalkingGatewayException, response
        end

    end

    def getUserData()
        url      = "#{USERDATA_URL}?username=#{@user_name}"
        response = executePost(url)
        if (@response_code == HTTP_OK)
            result = JSON.parse(response, :quirky_mode =>true)['UserData']
            return result
        else
            raise AfricasTalkingGatewayException, response
        end
    end

    def executePost(url_, data_ = nil)
        uri                  = URI.parse(url_)
        http             = Net::HTTP.new(uri.host, uri.port)
        http.use_ssl     = true
        headers = {
           "apikey" => @api_key,
           "Accept" => "application/json"
        }
        if(data_ != nil)
            request = Net::HTTP::Post.new(uri.request_uri)
            request.set_form_data(data_)
        else
            request = Net::HTTP::Get.new(uri.request_uri)
        end
        request["apikey"] = @api_key
        request["Accept"] = "application/json"

        response          = http.request(request)

        if (DEBUG)
            puts "Full response #{response.body}"
        end

        @response_code = response.code.to_i
        return response.body
    end
end