ppc 1.3.0 → 1.3.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.
- checksums.yaml +4 -4
- data/.gitignore +4 -1
- data/LICENSE +334 -17
- data/README.md +75 -3
- data/lib/ppc.rb +3 -1
- data/lib/ppc/api.rb +137 -2
- data/lib/ppc/api/baidu.rb +20 -99
- data/lib/ppc/api/baidu/account.rb +21 -21
- data/lib/ppc/api/baidu/bulk.rb +39 -3
- data/lib/ppc/api/baidu/creative.rb +33 -33
- data/lib/ppc/api/baidu/group.rb +14 -14
- data/lib/ppc/api/baidu/keyword.rb +57 -46
- data/lib/ppc/api/baidu/phone_new_creative.rb +51 -0
- data/lib/ppc/api/baidu/plan.rb +34 -31
- data/lib/ppc/api/baidu/rank.rb +23 -0
- data/lib/ppc/api/baidu/report.rb +100 -81
- data/lib/ppc/api/qihu.rb +150 -0
- data/lib/ppc/api/qihu/account.rb +86 -0
- data/lib/ppc/api/qihu/bulk.rb +35 -0
- data/lib/ppc/api/qihu/creative.rb +108 -0
- data/lib/ppc/api/qihu/group.rb +96 -0
- data/lib/ppc/api/qihu/keyword.rb +113 -0
- data/lib/ppc/api/qihu/plan.rb +64 -0
- data/lib/ppc/api/qihu/rank.rb +25 -0
- data/lib/ppc/api/qihu/report.rb +159 -0
- data/lib/ppc/api/qihu/sublink.rb +71 -0
- data/lib/ppc/api/shenma.rb +64 -0
- data/lib/ppc/api/shenma/report.rb +135 -0
- data/lib/ppc/api/sm.rb +50 -0
- data/lib/ppc/api/sm/account.rb +44 -0
- data/lib/ppc/api/sm/bulk.rb +69 -0
- data/lib/ppc/api/sm/creative.rb +86 -0
- data/lib/ppc/api/sm/group.rb +94 -0
- data/lib/ppc/api/sm/keyword.rb +132 -0
- data/lib/ppc/api/sm/phone_new_creative.rb +51 -0
- data/lib/ppc/api/sm/plan.rb +63 -0
- data/lib/ppc/api/sm/report.rb +136 -0
- data/lib/ppc/api/sogou.rb +118 -0
- data/lib/ppc/api/sogou/account.rb +42 -0
- data/lib/ppc/api/sogou/bulk.rb +69 -0
- data/lib/ppc/api/sogou/creative.rb +117 -0
- data/lib/ppc/api/sogou/group.rb +123 -0
- data/lib/ppc/api/sogou/keyword.rb +188 -0
- data/lib/ppc/api/sogou/plan.rb +66 -0
- data/lib/ppc/api/sogou/report.rb +129 -0
- data/lib/ppc/ext.rb +17 -0
- data/lib/ppc/operation.rb +50 -36
- data/lib/ppc/operation/account.rb +19 -7
- data/lib/ppc/operation/creative.rb +7 -7
- data/lib/ppc/operation/group.rb +2 -2
- data/lib/ppc/operation/keyword.rb +11 -8
- data/lib/ppc/operation/report.rb +23 -0
- data/ppc.gemspec +14 -4
- data/spec/baidu/api_baidu_account_spec.rb +16 -0
- data/spec/baidu/api_baidu_creative_spec.rb +73 -0
- data/spec/{api_baidu_group_spec.rb → baidu/api_baidu_group_spec.rb} +12 -17
- data/spec/baidu/api_baidu_keyword_spec.rb +61 -0
- data/spec/baidu/api_baidu_phone_spec.rb +22 -0
- data/spec/{api_baidu_plan_spec.rb → baidu/api_baidu_plan_spec.rb} +11 -10
- data/spec/baidu/api_baidu_report_spec.rb +44 -0
- data/spec/{api_baidu_spec.rb → baidu/api_baidu_spec.rb} +10 -15
- data/spec/operation/operation_baidu_report_spec.rb +17 -0
- data/spec/operation/operation_baidu_spec.rb +126 -0
- data/spec/operation/operation_qihu_report_spec.rb +18 -0
- data/spec/operation/operation_qihu_spec.rb +94 -0
- data/spec/operation/operation_sm_report_spec.rb +21 -0
- data/spec/operation/operation_sogou_report_spec.rb +17 -0
- data/spec/operation/operation_sogou_spec.rb +88 -0
- data/spec/{operation_spec_helper.rb → operation/operation_spec_helper.rb} +3 -5
- data/spec/qihu/api_qihu_account_spec.rb +29 -0
- data/spec/qihu/api_qihu_creative_spec.rb +48 -0
- data/spec/qihu/api_qihu_group_spec.rb +40 -0
- data/spec/qihu/api_qihu_keyword_spec.rb +50 -0
- data/spec/qihu/api_qihu_plan_spec.rb +39 -0
- data/spec/qihu/api_qihu_report_spec.rb +54 -0
- data/spec/qihu/api_qihu_sublink_spec.rb +36 -0
- data/spec/sm/api_sm_account_spec.rb +8 -0
- data/spec/sm/api_sm_creative_spec.rb +52 -0
- data/spec/sm/api_sm_group_spec.rb +75 -0
- data/spec/sm/api_sm_keyword_spec.rb +59 -0
- data/spec/sm/api_sm_plan_spec.rb +39 -0
- data/spec/sm/api_sm_report_spec.rb +30 -0
- data/spec/sogou/api_sogou_account_spec.rb +17 -0
- data/spec/sogou/api_sogou_creative_spec.rb +51 -0
- data/spec/sogou/api_sogou_group_spec.rb +50 -0
- data/spec/sogou/api_sogou_keyword_spec.rb +54 -0
- data/spec/sogou/api_sogou_plan_spec.rb +43 -0
- data/spec/sogou/api_sogou_report_spec.rb +51 -0
- data/spec/spec_helper.rb +49 -10
- metadata +140 -46
- data/lib/ppc/baidu.rb +0 -152
- data/lib/ppc/baidu/account.rb +0 -88
- data/lib/ppc/baidu/bulk.rb +0 -52
- data/lib/ppc/baidu/group.rb +0 -99
- data/lib/ppc/baidu/key.rb +0 -38
- data/lib/ppc/baidu/plan.rb +0 -85
- data/lib/ppc/baidu/report.rb +0 -82
- data/spec/api_baidu_account_spec.rb +0 -18
- data/spec/api_baidu_creative_spec.rb +0 -71
- data/spec/api_baidu_keyword_spec.rb +0 -64
- data/spec/api_baidu_report_spec.rb +0 -32
- data/spec/baidu_account_spec.rb +0 -32
- data/spec/baidu_bulk_spec.rb +0 -21
- data/spec/baidu_group_spec.rb +0 -56
- data/spec/baidu_plan_spec.rb +0 -129
- data/spec/baidu_report_spec.rb +0 -24
- data/spec/operation_spec.rb +0 -87
data/lib/ppc/api/baidu/group.rb
CHANGED
|
@@ -17,22 +17,22 @@ module PPC
|
|
|
17
17
|
[:reserved, :reserved]
|
|
18
18
|
]
|
|
19
19
|
|
|
20
|
-
def self.ids(auth
|
|
20
|
+
def self.ids(auth )
|
|
21
21
|
"""
|
|
22
22
|
@return : Array of campaignAdgroupIds
|
|
23
23
|
"""
|
|
24
24
|
response = request( auth, Service , "getAllAdgroupId" )
|
|
25
|
-
process( response, 'campaignAdgroupIds'
|
|
25
|
+
process( response, 'campaignAdgroupIds' ){ |x| make_planGroupIds( x ) }
|
|
26
26
|
end
|
|
27
27
|
|
|
28
|
-
def self.get( auth, ids
|
|
28
|
+
def self.get( auth, ids )
|
|
29
29
|
ids = [ ids ] unless ids.is_a? Array
|
|
30
30
|
body = { adgroupIds: ids }
|
|
31
31
|
response = request(auth, Service, "getAdgroupByAdgroupId",body )
|
|
32
|
-
process( response, 'adgroupTypes'
|
|
32
|
+
process( response, 'adgroupTypes' ){ |x| reverse_type(x) }
|
|
33
33
|
end
|
|
34
34
|
|
|
35
|
-
def self.add( auth, groups
|
|
35
|
+
def self.add( auth, groups )
|
|
36
36
|
"""
|
|
37
37
|
@ input : one or list of AdgroupType
|
|
38
38
|
@ output : list of AdgroupType
|
|
@@ -42,10 +42,10 @@ module PPC
|
|
|
42
42
|
body = {adgroupTypes: adgrouptypes }
|
|
43
43
|
|
|
44
44
|
response = request( auth, Service, "addAdgroup", body )
|
|
45
|
-
process( response, 'adgroupTypes'
|
|
45
|
+
process( response, 'adgroupTypes' ){ |x| reverse_type(x) }
|
|
46
46
|
end
|
|
47
47
|
|
|
48
|
-
def self.update( auth, groups
|
|
48
|
+
def self.update( auth, groups )
|
|
49
49
|
"""
|
|
50
50
|
@ input : one or list of AdgroupType
|
|
51
51
|
@ output : list of AdgroupType
|
|
@@ -54,31 +54,31 @@ module PPC
|
|
|
54
54
|
body = {adgroupTypes: adgrouptypes}
|
|
55
55
|
|
|
56
56
|
response = request( auth, Service, "updateAdgroup",body )
|
|
57
|
-
process( response, 'adgroupTypes'
|
|
57
|
+
process( response, 'adgroupTypes' ){ |x| reverse_type(x) }
|
|
58
58
|
end
|
|
59
59
|
|
|
60
|
-
def self.delete( auth, ids
|
|
60
|
+
def self.delete( auth, ids )
|
|
61
61
|
"""
|
|
62
62
|
delete group body has no message
|
|
63
63
|
"""
|
|
64
64
|
ids = [ ids ] unless ids.is_a? Array
|
|
65
65
|
body = { adgroupIds: ids }
|
|
66
66
|
response = request( auth, Service,"deleteAdgroup", body )
|
|
67
|
-
process( response, 'nil'
|
|
67
|
+
process( response, 'nil' ){ |x| x }
|
|
68
68
|
end
|
|
69
69
|
|
|
70
|
-
def self.search_by_plan_id( auth, ids
|
|
70
|
+
def self.search_by_plan_id( auth, ids )
|
|
71
71
|
ids = [ ids ] unless ids.class == Array
|
|
72
72
|
body = { campaignIds: ids }
|
|
73
73
|
response = request( auth, Service ,"getAdgroupByCampaignId", body )
|
|
74
|
-
process( response, 'campaignAdgroups'
|
|
74
|
+
process( response, 'campaignAdgroups' ){ |x| make_planGroups( x ) }
|
|
75
75
|
end
|
|
76
76
|
|
|
77
|
-
def self.search_id_by_plan_id( auth, ids
|
|
77
|
+
def self.search_id_by_plan_id( auth, ids )
|
|
78
78
|
ids = [ ids ] unless ids.class == Array
|
|
79
79
|
body = { campaignIds: ids }
|
|
80
80
|
response = request( auth, Service ,"getAdgroupIdByCampaignId", body )
|
|
81
|
-
process( response, 'campaignAdgroupIds'
|
|
81
|
+
process( response, 'campaignAdgroupIds' ){ |x| make_planGroupIds( x ) }
|
|
82
82
|
end
|
|
83
83
|
|
|
84
84
|
private
|
|
@@ -5,85 +5,85 @@ module PPC
|
|
|
5
5
|
class Keyword< Baidu
|
|
6
6
|
Service = 'Keyword'
|
|
7
7
|
|
|
8
|
-
Match_type = { 'exact' => 1, '
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
Device = { 'pc' => 0, 'mobile' => 1, 'all' => 2 }
|
|
12
|
-
Type = { 'plan' => 3, 'group' => 5, 'keyword' => 11 }
|
|
8
|
+
Match_type = { 'exact' => 1, 'phrase' => 2, 'wide' => 3,1 => 'exact', 2=> 'phrase' , 3 => 'wide' }
|
|
9
|
+
Device = { 'pc' => 0, 'mobile' => 1, 'all' => 2 }
|
|
10
|
+
Type = { 'plan' => 3, 'group' => 5, 'keyword' => 11 }
|
|
13
11
|
|
|
14
12
|
@map = [
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
13
|
+
[:id,:keywordId],
|
|
14
|
+
[:group_id,:adgroupId],
|
|
15
|
+
[:keyword,:keyword],
|
|
16
|
+
[:price,:price],
|
|
17
|
+
[:pc_destination,:pcDestinationUrl],
|
|
18
|
+
[:mobile_destination,:mobileDestinationUrl],
|
|
19
|
+
[:match_type,:matchType],
|
|
20
|
+
[:phrase_type,:phraseType],
|
|
21
|
+
[:status,:status],
|
|
22
|
+
[:pause,:pause]
|
|
23
|
+
]
|
|
24
24
|
|
|
25
25
|
@quality10_map = [
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
26
|
+
[ :id, :id ],
|
|
27
|
+
[ :group_id, :adgroupId ],
|
|
28
|
+
[ :plan_id, :Campaigned ],
|
|
29
|
+
[ :pc_quality, :pcQuality ],
|
|
30
|
+
[ :pc_reliable, :pcReliable ],
|
|
31
|
+
[ :pc_reason, :pcReason ],
|
|
32
|
+
[ :pc_scale, :pcScale ],
|
|
33
|
+
[ :mobile_quality, :mobileQuality ],
|
|
34
|
+
[ :mobile_reliable, :mobileReliable ],
|
|
35
|
+
[ :mobile_reason, :mobileReason ],
|
|
36
|
+
[ :mobile_scale, :mobileScale ]
|
|
37
|
+
]
|
|
38
38
|
|
|
39
39
|
# 后面改成info方法
|
|
40
|
-
def self.get( auth, ids
|
|
40
|
+
def self.get( auth, ids )
|
|
41
41
|
'''
|
|
42
42
|
getKeywordByKeywordId
|
|
43
43
|
'''
|
|
44
44
|
ids = [ ids ] unless ids.is_a? Array
|
|
45
45
|
body = { keywordIds: ids}
|
|
46
46
|
response = request( auth, Service, 'getKeywordByKeywordId', body )
|
|
47
|
-
return process(response, 'keywordTypes'
|
|
47
|
+
return process(response, 'keywordTypes' ){|x| reverse_type( x ) }
|
|
48
48
|
end
|
|
49
49
|
|
|
50
|
-
def self.add( auth, keywords
|
|
50
|
+
def self.add( auth, keywords )
|
|
51
51
|
'''
|
|
52
52
|
'''
|
|
53
53
|
keywordtypes = make_type( keywords )
|
|
54
54
|
body = { keywordTypes: keywordtypes }
|
|
55
55
|
response = request( auth, Service, "addKeyword", body )
|
|
56
|
-
return process(response, 'keywordTypes'
|
|
56
|
+
return process(response, 'keywordTypes' ){|x| reverse_type(x) }
|
|
57
57
|
end
|
|
58
58
|
|
|
59
|
-
def self.update( auth, keywords
|
|
59
|
+
def self.update( auth, keywords )
|
|
60
60
|
'''
|
|
61
61
|
'''
|
|
62
62
|
keywordtypes = make_type( keywords )
|
|
63
63
|
body = { keywordTypes: keywordtypes }
|
|
64
64
|
response = request( auth, Service, "updateKeyword", body )
|
|
65
|
-
return process(response, 'keywordTypes'
|
|
65
|
+
return process(response, 'keywordTypes' ){|x| reverse_type(x) }
|
|
66
66
|
end
|
|
67
67
|
|
|
68
|
-
def self.delete( auth, ids
|
|
68
|
+
def self.delete( auth, ids )
|
|
69
69
|
"""
|
|
70
70
|
"""
|
|
71
71
|
ids = [ ids ] unless ids.is_a? Array
|
|
72
72
|
body = { keywordIds: ids}
|
|
73
73
|
response = request( auth, Service, 'deleteKeyword', body )
|
|
74
|
-
return process(response, 'result'
|
|
74
|
+
return process(response, 'result' ){|x| x }
|
|
75
75
|
end
|
|
76
76
|
|
|
77
|
-
def self.activate( auth, ids
|
|
77
|
+
def self.activate( auth, ids )
|
|
78
78
|
"""
|
|
79
79
|
"""
|
|
80
80
|
ids = [ ids ] unless ids.is_a? Array
|
|
81
81
|
body = { keywordIds: ids }
|
|
82
82
|
response = request( auth, Service, 'activateKeyword', body)
|
|
83
|
-
return process(response, 'keywordTypes'
|
|
83
|
+
return process(response, 'keywordTypes' ){|x| reverse_type(x) }
|
|
84
84
|
end
|
|
85
85
|
|
|
86
|
-
def self.search_by_group_id( auth, group_ids
|
|
86
|
+
def self.search_by_group_id( auth, group_ids )
|
|
87
87
|
"""
|
|
88
88
|
getKeywordByGroupIds
|
|
89
89
|
@input: list of group id
|
|
@@ -92,33 +92,44 @@ module PPC
|
|
|
92
92
|
group_ids = [ group_ids ] unless group_ids.is_a? Array
|
|
93
93
|
body = { adgroupIds: group_ids }
|
|
94
94
|
response = request( auth, Service, "getKeywordByAdgroupId", body )
|
|
95
|
-
return process(response, 'groupKeywords'
|
|
95
|
+
return process(response, 'groupKeywords' ){|x| make_groupKeywords( x ) }
|
|
96
96
|
end
|
|
97
97
|
|
|
98
|
-
def self.search_id_by_group_id( auth, group_ids
|
|
98
|
+
def self.search_id_by_group_id( auth, group_ids )
|
|
99
99
|
group_ids = [ group_ids ] unless group_ids.is_a? Array
|
|
100
100
|
body = { adgroupIds: group_ids }
|
|
101
101
|
response = request( auth, Service, "getKeywordIdByAdgroupId", body )
|
|
102
|
-
return process(response, 'groupKeywordIds'
|
|
102
|
+
return process(response, 'groupKeywordIds' ){|x| make_groupKeywordIds( x ) }
|
|
103
103
|
end
|
|
104
104
|
|
|
105
105
|
# 下面三个操作操作对象包括计划,组和关键字
|
|
106
106
|
# 不知道放在这里合不合适
|
|
107
|
-
def self.status( auth, ids, type
|
|
107
|
+
def self.status( auth, ids, type )
|
|
108
|
+
'''
|
|
109
|
+
Return [{ id: id, status: status } ... ]
|
|
110
|
+
'''
|
|
108
111
|
ids = [ ids ] unless ids.is_a? Array
|
|
109
112
|
body = { ids: ids, type: Type[type]}
|
|
110
113
|
response = request( auth, Service, 'getKeywordStatus', body )
|
|
111
|
-
return process(response, 'keywordStatus'
|
|
114
|
+
return process(response, 'keywordStatus' ){ |statusTypes|
|
|
115
|
+
statusTypes = [statusTypes] unless statusTypes.is_a? Array
|
|
116
|
+
status =[]
|
|
117
|
+
|
|
118
|
+
statusTypes.each do |statusType|
|
|
119
|
+
status << { id: statusType['id'], status: statusType['status'] }
|
|
120
|
+
end
|
|
121
|
+
return status
|
|
122
|
+
}
|
|
112
123
|
end
|
|
113
124
|
|
|
114
|
-
def self.quality( auth ,ids, type, device
|
|
125
|
+
def self.quality( auth ,ids, type, device )
|
|
115
126
|
'''
|
|
116
127
|
Return 10Quanlity *Not the old Quality* of given ketword id
|
|
117
128
|
'''
|
|
118
129
|
ids = [ ids ] unless ids.is_a? Array
|
|
119
130
|
body = { ids: ids, type: Type[type], device:Device[device] }
|
|
120
131
|
response = request( auth, Service, 'getKeyword10Quality', body )
|
|
121
|
-
return process(response, 'keyword10Quality'
|
|
132
|
+
return process(response, 'keyword10Quality' ){|x| reverse_type( x, @quality10_map ) }
|
|
122
133
|
end
|
|
123
134
|
|
|
124
135
|
private
|
|
@@ -176,7 +187,7 @@ module PPC
|
|
|
176
187
|
map.each do |key|
|
|
177
188
|
if key[0] == :match_type
|
|
178
189
|
value = type[ key[1].to_s ]
|
|
179
|
-
param[ key[0] ] =
|
|
190
|
+
param[ key[0] ] = Match_type[ value ] if value
|
|
180
191
|
else
|
|
181
192
|
value = type[ key[1].to_s ]
|
|
182
193
|
param[ key[0] ] = value if value
|
|
@@ -190,4 +201,4 @@ module PPC
|
|
|
190
201
|
end # keyword
|
|
191
202
|
end # Baidu
|
|
192
203
|
end # API
|
|
193
|
-
end # PPC
|
|
204
|
+
end # PPC
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# -*- coding:utf-8 -*-
|
|
2
|
+
module PPC
|
|
3
|
+
module API
|
|
4
|
+
class Baidu
|
|
5
|
+
class Phone < Baidu
|
|
6
|
+
Service = 'NewCreative'
|
|
7
|
+
|
|
8
|
+
@map =[
|
|
9
|
+
[:id,:phoneId],
|
|
10
|
+
[:group_id,:adgroupId],
|
|
11
|
+
[:phone_num,:phoneNum],
|
|
12
|
+
[:pause,:pause],
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
def self.update( auth, phones )
|
|
16
|
+
'''
|
|
17
|
+
根据实际使用情况,更新的时候creative title为必填选
|
|
18
|
+
'''
|
|
19
|
+
body = { phoneTypes: make_type( phones ) }
|
|
20
|
+
response = request( auth, Service, 'updatePhone', body )
|
|
21
|
+
process( response, 'phoneTypes' ){ |x| reverse_type(x) }
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def self.search_id_by_group_id( auth, ids, getTemp = 0 )
|
|
25
|
+
'''
|
|
26
|
+
\'getPhoneIdByAdgroupId\'
|
|
27
|
+
@ input: group ids
|
|
28
|
+
@ output: groupPhoneIds
|
|
29
|
+
'''
|
|
30
|
+
ids = [ ids ] unless ids.is_a? Array
|
|
31
|
+
body = { adgroupIds: ids, getTemp: getTemp }
|
|
32
|
+
response = request( auth, Service, 'getPhoneIdByAdgroupId', body )
|
|
33
|
+
process( response, 'groupPhoneIds' ){ |x| make_groupPhoneIds( x ) }
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
private
|
|
37
|
+
def self.make_groupPhoneIds( groupPhoneIds )
|
|
38
|
+
group_phone_ids = []
|
|
39
|
+
groupPhoneIds.each do |phone_id|
|
|
40
|
+
group_phone_id = { }
|
|
41
|
+
group_phone_id[:group_id] = phone_id['adgroupId']
|
|
42
|
+
group_phone_id[:phone_ids] = phone_id['phoneIds']
|
|
43
|
+
group_phone_ids << group_phone_id
|
|
44
|
+
end
|
|
45
|
+
return group_phone_ids
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
data/lib/ppc/api/baidu/plan.rb
CHANGED
|
@@ -5,61 +5,64 @@ module PPC
|
|
|
5
5
|
Service = 'Campaign'
|
|
6
6
|
|
|
7
7
|
@map = [
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
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
|
+
[:is_dynamic,:isDynamicCreative],
|
|
21
|
+
[:pause,:pause],
|
|
22
|
+
[:status,:status]
|
|
23
|
+
]
|
|
23
24
|
|
|
24
|
-
def self.all( auth
|
|
25
|
+
def self.all( auth )
|
|
25
26
|
response = request( auth, Service, 'getAllCampaign' )
|
|
26
|
-
process( response, 'campaignTypes'
|
|
27
|
+
process( response, 'campaignTypes' ){ |x| reverse_type(x) }
|
|
27
28
|
end
|
|
28
29
|
|
|
29
|
-
def self.ids( auth
|
|
30
|
+
def self.ids( auth )
|
|
30
31
|
response = request( auth, Service, 'getAllCampaignId' )
|
|
31
|
-
process( response, 'campaignIds'
|
|
32
|
+
process( response, 'campaignIds' ){ |x| x }
|
|
32
33
|
end
|
|
33
34
|
|
|
34
|
-
def self.get( auth, ids
|
|
35
|
+
def self.get( auth, ids )
|
|
35
36
|
ids = [ ids ] unless ids.is_a? Array
|
|
36
37
|
body = { campaignIds: ids }
|
|
37
38
|
response = request( auth, Service, 'getCampaignByCampaignId', body)
|
|
38
|
-
process( response, 'campaignTypes'
|
|
39
|
+
process( response, 'campaignTypes' ){ |x| reverse_type(x) }
|
|
39
40
|
end
|
|
40
41
|
|
|
41
|
-
def self.add( auth, plans
|
|
42
|
+
def self.add( auth, plans )
|
|
42
43
|
campaigntypes = make_type( plans )
|
|
43
|
-
|
|
44
|
+
# set extended = 1 to allow change of isDynamicCreative
|
|
45
|
+
body = { campaignTypes: campaigntypes, extended:1 }
|
|
44
46
|
response = request( auth, Service, 'addCampaign', body)
|
|
45
|
-
process( response, 'campaignTypes'
|
|
47
|
+
process( response, 'campaignTypes' ){ |x| reverse_type(x) }
|
|
46
48
|
end
|
|
47
49
|
|
|
48
|
-
def self.update(auth,plans
|
|
50
|
+
def self.update(auth,plans )
|
|
49
51
|
campaigntypes = make_type( plans )
|
|
50
|
-
|
|
52
|
+
# set extended = 1 to allow change of isDynamicCreative
|
|
53
|
+
body = { campaignTypes: campaigntypes, extended:1 }
|
|
51
54
|
response = request( auth, Service, 'updateCampaign', body)
|
|
52
|
-
process( response, 'campaignTypes'
|
|
55
|
+
process( response, 'campaignTypes' ){ |x| reverse_type(x) }
|
|
53
56
|
end
|
|
54
57
|
|
|
55
|
-
def self.delete(auth, ids
|
|
58
|
+
def self.delete(auth, ids )
|
|
56
59
|
ids = [ ids ] unless ids.class == Array
|
|
57
60
|
body = { campaignIds: ids }
|
|
58
|
-
response = request( auth,
|
|
59
|
-
process( response, 'result'
|
|
61
|
+
response = request( auth, Service, 'deleteCampaign', body)
|
|
62
|
+
process( response, 'result' ){ |x| x }
|
|
60
63
|
end
|
|
61
64
|
|
|
62
65
|
end # Service
|
|
63
66
|
end # baidu
|
|
64
67
|
end # API
|
|
65
|
-
end # PPC
|
|
68
|
+
end # PPC
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module PPC
|
|
2
|
+
module API
|
|
3
|
+
class Baidu
|
|
4
|
+
class Rank< Baidu
|
|
5
|
+
Service = 'Rank'
|
|
6
|
+
|
|
7
|
+
def self.get_rank(auth, keyword, device)
|
|
8
|
+
body = {:keyWords => [keyword], :device => 0, :region => 1000, :page => 0, :display => 0}
|
|
9
|
+
response = request(auth, Service, 'getPreview', body)
|
|
10
|
+
result = process(response, 'previewInfos' ){|x| x }
|
|
11
|
+
p result
|
|
12
|
+
data = result[:result][0]["data"]
|
|
13
|
+
plain = Base64.decode64(data)
|
|
14
|
+
gz = Zlib::GzipReader.new(StringIO.new(plain))
|
|
15
|
+
html_result = gz.read
|
|
16
|
+
gz.close
|
|
17
|
+
puts html_result
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
end # keyword
|
|
21
|
+
end # Baidu
|
|
22
|
+
end # API
|
|
23
|
+
end # PPC
|
data/lib/ppc/api/baidu/report.rb
CHANGED
|
@@ -7,115 +7,134 @@ module PPC
|
|
|
7
7
|
|
|
8
8
|
# 需要用到的映射集合
|
|
9
9
|
Type_map = { 'account' => 2, 'plan'=> 10, 'group'=> 11,
|
|
10
|
-
|
|
11
|
-
|
|
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 }
|
|
10
|
+
'keyword'=> 14, 'creative'=> 12, 'pair'=> 15,
|
|
11
|
+
'region'=> 3, 'wordid'=> 9 , 'query'=>6 }
|
|
17
12
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
response = request( auth, Service, 'getRealTimeData' ,body)
|
|
22
|
-
if debug
|
|
23
|
-
return response
|
|
24
|
-
end
|
|
13
|
+
Level_map = { 'account' => 2, 'plan' => 3, 'group' => 5,
|
|
14
|
+
'creative'=> 7, 'keywordid' => 11, 'pair' => 12,
|
|
15
|
+
'wordid' => 6 }
|
|
25
16
|
|
|
26
|
-
|
|
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
|
|
17
|
+
Device_map = { 'all' => 0, 'pc' => 1, 'mobile' => 2 }
|
|
33
18
|
|
|
19
|
+
Unit_map = { 'day' => 5, 'week' => 4, 'month' => 3, 'year' => 1, 'hour' => 7 }
|
|
34
20
|
|
|
35
|
-
|
|
36
|
-
|
|
21
|
+
########################
|
|
22
|
+
# API wraping function #
|
|
23
|
+
########################
|
|
24
|
+
def self.get_id( auth, params )
|
|
25
|
+
request = make_reportrequest( params )
|
|
37
26
|
body = { reportRequestType: request }
|
|
38
27
|
response = request( auth, Service, 'getProfessionalReportId' ,body)
|
|
39
|
-
process( response, 'reportId'
|
|
28
|
+
process( response, 'reportId' ){ |x| x }
|
|
40
29
|
end
|
|
41
30
|
|
|
42
|
-
def self.
|
|
31
|
+
def self.get_state( auth, id )
|
|
43
32
|
'''
|
|
44
33
|
input id should be string
|
|
45
34
|
'''
|
|
46
35
|
status = {1=>'Waiting' ,2=>'Opearting' ,3=>'Finished'}
|
|
47
36
|
body = { reportId: id }
|
|
48
37
|
response = request( auth, Service, 'getReportState' ,body)
|
|
49
|
-
process( response, 'isGenerated'
|
|
38
|
+
process( response, 'isGenerated' ){ |x| status[x] }
|
|
50
39
|
end
|
|
51
40
|
|
|
52
|
-
def self.
|
|
41
|
+
def self.get_url( auth, id )
|
|
53
42
|
body = { reportId: id }
|
|
54
43
|
response = request( auth, Service, 'getReportFileUrl' ,body)
|
|
55
|
-
process( response, 'reportFilePath'
|
|
44
|
+
process( response, 'reportFilePath' ){ |x| x }
|
|
56
45
|
end
|
|
57
|
-
|
|
46
|
+
|
|
58
47
|
private
|
|
59
|
-
def self.
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
48
|
+
def self.make_reportrequest( param )
|
|
49
|
+
"""
|
|
50
|
+
make RepoerRequestType
|
|
51
|
+
==============
|
|
52
|
+
@Input : :fields,:type,:level,:range,:unit,:device,:id_only,:startDate:endDate
|
|
53
|
+
==============
|
|
54
|
+
Note:
|
|
55
|
+
We cast [ type, level, range, unit,device ] from int to string.
|
|
56
|
+
For more information please see those map at the begining of the file
|
|
57
|
+
"""
|
|
58
|
+
requesttype = {}
|
|
59
|
+
requesttype[:performanceData] = param[:fields] || %w(click impression)
|
|
60
|
+
requesttype[:reportType] = Type_map[ param[:type] ] if param[:type]
|
|
61
|
+
requesttype[:levelOfDetails] = Level_map[ param[:level] ] if param[:level]
|
|
62
|
+
requesttype[:statRange] = Level_map[ param[:range] ] if param[:range]
|
|
63
|
+
requesttype[:unitOfTime] = Unit_map[ param[:unit] ] if param[:unit]
|
|
64
|
+
requesttype[:device] = Device_map[ param[:device] ] if param[:device]
|
|
65
|
+
requesttype[:idOnly] = param[:id_only] || false
|
|
66
|
+
requesttype[:startDate] = parse_date( param[:startDate] )
|
|
67
|
+
requesttype[:endDate] = parse_date( param[:endDate] )
|
|
68
|
+
return requesttype
|
|
68
69
|
end
|
|
69
70
|
|
|
70
71
|
private
|
|
71
|
-
def self.
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
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
|
|
72
|
+
def self.parse_date( date )
|
|
73
|
+
"""
|
|
74
|
+
Cast string to time:
|
|
75
|
+
'YYYYMMDD' => Time
|
|
76
|
+
"""
|
|
77
|
+
if date
|
|
78
|
+
y = date[0..3]
|
|
79
|
+
m = date[4..5]
|
|
80
|
+
d = date[6..7]
|
|
81
|
+
date = Time.new( y, m, d )
|
|
82
|
+
else
|
|
83
|
+
date = (Time.now - 24*3600)
|
|
92
84
|
end
|
|
93
|
-
|
|
85
|
+
date
|
|
94
86
|
end
|
|
95
87
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
88
|
+
#################################
|
|
89
|
+
# useful function for operation #
|
|
90
|
+
#################################
|
|
91
|
+
def self.query_report( auth, param = nil, debug = false )
|
|
92
|
+
param = {} if not param
|
|
93
|
+
param[:type] ||= 'query'
|
|
94
|
+
param[:fields] ||= %w(click impression)
|
|
95
|
+
param[:level] ||= 'pair'
|
|
96
|
+
param[:range] ||= 'account'
|
|
97
|
+
param[:unit] ||= 'day'
|
|
98
|
+
download_report( auth, param, debug )
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def self.creative_report( auth, param = nil, debug = false )
|
|
102
|
+
param = {} if not param
|
|
103
|
+
param[:type] ||= 'creative'
|
|
104
|
+
param[:fields] ||= %w(impression click cpc cost ctr cpm position conversion)
|
|
105
|
+
param[:level] ||= 'creative'
|
|
106
|
+
param[:range] ||= 'creative'
|
|
107
|
+
param[:unit] ||= 'day'
|
|
108
|
+
download_report( auth, param, debug )
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def self.keyword_report( auth, param = nil, debug = false )
|
|
112
|
+
param = {} if not param
|
|
113
|
+
param[:type] ||= 'keyword'
|
|
114
|
+
param[:fields] ||= %w(impression click cpc cost ctr cpm position conversion)
|
|
115
|
+
param[:level] ||= 'keywordid'
|
|
116
|
+
param[:range] ||= 'keywordid'
|
|
117
|
+
param[:unit] ||= 'day'
|
|
118
|
+
download_report( auth, param, debug )
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def self.download_report( auth, param, debug = false )
|
|
122
|
+
p param
|
|
123
|
+
response = get_id( auth, param )
|
|
124
|
+
if response[:succ]
|
|
125
|
+
id = response[:result]
|
|
126
|
+
p "Got report id:" + id.to_s if debug
|
|
127
|
+
loop do
|
|
128
|
+
sleep 2
|
|
129
|
+
break if get_state( auth, id )[:result].to_s[/(Finished|3)/]
|
|
130
|
+
p "Report is not generated, waiting..." if debug
|
|
131
|
+
end
|
|
106
132
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
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
|
|
133
|
+
url = get_url( auth, id )[:result]
|
|
134
|
+
return open(url).read.force_encoding('gb18030').encode('utf-8')
|
|
135
|
+
else
|
|
136
|
+
raise response[:failure][0]["message"]
|
|
117
137
|
end
|
|
118
|
-
return requesttypes
|
|
119
138
|
end
|
|
120
139
|
|
|
121
140
|
end # Repost
|