yandex-api 0.0.2
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.
- 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: []
|