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.
Files changed (107) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +4 -1
  3. data/LICENSE +334 -17
  4. data/README.md +75 -3
  5. data/lib/ppc.rb +3 -1
  6. data/lib/ppc/api.rb +137 -2
  7. data/lib/ppc/api/baidu.rb +20 -99
  8. data/lib/ppc/api/baidu/account.rb +21 -21
  9. data/lib/ppc/api/baidu/bulk.rb +39 -3
  10. data/lib/ppc/api/baidu/creative.rb +33 -33
  11. data/lib/ppc/api/baidu/group.rb +14 -14
  12. data/lib/ppc/api/baidu/keyword.rb +57 -46
  13. data/lib/ppc/api/baidu/phone_new_creative.rb +51 -0
  14. data/lib/ppc/api/baidu/plan.rb +34 -31
  15. data/lib/ppc/api/baidu/rank.rb +23 -0
  16. data/lib/ppc/api/baidu/report.rb +100 -81
  17. data/lib/ppc/api/qihu.rb +150 -0
  18. data/lib/ppc/api/qihu/account.rb +86 -0
  19. data/lib/ppc/api/qihu/bulk.rb +35 -0
  20. data/lib/ppc/api/qihu/creative.rb +108 -0
  21. data/lib/ppc/api/qihu/group.rb +96 -0
  22. data/lib/ppc/api/qihu/keyword.rb +113 -0
  23. data/lib/ppc/api/qihu/plan.rb +64 -0
  24. data/lib/ppc/api/qihu/rank.rb +25 -0
  25. data/lib/ppc/api/qihu/report.rb +159 -0
  26. data/lib/ppc/api/qihu/sublink.rb +71 -0
  27. data/lib/ppc/api/shenma.rb +64 -0
  28. data/lib/ppc/api/shenma/report.rb +135 -0
  29. data/lib/ppc/api/sm.rb +50 -0
  30. data/lib/ppc/api/sm/account.rb +44 -0
  31. data/lib/ppc/api/sm/bulk.rb +69 -0
  32. data/lib/ppc/api/sm/creative.rb +86 -0
  33. data/lib/ppc/api/sm/group.rb +94 -0
  34. data/lib/ppc/api/sm/keyword.rb +132 -0
  35. data/lib/ppc/api/sm/phone_new_creative.rb +51 -0
  36. data/lib/ppc/api/sm/plan.rb +63 -0
  37. data/lib/ppc/api/sm/report.rb +136 -0
  38. data/lib/ppc/api/sogou.rb +118 -0
  39. data/lib/ppc/api/sogou/account.rb +42 -0
  40. data/lib/ppc/api/sogou/bulk.rb +69 -0
  41. data/lib/ppc/api/sogou/creative.rb +117 -0
  42. data/lib/ppc/api/sogou/group.rb +123 -0
  43. data/lib/ppc/api/sogou/keyword.rb +188 -0
  44. data/lib/ppc/api/sogou/plan.rb +66 -0
  45. data/lib/ppc/api/sogou/report.rb +129 -0
  46. data/lib/ppc/ext.rb +17 -0
  47. data/lib/ppc/operation.rb +50 -36
  48. data/lib/ppc/operation/account.rb +19 -7
  49. data/lib/ppc/operation/creative.rb +7 -7
  50. data/lib/ppc/operation/group.rb +2 -2
  51. data/lib/ppc/operation/keyword.rb +11 -8
  52. data/lib/ppc/operation/report.rb +23 -0
  53. data/ppc.gemspec +14 -4
  54. data/spec/baidu/api_baidu_account_spec.rb +16 -0
  55. data/spec/baidu/api_baidu_creative_spec.rb +73 -0
  56. data/spec/{api_baidu_group_spec.rb → baidu/api_baidu_group_spec.rb} +12 -17
  57. data/spec/baidu/api_baidu_keyword_spec.rb +61 -0
  58. data/spec/baidu/api_baidu_phone_spec.rb +22 -0
  59. data/spec/{api_baidu_plan_spec.rb → baidu/api_baidu_plan_spec.rb} +11 -10
  60. data/spec/baidu/api_baidu_report_spec.rb +44 -0
  61. data/spec/{api_baidu_spec.rb → baidu/api_baidu_spec.rb} +10 -15
  62. data/spec/operation/operation_baidu_report_spec.rb +17 -0
  63. data/spec/operation/operation_baidu_spec.rb +126 -0
  64. data/spec/operation/operation_qihu_report_spec.rb +18 -0
  65. data/spec/operation/operation_qihu_spec.rb +94 -0
  66. data/spec/operation/operation_sm_report_spec.rb +21 -0
  67. data/spec/operation/operation_sogou_report_spec.rb +17 -0
  68. data/spec/operation/operation_sogou_spec.rb +88 -0
  69. data/spec/{operation_spec_helper.rb → operation/operation_spec_helper.rb} +3 -5
  70. data/spec/qihu/api_qihu_account_spec.rb +29 -0
  71. data/spec/qihu/api_qihu_creative_spec.rb +48 -0
  72. data/spec/qihu/api_qihu_group_spec.rb +40 -0
  73. data/spec/qihu/api_qihu_keyword_spec.rb +50 -0
  74. data/spec/qihu/api_qihu_plan_spec.rb +39 -0
  75. data/spec/qihu/api_qihu_report_spec.rb +54 -0
  76. data/spec/qihu/api_qihu_sublink_spec.rb +36 -0
  77. data/spec/sm/api_sm_account_spec.rb +8 -0
  78. data/spec/sm/api_sm_creative_spec.rb +52 -0
  79. data/spec/sm/api_sm_group_spec.rb +75 -0
  80. data/spec/sm/api_sm_keyword_spec.rb +59 -0
  81. data/spec/sm/api_sm_plan_spec.rb +39 -0
  82. data/spec/sm/api_sm_report_spec.rb +30 -0
  83. data/spec/sogou/api_sogou_account_spec.rb +17 -0
  84. data/spec/sogou/api_sogou_creative_spec.rb +51 -0
  85. data/spec/sogou/api_sogou_group_spec.rb +50 -0
  86. data/spec/sogou/api_sogou_keyword_spec.rb +54 -0
  87. data/spec/sogou/api_sogou_plan_spec.rb +43 -0
  88. data/spec/sogou/api_sogou_report_spec.rb +51 -0
  89. data/spec/spec_helper.rb +49 -10
  90. metadata +140 -46
  91. data/lib/ppc/baidu.rb +0 -152
  92. data/lib/ppc/baidu/account.rb +0 -88
  93. data/lib/ppc/baidu/bulk.rb +0 -52
  94. data/lib/ppc/baidu/group.rb +0 -99
  95. data/lib/ppc/baidu/key.rb +0 -38
  96. data/lib/ppc/baidu/plan.rb +0 -85
  97. data/lib/ppc/baidu/report.rb +0 -82
  98. data/spec/api_baidu_account_spec.rb +0 -18
  99. data/spec/api_baidu_creative_spec.rb +0 -71
  100. data/spec/api_baidu_keyword_spec.rb +0 -64
  101. data/spec/api_baidu_report_spec.rb +0 -32
  102. data/spec/baidu_account_spec.rb +0 -32
  103. data/spec/baidu_bulk_spec.rb +0 -21
  104. data/spec/baidu_group_spec.rb +0 -56
  105. data/spec/baidu_plan_spec.rb +0 -129
  106. data/spec/baidu_report_spec.rb +0 -24
  107. data/spec/operation_spec.rb +0 -87
@@ -0,0 +1,66 @@
1
+ module PPC
2
+ module API
3
+ class Sogou
4
+ class Plan< Sogou
5
+ Service = 'CpcPlan'
6
+
7
+ @map = [
8
+ [:id,:cpcPlanId],
9
+ [:name,:cpcPlanName],
10
+ [:budget,:budget],
11
+ [:region,:regions],
12
+ [:ip,:excludeIps] ,
13
+ [:negative,:negativeWords],
14
+ [:exact_negative,:exactNegativeWords],
15
+ [:schedule,:schedule],
16
+ [:budget_offline_time,:budgetOfflineTime],
17
+ [:show_prob,:showProb],
18
+ [:join_union ,:joinUnion],
19
+ [:device,:device],
20
+ [:price_ratio,:mobilePriceRate ],
21
+ [:pause,:pause],
22
+ [:status,:status],
23
+ ]
24
+
25
+ def self.all( auth )
26
+ response = request( auth, Service, 'getAllCpcPlan' )
27
+ process( response, 'cpcPlanTypes' ){ |x| reverse_type(x) }
28
+ end
29
+
30
+ def self.ids( auth )
31
+ response = request( auth, Service, 'getAllCpcPlanId' )
32
+ process( response, 'cpcPlanIds' ){ |x| x }
33
+ end
34
+
35
+ def self.get( auth, ids )
36
+ ids = [ ids ] unless ids.is_a? Array
37
+ body = { cpcPlanIds: ids }
38
+ response = request( auth, Service, 'getCpcPlanByCpcPlanId', body)
39
+ process( response, 'cpcPlanTypes' ){ |x| reverse_type(x) }
40
+ end
41
+
42
+ def self.add( auth, plans )
43
+ cpcPlanTypes = make_type( plans )
44
+ body = { cpcPlanTypes: cpcPlanTypes }
45
+ response = request( auth, Service, 'addCpcPlan', body)
46
+ process( response, 'cpcPlanTypes' ){ |x| reverse_type(x) }
47
+ end
48
+
49
+ def self.update( auth, plans )
50
+ cpcPlanTypes = make_type( plans )
51
+ body = { cpcPlanTypes: cpcPlanTypes }
52
+ response = request( auth, Service, 'updateCpcPlan', body)
53
+ process( response, 'cpcPlanTypes' ){ |x| reverse_type(x) }
54
+ end
55
+
56
+ def self.delete(auth, ids )
57
+ ids = [ ids ] unless ids.class == Array
58
+ body = { cpcPlanIds: ids }
59
+ response = request( auth, Service, 'deleteCpcPlan', body)
60
+ process( response, '' ){ |x| x }
61
+ end
62
+
63
+ end # Service
64
+ end # baidu
65
+ end # API
66
+ end # PP
@@ -0,0 +1,129 @@
1
+ # -*- coding:utf-8 -*-
2
+ module PPC
3
+ module API
4
+ class Sogou
5
+ class Report< Sogou
6
+ Service = 'Report'
7
+
8
+ # 需要用到的映射集合
9
+ Type_map = { 'account' => 1, 'plan'=> 2, 'group'=> 3,
10
+ 'keyword'=> 5, 'creative'=> 4, 'pair'=> 15,
11
+ 'query'=> 3 }
12
+
13
+ Range_map = { 'account' => 1, 'plan' => 2, 'group' => 3,
14
+ 'creative' => 4, 'keyword' => 5 }
15
+
16
+ Device_map = { 'all' => 0, 'pc' => 1, 'mobile' => 2 }
17
+
18
+ Unit_map = { 'day' => 1, 'week' => 2, 'month' => 3 }
19
+
20
+ def self.get_id( auth, params )
21
+ request = make_reportrequest( params )
22
+ body = { reportRequestType: request }
23
+ response = request( auth, Service, 'getReportId' ,body)
24
+ process( response, 'reportId' ){ |x| x }
25
+ end
26
+
27
+ def self.get_state( auth, id )
28
+ '''
29
+ input id should be string
30
+ '''
31
+ status = {'-1'=>'Waiting' ,'0'=>'Opearting' ,'1'=>'Finished'}
32
+ body = { reportId: id }
33
+ response = request( auth, Service, 'getReportState' ,body)
34
+ process( response, 'isGenerated' ){ |x| status[x] }
35
+ end
36
+
37
+ def self.get_url( auth, id )
38
+ body = { reportId: id }
39
+ response = request( auth, Service, 'getReportPath' ,body)
40
+ process( response, 'reportFilePath' ){ |x| x }
41
+ end
42
+
43
+ private
44
+ def self.make_reportrequest( param )
45
+ '''
46
+ make RepoerRequestType
47
+ ======================
48
+ For more docs please have a look at
49
+ ::PPC::API::Baidu::Report:make_reportrequest()
50
+ '''
51
+ requesttype = {}
52
+ requesttype[:performanceData] = param[:fields] || %w(click)
53
+ requesttype[:reportType] = Type_map[ param[:type] ] if param[:type]
54
+ requesttype[:statRange] = Range_map[ param[:range] ] if param[:range]
55
+ requesttype[:unitOfTime] = Unit_map[ param[:unit] ] if param[:unit]
56
+ requesttype[:platform] = Device_map[ param[:device] ] if param[:device]
57
+ requesttype[:idOnly] = param[:id_only] if param[:id_only]!=nil
58
+ requesttype[:startDate] = parse_date( param[:startDate] )
59
+ requesttype[:endDate] = parse_date( param[:endDate] )
60
+ return requesttype
61
+ end
62
+
63
+ private
64
+ def self.parse_date( date )
65
+ """
66
+ Cast string to time:
67
+ 'YYYYMMDD' => Time
68
+ """
69
+ if date
70
+ y = date[0..3]
71
+ m = date[4..5]
72
+ d = date[6..7]
73
+ date = Time.new( y, m, d )
74
+ else
75
+ date = (Time.now - 24*3600)
76
+ end
77
+ date.utc.iso8601
78
+ end
79
+
80
+ ###########################
81
+ # intreface for Operation #
82
+ ###########################
83
+ def self.download_report( auth, param, debug = false )
84
+ response = get_id( auth, param )
85
+ if response[:succ]
86
+ id = response[:result]
87
+ p "Got report id:" + id.to_s if debug
88
+ loop do
89
+ sleep 2
90
+ break if get_state( auth, id )[:result] == 'Finished'
91
+ p "Report is not generated, waiting..." if debug
92
+ end
93
+
94
+ url = get_url( auth, id )[:result]
95
+ ActiveSupport::Gzip.decompress( open(url).read ).force_encoding('gb18030').encode('utf-8')
96
+ else
97
+ raise response[:failure][:message]
98
+ end
99
+ end
100
+
101
+ def self.query_report( auth, param = nil, debug = false )
102
+ param = {} if not param
103
+ param[:type] ||= 'query'
104
+ param[:fields] ||= %w(click)
105
+ param[:range] ||= 'account'
106
+ param[:unit] ||= 'day'
107
+ download_report( auth, param, debug )
108
+ end
109
+
110
+ def self.creative_report( auth, param = nil, debug = false )
111
+ param = {} if not param
112
+ param[:type] ||= 'creative'
113
+ param[:fields] ||= %w( cost cpc click impression ctr )
114
+ param[:range] ||= 'account'
115
+ download_report( auth, param, debug )
116
+ end
117
+
118
+ def self.keyword_report( auth, param = nil, debug = false )
119
+ param = {} if not param
120
+ param[:type] ||= 'keyword'
121
+ param[:fields] ||= %w( cost cpc click impression ctr )
122
+ param[:range] ||= 'account'
123
+ download_report( auth, param, debug )
124
+ end
125
+
126
+ end # Repost
127
+ end # Baidu
128
+ end # API
129
+ end # PPC
data/lib/ppc/ext.rb ADDED
@@ -0,0 +1,17 @@
1
+ class String
2
+ def snake_case
3
+ self.gsub(/::/, '/').
4
+ gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
5
+ gsub(/([a-z\d])([A-Z])/,'\1_\2').
6
+ tr("-", "_").
7
+ downcase
8
+ end
9
+ end
10
+ class Hash
11
+ def filter_and_replace_key(key_new, key_old)
12
+ return self if key_new == key_old
13
+ value = self.delete(key_old)
14
+ self[key_new] = value unless value.nil?
15
+ self
16
+ end
17
+ end
data/lib/ppc/operation.rb CHANGED
@@ -3,55 +3,67 @@ module PPC
3
3
 
4
4
  attr_accessor :id
5
5
 
6
- def initialize(params)
7
- @id = params[:id]
8
- @se = params[:se]
6
+ def initialize( params )
7
+
8
+ if params[:se] == nil
9
+ raise 'please specific a search engine'
10
+ else
11
+ @se = params[:se]
12
+ end
13
+ @id = params[:id]
9
14
  @auth = {
10
15
  username: params[:username],
11
16
  password: params[:password],
12
- token: params[:token]
17
+ # 在qihu360的api中,apikey就是auth[:token]
18
+ token: params[:token],
19
+ target: params[:target]
13
20
  }
21
+ # add support for qihu360
22
+ if @se == 'qihu'
23
+ raise "you are using qihu service, please enter api_key" if params[:api_key].nil?
24
+ @auth[:api_key] = params[:api_key]
25
+ end
26
+ if @se == 'qihu' && params[:token].nil?
27
+ raise "you are using qihu service, please enter api_secret" if params[:api_secret].nil?
28
+ @auth[:api_secret] = params[:api_secret]
29
+ @auth[:token] = qihu_refresh_token
30
+ end
14
31
  end
15
32
 
16
- def call(service)
17
- eval "::PPC::API::#{@se.capitalize}::#{service.capitalize}"
33
+ def qihu_refresh_token
34
+ cipher_aes = OpenSSL::Cipher::AES.new(128, :CBC)
35
+ cipher_aes.encrypt
36
+ cipher_aes.key = @auth[:api_secret][0,16]
37
+ cipher_aes.iv = @auth[:api_secret][16,16]
38
+ encrypted = (cipher_aes.update(Digest::MD5.hexdigest(@auth[:password])) + cipher_aes.final).unpack('H*').join
39
+ url = "https://api.e.360.cn/account/clientLogin"
40
+ response = HTTParty.post(url,
41
+ :body => {
42
+ :username => @auth[:username],
43
+ :passwd => encrypted[0,64]
44
+ },
45
+ :headers => {'apiKey' => @auth[:api_key] }
46
+ )
47
+ data = response.parsed_response
48
+ data["account_clientLogin_response"]["accessToken"]
18
49
  end
19
50
 
20
- def download(params = {})
21
- bulk = ::PPC::Baidu::Bulk.new({
22
- username: @username,
23
- password: @password,
24
- token: @token,
25
- debug: @debug
26
- })
27
-
28
- params[:extended] = params[:extended] || 2
29
-
30
- begin
31
- file_id = bulk.file_id_of_all(params)
32
- puts "file_id: #{file_id}" if @debug
33
-
34
- loop do
35
- state = bulk.state(file_id)
36
- raise "invalid file state: #{state}" unless %w(1 2 3 null).include? state
37
- break if state == '3'
38
- puts "waiting for #{file_id} to be ready. current state:#{state}" if @debug
39
- sleep 3
40
- end
41
- puts "#{file_id} is ready" if @debug
42
- return bulk.path(file_id)
43
- rescue
44
- raise BulkException.new(file_id,bulk)
45
- end
51
+ def download( param = nil )
52
+ """
53
+ download all objs of an account
54
+ """
55
+ eval("::PPC::API::#{@se.capitalize}::Bulk").download( @auth, param )
56
+ end
46
57
 
47
- return false
58
+ def call(service)
59
+ eval "::PPC::API::#{@se.capitalize}::#{service.capitalize}"
48
60
  end
49
61
 
50
62
  # ++++++++ #
51
63
  # Lazy Code #
52
64
  # ++++++++ #
53
65
 
54
- # auxilary fucntion
66
+ # helper fucntion
55
67
  def get_obj( ids, service )
56
68
  '''
57
69
  Return service object.
@@ -68,7 +80,7 @@ module PPC
68
80
  objs << class_obj.new( param )
69
81
  end
70
82
 
71
- return objs[0] if objs.length == 1 else objs
83
+ return objs.length == 1 ? objs[0] : objs
72
84
  end
73
85
 
74
86
  # +++++ Plan opeartion funcitons +++++ #
@@ -154,8 +166,10 @@ end # PPC
154
166
  # because if we load files before defining the
155
167
  # module ::PPC::Operation. Errors of 'uninitialized constance'
156
168
  # will occur
169
+ require 'ppc/operation/report'
157
170
  require 'ppc/operation/account'
158
171
  require 'ppc/operation/group'
159
172
  require 'ppc/operation/plan'
160
173
  require 'ppc/operation/keyword'
161
- require 'ppc/operation/creative'
174
+ require 'ppc/operation/creative'
175
+
@@ -1,12 +1,12 @@
1
- require 'ppc/operation'
2
1
  module PPC
3
2
  module Operation
4
3
  class Account
5
4
  include ::PPC::Operation
6
5
 
6
+ # self operations
7
7
  def info
8
8
  info = call('account').info(@auth)
9
- @id = info[:result][0][:id] if @id == nil
9
+ @id = info[:result][:id] if @id == nil
10
10
  return info
11
11
  end
12
12
 
@@ -14,7 +14,7 @@ module PPC
14
14
  call('account').update(@auth,account)
15
15
  end
16
16
 
17
- # plan methods
17
+ # subobject(plan) operations
18
18
  def plans
19
19
  call('plan').all(@auth)
20
20
  end
@@ -22,19 +22,31 @@ module PPC
22
22
  def plan_ids
23
23
  call('plan').ids(@auth)
24
24
  end
25
+
26
+ # some useful keyword operations
27
+ def keywords(group_id)
28
+ call( 'keyword' ).search_by_group_id( @auth, group_id )
29
+ end
25
30
 
26
- # plan operation
31
+ def keyword_ids(group_id)
32
+ call( 'keyword' ).search_id_by_group_id( @auth, group_id )
33
+ end
34
+
35
+ # plan operations
27
36
  include ::PPC::Operation::Plan_operation
28
37
 
29
- # group opeartion
38
+ # group opeartions
30
39
  include ::PPC::Operation::Group_operation
31
40
 
32
- # keyword opeartion
41
+ # keyword opeartions
33
42
  include ::PPC::Operation::Keyword_operation
34
43
 
35
- # creative opeartion
44
+ # creative opeartions
36
45
  include ::PPC::Operation::Creative_operation
37
46
 
47
+ # report operations
48
+ include ::PPC::Operation::Report
49
+
38
50
  end
39
51
  end
40
52
  end
@@ -4,25 +4,25 @@ module PPC
4
4
  include ::PPC::Operation
5
5
 
6
6
  def info()
7
- ::PPC::API::Baidu::Creative::get( @auth, @id )
7
+ call( 'creative' ).get( @auth, @id )
8
8
  end
9
9
 
10
- def update( keywordType )
11
- ::PPC::API::Baidu::Keyword::update( @auth, keywordType )
10
+ def update( type )
11
+ call( 'creative' ).update( @auth, type.merge( id:@id) )
12
12
  end
13
13
 
14
14
  def activate()
15
- ::PPC::API::Baidu::Creative::activate( @auth, @id )
15
+ call( 'creative' ).activate( @auth, @id )
16
16
  end
17
17
 
18
18
  def status()
19
- ::PPC::API::Baidu::Creative::status( @auth, @id )
19
+ call( 'creative' ).status( @auth, @id )
20
20
  end
21
21
 
22
22
  def delete()
23
- ::PPC::API::Baidu::Creative::delete( @auth, @id )
23
+ call( 'creative' ).delete( @auth, @id )
24
24
  end
25
25
 
26
26
  end
27
27
  end
28
- end
28
+ end
@@ -8,7 +8,7 @@ module PPC
8
8
  end
9
9
 
10
10
  def update( info )
11
- info[:id] = @id unless info[:id]
11
+ info[:id] = @id if (info.is_a? Hash) && info[:id].nil?
12
12
  call('group').update(@auth, info)
13
13
  end
14
14
 
@@ -56,4 +56,4 @@ module PPC
56
56
 
57
57
  end # Group
58
58
  end # Operation
59
- end # PPC
59
+ end # PPC
@@ -4,29 +4,32 @@ module PPC
4
4
  include ::PPC::Operation
5
5
 
6
6
  def info()
7
- ::PPC::API::Baidu::Keyword::get( @auth, @id )
7
+ call( 'keyword' ).get( @auth, @id )
8
8
  end
9
9
 
10
10
  def update( type )
11
- ::PPC::API::Baidu::Keyword::update( @auth, type.merge( id:@id) )
11
+ type.merge(id: @id) if type.is_a? Hash
12
+ call( 'keyword' ).update( @auth, type )
12
13
  end
13
14
 
15
+ # Todo: Implement Activate method in Sogou API
14
16
  def activate()
15
- ::PPC::API::Baidu::Keyword::activate( @auth, @id )
17
+ call( 'keyword' ).activate( @auth, @id )
16
18
  end
17
19
 
18
20
  def status()
19
- ::PPC::API::Baidu::Keyword::status( @auth, @id )
21
+ call( 'keyword' ).status( @auth, @id )
20
22
  end
21
23
 
22
24
  def quality()
23
- ::PPC::API::Baidu::Keyword::quality( @auth, @id )
25
+ call( 'keyword' ).quality( @auth, @id )
24
26
  end
25
27
 
26
- def delete()
27
- ::PPC::API::Baidu::Keyword::delete( @auth, @id )
28
+ def delete( ids = nil )
29
+ ids ||= @id
30
+ call( 'keyword' ).delete( @auth, ids )
28
31
  end
29
32
 
30
33
  end
31
34
  end
32
- end
35
+ end