ppc 1.0.6 → 1.3.0

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 (53) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +31 -23
  3. data/LICENSE +22 -0
  4. data/README.md +5 -28
  5. data/lib/ppc/api/baidu/account.rb +47 -0
  6. data/lib/ppc/api/baidu/bulk.rb +41 -0
  7. data/lib/ppc/api/baidu/creative.rb +125 -0
  8. data/lib/ppc/api/baidu/group.rb +111 -0
  9. data/lib/ppc/api/baidu/keyword.rb +193 -0
  10. data/lib/ppc/api/baidu/plan.rb +65 -0
  11. data/lib/ppc/api/baidu/report.rb +124 -0
  12. data/lib/ppc/api/baidu.rb +132 -0
  13. data/lib/ppc/api.rb +8 -0
  14. data/lib/ppc/baidu/account.rb +55 -27
  15. data/lib/ppc/baidu/group.rb +99 -0
  16. data/lib/ppc/baidu/key.rb +38 -0
  17. data/lib/ppc/baidu/plan.rb +69 -0
  18. data/lib/ppc/baidu/report.rb +45 -13
  19. data/lib/ppc/baidu.rb +28 -25
  20. data/lib/ppc/operation/account.rb +40 -0
  21. data/lib/ppc/operation/creative.rb +28 -0
  22. data/lib/ppc/operation/group.rb +59 -0
  23. data/lib/ppc/operation/keyword.rb +32 -0
  24. data/lib/ppc/operation/plan.rb +47 -0
  25. data/lib/ppc/operation.rb +161 -0
  26. data/lib/ppc.rb +3 -7
  27. data/ppc.gemspec +4 -4
  28. data/spec/api_baidu_account_spec.rb +18 -0
  29. data/spec/api_baidu_creative_spec.rb +71 -0
  30. data/spec/api_baidu_group_spec.rb +50 -0
  31. data/spec/api_baidu_keyword_spec.rb +64 -0
  32. data/spec/api_baidu_plan_spec.rb +42 -0
  33. data/spec/api_baidu_report_spec.rb +32 -0
  34. data/spec/api_baidu_spec.rb +60 -0
  35. data/spec/baidu_account_spec.rb +32 -0
  36. data/spec/baidu_bulk_spec.rb +21 -0
  37. data/spec/baidu_group_spec.rb +56 -0
  38. data/spec/baidu_plan_spec.rb +129 -0
  39. data/spec/{report_spec.rb → baidu_report_spec.rb} +0 -0
  40. data/spec/operation_spec.rb +87 -0
  41. data/spec/operation_spec_helper.rb +53 -0
  42. data/spec/spec_helper.rb +18 -1
  43. metadata +53 -22
  44. data/Gemfile +0 -4
  45. data/LICENSE.txt +0 -22
  46. data/Rakefile +0 -2
  47. data/lib/ppc/qihu/account.rb +0 -0
  48. data/lib/ppc/qihu.rb +0 -0
  49. data/lib/ppc/sogou/bulk.rb +0 -48
  50. data/lib/ppc/sogou.rb +0 -125
  51. data/spec/account_spec.rb +0 -16
  52. data/spec/bulk_spec.rb +0 -35
  53. data/spec/plan_spec.rb +0 -17
@@ -0,0 +1,65 @@
1
+ module PPC
2
+ module API
3
+ class Baidu
4
+ class Plan< Baidu
5
+ Service = 'Campaign'
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
+ [:pause,:pause],
21
+ [:status,:status],
22
+ ]
23
+
24
+ def self.all( auth, debug = false )
25
+ response = request( auth, Service, 'getAllCampaign' )
26
+ process( response, 'campaignTypes' , debug ){ |x| reverse_type(x) }
27
+ end
28
+
29
+ def self.ids( auth, debug = false )
30
+ response = request( auth, Service, 'getAllCampaignId' )
31
+ process( response, 'campaignIds' , debug ){ |x| x }
32
+ end
33
+
34
+ def self.get( auth, ids, debug = false )
35
+ ids = [ ids ] unless ids.is_a? Array
36
+ body = { campaignIds: ids }
37
+ response = request( auth, Service, 'getCampaignByCampaignId', body)
38
+ process( response, 'campaignTypes' , debug ){ |x| reverse_type(x) }
39
+ end
40
+
41
+ def self.add( auth, plans, debug = false )
42
+ campaigntypes = make_type( plans )
43
+ body = { campaignTypes: campaigntypes }
44
+ response = request( auth, Service, 'addCampaign', body)
45
+ process( response, 'campaignTypes' , debug ){ |x| reverse_type(x) }
46
+ end
47
+
48
+ def self.update(auth,plans, debug = false )
49
+ campaigntypes = make_type( plans )
50
+ body = { campaignTypes: campaigntypes }
51
+ response = request( auth, Service, 'updateCampaign', body)
52
+ process( response, 'campaignTypes' , debug ){ |x| reverse_type(x) }
53
+ end
54
+
55
+ def self.delete(auth, ids, debug = false )
56
+ ids = [ ids ] unless ids.class == Array
57
+ body = { campaignIds: ids }
58
+ response = request( auth, 'Campaign', 'deleteCampaign', body)
59
+ process( response, 'result' , debug ){ |x| x }
60
+ end
61
+
62
+ end # Service
63
+ end # baidu
64
+ end # API
65
+ end # PPC
@@ -0,0 +1,124 @@
1
+ # -*- coding:utf-8 -*-
2
+ module PPC
3
+ module API
4
+ class Baidu
5
+ class Report< Baidu
6
+ Service = 'Report'
7
+
8
+ # 需要用到的映射集合
9
+ Type_map = { 'account' => 2, 'plan'=> 10, 'group'=> 11,
10
+ 'keyword'=> 14, 'creative'=> 12, 'pair'=> 15,
11
+ 'region'=> 3, 'wordid'=> 9 }
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 }
17
+
18
+ def self.get_realtime( auth, params, type = 'data', debug = false )
19
+ request = make_realtimerequest( params )[0]
20
+ body = { realTimeRequestTypes: request }
21
+ response = request( auth, Service, 'getRealTimeData' ,body)
22
+ if debug
23
+ return response
24
+ end
25
+
26
+ response = case type
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
33
+
34
+
35
+ def self.get_id( auth, params, debug = false )
36
+ request = make_reportrequest( params )[0]
37
+ body = { reportRequestType: request }
38
+ response = request( auth, Service, 'getProfessionalReportId' ,body)
39
+ process( response, 'reportId', debug ){ |x| x }
40
+ end
41
+
42
+ def self.get_status( auth, id, debug = false)
43
+ '''
44
+ input id should be string
45
+ '''
46
+ status = {1=>'Waiting' ,2=>'Opearting' ,3=>'Finished'}
47
+ body = { reportId: id }
48
+ response = request( auth, Service, 'getReportState' ,body)
49
+ process( response, 'isGenerated', debug ){ |x| status[x] }
50
+ end
51
+
52
+ def self.get_file_url( auth, id, debug = false )
53
+ body = { reportId: id }
54
+ response = request( auth, Service, 'getReportFileUrl' ,body)
55
+ process( response, 'reportFilePath', debug ){ |x| x }
56
+ end
57
+
58
+ private
59
+ def self.get_date()
60
+ begin
61
+ startDate = DateTime.parse(params[:start]).iso8601
62
+ endDate = DateTime.parse(params[:end]).iso8601
63
+ rescue Exception => e
64
+ startDate = (Time.now - 2*24*3600).utc.iso8601
65
+ endDate = (Time.now - 24*3600).utc.iso8601
66
+ end
67
+ return startDate,endDate
68
+ end
69
+
70
+ private
71
+ def self.make_realtimerequest( params )
72
+ '''
73
+ make RealTimeRequestType
74
+ 没有封装关键字:attribute,order,statIds
75
+ '''
76
+ params = [ params ] unless params.is_a? Array
77
+ requesttypes = []
78
+ params.each do |param|
79
+ requesttype = {}
80
+ startDate, endDate = get_date()
81
+
82
+ requesttype[:performanceData] = param[:fields] || %w(click impression)
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
92
+ end
93
+ return requesttypes
94
+ end
95
+
96
+ private
97
+ def self.make_reportrequest( params )
98
+ '''
99
+ make RepoerRequestType
100
+ '''
101
+ params = [ params ] unless params.is_a? Array
102
+ requesttypes = []
103
+ params.each do |param|
104
+ requesttype = {}
105
+ startDate, endDate = get_date()
106
+
107
+ requesttype[:performanceData] = param[:fields] || %w(click impression)
108
+ requesttype[:reportType] = Type_map[ param[:type] ] if param[:type]
109
+ requesttype[:levelOfDetails] = Level_map[ param[:level] ] if param[:level]
110
+ requesttype[:statRange] = Level_map[ param[:range] ] if param[:range]
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
117
+ end
118
+ return requesttypes
119
+ end
120
+
121
+ end # Repost
122
+ end # Baidu
123
+ end # API
124
+ end # PPC
@@ -0,0 +1,132 @@
1
+ # -*- coding:utf-8 -*-
2
+ require 'ppc/api/baidu/account'
3
+ require 'ppc/api/baidu/plan'
4
+ require 'ppc/api/baidu/bulk'
5
+ require 'ppc/api/baidu/group'
6
+ require 'ppc/api/baidu/keyword'
7
+ require 'ppc/api/baidu/report'
8
+ require 'ppc/api/baidu/creative'
9
+ require 'awesome_print'
10
+ require 'net/http'
11
+ require 'net/https'
12
+ require 'json'
13
+ module PPC
14
+ module API
15
+ class Baidu
16
+
17
+ @map = nil
18
+
19
+ def self.request( auth, service, method, params = {} )
20
+ '''
21
+ request should return whole http response including header
22
+ '''
23
+ uri = URI("https://api.baidu.com/json/sms/v3/#{service}Service/#{method}")
24
+ http_body = {
25
+ header: {
26
+ username: auth[:username],
27
+ password: auth[:password],
28
+ token: auth[:token]
29
+ },
30
+ body: params
31
+ }.to_json
32
+
33
+ http_header = {
34
+ 'Content-Type' => 'application/json; charset=UTF-8'
35
+ }
36
+
37
+ http = Net::HTTP.new(uri.host, 443)
38
+ http.set_debug_output $stderr
39
+ http.use_ssl = true
40
+
41
+ response = http.post(uri.path, http_body, http_header)
42
+ response = JSON.parse response.body
43
+
44
+ # return response if with_header else response['body']
45
+ end
46
+
47
+ def self.process( response, key , debug = false , &func)
48
+ '''
49
+ Process Http response. If operation successes, return value of given keys.
50
+ You can process the result using function &func, or do nothing by passing
51
+ block {|x|x}
52
+ ===========================
53
+ @Output: resultType{ desc: boolean, failure: Array, result: Array }
54
+ failure is the failures part of response\'s header
55
+ result is the processed response body.
56
+ '''
57
+ # 保留 debug 功能
58
+ return response if debug
59
+
60
+ result = {}
61
+ result[:succ] = response['header']['desc']=='success'? true : false
62
+ result[:failure] = response['header']['failures']
63
+ result[:result] = func[ response['body'][key] ]
64
+ return result
65
+ end # process
66
+
67
+ def self.make_type( params, map = @map)
68
+ '''
69
+ tranfesr ppc api to search engine api
70
+ @ input
71
+ params : list of hash complying with PPC gem api
72
+ map : list of pairs(lists) of symbol complying with following api
73
+ map = [
74
+ [ ppc_key, api_key ],
75
+ [ ppc_key, api_key ],
76
+ [ ppc_key, api_key ],
77
+ ...
78
+ ]
79
+ Ex:
80
+ baidu_group_map = [ [ :id, :adgroupId],
81
+ [ :price, :maxPrice],
82
+ ... ]
83
+ ===================
84
+ @ output:
85
+ : types : list of hash that complying with search engine api
86
+ '''
87
+ params = [ params ] unless params.is_a? Array
88
+
89
+ types = []
90
+ params.each do |param|
91
+ type = {}
92
+
93
+ map.each do |key|
94
+ value = param[ key[0] ]
95
+ type[ key[1] ] = value if value
96
+ end
97
+
98
+ types << type
99
+ end
100
+ return types
101
+ end
102
+
103
+ def self.reverse_type( types, map = @map )
104
+ '''
105
+ transfer search engine api to ppc api
106
+ @ input
107
+ types : list of hash that complying with search engine api
108
+ map : list of pairs(lists) of symbol, for more details please
109
+ read docs of make_type()
110
+ ===================
111
+ @ output:
112
+ params : list of hash complying with PPC gem api
113
+ '''
114
+ types = [ types ] unless types.is_a? Array
115
+
116
+ params = []
117
+ types.each do |type|
118
+ param = {}
119
+
120
+ map.each do |key|
121
+ value = type[ key[1].to_s ]
122
+ param[ key[0] ] = value if value
123
+ end
124
+
125
+ params << param
126
+ end
127
+ return params
128
+ end
129
+
130
+ end # Baidu
131
+ end # API
132
+ end # PPC
data/lib/ppc/api.rb ADDED
@@ -0,0 +1,8 @@
1
+ require 'ppc/api/baidu'
2
+
3
+ module PPC
4
+ module API
5
+ attr_reader :header,:body,:rquota,:quota,:status,:desc,:oprs,:oprtime,:code,:message
6
+ attr_accessor :username,:password,:token,:debug
7
+ end
8
+ end
@@ -6,17 +6,42 @@ module PPC
6
6
  super(params)
7
7
  end
8
8
 
9
+ def info
10
+ response = request('getAccountInfo')["accountInfoType"]
11
+ end
12
+
9
13
  def all(params = {})
10
14
  download(params)
11
15
  end
12
16
 
17
+ def update( params = {} )
18
+ """
19
+ update account info
20
+ @ params : account_info_type
21
+ @return : account info_type
22
+ """
23
+ info = {
24
+ accountInfoType: {
25
+ budgetType: params[:budget_type] ,
26
+ budget: params[:budget],
27
+ regionTarget: params[:region],
28
+ excludeIp: params[:excludeip] ,
29
+ isDynamicCreative: params[:isdynamic],
30
+ dynamicCreativeParam: params[:creativeparam]
31
+ }
32
+ }
33
+ # delete null symbol
34
+ info[:accountInfoType].each{
35
+ |pair|
36
+ key, value = pair
37
+ info[:accountInfoType].delete(key) if value == nil
38
+ }
39
+
40
+ request('updateAccountInfo', info)["accountInfoType"]
41
+ end
42
+
13
43
  def query_report(params = {})
14
- report = ::PPC::Baidu::Report.new({
15
- username: @username,
16
- password: @password,
17
- token: @token,
18
- debug: @debug
19
- })
44
+ report = ::PPC::Baidu::Report.new({username: @username, password: @password, token: @token, debug: @debug})
20
45
 
21
46
  begin
22
47
  @file_id = report.file_id_of_query(params)
@@ -30,31 +55,34 @@ module PPC
30
55
  sleep 3
31
56
  end
32
57
 
58
+ url = report.path(@file_id)
59
+ open(url).read.force_encoding('gb18030').encode('utf-8')
60
+ rescue Exception => e
61
+ raise ReportException.new(@file_id,report,e)
62
+ end
63
+ end
64
+
65
+ def cost_report(params = {})
66
+ report = ::PPC::Baidu::Report.new({username: @username, password: @password, token: @token, debug: @debug})
67
+ begin
68
+ @file_id = report.file_id_of_cost(params)
69
+ print_debug(@file_id,'file_id') if @debug
70
+
71
+ loop do
72
+ state = report.state(@file_id)
73
+ raise "invalid file state: #{state}" unless %w(1 2 3 null).include? state
74
+ break if state == '3'
75
+ print_debug(state,'file_id.state') if @debug
76
+ sleep 3
77
+ end
33
78
 
34
- return report.path(@file_id)
79
+ url = report.path(@file_id)
80
+ open(url).read.force_encoding('gb18030').encode('utf-8')
35
81
  rescue Exception => e
36
- # @header = bulk.header
37
- # @oprs = bulk.oprs
38
- # @oprtime = bulk.oprtime
39
- # @quota = bulk.quota
40
- # @rquota = bulk.rquota
41
- # @status = bulk.status
42
-
43
- # @desc = bulk.desc
44
-
45
- # case @desc
46
- # when 'success'
47
- # when 'failure'
48
- # @code = bulk.code
49
- # @message = bulk.message
50
- # when 'system failure'
51
- # @code = bulk.code
52
- # @message = bulk.message
53
- # else
54
- raise ReportException.new(@file_id,report,e)#,"unknown desc from baidu: #{@desc}"
55
- # end
82
+ raise ReportException.new(@file_id,report,e)
56
83
  end
57
84
  end
85
+
58
86
  end
59
87
  end
60
88
  end
@@ -0,0 +1,99 @@
1
+ module PPC
2
+ class Baidu
3
+ class Group < ::PPC::Baidu
4
+ def initialize(params = {})
5
+ params[:service] = 'Adgroup'
6
+ super(params)
7
+ end
8
+
9
+ def all()
10
+ """
11
+ @return : Array of campaignAdgroupIds
12
+ """
13
+ request( "getAllAdgroupId" )["campaignAdgroupIds"]
14
+ end
15
+
16
+ def add( params={}, test = false)
17
+ """
18
+ @ input : one or list of AdgroupType
19
+ @ output : list of AdgroupType
20
+ """
21
+ params = [ params ] unless params.class == Array
22
+ adgroupType = []
23
+
24
+ params.each{ | group_i |
25
+ adgroupType << make_adgrouptype( group_i )
26
+ }
27
+
28
+ body = {adgroupTypes: adgroupType}
29
+ response = request( "addAdgroup", body, test )
30
+ return response['adgroupTypes'] unless test else response
31
+ end
32
+
33
+ def update( params={}, test = false )
34
+ """
35
+ @ input : one or list of AdgroupType
36
+ @ output : list of AdgroupType
37
+ """
38
+ params = [ params ] unless params.class == Array
39
+ adgroupType = []
40
+
41
+ params.each{ | group_i |
42
+ adgroupType << make_adgrouptype( group_i )
43
+ }
44
+
45
+ body = {adgroupTypes: adgroupType}
46
+ responses = request( "updateAdgroup", body, test )
47
+ return responses['adgroupTypes'] unless test else responses
48
+ end
49
+
50
+ def delete( ids )
51
+ # delete responses have no content therefore we
52
+ #return header.desc to judge whether operation success
53
+ ids = [ ids ] unless ids.class == Array
54
+
55
+ body = { adgroupIds: ids }
56
+ request( "deleteAdgroup", body, true )[ 'header' ][ 'desc' ]
57
+ end
58
+
59
+ def search_by_planid( ids, test = false )
60
+ ids = [ ids ] unless ids.class == Array
61
+ body = { campaignIds: ids }
62
+ responses = request("getAdgroupByCampaignId", body, test )
63
+ return responses["campaignAdgroups"] unless test else responses
64
+ end
65
+
66
+ def search_by_groupid( ids, test = false )
67
+ ids = [ ids ] unless ids.class == Array
68
+ body = { adgroupIds: ids }
69
+ responses = request("getAdgroupByAdgroupId",body, test )
70
+ return responses["adgroupTypes"] unless test else responses
71
+ end
72
+
73
+ private
74
+ def make_adgrouptype( params={} )
75
+ adgrouptype = {
76
+ campaignId: params[:plan_id],
77
+ adgroupId: params[:group_id],
78
+ adgroupName: params[:name],
79
+ maxPrice: params[:maxprice],
80
+ negativeWords: params[:negative],
81
+ exactNegativeWords: params[:exact_negative],
82
+ pause: params[:pause],
83
+ status: params[:status],
84
+ reserved: params[:reserved]
85
+ }
86
+ # delete empty node
87
+ adgrouptype.each{
88
+ |pair|
89
+ key, value = pair
90
+ adgrouptype.delete(key) if value == nil
91
+ }
92
+ # delete invalid note according to request type
93
+ # unimplemented
94
+ return adgrouptype
95
+ end #make_adgrouptype
96
+
97
+ end # class group
98
+ end # class baidu
99
+ end # module
@@ -0,0 +1,38 @@
1
+ module PPC
2
+ class Baidu
3
+ class Key < ::PPC::Baidu
4
+ def initialize(params = {})
5
+ params[:service] = 'Keyword'
6
+ @se_id = params[:se_id]
7
+ super(params)
8
+ end
9
+
10
+ def add()
11
+ end
12
+
13
+ def update()
14
+ end
15
+
16
+ def delete()
17
+ end
18
+
19
+ def active()
20
+ end
21
+
22
+ def search_by_groupid( ids, return_id = false )
23
+ end
24
+
25
+ def search_by_keywordid( ids )
26
+ end
27
+
28
+ def get_status()
29
+ end
30
+
31
+ def get_quality()
32
+ end
33
+
34
+ def get_10quality()
35
+ end
36
+ end
37
+ end
38
+ end
@@ -11,6 +11,75 @@ module PPC
11
11
  params[:plan_ids] = [@se_id]
12
12
  download(params)
13
13
  end
14
+
15
+ def ids
16
+ request('getAllCampaignId')['campaignIds']
17
+ end
18
+
19
+ #add one or more plans
20
+ def add(plans)
21
+ if plans.class == Hash
22
+ plans = [plans]
23
+ single = true
24
+ end
25
+ campaignTypes = []
26
+
27
+ plans.each do |plan|
28
+ campaignTypes << {
29
+ campaignName: plan[:name],
30
+ negativeWords: plan[:negative],
31
+ exactNegativeWords: plan[:exact_negative]
32
+ }
33
+ end
34
+
35
+ options = {campaignTypes: campaignTypes}
36
+ response = request('addCampaign',options)['campaignTypes']
37
+ if single
38
+ response.first
39
+ else
40
+ response
41
+ end
42
+ end
43
+
44
+ def get(ids)
45
+ if ids.class != Array
46
+ ids = [ids]
47
+ single = true
48
+ end
49
+
50
+ options = {campaignIds: ids}
51
+ response = request('getCampaignByCampaignId',options)['campaignTypes']
52
+
53
+ if single
54
+ response.first
55
+ else
56
+ response
57
+ end
58
+ end
59
+
60
+ # @todo needs testing
61
+ def updates(params)
62
+ params['campaignId'] = @se_id
63
+ options = {campaignTypes: [params]}
64
+ request('updateCampaign',options)['campaignTypes']
65
+ end
66
+
67
+ def update_by_id(id,params = {})
68
+ params['campaignId'] = id
69
+ options = {campaignTypes: [params]}
70
+ request('updateCampaign',options)['campaignTypes']
71
+ end
72
+
73
+ def update(plans)
74
+ options = {campaignTypes: plans}
75
+ request('updateCampaign',options)['campaignTypes']
76
+ end
77
+
78
+ def delete(ids)
79
+ ids = [ids] unless ids.class == Array
80
+ options = {campaignIds: ids}
81
+ request('deleteCampaign',options)['result'] == 1
82
+ end
14
83
  end
15
84
  end
16
85
  end