ppc 1.3.2 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE +21 -339
- data/README.md +46 -28
- data/Rakefile +1 -0
- data/lib/ppc.rb +1 -1
- data/lib/ppc/api.rb +18 -14
- data/lib/ppc/api/baidu.rb +5 -14
- data/lib/ppc/api/baidu/account.rb +28 -23
- data/lib/ppc/api/baidu/bulk.rb +1 -1
- data/lib/ppc/api/baidu/creative.rb +47 -86
- data/lib/ppc/api/baidu/group.rb +43 -74
- data/lib/ppc/api/baidu/keyword.rb +73 -166
- data/lib/ppc/api/baidu/phone_new_creative.rb +8 -7
- data/lib/ppc/api/baidu/plan.rb +51 -34
- data/lib/ppc/api/baidu/report.rb +9 -29
- data/lib/ppc/api/qihu.rb +7 -111
- data/lib/ppc/api/qihu/account.rb +31 -25
- data/lib/ppc/api/qihu/bulk.rb +1 -2
- data/lib/ppc/api/qihu/creative.rb +57 -74
- data/lib/ppc/api/qihu/group.rb +40 -63
- data/lib/ppc/api/qihu/keyword.rb +58 -74
- data/lib/ppc/api/qihu/plan.rb +52 -32
- data/lib/ppc/api/qihu/rank.rb +11 -10
- data/lib/ppc/api/qihu/report.rb +41 -94
- data/lib/ppc/api/qihu/sublink.rb +44 -41
- data/lib/ppc/api/sm.rb +3 -12
- data/lib/ppc/api/sm/account.rb +20 -19
- data/lib/ppc/api/sm/creative.rb +36 -50
- data/lib/ppc/api/sm/group.rb +40 -61
- data/lib/ppc/api/sm/keyword.rb +44 -102
- data/lib/ppc/api/sm/phone_new_creative.rb +9 -8
- data/lib/ppc/api/sm/plan.rb +36 -26
- data/lib/ppc/api/sm/report.rb +5 -24
- data/lib/ppc/api/sogou.rb +5 -55
- data/lib/ppc/api/sogou/account.rb +17 -17
- data/lib/ppc/api/sogou/creative.rb +52 -75
- data/lib/ppc/api/sogou/group.rb +44 -91
- data/lib/ppc/api/sogou/keyword.rb +60 -143
- data/lib/ppc/api/sogou/plan.rb +37 -23
- data/lib/ppc/api/sogou/report.rb +2 -19
- data/lib/ppc/ext.rb +0 -8
- data/lib/ppc/operation.rb +60 -83
- data/lib/ppc/operation/account.rb +13 -19
- data/lib/ppc/operation/creative.rb +0 -20
- data/lib/ppc/operation/group.rb +18 -27
- data/lib/ppc/operation/keyword.rb +0 -27
- data/lib/ppc/operation/plan.rb +34 -22
- data/lib/ppc/operation/report.rb +4 -4
- data/lib/ppc/operation/sublink.rb +8 -0
- data/ppc.gemspec +5 -5
- metadata +16 -10
- data/lib/ppc/api/shenma.rb +0 -64
- data/lib/ppc/api/shenma/report.rb +0 -135
@@ -5,13 +5,14 @@ module PPC
|
|
5
5
|
class Phone < Sm
|
6
6
|
Service = 'NewCreative'
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
8
|
+
PhoneType = {
|
9
|
+
id: :phoneId,
|
10
|
+
group_id: :adgroupId,
|
11
|
+
phone_num: :phoneNum,
|
12
|
+
pause: :pause,
|
13
|
+
}
|
14
|
+
@map = PhoneType
|
15
|
+
|
15
16
|
def self.update( auth, phones )
|
16
17
|
'''
|
17
18
|
根据实际使用情况,更新的时候creative title为必填选
|
@@ -21,7 +22,7 @@ module PPC
|
|
21
22
|
process( response, 'phoneTypes' ){ |x| reverse_type(x) }
|
22
23
|
end
|
23
24
|
|
24
|
-
def self.
|
25
|
+
def self.ids( auth, ids, getTemp = 0 )
|
25
26
|
'''
|
26
27
|
\'getPhoneIdByAdgroupId\'
|
27
28
|
@ input: group ids
|
data/lib/ppc/api/sm/plan.rb
CHANGED
@@ -4,20 +4,26 @@ module PPC
|
|
4
4
|
class Plan < Sm
|
5
5
|
Service = 'campaign'
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
7
|
+
PlanType = {
|
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
|
+
pause: :pause,
|
19
|
+
status: :status,
|
20
|
+
}
|
21
|
+
@map = PlanType
|
22
|
+
|
23
|
+
def self.info( auth, ids )
|
24
|
+
response = request( auth, Service, 'getCampaignByCampaignId', {campaignIds: ids})
|
25
|
+
process( response, 'campaignTypes' ){ |x| reverse_type(x)[0] }
|
26
|
+
end
|
21
27
|
|
22
28
|
def self.all( auth )
|
23
29
|
response = request( auth, Service, 'getAllCampaign' )
|
@@ -30,32 +36,36 @@ module PPC
|
|
30
36
|
end
|
31
37
|
|
32
38
|
def self.get( auth, ids )
|
33
|
-
|
34
|
-
body = { campaignIds: ids }
|
35
|
-
response = request( auth, Service, 'getCampaignByCampaignId', body)
|
39
|
+
response = request( auth, Service, 'getCampaignByCampaignId', {campaignIds: ids})
|
36
40
|
process( response, 'campaignTypes' ){ |x| reverse_type(x) }
|
37
41
|
end
|
38
42
|
|
39
43
|
def self.add( auth, plans )
|
40
|
-
|
41
|
-
body = { campaignTypes: campaign_types }
|
44
|
+
body = { campaignTypes: make_type( plans ) }
|
42
45
|
response = request( auth, Service, 'addCampaign', body)
|
43
46
|
process( response, 'campaignTypes' ){ |x| reverse_type(x) }
|
44
47
|
end
|
45
48
|
|
46
|
-
def self.update(auth,plans )
|
47
|
-
|
48
|
-
body = { campaignTypes: campaign_types }
|
49
|
+
def self.update( auth, plans )
|
50
|
+
body = { campaignTypes: make_type( plans ) }
|
49
51
|
response = request( auth, Service, 'updateCampaign', body)
|
50
52
|
process( response, 'campaignTypes' ){ |x| reverse_type(x) }
|
51
53
|
end
|
52
54
|
|
53
|
-
def self.delete(auth, ids )
|
54
|
-
|
55
|
-
body = { campaignIds: ids }
|
56
|
-
response = request( auth, Service, 'deleteCampaign', body, "delete")
|
55
|
+
def self.delete( auth, ids )
|
56
|
+
response = request( auth, Service, 'deleteCampaign', {campaignIds: ids}, "delete")
|
57
57
|
process( response, 'result' ){ |x| x }
|
58
58
|
end
|
59
|
+
|
60
|
+
def self.enable( auth, ids )
|
61
|
+
plans = ids.map{|id| {id: id, pause: false} }
|
62
|
+
self.update( auth, plans )
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.pause( auth, ids )
|
66
|
+
plans = ids.map{|id| {id: id, pause: true} }
|
67
|
+
self.update( auth, plans )
|
68
|
+
end
|
59
69
|
|
60
70
|
end # Service
|
61
71
|
end # baidu
|
data/lib/ppc/api/sm/report.rb
CHANGED
@@ -29,23 +29,17 @@ module PPC
|
|
29
29
|
end
|
30
30
|
|
31
31
|
def self.get_state( auth, id )
|
32
|
-
'''
|
33
|
-
input id should be string
|
34
|
-
'''
|
35
|
-
body = { taskId: id }
|
36
|
-
response = request( auth, 'task' , 'getTaskState' ,body)
|
32
|
+
response = request( auth, 'task' , 'getTaskState' , {taskId: id} )
|
37
33
|
process( response, 'status' ){ |x| x }
|
38
34
|
end
|
39
35
|
|
40
36
|
def self.get_fileId( auth, id )
|
41
|
-
|
42
|
-
response = request( auth, 'task' , 'getTaskState' ,body)
|
37
|
+
response = request( auth, 'task' , 'getTaskState' , {taskId: id} )
|
43
38
|
process( response, 'fileId' ){ |x| x }
|
44
39
|
end
|
45
40
|
|
46
41
|
def self.get_file( auth, id )
|
47
|
-
|
48
|
-
response = request( auth, 'file' , 'download' ,body)
|
42
|
+
request( auth, 'file' , 'download' , {fileId: id} )
|
49
43
|
end
|
50
44
|
|
51
45
|
private
|
@@ -67,25 +61,12 @@ module PPC
|
|
67
61
|
requesttype[:unitOfTime] = Unit_map[ param[:unit] ] if param[:unit]
|
68
62
|
requesttype[:device] = Device_map[ param[:device] ] if param[:device]
|
69
63
|
requesttype[:idOnly] = param[:id_only] || false
|
70
|
-
requesttype[:startDate] =
|
71
|
-
requesttype[:endDate] =
|
64
|
+
requesttype[:startDate] = Date.parse( param[:startDate] ) rescue Date.today
|
65
|
+
requesttype[:endDate] = Date.parse( param[:endDate] ) rescue Date.today
|
72
66
|
requesttype[:statIds] = param[:statIds] if param[:type] == "keyword" && param[:range] != "account"
|
73
67
|
return requesttype
|
74
68
|
end
|
75
69
|
|
76
|
-
private
|
77
|
-
def self.parse_date( date )
|
78
|
-
"""
|
79
|
-
Cast string to time:
|
80
|
-
'YYYYMMDD' => Time
|
81
|
-
"""
|
82
|
-
if date
|
83
|
-
date = Date.parse(date)
|
84
|
-
else
|
85
|
-
date = Date.today
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
70
|
#################################
|
90
71
|
# useful function for operation #
|
91
72
|
#################################
|
data/lib/ppc/api/sogou.rb
CHANGED
@@ -54,64 +54,14 @@ module PPC
|
|
54
54
|
into snake_case symbol inside the method
|
55
55
|
'''
|
56
56
|
result = {}
|
57
|
-
result[:succ]
|
57
|
+
result[:succ] = response[:header][:desc] == 'success'
|
58
58
|
result[:failure] = response[:header][:failures]
|
59
|
-
result[:no_quota] =
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
return result
|
59
|
+
result[:no_quota] = (response[:header][:failures][:code] == '18') rescue false
|
60
|
+
result[:result] = func[ response[:body][ key.snake_case.to_sym ] ] rescue nil
|
61
|
+
result[:rquota] = response[:header][:rquota] if response[:header][:rquota]
|
62
|
+
result
|
64
63
|
end
|
65
64
|
|
66
|
-
# def self.make_type( params, map = @map)
|
67
|
-
# '''
|
68
|
-
# For more info visit ::PPC::API::sogou:make_type
|
69
|
-
# '''
|
70
|
-
# params = [ params ] unless params.is_a? Array
|
71
|
-
#
|
72
|
-
# types = []
|
73
|
-
# params.each do |param|
|
74
|
-
# type = {}
|
75
|
-
#
|
76
|
-
# map.each do |key|
|
77
|
-
# value = param[ key[0] ]
|
78
|
-
# type[ key[1] ] = value if value != nil
|
79
|
-
# end
|
80
|
-
#
|
81
|
-
# types << type
|
82
|
-
# end
|
83
|
-
# return types
|
84
|
-
# end
|
85
|
-
def self.reverse_type( types, maps = @map )
|
86
|
-
types = [ types ] unless types.is_a? Array
|
87
|
-
types.map do |item|
|
88
|
-
maps.each{|m| item.filter_and_replace_key(m[0],m[1].to_s.snake_case.to_sym)}
|
89
|
-
item
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
|
-
# def self.reverse_type( types, map = @map )
|
94
|
-
# '''
|
95
|
-
# For more info visit ::PPC::API::sogou:reverse_type
|
96
|
-
# Here, the camel key will be turn into snake key
|
97
|
-
# '''
|
98
|
-
# types = [ types ] unless types.is_a? Array
|
99
|
-
#
|
100
|
-
# params = []
|
101
|
-
# types.each do |type|
|
102
|
-
# param = {}
|
103
|
-
#
|
104
|
-
# map.each do |key|
|
105
|
-
# # 这里做两次转换并不是十分高效的方法,考虑maintain两张map
|
106
|
-
# value = type[ key[1].to_s.snake_case.to_sym ]
|
107
|
-
# param[ key[0] ] = value if value != nil
|
108
|
-
# end
|
109
|
-
|
110
|
-
# params << param
|
111
|
-
# end
|
112
|
-
# return params
|
113
|
-
# end
|
114
|
-
|
115
65
|
end
|
116
66
|
end
|
117
67
|
end
|
@@ -4,22 +4,23 @@ module PPC
|
|
4
4
|
class Account < Sogou
|
5
5
|
Service = 'Account'
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
7
|
+
AccountType = {
|
8
|
+
id: :accountid,
|
9
|
+
balance: :balance,
|
10
|
+
cost: :total_cost,
|
11
|
+
payment: :total_pay,
|
12
|
+
budget_type: :type,
|
13
|
+
budget: :budget,
|
14
|
+
region: :regions,
|
15
|
+
exclude_ip: :excludeIps,
|
16
|
+
open_domains: :domains,
|
17
|
+
offline_time: :budgetOfflineTime,
|
18
|
+
opt: :opt,
|
19
|
+
}
|
20
|
+
@map = AccountType
|
20
21
|
|
21
|
-
def self.info(auth)
|
22
|
-
response = request(auth,Service,'getAccountInfo'
|
22
|
+
def self.info( auth )
|
23
|
+
response = request(auth,Service,'getAccountInfo' )
|
23
24
|
process( response, 'accountInfoType' ){ |x|reverse_type(x)[0] }
|
24
25
|
end
|
25
26
|
|
@@ -30,8 +31,7 @@ module PPC
|
|
30
31
|
@return : account info_type
|
31
32
|
"""
|
32
33
|
# for account service, there is not bulk operation
|
33
|
-
|
34
|
-
body = { accountInfoType: infoType }
|
34
|
+
body = { accountInfoType: make_type( param )[0] }
|
35
35
|
response = request(auth,Service,'updateAccountInfo', body)
|
36
36
|
process( response, 'accountInfoType' ){ |x|reverse_type(x)[0] }
|
37
37
|
end
|
@@ -5,25 +5,49 @@ module PPC
|
|
5
5
|
class Creative< Sogou
|
6
6
|
Service = 'CpcIdea'
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
8
|
+
CreativeType = {
|
9
|
+
id: :cpcIdeaId,
|
10
|
+
group_id: :cpcGrpId,
|
11
|
+
title: :title,
|
12
|
+
description1: :description1,
|
13
|
+
description2: :description2,
|
14
|
+
pc_destination: :visitUrl,
|
15
|
+
pc_display: :showUrl,
|
16
|
+
moile_destination: :mobileVisitUrl,
|
17
|
+
mobile_display: :mobileShowUrl,
|
18
|
+
pause: :pause,
|
19
|
+
status: :status,
|
20
|
+
"group_id" => :cpc_grp_id,
|
21
|
+
"id" => :cpc_idea_id,
|
22
|
+
"pc_destination" => :visit_url,
|
23
|
+
"pc_display" => :show_url,
|
24
|
+
"mobile_display" => :mobile_show_url,
|
25
|
+
"creative_ids" => :cpc_idea_ids,
|
26
|
+
}
|
27
|
+
@map = CreativeType
|
21
28
|
|
22
|
-
@status_map =
|
23
|
-
|
24
|
-
|
25
|
-
|
29
|
+
@status_map = {
|
30
|
+
id: :cpcIdeaId,
|
31
|
+
status: :status,
|
32
|
+
}
|
26
33
|
|
34
|
+
def self.info( auth, ids, getTemp = 0 )
|
35
|
+
body = { cpcIdeaIds: ids, getTemp: getTemp }
|
36
|
+
response = request( auth, Service, 'getCpcIdeaByCpcIdeaId', body )
|
37
|
+
process( response, 'cpcIdeaTypes' ){ |x| reverse_type(x)[0] }
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.all( auth, ids, getTemp = 0 )
|
41
|
+
body = { cpcGrpIds: ids, getTemp: getTemp }
|
42
|
+
response = request( auth, Service, 'getCpcIdeaByCpcGrpId', body )
|
43
|
+
process( response, 'cpcGrpIdeas' ){ |x| ids.count == 1 ? reverse_type(x[:cpc_idea_types]) : x.map{|y| reverse_type(y[:cpc_idea_types])}.flatten }
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.ids( auth, ids, getTemp = 0 )
|
47
|
+
body = { cpcGrpIds: ids, getTemp: getTemp }
|
48
|
+
response = request( auth, Service, 'getCpcIdeaIdByCpcGrpId', body )
|
49
|
+
process( response, 'cpcGrpIdeaIds' ){ |x| reverse_type( x ) }
|
50
|
+
end
|
27
51
|
|
28
52
|
def self.add( auth, creatives )
|
29
53
|
body = { cpcIdeaTypes: make_type( creatives ) }
|
@@ -32,83 +56,36 @@ module PPC
|
|
32
56
|
end
|
33
57
|
|
34
58
|
def self.get( auth, ids, getTemp = 0 )
|
35
|
-
'''
|
36
|
-
\'getCreativeByCreativeId\'
|
37
|
-
@ input : creative ids
|
38
|
-
@ output: creative informations
|
39
|
-
'''
|
40
|
-
ids = [ ids ] unless ids.is_a? Array
|
41
59
|
body = { cpcIdeaIds: ids, getTemp: getTemp }
|
42
60
|
response = request( auth, Service, 'getCpcIdeaByCpcIdeaId', body )
|
43
61
|
process( response, 'cpcIdeaTypes' ){ |x| reverse_type(x) }
|
44
62
|
end
|
45
63
|
|
46
64
|
def self.update( auth, creatives )
|
47
|
-
'''
|
48
|
-
根据实际使用情况,更新的时候creative title为必填选
|
49
|
-
'''
|
50
65
|
body = { cpcIdeaTypes: make_type( creatives ) }
|
51
66
|
response = request( auth, Service, 'updateCpcIdea', body )
|
52
67
|
process( response, 'cpcIdeaTypes' ){ |x| reverse_type(x) }
|
53
68
|
end
|
54
69
|
|
55
70
|
def self.delete( auth, ids )
|
56
|
-
|
57
|
-
body = { cpcIdeaIds: ids }
|
58
|
-
response = request( auth, Service, 'deleteCpcIdea', body )
|
71
|
+
response = request( auth, Service, 'deleteCpcIdea', { cpcIdeaIds: ids } )
|
59
72
|
process( response, '' ){ |x| x }
|
60
73
|
end
|
61
74
|
|
62
|
-
def self.
|
63
|
-
|
64
|
-
|
65
|
-
response = request( auth, Service, 'getCpcIdeaByCpcIdeaId', body )
|
66
|
-
process( response, 'cpcIdeaTypes' ){ |x| reverse_type(x, @status_map) }
|
75
|
+
def self.enable( auth, ids )
|
76
|
+
keywords = ids.map{|id| {id: id, pause: false} }
|
77
|
+
self.update( auth, keywords )
|
67
78
|
end
|
68
79
|
|
69
|
-
def self.
|
70
|
-
|
71
|
-
|
72
|
-
@ input: group ids
|
73
|
-
@ output: groupCreativeIds
|
74
|
-
'''
|
75
|
-
ids = [ ids ] unless ids.is_a? Array
|
76
|
-
body = { cpcGrpIds: ids, getTemp: getTemp }
|
77
|
-
response = request( auth, Service, 'getCpcIdeaIdByCpcGrpId', body )
|
78
|
-
process( response, 'cpcGrpIdeaIds' ){ |x| make_groupCreativeIds( x ) }
|
79
|
-
end
|
80
|
-
|
81
|
-
def self.search_by_group_id( auth, ids, getTemp = 0 )
|
82
|
-
ids = [ ids ] unless ids.is_a? Array
|
83
|
-
body = { cpcGrpIds: ids, getTemp: getTemp }
|
84
|
-
response = request( auth, Service, 'getCpcIdeaByCpcGrpId', body )
|
85
|
-
process( response, 'cpcGrpIdeas' ){ |x| make_groupCreatives( x ) }
|
80
|
+
def self.pause( auth, ids )
|
81
|
+
keywords = ids.map{|id| {id: id, pause: true} }
|
82
|
+
self.update( auth, keywords )
|
86
83
|
end
|
87
84
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
cpcGrpIdeaIdTypes.each do |cpcGrpIdeaIdType|
|
93
|
-
group_creative_id = { }
|
94
|
-
group_creative_id[:group_id] = cpcGrpIdeaIdType[:cpc_grp_id]
|
95
|
-
group_creative_id[:creative_ids] = cpcGrpIdeaIdType[:cpc_idea_ids]
|
96
|
-
group_creative_ids << group_creative_id
|
97
|
-
end
|
98
|
-
return group_creative_ids
|
99
|
-
end
|
100
|
-
|
101
|
-
private
|
102
|
-
def self.make_groupCreatives( cpcGrpIdeaTypes )
|
103
|
-
cpcGrpIdeaTypes = [cpcGrpIdeaTypes] unless cpcGrpIdeaTypes.is_a? Array
|
104
|
-
group_creatives = []
|
105
|
-
cpcGrpIdeaTypes.each do |cpcGrpIdeaType|
|
106
|
-
group_creative = {}
|
107
|
-
group_creative[:group_id] = cpcGrpIdeaType[:cpc_grp_id]
|
108
|
-
group_creative[:creatives] = reverse_type( cpcGrpIdeaType[:cpc_idea_types] )
|
109
|
-
group_creatives << group_creative
|
110
|
-
end
|
111
|
-
return group_creatives
|
85
|
+
def self.status( auth, ids, getTemp = 0 )
|
86
|
+
body = { cpcIdeaIds: ids, getTemp: getTemp }
|
87
|
+
response = request( auth, Service, 'getCpcIdeaByCpcIdeaId', body )
|
88
|
+
process( response, 'cpcIdeaTypes' ){ |x| reverse_type(x, @status_map) }
|
112
89
|
end
|
113
90
|
|
114
91
|
end
|