ppc 1.3.2 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +21 -339
  3. data/README.md +46 -28
  4. data/Rakefile +1 -0
  5. data/lib/ppc.rb +1 -1
  6. data/lib/ppc/api.rb +18 -14
  7. data/lib/ppc/api/baidu.rb +5 -14
  8. data/lib/ppc/api/baidu/account.rb +28 -23
  9. data/lib/ppc/api/baidu/bulk.rb +1 -1
  10. data/lib/ppc/api/baidu/creative.rb +47 -86
  11. data/lib/ppc/api/baidu/group.rb +43 -74
  12. data/lib/ppc/api/baidu/keyword.rb +73 -166
  13. data/lib/ppc/api/baidu/phone_new_creative.rb +8 -7
  14. data/lib/ppc/api/baidu/plan.rb +51 -34
  15. data/lib/ppc/api/baidu/report.rb +9 -29
  16. data/lib/ppc/api/qihu.rb +7 -111
  17. data/lib/ppc/api/qihu/account.rb +31 -25
  18. data/lib/ppc/api/qihu/bulk.rb +1 -2
  19. data/lib/ppc/api/qihu/creative.rb +57 -74
  20. data/lib/ppc/api/qihu/group.rb +40 -63
  21. data/lib/ppc/api/qihu/keyword.rb +58 -74
  22. data/lib/ppc/api/qihu/plan.rb +52 -32
  23. data/lib/ppc/api/qihu/rank.rb +11 -10
  24. data/lib/ppc/api/qihu/report.rb +41 -94
  25. data/lib/ppc/api/qihu/sublink.rb +44 -41
  26. data/lib/ppc/api/sm.rb +3 -12
  27. data/lib/ppc/api/sm/account.rb +20 -19
  28. data/lib/ppc/api/sm/creative.rb +36 -50
  29. data/lib/ppc/api/sm/group.rb +40 -61
  30. data/lib/ppc/api/sm/keyword.rb +44 -102
  31. data/lib/ppc/api/sm/phone_new_creative.rb +9 -8
  32. data/lib/ppc/api/sm/plan.rb +36 -26
  33. data/lib/ppc/api/sm/report.rb +5 -24
  34. data/lib/ppc/api/sogou.rb +5 -55
  35. data/lib/ppc/api/sogou/account.rb +17 -17
  36. data/lib/ppc/api/sogou/creative.rb +52 -75
  37. data/lib/ppc/api/sogou/group.rb +44 -91
  38. data/lib/ppc/api/sogou/keyword.rb +60 -143
  39. data/lib/ppc/api/sogou/plan.rb +37 -23
  40. data/lib/ppc/api/sogou/report.rb +2 -19
  41. data/lib/ppc/ext.rb +0 -8
  42. data/lib/ppc/operation.rb +60 -83
  43. data/lib/ppc/operation/account.rb +13 -19
  44. data/lib/ppc/operation/creative.rb +0 -20
  45. data/lib/ppc/operation/group.rb +18 -27
  46. data/lib/ppc/operation/keyword.rb +0 -27
  47. data/lib/ppc/operation/plan.rb +34 -22
  48. data/lib/ppc/operation/report.rb +4 -4
  49. data/lib/ppc/operation/sublink.rb +8 -0
  50. data/ppc.gemspec +5 -5
  51. metadata +16 -10
  52. data/lib/ppc/api/shenma.rb +0 -64
  53. data/lib/ppc/api/shenma/report.rb +0 -135
@@ -6,196 +6,103 @@ module PPC
6
6
  Service = 'Keyword'
7
7
 
8
8
  Match_type = { 'exact' => 1, 'phrase' => 2, 'wide' => 3,1 => 'exact', 2=> 'phrase' , 3 => 'wide' }
9
+ @match_types = Match_type
9
10
  Device = { 'pc' => 0, 'mobile' => 1, 'all' => 2 }
10
11
  Type = { 'plan' => 3, 'group' => 5, 'keyword' => 11 }
11
12
 
12
- @map = [
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
- ]
13
+ KeywordType = {
14
+ id: :keywordId,
15
+ group_id: :adgroupId,
16
+ plan_id: :campaignId,
17
+ keyword: :keyword,
18
+ price: :price,
19
+ pc_destination: :pcDestinationUrl,
20
+ mobile_destination: :mobileDestinationUrl,
21
+ match_type: :matchType,
22
+ phrase_type: :phraseType,
23
+ status: :status,
24
+ pause: :pause,
25
+ wmatchprefer: :wmatchprefer,
26
+ }
27
+ @map = KeywordType
28
+
29
+ KeywordQualityType = {
30
+ id: :id,
31
+ group_id: :adgroupId,
32
+ plan_id: :campaignId,
33
+ pc_quality: :pcQuality,
34
+ pc_reliable: :pcReliable,
35
+ pc_reason: :pcReason,
36
+ pc_scale: :pcScale,
37
+ mobile_quality: :mobileQuality,
38
+ mobile_reliable: :mobileReliable,
39
+ mobile_reason: :mobileReason,
40
+ mobile_scale: :mobileScale,
41
+ }
42
+ @quality10_map = KeywordQualityType
43
+
44
+ def self.info( auth, ids )
45
+ body = { ids: ids, idType: 11, wordFields: KeywordType.values}
46
+ response = request( auth, Service, 'getWord', body )
47
+ process(response, 'keywordType' ){|x| reverse_type( x )[0] }
48
+ end
49
+
50
+ def self.all( auth, group_ids )
51
+ body = { ids: group_ids, idType: 5, wordFields: KeywordType.values}
52
+ response = request( auth, Service, 'getWord', body )
53
+ process(response, 'groupKeywords' ){|x| reverse_type( x ) }
54
+ end
24
55
 
25
- @quality10_map = [
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
- ]
56
+ def self.ids( auth, group_ids )
57
+ body = { ids: group_ids, idType: 5, wordFields: [:keywordId]}
58
+ response = request( auth, Service, 'getWord', body )
59
+ process(response, 'groupKeywordIds' ){|x| reverse_type( x ) }
60
+ end
38
61
 
39
- # 后面改成info方法
40
62
  def self.get( auth, ids )
41
- '''
42
- getKeywordByKeywordId
43
- '''
44
- ids = [ ids ] unless ids.is_a? Array
45
- body = { keywordIds: ids}
46
- response = request( auth, Service, 'getKeywordByKeywordId', body )
47
- return process(response, 'keywordTypes' ){|x| reverse_type( x ) }
63
+ body = { ids: ids, idType: 11, wordFields: KeywordType.values}
64
+ response = request( auth, Service, 'getWord', body )
65
+ process(response, 'keywordTypes' ){|x| reverse_type( x ) }
48
66
  end
49
67
 
50
68
  def self.add( auth, keywords )
51
- '''
52
- '''
53
- keywordtypes = make_type( keywords )
54
- body = { keywordTypes: keywordtypes }
55
- response = request( auth, Service, "addKeyword", body )
56
- return process(response, 'keywordTypes' ){|x| reverse_type(x) }
69
+ body = { keywordTypes: make_type( keywords ) }
70
+ response = request( auth, Service, "addWord", body )
71
+ process(response, 'keywordTypes' ){|x| reverse_type(x) }
57
72
  end
58
73
 
59
74
  def self.update( auth, keywords )
60
- '''
61
- '''
62
- keywordtypes = make_type( keywords )
63
- body = { keywordTypes: keywordtypes }
64
- response = request( auth, Service, "updateKeyword", body )
65
- return process(response, 'keywordTypes' ){|x| reverse_type(x) }
75
+ body = { keywordTypes: make_type( keywords ) }
76
+ response = request( auth, Service, "updateWord", body )
77
+ process(response, 'keywordTypes' ){|x| reverse_type(x) }
66
78
  end
67
79
 
68
80
  def self.delete( auth, ids )
69
- """
70
- """
71
- ids = [ ids ] unless ids.is_a? Array
72
81
  body = { keywordIds: ids}
73
- response = request( auth, Service, 'deleteKeyword', body )
74
- return process(response, 'result' ){|x| x }
75
- end
76
-
77
- def self.activate( auth, ids )
78
- """
79
- """
80
- ids = [ ids ] unless ids.is_a? Array
81
- body = { keywordIds: ids }
82
- response = request( auth, Service, 'activateKeyword', body)
83
- return process(response, 'keywordTypes' ){|x| reverse_type(x) }
84
- end
85
-
86
- def self.search_by_group_id( auth, group_ids )
87
- """
88
- getKeywordByGroupIds
89
- @input: list of group id
90
- @output: list of groupKeyword
91
- """
92
- group_ids = [ group_ids ] unless group_ids.is_a? Array
93
- body = { adgroupIds: group_ids }
94
- response = request( auth, Service, "getKeywordByAdgroupId", body )
95
- return process(response, 'groupKeywords' ){|x| make_groupKeywords( x ) }
96
- end
97
-
98
- def self.search_id_by_group_id( auth, group_ids )
99
- group_ids = [ group_ids ] unless group_ids.is_a? Array
100
- body = { adgroupIds: group_ids }
101
- response = request( auth, Service, "getKeywordIdByAdgroupId", body )
102
- return process(response, 'groupKeywordIds' ){|x| make_groupKeywordIds( x ) }
103
- end
104
-
105
- # 下面三个操作操作对象包括计划,组和关键字
106
- # 不知道放在这里合不合适
107
- def self.status( auth, ids, type )
108
- '''
109
- Return [{ id: id, status: status } ... ]
110
- '''
111
- ids = [ ids ] unless ids.is_a? Array
112
- body = { ids: ids, type: Type[type]}
113
- response = request( auth, Service, 'getKeywordStatus', body )
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
- }
123
- end
124
-
125
- def self.quality( auth ,ids, type, device )
126
- '''
127
- Return 10Quanlity *Not the old Quality* of given ketword id
128
- '''
129
- ids = [ ids ] unless ids.is_a? Array
130
- body = { ids: ids, type: Type[type], device:Device[device] }
131
- response = request( auth, Service, 'getKeyword10Quality', body )
132
- return process(response, 'keyword10Quality' ){|x| reverse_type( x, @quality10_map ) }
82
+ response = request( auth, Service, 'deleteWord', body )
83
+ process(response, 'result' ){|x| x }
133
84
  end
134
85
 
135
- private
136
- def self.make_groupKeywordIds( groupKeywordIds )
137
- group_keyword_ids = []
138
- groupKeywordIds.each do |groupKeywordId|
139
- group_keyword_id = { }
140
- group_keyword_id[:group_id] = groupKeywordId['adgroupIds']
141
- group_keyword_id[:keyword_ids] = groupKeywordId['keywordIds']
142
- group_keyword_ids << group_keyword_id
143
- end
144
- return group_keyword_ids
86
+ def self.enable( auth, ids )
87
+ keywords = ids.map{|id| {id: id, pause: false} }
88
+ self.update( auth, keywords )
145
89
  end
146
90
 
147
- private
148
- def self.make_groupKeywords( groupKeywords )
149
- group_keywords = []
150
- groupKeywords.each do |groupKeyword|
151
- group_keyword = {}
152
- group_keyword[:group_id] = groupKeyword['adgroupId']
153
- group_keyword[:keywords] = reverse_type( groupKeyword['keywordTypes'] )
154
- group_keywords << group_keyword
155
- end
156
- return group_keywords
91
+ def self.pause( auth, ids )
92
+ keywords = ids.map{|id| {id: id, pause: true} }
93
+ self.update( auth, keywords )
157
94
  end
158
95
 
159
- # Override
160
- def self.make_type( params, map = @map)
161
- params = [ params ] unless params.is_a? Array
162
- types = []
163
- params.each do |param|
164
- type = {}
165
- map.each do |key|
166
- # 增加对matchtype的自动转换
167
- if key[0] == :match_type
168
- value = param[ key[0] ]
169
- type[ key[1] ] = Match_type[ value ] if value
170
- else
171
- value = param[ key[0] ]
172
- type[ key[1] ] = value if value
173
- end
174
- end
175
- types << type
176
- end
177
- return types
96
+ def self.status( auth, ids )
97
+ body = { ids: ids, idType: 11, keywordTypes: [:keywordId, :status]}
98
+ response = request( auth, Service, 'getWord', body )
99
+ process(response, 'groupKeywords' ){|x| reverse_type( x ) }
178
100
  end
179
101
 
180
- # Overwrite
181
- def self.reverse_type( types, map = @map )
182
- types = [ types ] unless types.is_a? Array
183
- params = []
184
- types.each do |type|
185
- param = {}
186
- # 增加对matchtype的自动转换
187
- map.each do |key|
188
- if key[0] == :match_type
189
- value = type[ key[1].to_s ]
190
- param[ key[0] ] = Match_type[ value ] if value
191
- else
192
- value = type[ key[1].to_s ]
193
- param[ key[0] ] = value if value
194
- end
195
- end # map.each
196
- params << param
197
- end # types.each
198
- return params
102
+ def self.quality( auth, ids )
103
+ body = { ids: ids, idType: 11, keywordTypes: KeywordQualityType.values}
104
+ response = request( auth, Service, 'getWord', body )
105
+ process(response, 'groupKeywords' ){|x| reverse_type( x , KeywordQualityType) }
199
106
  end
200
107
 
201
108
  end # keyword
@@ -5,12 +5,13 @@ module PPC
5
5
  class Phone < Baidu
6
6
  Service = 'NewCreative'
7
7
 
8
- @map =[
9
- [:id,:phoneId],
10
- [:group_id,:adgroupId],
11
- [:phone_num,:phoneNum],
12
- [:pause,:pause],
13
- ]
8
+ PhoneType = {
9
+ id: :phoneId,
10
+ group_id: :adgroupId,
11
+ phone_num: :phoneNum,
12
+ pause: :pause,
13
+ }
14
+ @map = PhoneType
14
15
 
15
16
  def self.update( auth, phones )
16
17
  '''
@@ -21,7 +22,7 @@ module PPC
21
22
  process( response, 'phoneTypes' ){ |x| reverse_type(x) }
22
23
  end
23
24
 
24
- def self.search_id_by_group_id( auth, ids, getTemp = 0 )
25
+ def self.ids( auth, ids, getTemp = 0 )
25
26
  '''
26
27
  \'getPhoneIdByAdgroupId\'
27
28
  @ input: group ids
@@ -4,63 +4,80 @@ module PPC
4
4
  class Plan< Baidu
5
5
  Service = 'Campaign'
6
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
- [:is_dynamic,:isDynamicCreative],
21
- [:pause,:pause],
22
- [:status,:status]
23
- ]
7
+ PlanType = {
8
+ id: :campaignId,
9
+ name: :campaignName,
10
+ budget: :budget,
11
+ region: :regionTarget,
12
+ negative: :negativeWords,
13
+ exact_negative: :exactNegativeWords,
14
+ schedule: :schedule,
15
+ budget_offline_time: :budgetOfflineTime,
16
+ show_prob: :showProb,
17
+ device: :device,
18
+ price_ratio: :priceRatio,
19
+ is_dynamic: :isDynamicCreative,
20
+ pause: :pause,
21
+ status: :status,
22
+ rmkt_status: :rmktStatus,
23
+ type: :campaignType,
24
+ isdynamictagsublink: :isDynamicTagSublink,
25
+ isdynamichotredirect: :isDynamicHotRedirect,
26
+ isdynamictitle: :isDynamicTitle,
27
+ rmkt_price_ratio: :rmktPriceRatio,
28
+ }
29
+ @map = PlanType
30
+
31
+ def self.info( auth, ids )
32
+ body = { campaignIds: ids, campaignFields: PlanType.values}
33
+ response = request(auth,Service,'getCampaign',body)
34
+ process( response, 'campaignType' ){ |x|reverse_type(x)[0] }
35
+ end
24
36
 
25
37
  def self.all( auth )
26
- response = request( auth, Service, 'getAllCampaign' )
27
- process( response, 'campaignTypes' ){ |x| reverse_type(x) }
38
+ body = { campaignIds: nil, campaignFields: PlanType.values}
39
+ response = request(auth,Service,'getCampaign',body)
40
+ process( response, 'campaignTypes' ){ |x|reverse_type(x) }
28
41
  end
29
42
 
30
43
  def self.ids( auth )
31
- response = request( auth, Service, 'getAllCampaignId' )
32
- process( response, 'campaignIds' ){ |x| x }
44
+ body = { campaignIds: nil, campaignFields: ["campaignId"]}
45
+ response = request(auth,Service,'getCampaign',body)
46
+ process( response, 'campaignIds' ){ |x|reverse_type(x) }
33
47
  end
34
48
 
35
49
  def self.get( auth, ids )
36
- ids = [ ids ] unless ids.is_a? Array
37
- body = { campaignIds: ids }
38
- response = request( auth, Service, 'getCampaignByCampaignId', body)
39
- process( response, 'campaignTypes' ){ |x| reverse_type(x) }
50
+ body = { campaignIds: ids, campaignFields: PlanType.values}
51
+ response = request( auth, Service, 'getCampaign', body)
52
+ process( response, 'campaignTypes' ){ |x| reverse_type(x)}
40
53
  end
41
54
 
42
55
  def self.add( auth, plans )
43
- campaigntypes = make_type( plans )
44
- # set extended = 1 to allow change of isDynamicCreative
45
- body = { campaignTypes: campaigntypes, extended:1 }
56
+ body = { campaignTypes: make_type( plans ) }
46
57
  response = request( auth, Service, 'addCampaign', body)
47
58
  process( response, 'campaignTypes' ){ |x| reverse_type(x) }
48
59
  end
49
60
 
50
61
  def self.update(auth,plans )
51
- campaigntypes = make_type( plans )
52
- # set extended = 1 to allow change of isDynamicCreative
53
- body = { campaignTypes: campaigntypes, extended:1 }
62
+ body = { campaignTypes: make_type( plans ) }
54
63
  response = request( auth, Service, 'updateCampaign', body)
55
64
  process( response, 'campaignTypes' ){ |x| reverse_type(x) }
56
65
  end
57
66
 
58
67
  def self.delete(auth, ids )
59
- ids = [ ids ] unless ids.class == Array
60
- body = { campaignIds: ids }
61
- response = request( auth, Service, 'deleteCampaign', body)
68
+ response = request( auth, Service, 'deleteCampaign', {campaignIds: ids} )
62
69
  process( response, 'result' ){ |x| x }
63
70
  end
71
+
72
+ def self.enable( auth, ids )
73
+ plans = ids.map{|id| {id: id, pause: false} }
74
+ self.update( auth, plans )
75
+ end
76
+
77
+ def self.pause( auth, ids )
78
+ plans = ids.map{|id| {id: id, pause: true} }
79
+ self.update( auth, plans )
80
+ end
64
81
 
65
82
  end # Service
66
83
  end # baidu
@@ -25,7 +25,7 @@ module PPC
25
25
  request = make_reportrequest( params )
26
26
  body = { reportRequestType: request }
27
27
  response = request( auth, Service, 'getProfessionalReportId' ,body)
28
- process( response, 'reportId' ){ |x| x }
28
+ process( response, 'reportId' ){ |x| x[0]["reportId"] }
29
29
  end
30
30
 
31
31
  def self.get_state( auth, id )
@@ -35,13 +35,13 @@ module PPC
35
35
  status = {1=>'Waiting' ,2=>'Opearting' ,3=>'Finished'}
36
36
  body = { reportId: id }
37
37
  response = request( auth, Service, 'getReportState' ,body)
38
- process( response, 'isGenerated' ){ |x| status[x] }
38
+ process( response, 'isGenerated' ){ |x| status[x[0]["isGenerated"]] }
39
39
  end
40
40
 
41
41
  def self.get_url( auth, id )
42
42
  body = { reportId: id }
43
43
  response = request( auth, Service, 'getReportFileUrl' ,body)
44
- process( response, 'reportFilePath' ){ |x| x }
44
+ process( response, 'reportFilePath' ){ |x| x[0]["reportFilePath"] }
45
45
  end
46
46
 
47
47
  private
@@ -63,33 +63,15 @@ module PPC
63
63
  requesttype[:unitOfTime] = Unit_map[ param[:unit] ] if param[:unit]
64
64
  requesttype[:device] = Device_map[ param[:device] ] if param[:device]
65
65
  requesttype[:idOnly] = param[:id_only] || false
66
- requesttype[:startDate] = parse_date( param[:startDate] )
67
- requesttype[:endDate] = parse_date( param[:endDate] )
68
- return requesttype
69
- end
70
-
71
- private
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)
84
- end
85
- date
66
+ requesttype[:startDate] = Time.parse( param[:startDate] ) rescue Time.now - 86400
67
+ requesttype[:endDate] = Time.parse( param[:endDate] ) rescue Time.now - 86400
68
+ requesttype
86
69
  end
87
70
 
88
71
  #################################
89
72
  # useful function for operation #
90
73
  #################################
91
- def self.query_report( auth, param = nil, debug = false )
92
- param = {} if not param
74
+ def self.query_report( auth, param = {}, debug = false )
93
75
  param[:type] ||= 'query'
94
76
  param[:fields] ||= %w(click impression)
95
77
  param[:level] ||= 'pair'
@@ -98,8 +80,7 @@ module PPC
98
80
  download_report( auth, param, debug )
99
81
  end
100
82
 
101
- def self.creative_report( auth, param = nil, debug = false )
102
- param = {} if not param
83
+ def self.creative_report( auth, param = {}, debug = false )
103
84
  param[:type] ||= 'creative'
104
85
  param[:fields] ||= %w(impression click cpc cost ctr cpm position conversion)
105
86
  param[:level] ||= 'creative'
@@ -108,8 +89,7 @@ module PPC
108
89
  download_report( auth, param, debug )
109
90
  end
110
91
 
111
- def self.keyword_report( auth, param = nil, debug = false )
112
- param = {} if not param
92
+ def self.keyword_report( auth, param = {}, debug = false )
113
93
  param[:type] ||= 'keyword'
114
94
  param[:fields] ||= %w(impression click cpc cost ctr cpm position conversion)
115
95
  param[:level] ||= 'keywordid'