ppc 1.0.6 → 1.3.0
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.
- checksums.yaml +4 -4
- data/.gitignore +31 -23
- data/LICENSE +22 -0
- data/README.md +5 -28
- data/lib/ppc/api/baidu/account.rb +47 -0
- data/lib/ppc/api/baidu/bulk.rb +41 -0
- data/lib/ppc/api/baidu/creative.rb +125 -0
- data/lib/ppc/api/baidu/group.rb +111 -0
- data/lib/ppc/api/baidu/keyword.rb +193 -0
- data/lib/ppc/api/baidu/plan.rb +65 -0
- data/lib/ppc/api/baidu/report.rb +124 -0
- data/lib/ppc/api/baidu.rb +132 -0
- data/lib/ppc/api.rb +8 -0
- data/lib/ppc/baidu/account.rb +55 -27
- data/lib/ppc/baidu/group.rb +99 -0
- data/lib/ppc/baidu/key.rb +38 -0
- data/lib/ppc/baidu/plan.rb +69 -0
- data/lib/ppc/baidu/report.rb +45 -13
- data/lib/ppc/baidu.rb +28 -25
- data/lib/ppc/operation/account.rb +40 -0
- data/lib/ppc/operation/creative.rb +28 -0
- data/lib/ppc/operation/group.rb +59 -0
- data/lib/ppc/operation/keyword.rb +32 -0
- data/lib/ppc/operation/plan.rb +47 -0
- data/lib/ppc/operation.rb +161 -0
- data/lib/ppc.rb +3 -7
- data/ppc.gemspec +4 -4
- data/spec/api_baidu_account_spec.rb +18 -0
- data/spec/api_baidu_creative_spec.rb +71 -0
- data/spec/api_baidu_group_spec.rb +50 -0
- data/spec/api_baidu_keyword_spec.rb +64 -0
- data/spec/api_baidu_plan_spec.rb +42 -0
- data/spec/api_baidu_report_spec.rb +32 -0
- data/spec/api_baidu_spec.rb +60 -0
- data/spec/baidu_account_spec.rb +32 -0
- data/spec/baidu_bulk_spec.rb +21 -0
- data/spec/baidu_group_spec.rb +56 -0
- data/spec/baidu_plan_spec.rb +129 -0
- data/spec/{report_spec.rb → baidu_report_spec.rb} +0 -0
- data/spec/operation_spec.rb +87 -0
- data/spec/operation_spec_helper.rb +53 -0
- data/spec/spec_helper.rb +18 -1
- metadata +53 -22
- data/Gemfile +0 -4
- data/LICENSE.txt +0 -22
- data/Rakefile +0 -2
- data/lib/ppc/qihu/account.rb +0 -0
- data/lib/ppc/qihu.rb +0 -0
- data/lib/ppc/sogou/bulk.rb +0 -48
- data/lib/ppc/sogou.rb +0 -125
- data/spec/account_spec.rb +0 -16
- data/spec/bulk_spec.rb +0 -35
- data/spec/plan_spec.rb +0 -17
@@ -0,0 +1,65 @@
|
|
1
|
+
module PPC
|
2
|
+
module API
|
3
|
+
class Baidu
|
4
|
+
class Plan< Baidu
|
5
|
+
Service = 'Campaign'
|
6
|
+
|
7
|
+
@map = [
|
8
|
+
[:id,:campaignId],
|
9
|
+
[:name,:campaignName],
|
10
|
+
[:budget,:budget],
|
11
|
+
[:region,:regionTarget],
|
12
|
+
[:ip,:excludeIp] ,
|
13
|
+
[:negative,:negativeWords],
|
14
|
+
[:exact_negative,:exactNegativeWords],
|
15
|
+
[:schedule,:schedule],
|
16
|
+
[:budget_offline_time,:budgetOfflineTime],
|
17
|
+
[:show_prob,:showProb],
|
18
|
+
[:device,:device],
|
19
|
+
[:price_ratio,:priceRatio],
|
20
|
+
[:pause,:pause],
|
21
|
+
[:status,:status],
|
22
|
+
]
|
23
|
+
|
24
|
+
def self.all( auth, debug = false )
|
25
|
+
response = request( auth, Service, 'getAllCampaign' )
|
26
|
+
process( response, 'campaignTypes' , debug ){ |x| reverse_type(x) }
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.ids( auth, debug = false )
|
30
|
+
response = request( auth, Service, 'getAllCampaignId' )
|
31
|
+
process( response, 'campaignIds' , debug ){ |x| x }
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.get( auth, ids, debug = false )
|
35
|
+
ids = [ ids ] unless ids.is_a? Array
|
36
|
+
body = { campaignIds: ids }
|
37
|
+
response = request( auth, Service, 'getCampaignByCampaignId', body)
|
38
|
+
process( response, 'campaignTypes' , debug ){ |x| reverse_type(x) }
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.add( auth, plans, debug = false )
|
42
|
+
campaigntypes = make_type( plans )
|
43
|
+
body = { campaignTypes: campaigntypes }
|
44
|
+
response = request( auth, Service, 'addCampaign', body)
|
45
|
+
process( response, 'campaignTypes' , debug ){ |x| reverse_type(x) }
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.update(auth,plans, debug = false )
|
49
|
+
campaigntypes = make_type( plans )
|
50
|
+
body = { campaignTypes: campaigntypes }
|
51
|
+
response = request( auth, Service, 'updateCampaign', body)
|
52
|
+
process( response, 'campaignTypes' , debug ){ |x| reverse_type(x) }
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.delete(auth, ids, debug = false )
|
56
|
+
ids = [ ids ] unless ids.class == Array
|
57
|
+
body = { campaignIds: ids }
|
58
|
+
response = request( auth, 'Campaign', 'deleteCampaign', body)
|
59
|
+
process( response, 'result' , debug ){ |x| x }
|
60
|
+
end
|
61
|
+
|
62
|
+
end # Service
|
63
|
+
end # baidu
|
64
|
+
end # API
|
65
|
+
end # PPC
|
@@ -0,0 +1,124 @@
|
|
1
|
+
# -*- coding:utf-8 -*-
|
2
|
+
module PPC
|
3
|
+
module API
|
4
|
+
class Baidu
|
5
|
+
class Report< Baidu
|
6
|
+
Service = 'Report'
|
7
|
+
|
8
|
+
# 需要用到的映射集合
|
9
|
+
Type_map = { 'account' => 2, 'plan'=> 10, 'group'=> 11,
|
10
|
+
'keyword'=> 14, 'creative'=> 12, 'pair'=> 15,
|
11
|
+
'region'=> 3, 'wordid'=> 9 }
|
12
|
+
Level_map = { 'account' => 2, 'plan' => 3, 'group' => 5,
|
13
|
+
'creative' => 7, 'keywordid' => 11, 'pair' => 12,
|
14
|
+
'wordid' => 6 }
|
15
|
+
Device_map = { 'all' => 0, 'pc' => 1, 'mobile' => 2 }
|
16
|
+
Unit_map = { 'day' => 5, 'week' => 4, 'month' => 3, 'year' => 1, 'hour' => 7 }
|
17
|
+
|
18
|
+
def self.get_realtime( auth, params, type = 'data', debug = false )
|
19
|
+
request = make_realtimerequest( params )[0]
|
20
|
+
body = { realTimeRequestTypes: request }
|
21
|
+
response = request( auth, Service, 'getRealTimeData' ,body)
|
22
|
+
if debug
|
23
|
+
return response
|
24
|
+
end
|
25
|
+
|
26
|
+
response = case type
|
27
|
+
when 'data' then response['body']['realTimeResultTypes']
|
28
|
+
when 'query' then response['body']['realTimeQueryResultTypes']
|
29
|
+
when 'pair' then response['body']['realTimePairResultTypes']
|
30
|
+
end
|
31
|
+
return response
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
def self.get_id( auth, params, debug = false )
|
36
|
+
request = make_reportrequest( params )[0]
|
37
|
+
body = { reportRequestType: request }
|
38
|
+
response = request( auth, Service, 'getProfessionalReportId' ,body)
|
39
|
+
process( response, 'reportId', debug ){ |x| x }
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.get_status( auth, id, debug = false)
|
43
|
+
'''
|
44
|
+
input id should be string
|
45
|
+
'''
|
46
|
+
status = {1=>'Waiting' ,2=>'Opearting' ,3=>'Finished'}
|
47
|
+
body = { reportId: id }
|
48
|
+
response = request( auth, Service, 'getReportState' ,body)
|
49
|
+
process( response, 'isGenerated', debug ){ |x| status[x] }
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.get_file_url( auth, id, debug = false )
|
53
|
+
body = { reportId: id }
|
54
|
+
response = request( auth, Service, 'getReportFileUrl' ,body)
|
55
|
+
process( response, 'reportFilePath', debug ){ |x| x }
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
def self.get_date()
|
60
|
+
begin
|
61
|
+
startDate = DateTime.parse(params[:start]).iso8601
|
62
|
+
endDate = DateTime.parse(params[:end]).iso8601
|
63
|
+
rescue Exception => e
|
64
|
+
startDate = (Time.now - 2*24*3600).utc.iso8601
|
65
|
+
endDate = (Time.now - 24*3600).utc.iso8601
|
66
|
+
end
|
67
|
+
return startDate,endDate
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
def self.make_realtimerequest( params )
|
72
|
+
'''
|
73
|
+
make RealTimeRequestType
|
74
|
+
没有封装关键字:attribute,order,statIds
|
75
|
+
'''
|
76
|
+
params = [ params ] unless params.is_a? Array
|
77
|
+
requesttypes = []
|
78
|
+
params.each do |param|
|
79
|
+
requesttype = {}
|
80
|
+
startDate, endDate = get_date()
|
81
|
+
|
82
|
+
requesttype[:performanceData] = param[:fields] || %w(click impression)
|
83
|
+
requesttype[:reportType] = Type_map[ param[:type] ] if param[:type]
|
84
|
+
requesttype[:levelOfDetails] = Level_map[ param[:level] ] if param[:level]
|
85
|
+
requesttype[:statRange] = Level_map[ param[:range] ] if param[:range]
|
86
|
+
requesttype[:unitOfTime] = Unit_map[ param[:unit] ] if param[:unit]
|
87
|
+
requesttype[:number] = param[:number] if param[:number]
|
88
|
+
requesttype[:device] = Device_map[ param[:device] ] if param[:device]
|
89
|
+
requesttype[:startDate] = startDate
|
90
|
+
requesttype[:endDate] = endDate
|
91
|
+
requesttypes << requesttype
|
92
|
+
end
|
93
|
+
return requesttypes
|
94
|
+
end
|
95
|
+
|
96
|
+
private
|
97
|
+
def self.make_reportrequest( params )
|
98
|
+
'''
|
99
|
+
make RepoerRequestType
|
100
|
+
'''
|
101
|
+
params = [ params ] unless params.is_a? Array
|
102
|
+
requesttypes = []
|
103
|
+
params.each do |param|
|
104
|
+
requesttype = {}
|
105
|
+
startDate, endDate = get_date()
|
106
|
+
|
107
|
+
requesttype[:performanceData] = param[:fields] || %w(click impression)
|
108
|
+
requesttype[:reportType] = Type_map[ param[:type] ] if param[:type]
|
109
|
+
requesttype[:levelOfDetails] = Level_map[ param[:level] ] if param[:level]
|
110
|
+
requesttype[:statRange] = Level_map[ param[:range] ] if param[:range]
|
111
|
+
requesttype[:unitOfTime] = Unit_map[ param[:unit] ] if param[:unit]
|
112
|
+
requesttype[:device] = Device_map[ param[:device] ] if param[:device]
|
113
|
+
requesttype[:idOnly] = param[:id_only] || false
|
114
|
+
requesttype[:startDate] = startDate
|
115
|
+
requesttype[:endDate] = endDate
|
116
|
+
requesttypes << requesttype
|
117
|
+
end
|
118
|
+
return requesttypes
|
119
|
+
end
|
120
|
+
|
121
|
+
end # Repost
|
122
|
+
end # Baidu
|
123
|
+
end # API
|
124
|
+
end # PPC
|
@@ -0,0 +1,132 @@
|
|
1
|
+
# -*- coding:utf-8 -*-
|
2
|
+
require 'ppc/api/baidu/account'
|
3
|
+
require 'ppc/api/baidu/plan'
|
4
|
+
require 'ppc/api/baidu/bulk'
|
5
|
+
require 'ppc/api/baidu/group'
|
6
|
+
require 'ppc/api/baidu/keyword'
|
7
|
+
require 'ppc/api/baidu/report'
|
8
|
+
require 'ppc/api/baidu/creative'
|
9
|
+
require 'awesome_print'
|
10
|
+
require 'net/http'
|
11
|
+
require 'net/https'
|
12
|
+
require 'json'
|
13
|
+
module PPC
|
14
|
+
module API
|
15
|
+
class Baidu
|
16
|
+
|
17
|
+
@map = nil
|
18
|
+
|
19
|
+
def self.request( auth, service, method, params = {} )
|
20
|
+
'''
|
21
|
+
request should return whole http response including header
|
22
|
+
'''
|
23
|
+
uri = URI("https://api.baidu.com/json/sms/v3/#{service}Service/#{method}")
|
24
|
+
http_body = {
|
25
|
+
header: {
|
26
|
+
username: auth[:username],
|
27
|
+
password: auth[:password],
|
28
|
+
token: auth[:token]
|
29
|
+
},
|
30
|
+
body: params
|
31
|
+
}.to_json
|
32
|
+
|
33
|
+
http_header = {
|
34
|
+
'Content-Type' => 'application/json; charset=UTF-8'
|
35
|
+
}
|
36
|
+
|
37
|
+
http = Net::HTTP.new(uri.host, 443)
|
38
|
+
http.set_debug_output $stderr
|
39
|
+
http.use_ssl = true
|
40
|
+
|
41
|
+
response = http.post(uri.path, http_body, http_header)
|
42
|
+
response = JSON.parse response.body
|
43
|
+
|
44
|
+
# return response if with_header else response['body']
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.process( response, key , debug = false , &func)
|
48
|
+
'''
|
49
|
+
Process Http response. If operation successes, return value of given keys.
|
50
|
+
You can process the result using function &func, or do nothing by passing
|
51
|
+
block {|x|x}
|
52
|
+
===========================
|
53
|
+
@Output: resultType{ desc: boolean, failure: Array, result: Array }
|
54
|
+
failure is the failures part of response\'s header
|
55
|
+
result is the processed response body.
|
56
|
+
'''
|
57
|
+
# 保留 debug 功能
|
58
|
+
return response if debug
|
59
|
+
|
60
|
+
result = {}
|
61
|
+
result[:succ] = response['header']['desc']=='success'? true : false
|
62
|
+
result[:failure] = response['header']['failures']
|
63
|
+
result[:result] = func[ response['body'][key] ]
|
64
|
+
return result
|
65
|
+
end # process
|
66
|
+
|
67
|
+
def self.make_type( params, map = @map)
|
68
|
+
'''
|
69
|
+
tranfesr ppc api to search engine api
|
70
|
+
@ input
|
71
|
+
params : list of hash complying with PPC gem api
|
72
|
+
map : list of pairs(lists) of symbol complying with following api
|
73
|
+
map = [
|
74
|
+
[ ppc_key, api_key ],
|
75
|
+
[ ppc_key, api_key ],
|
76
|
+
[ ppc_key, api_key ],
|
77
|
+
...
|
78
|
+
]
|
79
|
+
Ex:
|
80
|
+
baidu_group_map = [ [ :id, :adgroupId],
|
81
|
+
[ :price, :maxPrice],
|
82
|
+
... ]
|
83
|
+
===================
|
84
|
+
@ output:
|
85
|
+
: types : list of hash that complying with search engine api
|
86
|
+
'''
|
87
|
+
params = [ params ] unless params.is_a? Array
|
88
|
+
|
89
|
+
types = []
|
90
|
+
params.each do |param|
|
91
|
+
type = {}
|
92
|
+
|
93
|
+
map.each do |key|
|
94
|
+
value = param[ key[0] ]
|
95
|
+
type[ key[1] ] = value if value
|
96
|
+
end
|
97
|
+
|
98
|
+
types << type
|
99
|
+
end
|
100
|
+
return types
|
101
|
+
end
|
102
|
+
|
103
|
+
def self.reverse_type( types, map = @map )
|
104
|
+
'''
|
105
|
+
transfer search engine api to ppc api
|
106
|
+
@ input
|
107
|
+
types : list of hash that complying with search engine api
|
108
|
+
map : list of pairs(lists) of symbol, for more details please
|
109
|
+
read docs of make_type()
|
110
|
+
===================
|
111
|
+
@ output:
|
112
|
+
params : list of hash complying with PPC gem api
|
113
|
+
'''
|
114
|
+
types = [ types ] unless types.is_a? Array
|
115
|
+
|
116
|
+
params = []
|
117
|
+
types.each do |type|
|
118
|
+
param = {}
|
119
|
+
|
120
|
+
map.each do |key|
|
121
|
+
value = type[ key[1].to_s ]
|
122
|
+
param[ key[0] ] = value if value
|
123
|
+
end
|
124
|
+
|
125
|
+
params << param
|
126
|
+
end
|
127
|
+
return params
|
128
|
+
end
|
129
|
+
|
130
|
+
end # Baidu
|
131
|
+
end # API
|
132
|
+
end # PPC
|
data/lib/ppc/api.rb
ADDED
data/lib/ppc/baidu/account.rb
CHANGED
@@ -6,17 +6,42 @@ module PPC
|
|
6
6
|
super(params)
|
7
7
|
end
|
8
8
|
|
9
|
+
def info
|
10
|
+
response = request('getAccountInfo')["accountInfoType"]
|
11
|
+
end
|
12
|
+
|
9
13
|
def all(params = {})
|
10
14
|
download(params)
|
11
15
|
end
|
12
16
|
|
17
|
+
def update( params = {} )
|
18
|
+
"""
|
19
|
+
update account info
|
20
|
+
@ params : account_info_type
|
21
|
+
@return : account info_type
|
22
|
+
"""
|
23
|
+
info = {
|
24
|
+
accountInfoType: {
|
25
|
+
budgetType: params[:budget_type] ,
|
26
|
+
budget: params[:budget],
|
27
|
+
regionTarget: params[:region],
|
28
|
+
excludeIp: params[:excludeip] ,
|
29
|
+
isDynamicCreative: params[:isdynamic],
|
30
|
+
dynamicCreativeParam: params[:creativeparam]
|
31
|
+
}
|
32
|
+
}
|
33
|
+
# delete null symbol
|
34
|
+
info[:accountInfoType].each{
|
35
|
+
|pair|
|
36
|
+
key, value = pair
|
37
|
+
info[:accountInfoType].delete(key) if value == nil
|
38
|
+
}
|
39
|
+
|
40
|
+
request('updateAccountInfo', info)["accountInfoType"]
|
41
|
+
end
|
42
|
+
|
13
43
|
def query_report(params = {})
|
14
|
-
report = ::PPC::Baidu::Report.new({
|
15
|
-
username: @username,
|
16
|
-
password: @password,
|
17
|
-
token: @token,
|
18
|
-
debug: @debug
|
19
|
-
})
|
44
|
+
report = ::PPC::Baidu::Report.new({username: @username, password: @password, token: @token, debug: @debug})
|
20
45
|
|
21
46
|
begin
|
22
47
|
@file_id = report.file_id_of_query(params)
|
@@ -30,31 +55,34 @@ module PPC
|
|
30
55
|
sleep 3
|
31
56
|
end
|
32
57
|
|
58
|
+
url = report.path(@file_id)
|
59
|
+
open(url).read.force_encoding('gb18030').encode('utf-8')
|
60
|
+
rescue Exception => e
|
61
|
+
raise ReportException.new(@file_id,report,e)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def cost_report(params = {})
|
66
|
+
report = ::PPC::Baidu::Report.new({username: @username, password: @password, token: @token, debug: @debug})
|
67
|
+
begin
|
68
|
+
@file_id = report.file_id_of_cost(params)
|
69
|
+
print_debug(@file_id,'file_id') if @debug
|
70
|
+
|
71
|
+
loop do
|
72
|
+
state = report.state(@file_id)
|
73
|
+
raise "invalid file state: #{state}" unless %w(1 2 3 null).include? state
|
74
|
+
break if state == '3'
|
75
|
+
print_debug(state,'file_id.state') if @debug
|
76
|
+
sleep 3
|
77
|
+
end
|
33
78
|
|
34
|
-
|
79
|
+
url = report.path(@file_id)
|
80
|
+
open(url).read.force_encoding('gb18030').encode('utf-8')
|
35
81
|
rescue Exception => e
|
36
|
-
|
37
|
-
# @oprs = bulk.oprs
|
38
|
-
# @oprtime = bulk.oprtime
|
39
|
-
# @quota = bulk.quota
|
40
|
-
# @rquota = bulk.rquota
|
41
|
-
# @status = bulk.status
|
42
|
-
|
43
|
-
# @desc = bulk.desc
|
44
|
-
|
45
|
-
# case @desc
|
46
|
-
# when 'success'
|
47
|
-
# when 'failure'
|
48
|
-
# @code = bulk.code
|
49
|
-
# @message = bulk.message
|
50
|
-
# when 'system failure'
|
51
|
-
# @code = bulk.code
|
52
|
-
# @message = bulk.message
|
53
|
-
# else
|
54
|
-
raise ReportException.new(@file_id,report,e)#,"unknown desc from baidu: #{@desc}"
|
55
|
-
# end
|
82
|
+
raise ReportException.new(@file_id,report,e)
|
56
83
|
end
|
57
84
|
end
|
85
|
+
|
58
86
|
end
|
59
87
|
end
|
60
88
|
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
module PPC
|
2
|
+
class Baidu
|
3
|
+
class Group < ::PPC::Baidu
|
4
|
+
def initialize(params = {})
|
5
|
+
params[:service] = 'Adgroup'
|
6
|
+
super(params)
|
7
|
+
end
|
8
|
+
|
9
|
+
def all()
|
10
|
+
"""
|
11
|
+
@return : Array of campaignAdgroupIds
|
12
|
+
"""
|
13
|
+
request( "getAllAdgroupId" )["campaignAdgroupIds"]
|
14
|
+
end
|
15
|
+
|
16
|
+
def add( params={}, test = false)
|
17
|
+
"""
|
18
|
+
@ input : one or list of AdgroupType
|
19
|
+
@ output : list of AdgroupType
|
20
|
+
"""
|
21
|
+
params = [ params ] unless params.class == Array
|
22
|
+
adgroupType = []
|
23
|
+
|
24
|
+
params.each{ | group_i |
|
25
|
+
adgroupType << make_adgrouptype( group_i )
|
26
|
+
}
|
27
|
+
|
28
|
+
body = {adgroupTypes: adgroupType}
|
29
|
+
response = request( "addAdgroup", body, test )
|
30
|
+
return response['adgroupTypes'] unless test else response
|
31
|
+
end
|
32
|
+
|
33
|
+
def update( params={}, test = false )
|
34
|
+
"""
|
35
|
+
@ input : one or list of AdgroupType
|
36
|
+
@ output : list of AdgroupType
|
37
|
+
"""
|
38
|
+
params = [ params ] unless params.class == Array
|
39
|
+
adgroupType = []
|
40
|
+
|
41
|
+
params.each{ | group_i |
|
42
|
+
adgroupType << make_adgrouptype( group_i )
|
43
|
+
}
|
44
|
+
|
45
|
+
body = {adgroupTypes: adgroupType}
|
46
|
+
responses = request( "updateAdgroup", body, test )
|
47
|
+
return responses['adgroupTypes'] unless test else responses
|
48
|
+
end
|
49
|
+
|
50
|
+
def delete( ids )
|
51
|
+
# delete responses have no content therefore we
|
52
|
+
#return header.desc to judge whether operation success
|
53
|
+
ids = [ ids ] unless ids.class == Array
|
54
|
+
|
55
|
+
body = { adgroupIds: ids }
|
56
|
+
request( "deleteAdgroup", body, true )[ 'header' ][ 'desc' ]
|
57
|
+
end
|
58
|
+
|
59
|
+
def search_by_planid( ids, test = false )
|
60
|
+
ids = [ ids ] unless ids.class == Array
|
61
|
+
body = { campaignIds: ids }
|
62
|
+
responses = request("getAdgroupByCampaignId", body, test )
|
63
|
+
return responses["campaignAdgroups"] unless test else responses
|
64
|
+
end
|
65
|
+
|
66
|
+
def search_by_groupid( ids, test = false )
|
67
|
+
ids = [ ids ] unless ids.class == Array
|
68
|
+
body = { adgroupIds: ids }
|
69
|
+
responses = request("getAdgroupByAdgroupId",body, test )
|
70
|
+
return responses["adgroupTypes"] unless test else responses
|
71
|
+
end
|
72
|
+
|
73
|
+
private
|
74
|
+
def make_adgrouptype( params={} )
|
75
|
+
adgrouptype = {
|
76
|
+
campaignId: params[:plan_id],
|
77
|
+
adgroupId: params[:group_id],
|
78
|
+
adgroupName: params[:name],
|
79
|
+
maxPrice: params[:maxprice],
|
80
|
+
negativeWords: params[:negative],
|
81
|
+
exactNegativeWords: params[:exact_negative],
|
82
|
+
pause: params[:pause],
|
83
|
+
status: params[:status],
|
84
|
+
reserved: params[:reserved]
|
85
|
+
}
|
86
|
+
# delete empty node
|
87
|
+
adgrouptype.each{
|
88
|
+
|pair|
|
89
|
+
key, value = pair
|
90
|
+
adgrouptype.delete(key) if value == nil
|
91
|
+
}
|
92
|
+
# delete invalid note according to request type
|
93
|
+
# unimplemented
|
94
|
+
return adgrouptype
|
95
|
+
end #make_adgrouptype
|
96
|
+
|
97
|
+
end # class group
|
98
|
+
end # class baidu
|
99
|
+
end # module
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module PPC
|
2
|
+
class Baidu
|
3
|
+
class Key < ::PPC::Baidu
|
4
|
+
def initialize(params = {})
|
5
|
+
params[:service] = 'Keyword'
|
6
|
+
@se_id = params[:se_id]
|
7
|
+
super(params)
|
8
|
+
end
|
9
|
+
|
10
|
+
def add()
|
11
|
+
end
|
12
|
+
|
13
|
+
def update()
|
14
|
+
end
|
15
|
+
|
16
|
+
def delete()
|
17
|
+
end
|
18
|
+
|
19
|
+
def active()
|
20
|
+
end
|
21
|
+
|
22
|
+
def search_by_groupid( ids, return_id = false )
|
23
|
+
end
|
24
|
+
|
25
|
+
def search_by_keywordid( ids )
|
26
|
+
end
|
27
|
+
|
28
|
+
def get_status()
|
29
|
+
end
|
30
|
+
|
31
|
+
def get_quality()
|
32
|
+
end
|
33
|
+
|
34
|
+
def get_10quality()
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/lib/ppc/baidu/plan.rb
CHANGED
@@ -11,6 +11,75 @@ module PPC
|
|
11
11
|
params[:plan_ids] = [@se_id]
|
12
12
|
download(params)
|
13
13
|
end
|
14
|
+
|
15
|
+
def ids
|
16
|
+
request('getAllCampaignId')['campaignIds']
|
17
|
+
end
|
18
|
+
|
19
|
+
#add one or more plans
|
20
|
+
def add(plans)
|
21
|
+
if plans.class == Hash
|
22
|
+
plans = [plans]
|
23
|
+
single = true
|
24
|
+
end
|
25
|
+
campaignTypes = []
|
26
|
+
|
27
|
+
plans.each do |plan|
|
28
|
+
campaignTypes << {
|
29
|
+
campaignName: plan[:name],
|
30
|
+
negativeWords: plan[:negative],
|
31
|
+
exactNegativeWords: plan[:exact_negative]
|
32
|
+
}
|
33
|
+
end
|
34
|
+
|
35
|
+
options = {campaignTypes: campaignTypes}
|
36
|
+
response = request('addCampaign',options)['campaignTypes']
|
37
|
+
if single
|
38
|
+
response.first
|
39
|
+
else
|
40
|
+
response
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def get(ids)
|
45
|
+
if ids.class != Array
|
46
|
+
ids = [ids]
|
47
|
+
single = true
|
48
|
+
end
|
49
|
+
|
50
|
+
options = {campaignIds: ids}
|
51
|
+
response = request('getCampaignByCampaignId',options)['campaignTypes']
|
52
|
+
|
53
|
+
if single
|
54
|
+
response.first
|
55
|
+
else
|
56
|
+
response
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# @todo needs testing
|
61
|
+
def updates(params)
|
62
|
+
params['campaignId'] = @se_id
|
63
|
+
options = {campaignTypes: [params]}
|
64
|
+
request('updateCampaign',options)['campaignTypes']
|
65
|
+
end
|
66
|
+
|
67
|
+
def update_by_id(id,params = {})
|
68
|
+
params['campaignId'] = id
|
69
|
+
options = {campaignTypes: [params]}
|
70
|
+
request('updateCampaign',options)['campaignTypes']
|
71
|
+
end
|
72
|
+
|
73
|
+
def update(plans)
|
74
|
+
options = {campaignTypes: plans}
|
75
|
+
request('updateCampaign',options)['campaignTypes']
|
76
|
+
end
|
77
|
+
|
78
|
+
def delete(ids)
|
79
|
+
ids = [ids] unless ids.class == Array
|
80
|
+
options = {campaignIds: ids}
|
81
|
+
request('deleteCampaign',options)['result'] == 1
|
82
|
+
end
|
14
83
|
end
|
15
84
|
end
|
16
85
|
end
|