diff --git a/README.md b/README.md new file mode 100644 index 0000000..e53e8ae --- /dev/null +++ b/README.md @@ -0,0 +1,102 @@ +

+ Quick Email Verification +
+

+ + +# Official Email Validation API library client for Ruby + +QuickEmailVerification provides the quickest way to avoid fake / invalid emails. + +* Get actual users by scanning email address. +* Remove invalid, dead and fake emails from your email list. +* Save time and money by sending mail to actual users. + +## Let's Get Started + +To begin, signUp at [quickemailverification.com](https://quickemailverification.com) and create a FREE account. After signup logged in, click on **[API Settings](https://quickemailverification.com/apisettings)** and then click **Add API Key**. To use API you need 2 parameters. + +email - (string) This is a email address you need to verify. It should be url encoded. + +apikey - (string) This is the key you generated from "api settings" page. + +NOTE: Keep API key with you. You'll need it to setup the client as explained below. + +## Installation + +Make sure you have [rubygems](https://rubygems.org) installed + +```bash +$ gem install quickemailverification +``` + +#### Versions + +Works with [ 1.8.6 / 1.8.7 / 1.9.1 / 1.9.2 / 1.9.3 / 2.0.0 / 2.1.0 / 2.1.1 ] + +## Usage + +```ruby +require "quickemailverification" + +client = QuickEmailVerification::Client.new('Your_API_Key_Here') +quickemailverification = client.quickemailverification() +response = quickemailverification.verify("test@example.com") +puts response.body +``` + +### Response information + +A successful API call responds with the following values: + +- **result** `string` - The verified results will be: `valid`, `invalid`, `unknown` +- **reason** `string` - Reason definitions are as below: + - `invalid_email` - Specified email has invalid email address syntax + - `invalid_domain` - Domain name does not exist + - `rejected_email` - SMTP server rejected email. Email does not exist + - `accepted_email` - SMTP server accepted email address + - `no_connect` - SMTP server connection failure + - `timeout` - Session time out occurred at SMTP server + - `unavailable_smtp` - SMTP server is not available to process request + - `unexpected_error` - An unexpected error has occurred + - `no_mx_record` - Could not get MX records for domain + - `temporarily_blocked` - Email is temporarily greylisted + - `exceeded_storage` - SMTP server rejected email. Exceeded storage allocation + +- **disposable** `true | false` - *true* if the email address uses a *disposable* domain +- **accept_all** `true | false` - *true* if the domain appears to *accept all* emails delivered to that domain +- **role** `true | false` - *true* if the email address is a *role* address (`manager@example.com`, `ceo@example.com`, etc) +- **free** `true | false` - *true* if the email address is from free email provider like Gmail, Yahoo!, Hotmail etc. +- **email** `string` - Returns a normalized version. (`Niki@example.com` -> `niki@example.com`) +- **user** `string` - The local part of an email address. (`niki@example.com` -> `niki`) +- **domain** `string` - The domain of the provided email address. (`niki@example.com` -> `example.com`) +- **safe_to_send** `true | false` - *true* if the email address is safe for deliverability +- **did_you_mean** `string` - Returns email suggestions if specific typo errors found in email +- **success** `true | false` - *true* if the API request was successful +- **message** `string` - Describes API call failure reason + +### HTTP Response headers + +Total remaining credits can be found by http response header. It contains overall remaining credits, including Persistent & Per day credits. + +- **X-QEV-Remaining-Credits** - Your remaining email verification credits (i.e. Per Day Credits + Persistent Credits). + +## HTTP status codes for QuickEmailVerification API calls + +QuickEmailVerification API also returns following HTTP status codes to indicate success or failure of request. + +- `200` - Request is completed successfully. +- `400` - Server can not understand the request sent to it. This is kind of response can occur if parameters are passed wrongly. +- `401` - Server can not verify your authentication to use api. Please check whether API key is proper or not. +- `402` - You are running out of your credit limit. +- `404` - Requested API can not be found on server. +- `429` - Too many requests. Rate limit exceeded. + +## License +MIT + +## Bug Reports +Report [here](https://github.com/quickemailverification/quickemailverification-ruby/issues). + +## Need Help? Feel free to contact us +https://quickemailverification.com/contact-us diff --git a/lib/.directory b/lib/.directory new file mode 100644 index 0000000..7f81296 --- /dev/null +++ b/lib/.directory @@ -0,0 +1,4 @@ +[Dolphin] +Timestamp=2018,1,2,10,35,26 +Version=3 +ViewMode=2 diff --git a/lib/quickemailverification.rb b/lib/quickemailverification.rb new file mode 100644 index 0000000..9d3ef52 --- /dev/null +++ b/lib/quickemailverification.rb @@ -0,0 +1,8 @@ +require "rubygems" + +require "quickemailverification/client" +require "quickemailverification/error" +require "quickemailverification/http_client" + +module QuickEmailVerification +end diff --git a/lib/quickemailverification/api/quickemailverification.rb b/lib/quickemailverification/api/quickemailverification.rb new file mode 100644 index 0000000..1945d9d --- /dev/null +++ b/lib/quickemailverification/api/quickemailverification.rb @@ -0,0 +1,29 @@ +module QuickEmailVerification + + module Api + + # QuickEmailVerification Class for email verification + class Quickemailverification + + def initialize(client) + @client = client + end + + # Verify email address and get detailed response + # + # '/verify?email=:email' GET + # + # email - send email address in query parameter + def verify(email, options = {}) + body = options.fetch("query", {}) + + email = CGI::escape(email) + + @client.get("/verify?email=#{email}", body, options) + end + + end + + end + +end diff --git a/lib/quickemailverification/client.rb b/lib/quickemailverification/client.rb new file mode 100644 index 0000000..8b9e5e5 --- /dev/null +++ b/lib/quickemailverification/client.rb @@ -0,0 +1,21 @@ +require "faraday" +require "json" + +require "quickemailverification/api/quickemailverification" + +module QuickEmailVerification + + class Client + + def initialize(auth = {}, options = {}) + @http_client = QuickEmailVerification::HttpClient::HttpClient.new(auth, options) + end + + # QuickEmailVerification Class for email verification + def quickemailverification() + QuickEmailVerification::Api::Quickemailverification.new(@http_client) + end + + end + +end diff --git a/lib/quickemailverification/error.rb b/lib/quickemailverification/error.rb new file mode 100644 index 0000000..0427b09 --- /dev/null +++ b/lib/quickemailverification/error.rb @@ -0,0 +1,9 @@ +require "quickemailverification/error/client_error" + +module QuickEmailVerification + + module Error + + end + +end diff --git a/lib/quickemailverification/error/client_error.rb b/lib/quickemailverification/error/client_error.rb new file mode 100644 index 0000000..8407e0e --- /dev/null +++ b/lib/quickemailverification/error/client_error.rb @@ -0,0 +1,18 @@ +module QuickEmailVerification + + module Error + + class ClientError < ::StandardError + + attr_reader :code + + def initialize(message, code) + @code = code + super message + end + + end + + end + +end diff --git a/lib/quickemailverification/http_client.rb b/lib/quickemailverification/http_client.rb new file mode 100644 index 0000000..9ff33de --- /dev/null +++ b/lib/quickemailverification/http_client.rb @@ -0,0 +1,124 @@ +require "quickemailverification/http_client/auth_handler" +require "quickemailverification/http_client/error_handler" +require "quickemailverification/http_client/request_handler" +require "quickemailverification/http_client/response" +require "quickemailverification/http_client/response_handler" + +module QuickEmailVerification + + module HttpClient + + # Main HttpClient which is used by Api classes + class HttpClient + + attr_accessor :options, :headers + + def initialize(auth = {}, options = {}) + + if auth.is_a?(String) + auth = { :http_header => auth } + end + + @options = { + :base => "http://api.quickemailverification.com", + :api_version => "v1", + :user_agent => "quickemailverification-ruby/1.0.1 (https://github.com/quickemailverification/quickemailverification-ruby)" + } + + @options.update(options) + + @headers = { + "user-agent" => @options[:user_agent] + } + + if @options.has_key?(:headers) + @headers.update(Hash[@options[:headers].map { |k, v| [k.downcase, v] }]) + @options.delete(:headers) + end + + @client = Faraday.new(@options[:base]) do |conn| + conn.use(QuickEmailVerification::HttpClient::AuthHandler, auth) + conn.use(QuickEmailVerification::HttpClient::ErrorHandler) + + conn.adapter(Faraday.default_adapter) + end + end + + def get(path, params = {}, options = {}) + request(path, nil, "get", options.merge({ :query => params })) + end + + def post(path, body = {}, options = {}) + request(path, body, "post", options) + end + + def patch(path, body = {}, options = {}) + request(path, body, "patch", options) + end + + def delete(path, body = {}, options = {}) + request(path, body, "delete", options) + end + + def put(path, body = {}, options = {}) + request(path, body, "put", options) + end + + # Intermediate function which does three main things + # + # - Transforms the body of request into correct format + # - Creates the requests with give parameters + # - Returns response body after parsing it into correct format + def request(path, body, method, options) + options = @options.merge(options) + + options[:headers] = options[:headers] || {} + options[:headers] = @headers.merge(Hash[options[:headers].map { |k, v| [k.downcase, v] }]) + + options[:body] = body + + if method != "get" + options[:body] = options[:body] || {} + options = set_body(options) + end + + response = create_request(method, path, options) + + env = response.env + body = get_body(env) + + QuickEmailVerification::HttpClient::Response.new(body, env.status, env.response_headers) + end + + # Creating a request with the given arguments + # + # If api_version is set, appends it immediately after host + def create_request(method, path, options) + version = options.has_key?(:api_version) ? "/#{options[:api_version]}" : "" + + path = "#{version}#{path}" + + instance_eval <<-RUBY, __FILE__, __LINE__ + 1 + @client.#{method}(path) do |req| + req.body = options[:body] + req.headers.update(options[:headers]) + req.params.update(options[:query]) if options[:query] + end + RUBY + end + + # Get response body in correct format + def get_body(env) + QuickEmailVerification::HttpClient::ResponseHandler.get_body(env) + end + + # Set request body in correct format + def set_body(options) + QuickEmailVerification::HttpClient::RequestHandler.set_body(options) + end + + end + + end + +end diff --git a/lib/quickemailverification/http_client/auth_handler.rb b/lib/quickemailverification/http_client/auth_handler.rb new file mode 100644 index 0000000..91b1bcb --- /dev/null +++ b/lib/quickemailverification/http_client/auth_handler.rb @@ -0,0 +1,73 @@ +require "base64" + +module QuickEmailVerification + + module HttpClient + + # AuthHandler takes care of devising the auth type and using it + class AuthHandler < Faraday::Middleware + + HTTP_HEADER = 1 + + def initialize(app, auth = {}, options = {}) + @auth = auth + super(app) + end + + def call(env) + if !@auth.empty? + auth = get_auth_type + flag = false + + if auth == HTTP_HEADER + env = http_header(env) + flag = true + end + + if !flag + raise StandardError.new "Unable to calculate authorization method. Please check" + end + else + raise StandardError.new "Server requires authentication to proceed further. Please check" + end + + @app.call(env) + end + + # Calculating the Authentication Type + def get_auth_type() + + if @auth.has_key?(:http_header) + return HTTP_HEADER + end + + return -1 + end + + # Authorization with HTTP header + def http_header(env) + env[:request_headers]["Authorization"] = "token #{@auth[:http_header]}" + + return env + end + + def query_params(url) + if url.query.nil? or url.query.empty? + {} + else + Faraday::Utils.parse_query(url.query) + end + end + + def merge_query(env, query) + query = query.update query_params(env[:url]) + + env[:url].query = Faraday::Utils.build_query(query) + + return env + end + end + + end + +end diff --git a/lib/quickemailverification/http_client/error_handler.rb b/lib/quickemailverification/http_client/error_handler.rb new file mode 100644 index 0000000..f379c1d --- /dev/null +++ b/lib/quickemailverification/http_client/error_handler.rb @@ -0,0 +1,51 @@ +module QuickEmailVerification + + module HttpClient + + # ErrorHanlder takes care of selecting the error message from response body + class ErrorHandler < Faraday::Middleware + + def initialize(app) + super(app) + end + + def call(env) + @app.call(env).on_complete do |env| + code = env.status + type = env.response_headers["content-type"] || '' + + case code + when 500...599 + raise QuickEmailVerification::Error::ClientError.new("Error #{code}", code) + when 400...499 + body = QuickEmailVerification::HttpClient::ResponseHandler.get_body(env) + message = "" + + # If HTML, whole body is taken + if body.is_a?(String) + message = body + end + + # If JSON, a particular field is taken and used + if type.include?("json") and body.is_a?(Hash) + if body.has_key?("message") + message = body["message"] + else + message = "Unable to select error message from json returned by request responsible for error" + end + end + + if message == "" + message = "Unable to understand the content type of response returned by request responsible for error" + end + + raise QuickEmailVerification::Error::ClientError.new message, code + end + end + end + + end + + end + +end diff --git a/lib/quickemailverification/http_client/request_handler.rb b/lib/quickemailverification/http_client/request_handler.rb new file mode 100644 index 0000000..474ea6d --- /dev/null +++ b/lib/quickemailverification/http_client/request_handler.rb @@ -0,0 +1,24 @@ +module QuickEmailVerification + + module HttpClient + + # RequestHandler takes care of encoding the request body into format given by options + class RequestHandler + + def self.set_body(options) + type = options.fetch(:request_type, "raw") + + # Raw body + if type == "raw" + options[:body] = options[:body].is_a?(Hash) ? "" : options[:body] + options[:headers].delete("content-type") + end + + return options + end + + end + + end + +end diff --git a/lib/quickemailverification/http_client/response.rb b/lib/quickemailverification/http_client/response.rb new file mode 100644 index 0000000..b8cab87 --- /dev/null +++ b/lib/quickemailverification/http_client/response.rb @@ -0,0 +1,20 @@ +module QuickEmailVerification + + module HttpClient + + # Response object contains the response returned by the client + class Response + + attr_accessor :body, :code, :headers + + def initialize(body, code, headers) + @body = body + @code = code + @headers = headers + end + + end + + end + +end diff --git a/lib/quickemailverification/http_client/response_handler.rb b/lib/quickemailverification/http_client/response_handler.rb new file mode 100644 index 0000000..acb056b --- /dev/null +++ b/lib/quickemailverification/http_client/response_handler.rb @@ -0,0 +1,24 @@ +module QuickEmailVerification + + module HttpClient + + # ResponseHandler takes care of decoding the response body into suitable type + class ResponseHandler + + def self.get_body(env) + type = env.response_headers["content-type"] || '' + body = env.body + + # Response body is in JSON + if type.include?("json") + body = JSON.parse body + end + + return body + end + + end + + end + +end diff --git a/quickemailverification.gemspec b/quickemailverification.gemspec new file mode 100644 index 0000000..a8dff74 --- /dev/null +++ b/quickemailverification.gemspec @@ -0,0 +1,20 @@ +# -*- encoding: utf-8 -*- + +Gem::Specification.new do |gem| + gem.name = "quickemailverification" + gem.version = "1.0.1" + gem.description = "Official QuickEmailVerification API library client for ruby." + gem.summary = "Official QuickEmailVerification API library client for ruby" + + gem.author = "QuickEmailVerification" + gem.email = "support@quickemailverification.com" + gem.homepage = "https://quickemailverification.com" + gem.license = "MIT" + + gem.require_paths = ['lib'] + + gem.files = Dir["lib/**/*"] + + gem.add_dependency "faraday", "~> 0.9" + gem.add_dependency "json", "~> 1.8" +end