twitter-ads 0.3.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +2 -0
- data/CONTRIBUTING.md +77 -0
- data/LICENSE +22 -0
- data/README.md +111 -0
- data/Rakefile +86 -0
- data/bin/twitter-ads +42 -0
- data/lib/twitter-ads.rb +54 -0
- data/lib/twitter-ads/account.rb +229 -0
- data/lib/twitter-ads/audiences/tailored_audience.rb +177 -0
- data/lib/twitter-ads/campaign/app_list.rb +42 -0
- data/lib/twitter-ads/campaign/campaign.rb +40 -0
- data/lib/twitter-ads/campaign/funding_instrument.rb +33 -0
- data/lib/twitter-ads/campaign/line_item.rb +91 -0
- data/lib/twitter-ads/campaign/promotable_user.rb +28 -0
- data/lib/twitter-ads/campaign/targeting_criteria.rb +77 -0
- data/lib/twitter-ads/campaign/tweet.rb +83 -0
- data/lib/twitter-ads/client.rb +92 -0
- data/lib/twitter-ads/creative/app_download_card.rb +44 -0
- data/lib/twitter-ads/creative/image_app_download_card.rb +44 -0
- data/lib/twitter-ads/creative/image_conversation_card.rb +44 -0
- data/lib/twitter-ads/creative/lead_gen_card.rb +46 -0
- data/lib/twitter-ads/creative/promoted_account.rb +38 -0
- data/lib/twitter-ads/creative/promoted_tweet.rb +87 -0
- data/lib/twitter-ads/creative/video.rb +43 -0
- data/lib/twitter-ads/creative/video_app_download_card.rb +47 -0
- data/lib/twitter-ads/creative/video_conversation_card.rb +46 -0
- data/lib/twitter-ads/creative/website_card.rb +48 -0
- data/lib/twitter-ads/cursor.rb +127 -0
- data/lib/twitter-ads/enum.rb +135 -0
- data/lib/twitter-ads/error.rb +93 -0
- data/lib/twitter-ads/http/request.rb +127 -0
- data/lib/twitter-ads/http/response.rb +74 -0
- data/lib/twitter-ads/http/ton_upload.rb +140 -0
- data/lib/twitter-ads/legacy.rb +7 -0
- data/lib/twitter-ads/resources/analytics.rb +90 -0
- data/lib/twitter-ads/resources/dsl.rb +108 -0
- data/lib/twitter-ads/resources/persistence.rb +43 -0
- data/lib/twitter-ads/resources/resource.rb +92 -0
- data/lib/twitter-ads/targeting/reach_estimate.rb +69 -0
- data/lib/twitter-ads/utils.rb +76 -0
- data/lib/twitter-ads/version.rb +6 -0
- data/spec/fixtures/accounts_all.json +65 -0
- data/spec/fixtures/accounts_features.json +18 -0
- data/spec/fixtures/accounts_load.json +19 -0
- data/spec/fixtures/app_lists_all.json +22 -0
- data/spec/fixtures/app_lists_load.json +31 -0
- data/spec/fixtures/campaigns_all.json +208 -0
- data/spec/fixtures/campaigns_load.json +27 -0
- data/spec/fixtures/funding_instruments_all.json +74 -0
- data/spec/fixtures/funding_instruments_load.json +28 -0
- data/spec/fixtures/line_items_all.json +292 -0
- data/spec/fixtures/line_items_load.json +36 -0
- data/spec/fixtures/placements.json +35 -0
- data/spec/fixtures/promotable_users_all.json +57 -0
- data/spec/fixtures/promotable_users_load.json +18 -0
- data/spec/fixtures/promoted_tweets_all.json +212 -0
- data/spec/fixtures/promoted_tweets_load.json +19 -0
- data/spec/fixtures/reach_estimate.json +19 -0
- data/spec/fixtures/tailored_audiences_all.json +67 -0
- data/spec/fixtures/tailored_audiences_load.json +29 -0
- data/spec/fixtures/tweet_preview.json +24 -0
- data/spec/fixtures/videos_all.json +50 -0
- data/spec/fixtures/videos_load.json +22 -0
- data/spec/quality_spec.rb +15 -0
- data/spec/shared/properties.rb +20 -0
- data/spec/spec_helper.rb +61 -0
- data/spec/support/helpers.rb +42 -0
- data/spec/twitter-ads/account_spec.rb +315 -0
- data/spec/twitter-ads/audiences/tailored_audience_spec.rb +45 -0
- data/spec/twitter-ads/campaign/app_list_spec.rb +108 -0
- data/spec/twitter-ads/campaign/line_item_spec.rb +95 -0
- data/spec/twitter-ads/campaign/reach_estimate_spec.rb +98 -0
- data/spec/twitter-ads/campaign/targeting_criteria_spec.rb +39 -0
- data/spec/twitter-ads/campaign/tweet_spec.rb +83 -0
- data/spec/twitter-ads/client_spec.rb +115 -0
- data/spec/twitter-ads/creative/app_download_card_spec.rb +44 -0
- data/spec/twitter-ads/creative/image_app_download_card_spec.rb +43 -0
- data/spec/twitter-ads/creative/image_conversation_card_spec.rb +40 -0
- data/spec/twitter-ads/creative/lead_gen_card_spec.rb +46 -0
- data/spec/twitter-ads/creative/promoted_account_spec.rb +30 -0
- data/spec/twitter-ads/creative/promoted_tweet_spec.rb +46 -0
- data/spec/twitter-ads/creative/video_app_download_card_spec.rb +42 -0
- data/spec/twitter-ads/creative/video_conversation_card_spec.rb +52 -0
- data/spec/twitter-ads/creative/video_legacy_spec.rb +43 -0
- data/spec/twitter-ads/creative/video_spec.rb +43 -0
- data/spec/twitter-ads/creative/website_card_spec.rb +37 -0
- data/spec/twitter-ads/cursor_spec.rb +67 -0
- data/spec/twitter-ads/placements_spec.rb +36 -0
- data/spec/twitter-ads/utils_spec.rb +101 -0
- data/twitter-ads.gemspec +37 -0
- metadata +247 -0
- metadata.gz.sig +0 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c2a9baebef194bb1afe3d158260acac82197b4a9
|
4
|
+
data.tar.gz: 683bc57423beae4e79a1f41ecd58b0063b98a66b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 642dc745353d0f378aefa9a3dadde2820ddb6cec1d79c72f54e26d0958607fa6f4acf2235328d8e3e20b6a4af11a73288e4e0202f03887599c457e600986bfac
|
7
|
+
data.tar.gz: 51ccabfa2fdd681462f649ea6bd478e472760efa0290658b3e48b1f0851a240b2b035dc5763fa34e4949741c8a8dea125f78c9c48a5eca702333d254dd054f7c
|
checksums.yaml.gz.sig
ADDED
Binary file
|
data.tar.gz.sig
ADDED
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
# Contributing Guidelines
|
2
|
+
|
3
|
+
We love pull requests from everyone!
|
4
|
+
|
5
|
+
We encourage community contributions for all kinds of changes
|
6
|
+
both big and small, but we ask that you adhere to the following guidelines for contributing code.
|
7
|
+
|
8
|
+
##### Proposing Changes
|
9
|
+
|
10
|
+
As a starting point for all changes, we recommend [reporting an issue][report-issue]
|
11
|
+
before you begin making any changes. Make sure to search the issues on this repository
|
12
|
+
first to check and see the issue has already been previously discussed and whether or
|
13
|
+
not it's already being worked on.
|
14
|
+
|
15
|
+
- For small changes, improvements and bug fixes please feel free to send us a pull
|
16
|
+
request with proposed changes along-side the issue you report.
|
17
|
+
|
18
|
+
- For larger more involved or design related changes, please open an issue and discuss
|
19
|
+
the changes with the other contributors before submitting any pull requests.
|
20
|
+
|
21
|
+
[report-issue]: https://github.com/twitterdev/twitter-ruby-ads-sdk/issues?q=is%3Aopen+is%3Aissue
|
22
|
+
|
23
|
+
##### Submitting A Pull Request
|
24
|
+
|
25
|
+
1) Fork us and clone the repository locally.
|
26
|
+
|
27
|
+
```bash
|
28
|
+
git clone git@github.com:twitterdev/twitter-ruby-ads-sdk.git
|
29
|
+
```
|
30
|
+
|
31
|
+
2) Install development dependencies:
|
32
|
+
|
33
|
+
```bash
|
34
|
+
# install bundler (if you don't have it already)
|
35
|
+
gem install bundler
|
36
|
+
|
37
|
+
# install all development dependencies
|
38
|
+
bundle install
|
39
|
+
```
|
40
|
+
|
41
|
+
3) Make sure all tests pass before you start:
|
42
|
+
|
43
|
+
```bash
|
44
|
+
rake
|
45
|
+
```
|
46
|
+
|
47
|
+
4) Make your changes! (Don't forget tests and documentation)
|
48
|
+
|
49
|
+
5) Test your changes again and make sure everything passes:
|
50
|
+
|
51
|
+
```bash
|
52
|
+
rake
|
53
|
+
```
|
54
|
+
|
55
|
+
The test suite will automatically enforce test coverage and code style.
|
56
|
+
For the most part, we follow [this][style] community style guide with a
|
57
|
+
[few exceptions](https://github.com/twitterdev/twitter-ruby-ads-sdk/blob/master/.rubocop.yml).
|
58
|
+
|
59
|
+
[style]: https://github.com/bbatsov/ruby-style-guide
|
60
|
+
|
61
|
+
6) Submit your changes!
|
62
|
+
|
63
|
+
- [Squash](http://eli.thegreenplace.net/2014/02/19/squashing-github-pull-requests-into-a-single-commit) your development commits. Put features in a single clean commit whenever possible or logically split it into a few commits (no development commits). Test coverage can be included in a separate commit if preferred.
|
64
|
+
- Write a [good commit message][commit] for your change.
|
65
|
+
- Push to your fork.
|
66
|
+
- Submit a [pull request][pr].
|
67
|
+
|
68
|
+
[commit]: http://chris.beams.io/posts/git-commit/
|
69
|
+
[pr]: https://github.com/thoughtbot/suspenders/compare/
|
70
|
+
|
71
|
+
We try to at least comment on pull requests within one business day and may suggest changes.
|
72
|
+
|
73
|
+
##### Release Schedule and Versioning
|
74
|
+
|
75
|
+
We have a regular release cadence and adhere to [semantic versioning](http://semver.org/). When
|
76
|
+
exactly your change ships will depend on the scope of your changes and what type of upcoming release
|
77
|
+
its best suited for.
|
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (C) 2015 Twitter, Inc.
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
22
|
+
|
data/README.md
ADDED
@@ -0,0 +1,111 @@
|
|
1
|
+
Getting Started [![Build Status](https://travis-ci.org/twitterdev/twitter-ruby-ads-sdk.svg?branch=master)](https://travis-ci.org/twitterdev/twitter-ruby-ads-sdk) [![Code Climate](https://codeclimate.com/github/twitterdev/twitter-ruby-ads-sdk/badges/gpa.svg)](https://codeclimate.com/github/twitterdev/twitter-ruby-ads-sdk) [![Test Coverage](https://codeclimate.com/github/twitterdev/twitter-ruby-ads-sdk/badges/coverage.svg)](https://codeclimate.com/github/twitterdev/twitter-ruby-ads-sdk/coverage) [![Gem Version](https://badge.fury.io/rb/twitter-ads.svg)](http://badge.fury.io/rb/twitter-ads)
|
2
|
+
------
|
3
|
+
|
4
|
+
##### Installation
|
5
|
+
```bash
|
6
|
+
# installing the latest signed release
|
7
|
+
gem install twitter-ads
|
8
|
+
```
|
9
|
+
|
10
|
+
##### Quick Start
|
11
|
+
```ruby
|
12
|
+
require 'twitter-ads'
|
13
|
+
|
14
|
+
# initialize the client
|
15
|
+
client = TwitterAds::Client.new(
|
16
|
+
CONSUMER_KEY,
|
17
|
+
CONSUMER_SECRET,
|
18
|
+
ACCESS_TOKEN,
|
19
|
+
ACCESS_TOKEN_SECRET
|
20
|
+
)
|
21
|
+
|
22
|
+
# load the advertiser account instance
|
23
|
+
account = client.accounts('c3won9gy')
|
24
|
+
|
25
|
+
# load and update a specific campaign
|
26
|
+
campaign = account.campaigns('4m0gjms')
|
27
|
+
campaign.paused = true
|
28
|
+
campaign.save
|
29
|
+
|
30
|
+
# iterate through campaigns
|
31
|
+
account.campaigns.each do |camp|
|
32
|
+
# do stuff
|
33
|
+
end
|
34
|
+
```
|
35
|
+
|
36
|
+
##### Command Line Helper
|
37
|
+
```bash
|
38
|
+
# The twitter-ads command launches an interactive session for testing purposes
|
39
|
+
# with a client instance automatically loaded from your .twurlrc file.
|
40
|
+
|
41
|
+
~ ❯ twitter-ads
|
42
|
+
twitter-ads vX.X.X >> CLIENT
|
43
|
+
=> #<TwitterAds::Client:0x70101526238580 consumer_key="Fy90KQy57152sn5Mv7axji9409">
|
44
|
+
twitter-ads vX.X.X >> CLIENT.accounts.first
|
45
|
+
=> #<TwitterAds::Account:0x70101527905720 id="4lvtcum">
|
46
|
+
```
|
47
|
+
For more help please see our [Examples and Guides](https://github.com/twitterdev/twitter-ruby-ads-sdk/tree/master/examples) or check the online [Reference Documentation](http://twitterdev.github.io/twitter-ruby-ads-sdk/reference/index.html).
|
48
|
+
|
49
|
+
## Compatibility & Versioning
|
50
|
+
|
51
|
+
This project is designed to work with Ruby 2.0.0 or greater. While it may work on other version of Ruby, below are the platform and runtime versions we officially support and regularly test against.
|
52
|
+
|
53
|
+
Platform | Versions
|
54
|
+
-------- | --------
|
55
|
+
MRI | 2.0.0, 2.1.x, 2.2.x, 2.3.x
|
56
|
+
JRuby | 1.7.x, 9.0.0.0 (JDK7, JDK8, OpenJDK)
|
57
|
+
Rubinius | 2.4.x, 2.5.x
|
58
|
+
|
59
|
+
All releases adhere to strict [semantic versioning](http://semver.org). For Example, major.minor.patch-pre (aka. stick.carrot.oops-peek).
|
60
|
+
|
61
|
+
## Development
|
62
|
+
If you'd like to contribute to the project or try an unreleased development version of this project locally, you can do so quite easily by following the examples below.
|
63
|
+
```bash
|
64
|
+
# clone the repository
|
65
|
+
git clone git@github.com:twitterdev/twitter-ruby-ads-sdk.git
|
66
|
+
cd twitter-ruby-ads-sdk
|
67
|
+
|
68
|
+
# install dependencies
|
69
|
+
bundle install
|
70
|
+
|
71
|
+
rake docs # building documentation
|
72
|
+
rake spec # run all tests
|
73
|
+
|
74
|
+
# installing a local unsigned release
|
75
|
+
gem build twitter-ads.gemspec & gem install twitter-ads-X.X.X.gem
|
76
|
+
```
|
77
|
+
We love community contributions! If you're planning to send us a pull request, please make sure read our [Contributing Guidelines](https://github.com/twitterdev/twitter-ruby-ads-sdk/blob/master/CONTRIBUTING.md) first.
|
78
|
+
|
79
|
+
## Feedback and Bug Reports
|
80
|
+
Found an issue? Please open up a [GitHub issue](https://github.com/twitterdev/twitter-ruby-ads-sdk/issues) or even better yet [send us](https://github.com/twitterdev/twitter-ruby-ads-sdk/blob/master/CONTRIBUTING.md) a pull request.<br/>
|
81
|
+
Have a question? Want to discuss a new feature? Come chat with us in the [Twitter Community Forums](https://twittercommunity.com/c/advertiser-api).
|
82
|
+
|
83
|
+
## Error Handling
|
84
|
+
|
85
|
+
Like the [Response](https://github.com/twitterdev/twitter-ruby-ads-sdk/blob/master/lib/twitter-ads/http/response.rb) and [Request](https://github.com/twitterdev/twitter-ruby-ads-sdk/blob/master/lib/twitter-ads/http/request.rb) classes, the Ads API SDK fully models all [error objects](https://github.com/twitterdev/twitter-ruby-ads-sdk/blob/master/lib/twitter-ads/error.rb) for easy error handling.
|
86
|
+
|
87
|
+
<img src="http://i.imgur.com/opbv7Nh.png"/ alt="Error Hierarchy">
|
88
|
+
|
89
|
+
## License
|
90
|
+
|
91
|
+
The MIT License (MIT)
|
92
|
+
|
93
|
+
Copyright (C) 2015 Twitter, Inc.
|
94
|
+
|
95
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
96
|
+
of this software and associated documentation files (the "Software"), to deal
|
97
|
+
in the Software without restriction, including without limitation the rights
|
98
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
99
|
+
copies of the Software, and to permit persons to whom the Software is
|
100
|
+
furnished to do so, subject to the following conditions:
|
101
|
+
|
102
|
+
The above copyright notice and this permission notice shall be included in all
|
103
|
+
copies or substantial portions of the Software.
|
104
|
+
|
105
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
106
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
107
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
108
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
109
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
110
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
111
|
+
SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# Copyright (C) 2015 Twitter, Inc.
|
5
|
+
|
6
|
+
require 'rubygems'
|
7
|
+
|
8
|
+
begin
|
9
|
+
require 'bundler'
|
10
|
+
require 'bundler/gem_tasks'
|
11
|
+
rescue LoadError
|
12
|
+
raise '[FAIL] Bundler not found! Install it with ' \
|
13
|
+
'`gem install bundler; bundle install`.'
|
14
|
+
end
|
15
|
+
|
16
|
+
# Helper for making a bit of log noise.
|
17
|
+
def announce(type, message, &block)
|
18
|
+
print "[#{type.to_s.upcase}] #{message}... "
|
19
|
+
begin
|
20
|
+
yield block
|
21
|
+
print "[DONE]\n".colorize(color: :green).bold
|
22
|
+
rescue StandardError
|
23
|
+
print "[FAILED]\n".colorize(color: :red).bold
|
24
|
+
abort
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# Default Rake Task
|
29
|
+
if ENV['CI']
|
30
|
+
task default: ['spec'] # 'features'
|
31
|
+
Bundler.require(:default, :test)
|
32
|
+
else
|
33
|
+
task default: ['spec'] # 'features'
|
34
|
+
Bundler.require(:default, :test, :development, :release)
|
35
|
+
end
|
36
|
+
|
37
|
+
# Cucumber Setup
|
38
|
+
require 'cucumber'
|
39
|
+
require 'cucumber/rake/task'
|
40
|
+
Cucumber::Rake::Task.new(:features) do |t|
|
41
|
+
t.cucumber_opts = 'features --format progress --strict'
|
42
|
+
end
|
43
|
+
|
44
|
+
# RSpec Setup
|
45
|
+
require 'rspec/core/rake_task'
|
46
|
+
RSpec::Core::RakeTask.new(:spec)
|
47
|
+
|
48
|
+
unless ENV['CI']
|
49
|
+
|
50
|
+
# Release and Deployment
|
51
|
+
desc 'Builds the latest SDK docs locally'
|
52
|
+
task :docs do
|
53
|
+
FileUtils.rm_rf('doc')
|
54
|
+
YARD::CLI::CommandParser.run('--quiet')
|
55
|
+
end
|
56
|
+
|
57
|
+
namespace :docs do
|
58
|
+
git = Git.open(File.expand_path('../', __FILE__))
|
59
|
+
|
60
|
+
desc 'Builds and deploys the latest SDK docs'
|
61
|
+
task :deploy do
|
62
|
+
unless git.status.changed.empty?
|
63
|
+
puts 'Error! Cannot proceeed, you have pending changes.'.colorize(color: :red).bold
|
64
|
+
abort
|
65
|
+
end
|
66
|
+
FileUtils.rm_rf('doc')
|
67
|
+
YARD::CLI::CommandParser.run
|
68
|
+
|
69
|
+
current_branch = git.branch.name
|
70
|
+
announce(:build, "updating v#{TwitterAds::VERSION} documentation") do
|
71
|
+
git.branch('gh-pages').checkout
|
72
|
+
FileUtils.rm_rf('reference')
|
73
|
+
FileUtils.mv('doc', 'reference')
|
74
|
+
git.add('reference')
|
75
|
+
git.commit("[docs] updating v#{TwitterAds::VERSION} documentation")
|
76
|
+
end
|
77
|
+
|
78
|
+
announce(:push, "publishing v#{TwitterAds::VERSION} documentation") do
|
79
|
+
git.push('origin', 'gh-pages')
|
80
|
+
end
|
81
|
+
|
82
|
+
git.branch(current_branch).checkout
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
data/bin/twitter-ads
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
begin
|
4
|
+
require 'twitter'
|
5
|
+
rescue LoadError
|
6
|
+
end
|
7
|
+
|
8
|
+
$LOAD_PATH.push File.join(File.dirname(__FILE__), '..', 'lib')
|
9
|
+
require 'twitter-ads'
|
10
|
+
|
11
|
+
include TwitterAds
|
12
|
+
include TwitterAds::Enum
|
13
|
+
|
14
|
+
# load up a ready-to-go client instance if .twurlrc is setup
|
15
|
+
if File.exists?(File.expand_path('~/.twurlrc'))
|
16
|
+
require 'yaml'
|
17
|
+
twurl_config = YAML.load(File.read(File.expand_path('~/.twurlrc')))
|
18
|
+
profile_name = twurl_config['configuration']['default_profile'][0]
|
19
|
+
profile_key = twurl_config['configuration']['default_profile'][1]
|
20
|
+
default_profile = twurl_config['profiles'][profile_name][profile_key]
|
21
|
+
CLIENT = TwitterAds::Client.new(
|
22
|
+
default_profile['consumer_key'],
|
23
|
+
default_profile['consumer_secret'],
|
24
|
+
default_profile['token'],
|
25
|
+
default_profile['secret'],
|
26
|
+
)
|
27
|
+
end
|
28
|
+
|
29
|
+
begin
|
30
|
+
require 'pry'
|
31
|
+
KLASS = Pry
|
32
|
+
version_info = "twitter-ads v#{TwitterAds::VERSION}"
|
33
|
+
KLASS.config.prompt = [
|
34
|
+
proc { "#{version_info} >> " },
|
35
|
+
proc { "#{version_info} ... " }
|
36
|
+
]
|
37
|
+
rescue LoadError
|
38
|
+
require 'irb'
|
39
|
+
KLASS = IRB
|
40
|
+
end
|
41
|
+
|
42
|
+
KLASS.start(__FILE__)
|
data/lib/twitter-ads.rb
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
# rubocop:disable Style/FileName
|
2
|
+
# frozen_string_literal: true
|
3
|
+
# Copyright (C) 2015 Twitter, Inc.
|
4
|
+
# rubocop:enable Style/FileName
|
5
|
+
|
6
|
+
require 'time'
|
7
|
+
require 'oauth'
|
8
|
+
require 'multi_json'
|
9
|
+
require 'forwardable'
|
10
|
+
require 'logger'
|
11
|
+
|
12
|
+
require 'twitter-ads/version'
|
13
|
+
require 'twitter-ads/utils'
|
14
|
+
require 'twitter-ads/error'
|
15
|
+
|
16
|
+
require 'twitter-ads/resources/dsl'
|
17
|
+
require 'twitter-ads/resources/resource'
|
18
|
+
require 'twitter-ads/resources/persistence'
|
19
|
+
require 'twitter-ads/resources/analytics'
|
20
|
+
|
21
|
+
require 'twitter-ads/client'
|
22
|
+
require 'twitter-ads/cursor'
|
23
|
+
require 'twitter-ads/account'
|
24
|
+
|
25
|
+
require 'twitter-ads/http/request'
|
26
|
+
require 'twitter-ads/http/response'
|
27
|
+
require 'twitter-ads/http/ton_upload'
|
28
|
+
|
29
|
+
require 'twitter-ads/audiences/tailored_audience'
|
30
|
+
|
31
|
+
require 'twitter-ads/campaign/app_list'
|
32
|
+
require 'twitter-ads/campaign/campaign'
|
33
|
+
require 'twitter-ads/campaign/funding_instrument'
|
34
|
+
require 'twitter-ads/campaign/line_item'
|
35
|
+
require 'twitter-ads/campaign/promotable_user'
|
36
|
+
require 'twitter-ads/campaign/targeting_criteria'
|
37
|
+
require 'twitter-ads/campaign/tweet'
|
38
|
+
|
39
|
+
require 'twitter-ads/enum'
|
40
|
+
|
41
|
+
require 'twitter-ads/creative/app_download_card'
|
42
|
+
require 'twitter-ads/creative/image_app_download_card'
|
43
|
+
require 'twitter-ads/creative/image_conversation_card'
|
44
|
+
require 'twitter-ads/creative/lead_gen_card'
|
45
|
+
require 'twitter-ads/creative/promoted_account'
|
46
|
+
require 'twitter-ads/creative/promoted_tweet'
|
47
|
+
require 'twitter-ads/creative/video_app_download_card'
|
48
|
+
require 'twitter-ads/creative/video_conversation_card'
|
49
|
+
require 'twitter-ads/creative/website_card'
|
50
|
+
require 'twitter-ads/creative/video'
|
51
|
+
|
52
|
+
require 'twitter-ads/targeting/reach_estimate'
|
53
|
+
|
54
|
+
require 'twitter-ads/legacy.rb'
|
@@ -0,0 +1,229 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# Copyright (C) 2015 Twitter, Inc.
|
3
|
+
|
4
|
+
module TwitterAds
|
5
|
+
class Account
|
6
|
+
|
7
|
+
include TwitterAds::DSL
|
8
|
+
|
9
|
+
attr_reader :client
|
10
|
+
|
11
|
+
property :id, read_only: true
|
12
|
+
property :name, read_only: true
|
13
|
+
property :salt, read_only: true
|
14
|
+
property :timezone, read_only: true
|
15
|
+
property :timezone_switch_at, type: :time, read_only: true
|
16
|
+
property :created_at, type: :time, read_only: true
|
17
|
+
property :updated_at, type: :time, read_only: true
|
18
|
+
property :deleted, type: :bool, read_only: true
|
19
|
+
|
20
|
+
RESOURCE_COLLECTION = '/0/accounts'.freeze # @api private
|
21
|
+
RESOURCE = '/0/accounts/%{id}'.freeze # @api private
|
22
|
+
FEATURES = '/0/accounts/%{id}/features'.freeze # @api private
|
23
|
+
SCOPED_TIMELINE = '/0/accounts/%{id}/scoped_timeline'.freeze # @api private
|
24
|
+
AUTHENTICATED_USER_ACCESS = '/0/accounts/%{id}/authenticated_user_access'.freeze # @api private
|
25
|
+
|
26
|
+
def initialize(client)
|
27
|
+
@client = client
|
28
|
+
self
|
29
|
+
end
|
30
|
+
|
31
|
+
class << self
|
32
|
+
|
33
|
+
# Load a specific Account object by ID.
|
34
|
+
#
|
35
|
+
# @example
|
36
|
+
# account = Account.load(client, '7o4em', with_deleted: true)
|
37
|
+
#
|
38
|
+
# @param client [Client] The Client object instance.
|
39
|
+
# @param id [String] The Account ID value.
|
40
|
+
#
|
41
|
+
# @return [Account] The Account object instance.
|
42
|
+
#
|
43
|
+
# @since 0.1.0
|
44
|
+
def load(client, id)
|
45
|
+
resource = RESOURCE % { id: id }
|
46
|
+
response = Request.new(client, :get, resource).perform
|
47
|
+
new(client).from_response(response.body[:data])
|
48
|
+
end
|
49
|
+
|
50
|
+
# Fetches all available Accounts.
|
51
|
+
#
|
52
|
+
# @example
|
53
|
+
# account = Account.all(client, with_deleted: true, sort_by: 'updated_at-desc')
|
54
|
+
#
|
55
|
+
# @param client [Client] The Client object instance.
|
56
|
+
# @param opts [Hash] A Hash of extended options.
|
57
|
+
# @option opts [Boolean] :with_deleted Indicates if deleted items should be included.
|
58
|
+
# @option opts [String] :sort_by The object param to sort the API response by.
|
59
|
+
#
|
60
|
+
# @return [Cursor] A Cursor for the API results.
|
61
|
+
#
|
62
|
+
# @since 0.1.0
|
63
|
+
# @see https://dev.twitter.com/ads/basics/sorting Sorting
|
64
|
+
def all(client, opts = {})
|
65
|
+
request = Request.new(client, :get, RESOURCE_COLLECTION, params: opts)
|
66
|
+
Cursor.new(self, request, init_with: [client])
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
# Returns an inspection string for the current object instance.
|
72
|
+
#
|
73
|
+
# @return [String] The object instance detail.
|
74
|
+
def inspect
|
75
|
+
str = String.new("#<#{self.class.name}:0x#{object_id}")
|
76
|
+
str << " id=\"#{@id}\"" if @id
|
77
|
+
str << '>'
|
78
|
+
end
|
79
|
+
|
80
|
+
# Returns a collection of features available to the current account.
|
81
|
+
#
|
82
|
+
# @return [Array] The list of features enabled for the account.
|
83
|
+
#
|
84
|
+
# @since 0.1.0
|
85
|
+
def features
|
86
|
+
validate_loaded
|
87
|
+
resource = FEATURES % { id: @id }
|
88
|
+
response = Request.new(client, :get, resource).perform
|
89
|
+
response.body[:data]
|
90
|
+
end
|
91
|
+
|
92
|
+
# Returns a collection of promotable users available to the current account.
|
93
|
+
#
|
94
|
+
# @param id [String] The PromotableUser ID value.
|
95
|
+
# @param opts [Hash] A Hash of extended options.
|
96
|
+
# @option opts [Boolean] :with_deleted Indicates if deleted items should be included.
|
97
|
+
# @option opts [String] :sort_by The object param to sort the API response by.
|
98
|
+
#
|
99
|
+
# @return A Cursor or object instance.
|
100
|
+
#
|
101
|
+
# @since 0.1.0
|
102
|
+
def promotable_users(id = nil, opts = {})
|
103
|
+
load_resource(PromotableUser, id, opts)
|
104
|
+
end
|
105
|
+
|
106
|
+
# Returns a collection of funding instruments available to the current account.
|
107
|
+
#
|
108
|
+
# @param id [String] The FundingInstrument ID value.
|
109
|
+
# @param opts [Hash] A Hash of extended options.
|
110
|
+
# @option opts [Boolean] :with_deleted Indicates if deleted items should be included.
|
111
|
+
# @option opts [String] :sort_by The object param to sort the API response by.
|
112
|
+
#
|
113
|
+
# @return A Cursor or object instance.
|
114
|
+
#
|
115
|
+
# @since 0.1.0
|
116
|
+
def funding_instruments(id = nil, opts = {})
|
117
|
+
load_resource(FundingInstrument, id, opts)
|
118
|
+
end
|
119
|
+
|
120
|
+
# Returns a collection of campaigns available to the current account.
|
121
|
+
#
|
122
|
+
# @param id [String] The Campaign ID value.
|
123
|
+
# @param opts [Hash] A Hash of extended options.
|
124
|
+
# @option opts [Boolean] :with_deleted Indicates if deleted items should be included.
|
125
|
+
# @option opts [String] :sort_by The object param to sort the API response by.
|
126
|
+
#
|
127
|
+
# @return A Cursor or object instance.
|
128
|
+
#
|
129
|
+
# @since 0.1.0
|
130
|
+
def campaigns(id = nil, opts = {})
|
131
|
+
load_resource(Campaign, id, opts)
|
132
|
+
end
|
133
|
+
|
134
|
+
# Returns a collection of line items available to the current account.
|
135
|
+
#
|
136
|
+
# @param id [String] The LineItem ID value.
|
137
|
+
# @param opts [Hash] A Hash of extended options.
|
138
|
+
# @option opts [Boolean] :with_deleted Indicates if deleted items should be included.
|
139
|
+
# @option opts [String] :sort_by The object param to sort the API response by.
|
140
|
+
#
|
141
|
+
# @return A Cursor or object instance.
|
142
|
+
#
|
143
|
+
# @since 0.1.0
|
144
|
+
def line_items(id = nil, opts = {})
|
145
|
+
load_resource(LineItem, id, opts)
|
146
|
+
end
|
147
|
+
|
148
|
+
# Returns a collection of app lists available to the current account.
|
149
|
+
#
|
150
|
+
# @param id [String] The AppList ID value.
|
151
|
+
# @param opts [Hash] A Hash of extended options.
|
152
|
+
# @option opts [Boolean] :with_deleted Indicates if deleted items should be included.
|
153
|
+
# @option opts [String] :sort_by The object param to sort the API response by.
|
154
|
+
#
|
155
|
+
# @since 0.2.0
|
156
|
+
#
|
157
|
+
# @return A list or object instance.
|
158
|
+
def app_lists(id = nil, opts = {})
|
159
|
+
load_resource(AppList, id, opts)
|
160
|
+
end
|
161
|
+
|
162
|
+
# Returns a collection of tailored audiences available to the current account.
|
163
|
+
#
|
164
|
+
# @param id [String] The TailoredAudience ID value.
|
165
|
+
# @param opts [Hash] A Hash of extended options.
|
166
|
+
# @option opts [Boolean] :with_deleted Indicates if deleted items should be included.
|
167
|
+
# @option opts [String] :sort_by The object param to sort the API response by.
|
168
|
+
#
|
169
|
+
# @since 0.3.0
|
170
|
+
#
|
171
|
+
# @return A Cursor or object instance.
|
172
|
+
def tailored_audiences(id = nil, opts = {})
|
173
|
+
load_resource(TailoredAudience, id, opts)
|
174
|
+
end
|
175
|
+
|
176
|
+
# Returns a collection of videos available to the current account.
|
177
|
+
#
|
178
|
+
# @param id [String] The Video ID value.
|
179
|
+
# @param opts [Hash] A Hash of extended options.
|
180
|
+
# @option opts [Boolean] :with_deleted Indicates if deleted items should be included.
|
181
|
+
# @option opts [String] :sort_by The object param to sort the API response by.
|
182
|
+
#
|
183
|
+
# @since 0.3.0
|
184
|
+
#
|
185
|
+
# @return A Cursor or object instance.
|
186
|
+
def videos(id = nil, opts = {})
|
187
|
+
load_resource(Video, id, opts)
|
188
|
+
end
|
189
|
+
|
190
|
+
# Returns the most recent promotable Tweets created by one or more specified Twitter users.
|
191
|
+
#
|
192
|
+
# @param ids [Array] An Array of Twitter user IDs.
|
193
|
+
# @param opts [Hash] A Hash of extended options.
|
194
|
+
#
|
195
|
+
# @return [Array] An Array of Tweet objects.
|
196
|
+
#
|
197
|
+
# @since 0.2.3
|
198
|
+
def scoped_timeline(ids, opts = {})
|
199
|
+
ids = ids.join(',') if ids.is_a?(Array)
|
200
|
+
params = { user_ids: ids }.merge!(opts)
|
201
|
+
resource = SCOPED_TIMELINE % { id: @id }
|
202
|
+
request = Request.new(client, :get, resource, params: params)
|
203
|
+
response = request.perform
|
204
|
+
response.body[:data]
|
205
|
+
end
|
206
|
+
|
207
|
+
def authenticated_user_access
|
208
|
+
params = {}
|
209
|
+
resource = AUTHENTICATED_USER_ACCESS % { id: @id }
|
210
|
+
request = Request.new(client, :get, resource, params: params)
|
211
|
+
response = request.perform
|
212
|
+
response.body[:data]
|
213
|
+
end
|
214
|
+
|
215
|
+
private
|
216
|
+
|
217
|
+
def load_resource(klass, id = nil, opts = {})
|
218
|
+
validate_loaded
|
219
|
+
id ? klass.load(self, id, opts) : klass.all(self, opts)
|
220
|
+
end
|
221
|
+
|
222
|
+
def validate_loaded
|
223
|
+
raise ArgumentError.new(
|
224
|
+
"Error! #{self.class} object not yet initialized, " \
|
225
|
+
"call #{self.class}.load first") unless @id
|
226
|
+
end
|
227
|
+
|
228
|
+
end
|
229
|
+
end
|