Skip to content
This repository has been archived by the owner on Jan 19, 2022. It is now read-only.

Commit

Permalink
Add Deep Linking (#4)
Browse files Browse the repository at this point in the history
  • Loading branch information
rmarescu committed Sep 26, 2014
1 parent d6500db commit 5a96a11
Show file tree
Hide file tree
Showing 11 changed files with 150 additions and 15 deletions.
52 changes: 46 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,17 @@

Ruby wrapper for [LinkShare Publisher Web Services](https://rakutenlinkshare.zendesk.com).
Supported web services:
* [Automated LinkGenerator](#automated-link-generator)
* [Deep Linking](#deep-linking) (previously [Automated LinkGenerator](#automated-link-generator))
* [Merchandiser Query Tool](#merchandiser-query-tool)
* [Coupon Web Service](#coupon-web-service)

If you need services that are not yet supported, feel free to [contribute](#contributing).
For questions or bugs please [create an issue](../../issues/new).

## <a id="requirement"></a>Requirements

[Ruby](http://www.ruby-lang.org/en/downloads/) 1.9 or above.

## <a id="installation"></a>Installation

Add this line to your application's Gemfile:
Expand All @@ -26,27 +30,63 @@ Or install it yourself as:

$ gem install linkshare_api

## <a id="requirement"></a>Requirements
## <a id="configuration"></a>Configuration

[Ruby](http://www.ruby-lang.org/en/downloads/) 1.9 or above.
Before using **LinkShare API** you need to set up your publisher token first. If you use Ruby on Rails, the token can be set in a configuration file (i.e. `app/config/initializers/linkshare_api.rb`), otherwise just set it in your script. The token can be found on LinkShare's Web Services page under the Links tab.

## <a id="usage"></a>Usage
```ruby
LinkshareAPI.token = ENV["LINKSHARE_TOKEN"]
```

Before using **LinkShare API** you need to set up your publisher token first. If you use Ruby on Rails, the token can be set in a configuration file (i.e. `app/config/initializers/linkshare_api.rb`), otherwise just set it in your script. The token can be found on LinkShare's Web Services page under the Links tab.
Affiliate ID is required for using Deep Linking.

```ruby
LinkshareAPI.affiliate_id = ENV["LINKSHARE_AFFILIATE_ID"]
```

By default linkshare_api logs to STDOUT. To use your own logger implementation you have to specify it using `LinkshareAPI.logger`

### Configuration example

Would apply for Ruby on Rails. Create `app/config/initializers/linkshare_api.rb` and add the following content:

```ruby
require "linkshare_api" # no need for RoR
LinkshareAPI.token = ENV["LINKSHARE_TOKEN"]
LinkshareAPI.affiliate_id = ENV["LINKSHARE_AFFILIATE_ID"]
LinkshareAPI.logger = Rails.logger
```

## <a id="usage"></a>Usage

### Deep Linking

Generate affiliate URLs using [Deep Linking](https://rakutenlinkshare.zendesk.com/hc/en-us/articles/201295755-Guide-to-Deep-Linking) service.
Below is an example of generating an affiliate URL for [Walmart](http://www.walmart.com). Walmart merchant code is `2149`.

```ruby
require "linkshare_api" # No need for RoR

LinkshareAPI.affiliate_id = ENV["LINKSHARE_AFFILIATE_ID"] # must be set in order to use Deep Linking, otherwise will fall back to Automated Link Generator
url = "http://www.walmart.com/cp/Electronics/3944?povid=P1171-C1093.2766-L33"
affiliate_url = LinkshareAPI.link_generator(2149, url)
# http://click.linksynergy.com/deeplink?id=your_affiliate_id&mid=2149&murl=http%3A%2F%2Fwww.walmart.com%2Fcp%2FElectronics%2F3944%3Fpovid%3DP1171-C1093.2766-L33
```

**Note:** The link is generated manually, therefore you must ensure that the Affiliate ID provided is valid.

### Automated Link Generator

**Deprecation Notice**

**As of October 2014, Automated LinkGenerator is discontinued in favor of Deep Linking.** To use [Deep Linking](#deep-linking) instead, you only have to set `LinkshareAPI.affiliate_id`. Everything else remains the same.

Generate affiliate URLs using [Automated LinkGenerator](https://rakutenlinkshare.zendesk.com/hc/en-us/articles/201343135-Automated-LinkGenerator-Guidelines) service.
Below is an example of generating an affiliate URL for [Walmart](http://www.walmart.com). Walmart merchant code is `2149`.

```ruby
url = "http://www.walmart.com/cp/Electronics/3944?povid=P1171-C1093.2766-L33"
affiliate_url = LinkshareAPI.link_generator(2149, url)
# http://linksynergy.walmart.com/fs-bin/click?id=your_affiliate_id&subid=0&offerid=223073.1&type=10&tmpid=273&RD_PARM1=http%3A%2F%2Fwww.walmart.com%2Fcp%2FElectronics%2F3944%3F&RD_PARM2=povid%3DP1171-C1093.2766-L33
```

### Merchandiser Query Tool
Expand Down
20 changes: 18 additions & 2 deletions lib/linkshare_api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

# Resources
require File.expand_path("../linkshare_api/link_generator", __FILE__)
require File.expand_path("../linkshare_api/deep_linking", __FILE__)
require File.expand_path("../linkshare_api/product_search", __FILE__)
require File.expand_path("../linkshare_api/coupon_web_service", __FILE__)
require File.expand_path("../linkshare_api/response", __FILE__)
Expand All @@ -13,9 +14,13 @@
require File.expand_path("../linkshare_api/errors/connection_error", __FILE__)
require File.expand_path("../linkshare_api/errors/invalid_request_error", __FILE__)

# Misc
require File.expand_path("../linkshare_api/logger", __FILE__)

module LinkshareAPI
WEB_SERVICE_URIS = {
link_generator: "http://getdeeplink.linksynergy.com/createcustomlink.shtml",
deep_linking: "http://click.linksynergy.com/deeplink",
product_search: "http://productsearch.linksynergy.com/productsearch",
coupon_web_service: "http://couponfeed.linksynergy.com/coupon"
}
Expand All @@ -39,7 +44,7 @@ module LinkshareAPI
@api_timeout = 30

class << self
attr_accessor :token
attr_accessor :token, :affiliate_id, :logger
attr_reader :api_timeout
end

Expand All @@ -50,7 +55,18 @@ def self.api_timeout=(timeout)
end

def self.link_generator(mid, murl)
link_generator = LinkshareAPI::LinkGenerator.new
if affiliate_id.nil?
LinkshareAPI::Logger.log(
:warn,
"`Automated Link Generator` has been discontinued in favor of `Deep Linking`. " +
"To use `Deep Linking` you only have to set your Affiliate ID by executing " +
"'LinkshareAPI.affiliate_id = <AFFILIATE_ID>'. Everything else remains the same. " +
"See https://github.com/rmarescu/linkshare_api#deep-linking for details."
)
link_generator = LinkshareAPI::LinkGenerator.new
else
link_generator = LinkshareAPI::DeepLinking.new
end
link_generator.build(mid, murl)
end

Expand Down
1 change: 0 additions & 1 deletion lib/linkshare_api/coupon_web_service.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
require "addressable/uri"
require "httparty"

module LinkshareAPI
Expand Down
33 changes: 33 additions & 0 deletions lib/linkshare_api/deep_linking.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
require "addressable/uri"

module LinkshareAPI
# For implementation details please visit
# https://rakutenlinkshare.zendesk.com/hc/en-us/articles/201295755-Guide-to-Deep-Linking
class DeepLinking
attr_reader :base_url, :affiliate_id

def initialize
@affiliate_id = LinkshareAPI.affiliate_id
@base_url = LinkshareAPI::WEB_SERVICE_URIS[:deep_linking]

if @affiliate_id.nil?
raise AuthenticationError.new(
"No Affilite ID. Set your Affiliate ID by using 'LinkshareAPI.affiliate_id = <AFFILIATE_ID>'. " +
"See https://github.com/rmarescu/linkshare_api#deep-linking for details."
)
end
end

def build(mid, murl)
raise ArgumentError, "mid must be a Fixnum, got #{mid.class} instead" unless mid.is_a?(Fixnum)

uri = Addressable::URI.parse(base_url)
uri.query_values = {
id: affiliate_id,
mid: mid,
murl: murl
}
uri.to_s
end
end
end
1 change: 0 additions & 1 deletion lib/linkshare_api/link_generator.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
require "addressable/uri"
require "cgi"
require "httparty"

Expand Down
16 changes: 16 additions & 0 deletions lib/linkshare_api/logger.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
require "logger"

module LinkshareAPI
class Logger
attr_reader :logger

def self.log(level, message)

new.logger.send(level, "[linkshare_api] #{message}")
end

def initialize
@logger = LinkshareAPI.logger || ::Logger.new(STDOUT)
end
end
end
1 change: 0 additions & 1 deletion lib/linkshare_api/product_search.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
require "addressable/uri"
require "httparty"

module LinkshareAPI
Expand Down
2 changes: 1 addition & 1 deletion lib/linkshare_api/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module LinkshareAPI
VERSION = "0.2.0"
VERSION = "0.3.0"
end
5 changes: 3 additions & 2 deletions linkshare_api.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,11 @@ Gem::Specification.new do |s|
s.require_paths = ["lib"]

s.add_dependency "addressable", "~> 2.3"
s.add_dependency "formatador", "~>0.2"
s.add_dependency "httparty", "~> 0.13"
s.add_dependency "recursive-open-struct", "~> 0.4"
s.add_dependency "recursive-open-struct", "~> 0.5"

s.add_development_dependency "bundler", "~> 1.6"
s.add_development_dependency "bundler", "~> 1.7"
s.add_development_dependency "rake"
s.add_development_dependency "webmock"
s.add_development_dependency "test-unit"
Expand Down
32 changes: 31 additions & 1 deletion test/linkshare_api_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
class LinkshareAPITest < Test::Unit::TestCase
def test_link_generator_invalid_token
LinkshareAPI.token = nil
LinkshareAPI.affiliate_id = nil
assert_raise LinkshareAPI::AuthenticationError do
LinkshareAPI.link_generator(123, "http://www.example.com")
end
Expand All @@ -24,13 +25,15 @@ def test_link_generator_invalid_timeout

def test_link_generator_invalid_mid
LinkshareAPI.token = token
LinkshareAPI.affiliate_id = nil
assert_raise ArgumentError do
LinkshareAPI.link_generator(nil, nil)
end
end

def test_link_generator_missing_url
LinkshareAPI.token = token
LinkshareAPI.affiliate_id = nil
stub_request(
:get,
"http://getdeeplink.linksynergy.com/createcustomlink.shtml?token=#{token}&mid=123&murl="
Expand All @@ -48,6 +51,7 @@ def test_link_generator_missing_url

def test_link_generator_valid_request
LinkshareAPI.token = token
LinkshareAPI.affiliate_id = nil
mid = 2149
murl = "http://www.walmart.com/cp/blu-ray/616859?povid=P1171-C1110.2784+1455.2776+1115.2956-L44"
stub_request(
Expand All @@ -63,6 +67,28 @@ def test_link_generator_valid_request
assert_equal "http://linksynergy.walmart.com/fs-bin/click?id=yourid&subid=0&offerid=223073.1&type=10&tmpid=273&RD_PARM0=http%3A%2F%2Fwww.walmart.com%2Fcp%2Fblu-ray%2F616859%3Fpovid%3DP1171-C1110.2784%2B1455.2776%2B1115.2956-L44&RD_PARM1=http%3A%2F%2Fwww.walmart.com%2Fcp%2Fblu-ray%2F616859%3F&RD_PARM2=povid%3DP1171-C1110.2784%2B1455.2776%2B1115.2956-L44", url
end

def test_deep_linking_invalid_token
LinkshareAPI.affiliate_id = nil
assert_raise LinkshareAPI::AuthenticationError do
LinkshareAPI.link_generator(123, "http://www.example.com")
end
end

def test_deep_linking_invalid_mid
LinkshareAPI.affiliate_id = affiliate_id
assert_raise ArgumentError do
LinkshareAPI.link_generator(nil, nil)
end
end

def test_deep_linking_valid_request
LinkshareAPI.affiliate_id = affiliate_id
mid = 2149
murl = "http://www.walmart.com/cp/blu-ray/616859?povid=P1171-C1110.2784+1455.2776+1115.2956-L44"
url = LinkshareAPI.link_generator(mid, murl)
assert_equal "http://click.linksynergy.com/deeplink?id=secret_affiliate_id&mid=2149&murl=http%3A%2F%2Fwww.walmart.com%2Fcp%2Fblu-ray%2F616859%3Fpovid%3DP1171-C1110.2784%2B1455.2776%2B1115.2956-L44", url
end

def test_product_search_invalid_token
LinkshareAPI.token = nil
assert_raise LinkshareAPI::AuthenticationError do
Expand Down Expand Up @@ -221,6 +247,10 @@ def test_product_search_all_results
private

def token
"abcdef"
"secret_token"
end

def affiliate_id
"secret_affiliate_id"
end
end
2 changes: 2 additions & 0 deletions test/test_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@
$LOAD_PATH.unshift(File.dirname(__FILE__))
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
require "linkshare_api"

LinkshareAPI.logger = Logger.new("/dev/null")

0 comments on commit 5a96a11

Please sign in to comment.