bitly 1.1.2 → 2.0.0.beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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