ppc 1.3.0 → 1.3.2

Sign up to get free protection for your applications and to get access to all the features.
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