bitly 1.1.2 → 2.0.0.beta.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +36 -3
  3. data/.rspec +3 -0
  4. data/.travis.yml +5 -2
  5. data/CODE_OF_CONDUCT.md +74 -0
  6. data/Gemfile +5 -2
  7. data/History.txt +18 -1
  8. data/LICENSE.md +1 -1
  9. data/README.md +151 -58
  10. data/Rakefile +4 -9
  11. data/bin/console +14 -0
  12. data/bin/oauth +10 -0
  13. data/bin/setup +8 -0
  14. data/bitly.gemspec +24 -29
  15. data/config/env.yml.example +5 -0
  16. data/docs/authentication.md +51 -0
  17. data/docs/bitlinks.md +2 -0
  18. data/docs/branded_short_domains.md +20 -0
  19. data/docs/groups.md +80 -0
  20. data/docs/oauth_apps.md +20 -0
  21. data/docs/organizations.md +74 -0
  22. data/docs/premium_apis.md +0 -0
  23. data/docs/users.md +1 -0
  24. data/lib/bitly.rb +6 -7
  25. data/lib/bitly/api.rb +16 -0
  26. data/lib/bitly/api/base.rb +22 -0
  27. data/lib/bitly/api/bitlink.rb +341 -0
  28. data/lib/bitly/api/bitlink/clicks_summary.rb +35 -0
  29. data/lib/bitly/api/bitlink/deeplink.rb +29 -0
  30. data/lib/bitly/api/bitlink/link_click.rb +74 -0
  31. data/lib/bitly/api/bitlink/paginated_list.rb +51 -0
  32. data/lib/bitly/api/bsd.rb +24 -0
  33. data/lib/bitly/api/click_metric.rb +185 -0
  34. data/lib/bitly/api/client.rb +588 -0
  35. data/lib/bitly/api/group.rb +232 -0
  36. data/lib/bitly/api/group/preferences.rb +73 -0
  37. data/lib/bitly/api/list.rb +22 -0
  38. data/lib/bitly/api/oauth_app.rb +26 -0
  39. data/lib/bitly/api/organization.rb +104 -0
  40. data/lib/bitly/api/shorten_counts.rb +61 -0
  41. data/lib/bitly/api/user.rb +107 -0
  42. data/lib/bitly/error.rb +33 -0
  43. data/lib/bitly/http.rb +6 -0
  44. data/lib/bitly/http/adapters/net_http.rb +27 -0
  45. data/lib/bitly/http/client.rb +33 -0
  46. data/lib/bitly/http/request.rb +116 -0
  47. data/lib/bitly/http/response.rb +65 -0
  48. data/lib/bitly/oauth.rb +109 -0
  49. data/lib/bitly/version.rb +3 -1
  50. metadata +88 -108
  51. data/Manifest +0 -37
  52. data/lib/bitly/url.rb +0 -103
  53. data/lib/bitly/utils.rb +0 -57
  54. data/lib/bitly/v3.rb +0 -14
  55. data/lib/bitly/v3/bitly.rb +0 -7
  56. data/lib/bitly/v3/country.rb +0 -13
  57. data/lib/bitly/v3/day.rb +0 -13
  58. data/lib/bitly/v3/missing_url.rb +0 -15
  59. data/lib/bitly/v3/oauth.rb +0 -41
  60. data/lib/bitly/v3/realtime_link.rb +0 -18
  61. data/lib/bitly/v3/referrer.rb +0 -13
  62. data/lib/bitly/v3/url.rb +0 -154
  63. data/test/bitly/test_client.rb +0 -266
  64. data/test/bitly/test_config.rb +0 -28
  65. data/test/bitly/test_url.rb +0 -167
  66. data/test/bitly/test_utils.rb +0 -79
  67. data/test/fixtures/cnn.json +0 -1
  68. data/test/fixtures/cnn_and_google.json +0 -1
  69. data/test/fixtures/expand_cnn.json +0 -1
  70. data/test/fixtures/expand_cnn_and_google.json +0 -1
  71. data/test/fixtures/google_and_cnn_info.json +0 -1
  72. data/test/fixtures/google_info.json +0 -1
  73. data/test/fixtures/google_stats.json +0 -1
  74. data/test/fixtures/shorten_error.json +0 -1
  75. data/test/test_helper.rb +0 -39
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "bitly"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "bitly"
5
+ require "envyable"
6
+
7
+ Envyable.load('./config/env.yml')
8
+
9
+ oauth = Bitly::OAuth.new(client_id: ENV['CLIENT_ID'], client_secret: ENV['CLIENT_SECRET'])
10
+ puts oauth.authorize_uri('http://example.com/oauth/redirect')
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -1,38 +1,33 @@
1
- # -*- encoding: utf-8 -*-
2
- # stub: bitly 1.1.0 ruby lib
1
+
3
2
  lib = File.expand_path("../lib", __FILE__)
4
3
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
- require 'bitly/version'
4
+ require "bitly/version"
6
5
 
7
6
  Gem::Specification.new do |spec|
8
- spec.name = "bitly"
9
- spec.version = Bitly::VERSION
10
- spec.authors = ["Phil Nash"]
11
- spec.email = "philnash@gmail.com"
12
-
13
- spec.summary = "Use the bit.ly API to shorten or expand URLs"
14
- spec.description = "Use the bit.ly API to shorten or expand URLs"
15
- spec.homepage = "http://github.com/philnash/bitly"
16
- spec.license = "MIT"
7
+ spec.name = "bitly"
8
+ spec.version = Bitly::VERSION
9
+ spec.authors = ["Phil Nash"]
10
+ spec.email = ["philnash@gmail.com"]
17
11
 
18
- spec.files = `git ls-files -z`.split("\x0")
19
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
20
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
21
- spec.require_paths = ["lib"]
22
- spec.required_ruby_version = '>= 1.8.7'
12
+ spec.summary = %q{Use the bit.ly API to shorten or expand URLs}
13
+ spec.description = %q{Use the bit.ly API to shorten or expand URLs. Check out the API documentation at https://dev.bitly.com/.}
14
+ spec.homepage = "https://github.com/philnash/bitly"
15
+ spec.license = "MIT"
23
16
 
24
- spec.rdoc_options = ["--line-numbers", "--title", "Bitly", "--main", "README.md"]
25
- spec.extra_rdoc_files = ["LICENSE.md", "README.md"]
17
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
18
+ f.match(%r{^(test|spec|features)/})
19
+ end
20
+ spec.bindir = "exe"
21
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
+ spec.require_paths = ["lib"]
26
23
 
27
- spec.add_runtime_dependency "multi_json", "~> 1.3"
28
- spec.add_runtime_dependency "httparty", ">= 0.7.6"
29
- spec.add_runtime_dependency "oauth2", "< 2.0", ">= 0.5.0"
30
- spec.add_runtime_dependency "rack", "<2" if RUBY_VERSION.to_f < 2.2
24
+ spec.add_dependency "oauth2", "< 2.0", ">= 0.5.0"
31
25
 
32
- spec.add_development_dependency "bundler", "~> 1.15"
33
- spec.add_development_dependency "rake"
34
- spec.add_development_dependency "shoulda", "~> 3.5.0"
35
- spec.add_development_dependency "flexmock"
36
- spec.add_development_dependency "webmock"
37
- spec.add_development_dependency "minitest", "~> 5.8.3"
26
+ spec.add_development_dependency "bundler", "~> 2.0"
27
+ spec.add_development_dependency "rake", "~> 10.0"
28
+ spec.add_development_dependency "rspec", "~> 3.0"
29
+ spec.add_development_dependency "simplecov", "~> 0.17.1"
30
+ spec.add_development_dependency "webmock", "~> 3.7.6"
31
+ spec.add_development_dependency "vcr"
32
+ spec.add_development_dependency "envyable"
38
33
  end
@@ -0,0 +1,5 @@
1
+ CLIENT_ID:
2
+ CLIENT_SECRET:
3
+ OAUTH_CODE:
4
+ USERNAME:
5
+ PASSWORD:
@@ -0,0 +1,51 @@
1
+ # Authentication
2
+
3
+ Bitly requires OAuth access tokens to use the API. You will need to [register your application with the Bitly API](bitly.com/a/oauth_apps), you will get a `client_id` and `client_secret`.
4
+
5
+ There are 3 methods you can use to get an OAuth access token:
6
+
7
+ - [Account Generic Access Token](#account-generic-access-token)
8
+ - [OAuth Web Flow](#oauth-web-flow)
9
+ - [Resource Owner Credential Grant Flow](#resource-owner-credential-grant-flow)
10
+
11
+ ## Account Generic Access Token
12
+
13
+ You can get your own OAuth token for your account from the [Bitly console](https://app.bitly.com/). Click on the account drop down menu, then _Profile Settings_ then _Generic Access Token_. Fill in your password and you can generate an OAuth access token.
14
+
15
+ ## OAuth Web Flow
16
+
17
+ Redirect the user to the Bitly authorization page using your `client_id` and a `redirect_uri` that Bitly should redirect your user to after authorization. You can get the URL like so:
18
+
19
+ ```ruby
20
+ oauth = Bitly::OAuth.new(client_id: client_id, client_secret: client_secret)
21
+ oauth.authorize_uri("http://myexamplewebapp.com/oauth_page")
22
+ #=> "https://bitly.com/oauth/authorize?client_id=client_id&redirect_uri=http%3A%2F%2Fmyexamplewebapp.com%2Foauth_page"
23
+ ```
24
+
25
+ You can pass an optional `state` parameter that will be included, unchanged, in the redirect.
26
+
27
+ ```ruby
28
+ oauth.authorize_uri("http://myexamplewebapp.com/oauth_page", state: "state")
29
+ #=> "https://bitly.com/oauth/authorize?client_id=client_id&redirect_uri=http%3A%2F%2Fmyexamplewebapp.com%2Foauth_page&state=state"
30
+ ```
31
+
32
+ Once the user has authorized you to use their Bitly account, you will get a
33
+ `code` parameter in the redirect. You can exchange that code, along with the
34
+ redirect_uri, for the access token.
35
+
36
+ ```ruby
37
+ oauth.access_token(redirect_uri: "http://myexamplewebapp.com/oauth_page", code: "code")
38
+ #=> "<ACCESS_TOKEN>"
39
+ ```
40
+
41
+ ## Resource Owner Credential Grant Flow
42
+
43
+ If you cannot perform a web flow, the resource owner credential grant flow allows you to take a user's username and password and exchange it for an OAuth access token. If you use this method you _should_ store only the user's access token and never the password.
44
+
45
+ To use the resource owner credential grant flow, create an OAuth client object then request the access token with the username and password:
46
+
47
+ ```ruby
48
+ oauth = Bitly::OAuth.new(client_id: client_id, client_secret: client_secret)
49
+ oauth.access_token(username: username, password: password)
50
+ #=> "<ACCESS_TOKEN>"
51
+ ```
@@ -0,0 +1,2 @@
1
+ # Bitlinks
2
+
@@ -0,0 +1,20 @@
1
+ # Branded Short Domains
2
+
3
+ BSDs is an acronym for branded short domains. A branded short domain is a custom 15 character or less domain for bitlinks. This allows you to customize the domain to your brand.
4
+
5
+ See the full [Bitly API documentation for BSDs](https://dev.bitly.com/v4/#tag/BSDs).
6
+
7
+ ## List BSDs
8
+
9
+ With an API client you can list the BSDs available to the authorized user.
10
+
11
+ ```ruby
12
+ client = Bitly::API::Client.new(token: token)
13
+ bsds = client.bsds
14
+ ```
15
+
16
+ Or with the class method
17
+
18
+ ```ruby
19
+ bsds = Bitly::API::BSD.list(client: client)
20
+ ```
@@ -0,0 +1,80 @@
1
+ # Groups
2
+
3
+ Groups are a subdivision within an [organization](./organizations.md). A [user](./users.md) belongs to a group within an organization. Most actions in the API are on behalf of a group. For example, when you shorten a link, it will be on behalf of a user and a group.
4
+
5
+ See the full [Bitly API documentation for Groups](https://dev.bitly.com/v4/#tag/Groups).
6
+
7
+ ## List Groups
8
+
9
+ With an API client you can list the groups available to the authorized user.
10
+
11
+ ```ruby
12
+ client = Bitly::API::Client.new(token: token)
13
+ groups = client.groups
14
+ ```
15
+
16
+ Or with the class method
17
+
18
+ ```ruby
19
+ groups = Bitly::API::Group.list(client: client)
20
+ ```
21
+
22
+ You can also filter groups by an organization guid or an organization object, using the client.
23
+
24
+ ```ruby
25
+ groups = client.groups(organization: organization_guid)
26
+ groups = client.groups(organization: organization)
27
+ ```
28
+
29
+ Or the class method
30
+
31
+ ```ruby
32
+ groups = Bitly::API::Group.list(client: client, organization: organization_guid)
33
+ groups = Bitly::API::Group.list(client: client, organization: organization)
34
+ ```
35
+
36
+ ## Fetch a Group
37
+
38
+ If you have the guid of an group, you can fetch it directly.
39
+
40
+ ```ruby
41
+ group = client.group(guid)
42
+ ```
43
+
44
+ Or with the class method
45
+
46
+ ```ruby
47
+ group = Bitly::API::Group.fetch(client: client, guid: guid)
48
+ ```
49
+
50
+ ## Group attributes
51
+
52
+ Groups have the following attributes:
53
+
54
+ * `name`
55
+ * `guid`
56
+ * `is_active`
57
+ * `role`
58
+ * `bsds`
59
+ * `organization_guid`
60
+ * `created`
61
+ * `modified`
62
+
63
+ ### A Group's organization
64
+
65
+ With the `organization_guid` we can get the group's organization directly from the group object.
66
+
67
+ ```ruby
68
+ organization = group.organization
69
+ ```
70
+
71
+ ### Group preferences
72
+
73
+ You can set one preference for a group, the domain that is used to shorten links. Free accounts can only choose `bit.ly` and pro accounts can use any domains they have set up.
74
+
75
+ ```ruby
76
+ preferences = group.preferences
77
+ puts preferences.domain_preference
78
+
79
+ preferences.update(domain_preference: 'bit.ly')
80
+ ```
@@ -0,0 +1,20 @@
1
+ # OAuth Apps
2
+
3
+ You can fetch the details of an OAuth app you have in your account by the `client_id`.
4
+
5
+ See the full [Bitly documentation for OAuth apps](https://dev.bitly.com/v4/#operation/getOAuthApp)
6
+
7
+ ## Fetch an OAuth app
8
+
9
+ With the `client_id` of an OAuth app, you can fetch it directly.
10
+
11
+ ```ruby
12
+ client = Bitly::API::Client.new(token: token)
13
+ oauth_app = client.oauth_app(client_id: client_id)
14
+ ```
15
+
16
+ Or with the class method
17
+
18
+ ```ruby
19
+ oauth_app = Bitly::API::OAuthApp.fetch(client: client, client_id: client_id)
20
+ ```
@@ -0,0 +1,74 @@
1
+ # Organizations
2
+
3
+ An organization is the top level of the Bitly user hierarchy. Both [Users](./users.md) and [Groups](./groups.md) live within an organization.
4
+
5
+ See the full [Bitly API documentation for Organizations](https://dev.bitly.com/v4/#tag/Organizations).
6
+
7
+ ## List Organizations
8
+
9
+ With an API client you can list the organizations available to the authorized user.
10
+
11
+ ```ruby
12
+ client = Bitly::API::Client.new(token: token)
13
+ organizations = client.organizations
14
+ ```
15
+
16
+ Or with the class method:
17
+
18
+ ```ruby
19
+ organizations = Bitly::API::Organization.list(client: client)
20
+ ```
21
+
22
+ ## Fetch an Organization
23
+
24
+ If you have the guid of an organization, you can fetch it directly.
25
+
26
+ ```ruby
27
+ client = Bitly::API::Client.new(token: token)
28
+ organization = client.organization(guid)
29
+ ```
30
+
31
+ Or with the class method
32
+
33
+ ```ruby
34
+ organization = Bitly::API::Organization.fetch(client: client, organization_guid: guid)
35
+ ```
36
+
37
+ ## Organization attributes
38
+
39
+ Organizations have the following attributes:
40
+
41
+ * `name`
42
+ * `guid`
43
+ * `is_active`
44
+ * `tier`
45
+ * `tier_family`
46
+ * `tier_display_name`
47
+ * `role`
48
+ * `bsds`
49
+ * `created`
50
+ * `modified`
51
+
52
+ ### Organization groups
53
+
54
+ With an organization you can fetch its related [groups](./groups.md).
55
+
56
+ ```ruby
57
+ client = Bitly::API::Client.new(token: token)
58
+ organization = client.organization(guid)
59
+ groups = organization.groups
60
+ ```
61
+
62
+ This is the same as fetching groups and filtering by an organization guid.
63
+
64
+ ```ruby
65
+ client = Bitly::API::Client.new(token: token)
66
+ organization = client.organization(guid)
67
+ groups = client.groups(organization: organization)
68
+ ```
69
+
70
+ Or filtering in the class method directly.
71
+
72
+ ```ruby
73
+ groups = Bitly::API::Group.list(client: client, organization: organization)
74
+ ```
File without changes
@@ -0,0 +1 @@
1
+ # Users
@@ -1,8 +1,7 @@
1
- require 'multi_json'
1
+ # frozen_string_literal: true
2
2
 
3
- require 'bitly/config'
4
- require 'bitly/utils'
5
- require 'bitly/client'
6
- require 'bitly/url'
7
- require 'bitly/version'
8
- require 'bitly/v3'
3
+ require "bitly/version"
4
+ require "bitly/error"
5
+ require "bitly/oauth"
6
+ require "bitly/http"
7
+ require "bitly/api"
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bitly
4
+ module API
5
+ BASE_URL = URI("https://api-ssl.bitly.com/v4")
6
+ end
7
+ end
8
+
9
+ require_relative "./api/client"
10
+ require_relative "./api/click_metric"
11
+ require_relative "./api/bitlink"
12
+ require_relative "./api/organization"
13
+ require_relative "./api/group"
14
+ require_relative "./api/user"
15
+ require_relative "./api/bsd"
16
+ require_relative "./api/oauth_app"
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bitly
4
+ module API
5
+ module Base
6
+ attr_reader :response
7
+
8
+ def assign_attributes(attributes)
9
+ if self.class.respond_to?(:attributes)
10
+ self.class.attributes.each do |attr|
11
+ instance_variable_set("@#{attr}", attributes[attr.to_s]) if attributes[attr.to_s]
12
+ end
13
+ end
14
+ if self.class.respond_to?(:time_attributes)
15
+ self.class.time_attributes.each do |attr|
16
+ instance_variable_set("@#{attr}", Time.parse(attributes[attr.to_s])) if attributes[attr.to_s]
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,341 @@
1
+ # frozen_string_literal: true
2
+ require_relative "./base"
3
+ require_relative "./list"
4
+ require_relative "./bitlink/paginated_list"
5
+ require_relative "./bitlink/deeplink"
6
+ require_relative "./bitlink/clicks_summary"
7
+ require_relative "./bitlink/link_click"
8
+
9
+ module Bitly
10
+ module API
11
+ ##
12
+ # A Bitlink represents a shortened link within Bitly.
13
+ class Bitlink
14
+ include Base
15
+
16
+ class List < Bitly::API::List ; end
17
+
18
+ ##
19
+ # Shortens a long url.
20
+ # [`POST /v4/shorten`](https://dev.bitly.com/v4/#operation/createBitlink)
21
+ #
22
+ # @example
23
+ # bitlink = Bitly::API::Bitlink.shorten(client: client, long_url: long_url)
24
+ #
25
+ # @param client [Bitly::API::Client] An authorized API client
26
+ # @param long_url [String] A long URL that you want shortened
27
+ # @param domain [String] The bitly domain you want to shorten, API default
28
+ # is "bit.ly"
29
+ # @param group_guid [String] The GUID of the group for which you want to
30
+ # shorten this URL
31
+ #
32
+ # @return [Bitly::API::Bitlink]
33
+ def self.shorten(client:, long_url:, domain: nil, group_guid: nil)
34
+ response = client.request(
35
+ path: "/shorten",
36
+ method: "POST",
37
+ params: {
38
+ "long_url" => long_url,
39
+ "domain" => domain,
40
+ "group_guid" => group_guid
41
+ })
42
+ new(data: response.body, client: client, response: response)
43
+ end
44
+
45
+ ##
46
+ # Creates a new Bitlink from a long URL. Similar to #shorten but takes
47
+ # more parameters.
48
+ # [`POST /v4/bitlinks`](https://dev.bitly.com/v4/#operation/createFullBitlink)
49
+ #
50
+ # @example
51
+ # bitlink = Bitly::API::Bitlink.create(client: client, long_url: long_url)
52
+ #
53
+ # @param client [Bitly::API::Client] An authorized API client
54
+ # @param long_url [String] A long URL that you want shortened
55
+ # @param domain [String] The bitly domain you want to shorten, API default
56
+ # is "bit.ly"
57
+ # @param group_guid [String] The GUID of the group for which you want to
58
+ # shorten this URL
59
+ # @param title [String] A descriptive title for the link
60
+ # @param tags [Array<String>] Some tags for the Bitlink
61
+ # @param deeplinks [Array<Bitly::API::Bitlink::Deeplink>]
62
+ #
63
+ # @return [Bitly::API::Bitlink]
64
+ def self.create(client:, long_url:, domain: nil, group_guid: nil, title: nil, tags: nil, deeplinks: nil)
65
+ response = client.request(
66
+ path: "/bitlinks",
67
+ method: "POST",
68
+ params: {
69
+ "long_url" => long_url,
70
+ "domain" => domain,
71
+ "group_guid" => group_guid,
72
+ "title" => title,
73
+ "tags" => tags,
74
+ "deeplinks" => deeplinks
75
+ }
76
+ )
77
+ new(data: response.body, client: client, response: response)
78
+ end
79
+
80
+ ##
81
+ # Return information about a bitlink
82
+ # [`GET /v4/bitlink/{bitlink}`](https://dev.bitly.com/v4/#operation/getBitlink)
83
+ #
84
+ # @example
85
+ # bitlink = Bitly::API::Bitlink.fetch(client: client, bitlink: "bit.ly/example")
86
+ #
87
+ # @param client [Bitly::API::Client] An authorized API client
88
+ # @param bitlink [String] The bitlink you want information about
89
+ #
90
+ # @return [Bitly::API::Bitlink]
91
+ def self.fetch(client:, bitlink:)
92
+ response = client.request(path: "/bitlinks/#{bitlink}")
93
+ new(data: response.body, client: client, response: response)
94
+ end
95
+
96
+ ##
97
+ # Return public information about a bitlink
98
+ # [`POST /v4/expand`](https://dev.bitly.com/v4/#operation/expandBitlink)
99
+ #
100
+ # @example
101
+ # bitlink = Bitly::API::Bitlink.expand(client: client, bitlink: "bit.ly/example")
102
+ #
103
+ # @param client [Bitly::API::Client] An authorized API client
104
+ # @param bitlink [String] The bitlink you want information about
105
+ #
106
+ # @return [Bitly::API::Bitlink]
107
+ def self.expand(client:, bitlink:)
108
+ response = client.request(path: "/expand", method: "POST", params: { "bitlink_id" => bitlink })
109
+ new(data: response.body, client: client, response: response)
110
+ end
111
+
112
+ ##
113
+ # Retrieve a list of bitlinks by group
114
+ # [`GET /v4/groups/{group_guid}/bitlinks`](https://dev.bitly.com/v4/#operation/getBitlinksByGroup)
115
+ #
116
+ # @example
117
+ # bitlinks = Bitly::API::Bitlink.list(client: client, group_guid: guid)
118
+ #
119
+ # @param client [Bitly::API::Client] An authorized API client
120
+ # @param group_guid [String] The group guid for which you want bitlinks
121
+ # @param size [Integer] The number of Bitlinks to return, max 100
122
+ # @param page [Integer] The page of bitlinks to request
123
+ # @param keyword [String] Custom keyword to filter on history entries
124
+ # @param query [String] A value to search for Bitlinks
125
+ # @param created_before [Integer] Timestamp as an integer unix epoch
126
+ # @param created_after [Integer] Timestamp as an integer unix epoch
127
+ # @param modified_after [Integer] Timestamp as an integer unix epoch
128
+ # @param archived [String] Whether or not to include archived Bitlinks.
129
+ # One of "on", "off" or "both". Defaults to "off".
130
+ # @param deeplinks [String] Filter to only Bitlinks that contain
131
+ # deeplinks. One of "on", "off" or "both". Defaults to "both".
132
+ # @param domain_deeplinks [String] Filter to only Bitlinks that contain
133
+ # deeplinks configured with a custom domain. One of "on", "off" or
134
+ # "both". Defaults to "both".
135
+ # @param campaign_guid [String] Filter to return only links for the given
136
+ # campaign GUID, can be provided
137
+ # @param channel_guid [String] Filter to return only links for the given
138
+ # channel GUID, can be provided, overrides all other parameters
139
+ # @param custom_bitlink [String] Filter to return only custom Bitlinks.
140
+ # One of "on", "off" or "both". Defaults to "both".
141
+ # @param tags [Array<String>] Filter by the given tags.
142
+ # @param encoding_login [Array<String>] Filter by the login of the
143
+ # authenticated user that created the Bitlink.
144
+ #
145
+ # @return [Bitly::API::Bitlink::PaginatedList]
146
+ def self.list(
147
+ client:,
148
+ group_guid:,
149
+ size: nil,
150
+ page: nil,
151
+ keyword: nil,
152
+ query: nil,
153
+ created_before: nil,
154
+ created_after: nil,
155
+ modified_after: nil,
156
+ archived: nil,
157
+ deeplinks: nil,
158
+ domain_deeplinks: nil,
159
+ campaign_guid: nil,
160
+ channel_guid: nil,
161
+ custom_bitlink: nil,
162
+ tags: nil,
163
+ encoding_login: nil
164
+ )
165
+ params = {
166
+ "size" => size,
167
+ "page" => page,
168
+ "keyword" => keyword,
169
+ "query" => query,
170
+ "created_before" => created_before,
171
+ "created_after" => created_after,
172
+ "modified_after" => modified_after,
173
+ "archived" => archived,
174
+ "deeplinks" => deeplinks,
175
+ "domain_deeplinks" => domain_deeplinks,
176
+ "campaign_guid" => campaign_guid,
177
+ "channel_guid" => channel_guid,
178
+ "custom_bitlink" => custom_bitlink,
179
+ "tags" => tags,
180
+ "encoding_login" => encoding_login
181
+ }
182
+ response = client.request(path: "/groups/#{group_guid}/bitlinks", params: params)
183
+ bitlinks = response.body["links"].map do |link|
184
+ new(data: link, client: client)
185
+ end
186
+ PaginatedList.new(items: bitlinks, response: response, client: client)
187
+ end
188
+
189
+ ##
190
+ # Returns a list of Bitlinks sorted by clicks.
191
+ # [`GET /v4/groups/{group_guid}/bitlinks/{sort}`](https://dev.bitly.com/v4/#operation/getSortedBitlinks)
192
+ #
193
+ # The API returns a separate list of the links and the click counts, but
194
+ # this method assigns the number of clicks for each link to the Bitlink
195
+ # object and sorts the resulting list in descending order.
196
+ #
197
+ # Sorted lists are not paginated, so do not have any pagination detail.
198
+ #
199
+ # @example
200
+ # links = Bitly::API::Bitlink.sorted_list(client: client, group_guid: guid)
201
+ #
202
+ # @param client [Bitly::API::Client] An authorized API client
203
+ # @param group_guid [String] The group for which you want to return links
204
+ # @param sort [String] The data to sort on. Default and only option is
205
+ # "clicks".
206
+ # @param unit [String] A unit of time. Default is "day" and can be
207
+ # "minute", "hour", "day", "week" or "month"
208
+ # @param units [Integer] An integer representing the time units to query
209
+ # data for. pass -1 to return all units of time. Defaults to -1.
210
+ # @param unit_reference [String] An ISO-8601 timestamp, indicating the
211
+ # most recent time for which to pull metrics. Will default to current
212
+ # time.
213
+ # @param size [Integer] The number of links to be returned. Defaults to 50
214
+ #
215
+ # @returns [Bitly::API::Bitlink::List]
216
+ def self.sorted_list(client:, group_guid:, sort: "clicks", unit: nil, units: nil, unit_reference: nil, size: nil)
217
+ params = {
218
+ "unit" => unit,
219
+ "units" => units,
220
+ "unit_reference" => unit_reference,
221
+ "size" => size
222
+ }
223
+ response = client.request(path: "/groups/#{group_guid}/bitlinks/#{sort}", params: params)
224
+ link_clicks = response.body["sorted_links"]
225
+ bitlinks = response.body["links"].map do |link|
226
+ clicks = link_clicks.find { |c| c["id"] == link["id"] }["clicks"]
227
+ new(data: link, client: client, clicks: clicks)
228
+ end.sort { |a, b| b.clicks <=> a.clicks }
229
+ List.new(items: bitlinks, response: response)
230
+ end
231
+
232
+ def self.attributes
233
+ [:archived, :tags, :title, :created_by, :long_url, :client_id, :custom_bitlinks, :link, :id]
234
+ end
235
+ def self.time_attributes
236
+ [:created_at]
237
+ end
238
+ attr_reader(*(attributes + time_attributes))
239
+ attr_reader :deeplinks, :clicks
240
+
241
+ def initialize(data:, client:, response: nil, clicks: nil)
242
+ assign_attributes(data)
243
+ if data["deeplinks"]
244
+ @deeplinks = data["deeplinks"].map { |data| Deeplink.new(data: data) }
245
+ else
246
+ @deeplinks = []
247
+ end
248
+ @clicks = clicks
249
+ @client = client
250
+ @response = response
251
+ end
252
+
253
+ ##
254
+ # Update the Bitlink.
255
+ # [`PATCH /v4/bitlink/{bitlink}`](https://dev.bitly.com/v4/#operation/updateBitlink)
256
+ #
257
+ # The parameters listed below are from the documentation. Some only work
258
+ # if you have a Bitly Pro account.
259
+ #
260
+ # @example
261
+ # bitlink.update(title: "New title")
262
+ #
263
+ # @param archived [Boolean]
264
+ # @param tags [Array<String>]
265
+ # @param created_at [String]
266
+ # @param title [String]
267
+ # @param deeplinks [Array<Bitly::API::Bitlink::Deeplink>]
268
+ # @param created_by [String]
269
+ # @param long_url [String]
270
+ # @param client_id [String]
271
+ # @param custom_bitlinks [Array<String>]
272
+ # @param link [String]
273
+ # @param id [String]
274
+ # @param references [Hash<String, String>]
275
+ #
276
+ # @returns [Bitly::API::Bitlink]
277
+ def update(
278
+ archived: nil,
279
+ tags: nil,
280
+ created_at: nil,
281
+ title: nil,
282
+ deeplinks: nil,
283
+ created_by: nil,
284
+ long_url: nil,
285
+ client_id: nil,
286
+ custom_bitlinks: nil,
287
+ link: nil,
288
+ id: nil,
289
+ references: nil
290
+ )
291
+ @response = @client.request(
292
+ path: "/bitlinks/#{@id}",
293
+ method: "PATCH",
294
+ params: {
295
+ "archived" => archived,
296
+ "tags" => tags,
297
+ "created_at" => created_at,
298
+ "title" => title,
299
+ "deeplinks" => deeplinks,
300
+ "created_by" => created_by,
301
+ "long_url" =>long_url ,
302
+ "client_id" => client_id,
303
+ "custom_bitlinks" => custom_bitlinks,
304
+ "link" => link,
305
+ "id" => id,
306
+ "references" => references
307
+ }
308
+ )
309
+ assign_attributes(@response.body)
310
+ self
311
+ end
312
+
313
+ # [`GET /v4/bitlink/{bitlink}/clicks/summary`](https://dev.bitly.com/v4/#operation/getClicksSummaryForBitlink)
314
+ #
315
+ # @return [Bitly::API::Bitlink::ClicksSummary]
316
+ def clicks_summary(unit: nil, units: nil, unit_reference: nil, size: nil)
317
+ ClicksSummary.fetch(client: @client, bitlink: id, unit: unit, units: units, unit_reference: unit_reference, size: size)
318
+ end
319
+
320
+ ##
321
+ # Get the clicks for the bitlink.
322
+ # [`GET /v4/bitlink/{bitlink}/clicks`](https://dev.bitly.com/v4/#operation/getClicksForBitlink)
323
+ #
324
+ # @param sort [String] The data to sort on. Default and only option is
325
+ # "clicks".
326
+ # @param unit [String] A unit of time. Default is "day" and can be
327
+ # "minute", "hour", "day", "week" or "month"
328
+ # @param units [Integer] An integer representing the time units to query
329
+ # data for. pass -1 to return all units of time. Defaults to -1.
330
+ # @param unit_reference [String] An ISO-8601 timestamp, indicating the
331
+ # most recent time for which to pull metrics. Will default to current
332
+ # time.
333
+ # @param size [Integer] The number of links to be returned. Defaults to 50
334
+ #
335
+ # @return [Bitly::API::Bitlink::LinkClick::List]
336
+ def link_clicks(unit: nil, units: nil, unit_reference: nil, size: nil)
337
+ LinkClick.list(client: @client, bitlink: id, unit: unit, units: units, unit_reference: unit_reference, size: size)
338
+ end
339
+ end
340
+ end
341
+ end