yandex-api 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +55 -0
- data/Rakefile +2 -0
- data/lib/yandex-api.rb +12 -0
- data/lib/yandex-api/direct.rb +69 -0
- data/lib/yandex-api/direct/banner_info.rb +83 -0
- data/lib/yandex-api/direct/base.rb +69 -0
- data/lib/yandex-api/direct/campaign_info.rb +92 -0
- data/lib/yandex-api/version.rb +5 -0
- data/yandex-api.gemspec +17 -0
- metadata +57 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Evgeniy Shurmin
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
# Yandex::API
|
2
|
+
|
3
|
+
Позволяет работать с сервисами Яндекс доступными через API
|
4
|
+
|
5
|
+
Доступные модули:
|
6
|
+
* Direct - Автоматизация рекламных кампаний в Яндекс.Директе (http://direct.yandex.ru/)
|
7
|
+
|
8
|
+
## Установка
|
9
|
+
|
10
|
+
Добавить в Gemfile эту строчку:
|
11
|
+
|
12
|
+
gem 'yandex-api'
|
13
|
+
|
14
|
+
Выполнить команду:
|
15
|
+
|
16
|
+
$ bundle
|
17
|
+
|
18
|
+
Или уставновить через gem:
|
19
|
+
|
20
|
+
$ gem install yandex-api
|
21
|
+
|
22
|
+
## в Ruby:
|
23
|
+
|
24
|
+
Создать конфигурационный файл yandex_direct.yml
|
25
|
+
|
26
|
+
token: "token"
|
27
|
+
application_id: "id"
|
28
|
+
login: "login"
|
29
|
+
locale: "ru"
|
30
|
+
debug: true
|
31
|
+
|
32
|
+
Пример работы с gem-ом:
|
33
|
+
|
34
|
+
require 'yandex-api'
|
35
|
+
Yandex::API::Direct.load "yandex_direct.yml"
|
36
|
+
|
37
|
+
campaign = Yandex::API::Direct::CampaignInfo.list.first
|
38
|
+
|
39
|
+
puts campaign.inspect
|
40
|
+
puts campaign.banners.first.inspect
|
41
|
+
|
42
|
+
## в Ruby On Rails:
|
43
|
+
|
44
|
+
Создать конфигурационный файл yandex_direct.yml
|
45
|
+
|
46
|
+
development:
|
47
|
+
token: "token"
|
48
|
+
application_id: "id"
|
49
|
+
login: "login"
|
50
|
+
locale: "ru"
|
51
|
+
debug: true
|
52
|
+
|
53
|
+
Добавить в initializers файл yandex_direct.rb
|
54
|
+
|
55
|
+
Yandex::API::Direct.load File.join(Rails.root,"config","yandex_direct.yml"), Rails.env
|
data/Rakefile
ADDED
data/lib/yandex-api.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require "yandex-api/version"
|
2
|
+
require "yandex-api/direct"
|
3
|
+
require "yandex-api/direct/base"
|
4
|
+
require "yandex-api/direct/banner_info"
|
5
|
+
require "yandex-api/direct/campaign_info"
|
6
|
+
|
7
|
+
module Yandex
|
8
|
+
module API
|
9
|
+
class RuntimeError < RuntimeError ; end
|
10
|
+
class NotFound < RuntimeError ; end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'json'
|
3
|
+
require 'yaml'
|
4
|
+
require 'uri'
|
5
|
+
|
6
|
+
module Yandex
|
7
|
+
module API
|
8
|
+
module Direct
|
9
|
+
URL_API = "https://soap.direct.yandex.ru/json-api/v4/"
|
10
|
+
|
11
|
+
def self.configuration
|
12
|
+
if defined? @enviroment
|
13
|
+
raise RuntimeError.new("not configured Yandex.Direct for #{@enviroment} enviroment") unless @configuration
|
14
|
+
else
|
15
|
+
raise RuntimeError.new("not configured Yandex.Direct") unless @configuration
|
16
|
+
end
|
17
|
+
@configuration
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.load file, env = nil
|
21
|
+
@enviroment = env if env
|
22
|
+
config = YAML.load_file(file)
|
23
|
+
@configuration = defined?(@enviroment) ? config[@enviroment] : config
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.request method, params = {}
|
27
|
+
body = {
|
28
|
+
:locale => configuration["locale"],
|
29
|
+
:login => configuration["login"],
|
30
|
+
:application_id => configuration["application_id"],
|
31
|
+
:token => configuration["token"],
|
32
|
+
:method => method
|
33
|
+
}
|
34
|
+
|
35
|
+
body.merge!({:param => params}) unless params.empty?
|
36
|
+
url = URI.parse(URL_API)
|
37
|
+
|
38
|
+
if configuration["debug"]
|
39
|
+
puts "\t\033[32mURL: \033[0m#{URL_API}"
|
40
|
+
puts "\t\033[32mMethod: \033[0m#{method}"
|
41
|
+
puts "\t\033[32mParams: \033[0m#{params.inspect}"
|
42
|
+
end
|
43
|
+
|
44
|
+
http = Net::HTTP.new(url.host, url.port)
|
45
|
+
http.use_ssl = true
|
46
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
47
|
+
response = http.post(url.path,JSON.generate(body))
|
48
|
+
|
49
|
+
raise Yandex::API::RuntimeError.new("#{response.code} - #{response.message}") unless response.code.to_i == 200
|
50
|
+
|
51
|
+
json = {}
|
52
|
+
|
53
|
+
begin
|
54
|
+
json = JSON.parse(response.body)
|
55
|
+
rescue => e
|
56
|
+
raise RuntimeError.new "#{e.message} in response"
|
57
|
+
end
|
58
|
+
|
59
|
+
if json.has_key?("error_code")
|
60
|
+
code = json["error_code"].to_i
|
61
|
+
error = json.has_key?("error_detail") ? json["error_detail"] : json["error_str"]
|
62
|
+
raise RuntimeError.new "#{code} - #{error}"
|
63
|
+
end
|
64
|
+
|
65
|
+
return json["data"]
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
#
|
2
|
+
# Взаимодействие с API Яндекс.Директа в формате JSON.
|
3
|
+
# http://api.yandex.ru/direct/doc/concepts/JSON.xml
|
4
|
+
#
|
5
|
+
# (c) Copyright 2012 Евгений Шурмин. All Rights Reserved.
|
6
|
+
#
|
7
|
+
|
8
|
+
module Yandex::API
|
9
|
+
module Direct
|
10
|
+
#
|
11
|
+
# = PhraseUserParams
|
12
|
+
#
|
13
|
+
class PhraseUserParams < Base
|
14
|
+
direct_attributes :Param1, :Param2
|
15
|
+
end
|
16
|
+
#
|
17
|
+
# = Phrases
|
18
|
+
#
|
19
|
+
class BannerPhraseInfo < Base
|
20
|
+
direct_attributes :PhraseID, :Phrase, :IsRubric, :Price, :AutoBudgetPriority, :ContextPrice, :AutoBroker
|
21
|
+
direct_objects [:UserParams, PhraseUserParams]
|
22
|
+
end
|
23
|
+
|
24
|
+
#
|
25
|
+
# = Sitelink
|
26
|
+
#
|
27
|
+
class Sitelink < Base
|
28
|
+
direct_attributes :Title, :Href
|
29
|
+
end
|
30
|
+
|
31
|
+
#
|
32
|
+
# = MapPoint
|
33
|
+
#
|
34
|
+
class MapPoint < Base
|
35
|
+
direct_attributes :x, :y, :x1, :y1, :x2, :y2
|
36
|
+
end
|
37
|
+
|
38
|
+
#
|
39
|
+
# = ContactInfo
|
40
|
+
#
|
41
|
+
class ContactInfo < Base
|
42
|
+
direct_attributes :CompanyName, :ContactPerson, :Country, :CountryCode, :City, :Street, :House, :Build,
|
43
|
+
:Apart, :CityCode, :Phone, :PhoneExt, :IMClient, :IMLogin, :ExtraMessage, :ContactEmail, :WorkTime, :OGRN
|
44
|
+
direct_objects [:PointOnMap, MapPoint]
|
45
|
+
end
|
46
|
+
|
47
|
+
#
|
48
|
+
# = Banner
|
49
|
+
#
|
50
|
+
class BannerInfo < Base
|
51
|
+
direct_attributes :BannerID, :CampaignID, :Title, :Text, :Href, :Geo, :MinusKeywords
|
52
|
+
direct_arrays [:Phrases, BannerPhraseInfo], [:Sitelinks, Sitelink]
|
53
|
+
direct_objects [:ContactInfo, ContactInfo]
|
54
|
+
def self.find id
|
55
|
+
result = Direct::request("GetBanners", {:BannerIDS => [id]})
|
56
|
+
raise Yandex::NotFound.new("not found banner where id = #{id}") unless result.any?
|
57
|
+
banner = new(result.first)
|
58
|
+
end
|
59
|
+
def save
|
60
|
+
Direct::request("CreateOrUpdateBanners", [self.to_hash]).first
|
61
|
+
end
|
62
|
+
|
63
|
+
def archive
|
64
|
+
Direct::request("ArchiveBanners", {:CampaignID => self.CampaignID, :BannerIDS => [self.BannerID]})
|
65
|
+
end
|
66
|
+
def unarchive
|
67
|
+
Direct::request("UnArchiveCampaign", {:CampaignID => self.CampaignID, :BannerIDS => [self.BannerID]})
|
68
|
+
end
|
69
|
+
def moderate
|
70
|
+
Direct::request("ModerateBanners", {:CampaignID => self.CampaignID, :BannerIDS => [self.BannerID]})
|
71
|
+
end
|
72
|
+
def resume
|
73
|
+
Direct::request("ResumeBanners", {:CampaignID => self.CampaignID, :BannerIDS => [self.BannerID]})
|
74
|
+
end
|
75
|
+
def stop
|
76
|
+
Direct::request("StopBanners", {:CampaignID => self.CampaignID, :BannerIDS => [self.BannerID]})
|
77
|
+
end
|
78
|
+
def delete
|
79
|
+
Direct::request("DeleteBanners", {:CampaignID => self.CampaignID, :BannerIDS => [self.BannerID]})
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module Yandex::API::Direct
|
2
|
+
class Base
|
3
|
+
def self.attributes ; @attributes || [] ; end
|
4
|
+
def self.direct_attributes *args
|
5
|
+
@attributes = []
|
6
|
+
args.each do |arg|
|
7
|
+
@attributes << arg
|
8
|
+
self.class_eval("def #{arg};@#{arg};end")
|
9
|
+
self.class_eval("def #{arg}=(val);@#{arg}=val;end")
|
10
|
+
end
|
11
|
+
end
|
12
|
+
def self.objects ; @objects || [] ; end
|
13
|
+
def self.direct_objects *args
|
14
|
+
@objects = []
|
15
|
+
args.each do |object,type|
|
16
|
+
@objects << [object,type]
|
17
|
+
self.class_eval("def #{object};@#{object};end")
|
18
|
+
self.class_eval("def #{object}=(val);@#{object}=val;end")
|
19
|
+
end
|
20
|
+
end
|
21
|
+
def self.arrays ; @arrays || [] ; end
|
22
|
+
def self.direct_arrays *args
|
23
|
+
@arrays = []
|
24
|
+
args.each do |array,type|
|
25
|
+
@arrays << [array,type]
|
26
|
+
self.class_eval("def #{array};@#{array};end")
|
27
|
+
self.class_eval("def #{array}=(val);@#{array}=val;end")
|
28
|
+
end
|
29
|
+
end
|
30
|
+
def to_hash
|
31
|
+
result = {}
|
32
|
+
# build hash of attributes
|
33
|
+
self.class.attributes.each do |attribute|
|
34
|
+
value = send(attribute)
|
35
|
+
next unless value.present?
|
36
|
+
result[attribute] = value
|
37
|
+
end
|
38
|
+
# build hash of arrays
|
39
|
+
self.class.arrays.each do |array,type|
|
40
|
+
data_array = send(array)|| []
|
41
|
+
next if data_array.empty?
|
42
|
+
result[array] = []
|
43
|
+
data_array.each do |data|
|
44
|
+
result[array] << data.to_hash
|
45
|
+
end
|
46
|
+
end
|
47
|
+
# build hash of objects
|
48
|
+
self.class.objects.each do |object,type|
|
49
|
+
value_hash = send(object).try(:to_hash) || {}
|
50
|
+
next if value_hash.empty?
|
51
|
+
result[object] = value_hash
|
52
|
+
end
|
53
|
+
result
|
54
|
+
end
|
55
|
+
def initialize(params = {})
|
56
|
+
params.each do |key, value|
|
57
|
+
object = self.class.objects.find{|s| s.first.to_sym == key.to_sym}
|
58
|
+
array = self.class.arrays.find{|s| s.first.to_sym == key.to_sym}
|
59
|
+
if object
|
60
|
+
send("#{key}=", object.last.new(value))
|
61
|
+
elsif array
|
62
|
+
send("#{key}=", value.collect {|element| array.last.new(element)})
|
63
|
+
else
|
64
|
+
send("#{key}=", value) if respond_to? "#{key}="
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
#
|
2
|
+
# Взаимодействие с API Яндекс.Директа в формате JSON.
|
3
|
+
# http://api.yandex.ru/direct/doc/concepts/JSON.xml
|
4
|
+
#
|
5
|
+
# (c) Copyright 2012 Евгений Шурмин. All Rights Reserved.
|
6
|
+
#
|
7
|
+
|
8
|
+
module Yandex::API
|
9
|
+
module Direct
|
10
|
+
#
|
11
|
+
# = CampaignStrategy
|
12
|
+
#
|
13
|
+
class CampaignStrategy < Base
|
14
|
+
direct_attributes :StrategyName, :MaxPrice, :AveragePrice, :WeeklySumLimit, :ClicksPerWeek
|
15
|
+
end
|
16
|
+
|
17
|
+
#
|
18
|
+
# = SmsNotification
|
19
|
+
#
|
20
|
+
class SmsNotification < Base
|
21
|
+
direct_attributes :MetricaSms, :ModerateResultSms, :MoneyInSms, :MoneyOutSms, :SmsTimeFrom, :SmsTimeTo
|
22
|
+
end
|
23
|
+
|
24
|
+
#
|
25
|
+
# = EmailNotification
|
26
|
+
#
|
27
|
+
class EmailNotification < Base
|
28
|
+
direct_attributes :Email, :WarnPlaceInterval, :MoneyWarningValue, :SendAccNews, :SendWarn
|
29
|
+
end
|
30
|
+
|
31
|
+
#
|
32
|
+
# = TimeTargetInfo
|
33
|
+
#
|
34
|
+
class TimeTarget < Base
|
35
|
+
direct_attributes :ShowOnHolidays, :HolidayShowFrom, :HolidayShowTo, :DaysHours, :TimeZone
|
36
|
+
end
|
37
|
+
|
38
|
+
#
|
39
|
+
# = TimeTargetItem
|
40
|
+
#
|
41
|
+
class TimeTargetItem < Base
|
42
|
+
direct_attributes :Days, :Hours
|
43
|
+
end
|
44
|
+
#
|
45
|
+
# = CampaignInfo
|
46
|
+
#
|
47
|
+
class CampaignInfo < Base
|
48
|
+
direct_attributes :Login, :CampaignID, :Name, :FIO, :StartDate, :StatusBehavior, :StatusContextStop, :ContextLimit, :ContextLimitSum, :ContextPricePercent,
|
49
|
+
:AutoOptimization, :StatusMetricaControl, :DisabledDomains, :DisabledIps, :StatusOpenStat, :ConsiderTimeTarget, :MinusKeywords, :AddRelevantPhrases,
|
50
|
+
:RelevantPhrasesBudgetLimit
|
51
|
+
direct_objects [:Strategy, CampaignStrategy], [:SmsNotification, SmsNotification], [:EmailNotification, EmailNotification], [:TimeTarget, TimeTarget]
|
52
|
+
|
53
|
+
def banners
|
54
|
+
banners = []
|
55
|
+
Direct::request("GetBanners", {:CampaignIDS => [self.CampaignID]}).each do |banner|
|
56
|
+
banners << BannerInfo.new(banner)
|
57
|
+
end
|
58
|
+
banners
|
59
|
+
end
|
60
|
+
def save
|
61
|
+
Direct::request("CreateOrUpdateCampaign", self.to_hash)
|
62
|
+
end
|
63
|
+
def archive
|
64
|
+
Direct::request("ArchiveCampaign", {:CampaignID => self.CampaignID})
|
65
|
+
end
|
66
|
+
def unarchive
|
67
|
+
Direct::request("UnArchiveCampaign", {:CampaignID => self.CampaignID})
|
68
|
+
end
|
69
|
+
def resume
|
70
|
+
Direct::request("ResumeCampaign", {:CampaignID => self.CampaignID})
|
71
|
+
end
|
72
|
+
def stop
|
73
|
+
Direct::request("StopCampaign", {:CampaignID => self.CampaignID})
|
74
|
+
end
|
75
|
+
def delete
|
76
|
+
Direct::request("DeleteCampaign", {:CampaignID => self.CampaignID})
|
77
|
+
end
|
78
|
+
def self.find id
|
79
|
+
result = Direct::request("GetCampaignParams", {:CampaignID => id})
|
80
|
+
raise Yandex::NotFound.new("not found campaign where CampaignID = #{id}") if result.empty?
|
81
|
+
new(result)
|
82
|
+
end
|
83
|
+
def self.list
|
84
|
+
campaigs = []
|
85
|
+
Direct::request("GetCampaignsList").each do |campaig|
|
86
|
+
campaigs << new(campaig)
|
87
|
+
end
|
88
|
+
campaigs
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
data/yandex-api.gemspec
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/yandex-api/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Evgeniy Shurmin"]
|
6
|
+
gem.email = ["eshurmin@gmail.com"]
|
7
|
+
gem.description = %q{Yandex.API integration}
|
8
|
+
gem.summary = %q{Yandex.API integration}
|
9
|
+
gem.homepage = "https://github.com/jpascal/yandex-api"
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = "yandex-api"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = Yandex::API::VERSION
|
17
|
+
end
|
metadata
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: yandex-api
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Evgeniy Shurmin
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-08-08 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: Yandex.API integration
|
15
|
+
email:
|
16
|
+
- eshurmin@gmail.com
|
17
|
+
executables: []
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- .gitignore
|
22
|
+
- Gemfile
|
23
|
+
- LICENSE
|
24
|
+
- README.md
|
25
|
+
- Rakefile
|
26
|
+
- lib/yandex-api.rb
|
27
|
+
- lib/yandex-api/direct.rb
|
28
|
+
- lib/yandex-api/direct/banner_info.rb
|
29
|
+
- lib/yandex-api/direct/base.rb
|
30
|
+
- lib/yandex-api/direct/campaign_info.rb
|
31
|
+
- lib/yandex-api/version.rb
|
32
|
+
- yandex-api.gemspec
|
33
|
+
homepage: https://github.com/jpascal/yandex-api
|
34
|
+
licenses: []
|
35
|
+
post_install_message:
|
36
|
+
rdoc_options: []
|
37
|
+
require_paths:
|
38
|
+
- lib
|
39
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ! '>='
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: '0'
|
45
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
46
|
+
none: false
|
47
|
+
requirements:
|
48
|
+
- - ! '>='
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: '0'
|
51
|
+
requirements: []
|
52
|
+
rubyforge_project:
|
53
|
+
rubygems_version: 1.8.24
|
54
|
+
signing_key:
|
55
|
+
specification_version: 3
|
56
|
+
summary: Yandex.API integration
|
57
|
+
test_files: []
|