/
AddCompleteCampaignsUsingBatchJob.vb
executable file
·458 lines (387 loc) · 19.8 KB
/
AddCompleteCampaignsUsingBatchJob.vb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
' Copyright 2018 Google LLC
'
' Licensed under the Apache License, Version 2.0 (the "License");
' you may not use this file except in compliance with the License.
' You may obtain a copy of the License at
'
' http://www.apache.org/licenses/LICENSE-2.0
'
' Unless required by applicable law or agreed to in writing, software
' distributed under the License is distributed on an "AS IS" BASIS,
' WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
' See the License for the specific language governing permissions and
' limitations under the License.
Imports System.Threading
Imports Google.Api.Ads.AdWords.Lib
Imports Google.Api.Ads.AdWords.Util.BatchJob.v201809
Imports Google.Api.Ads.AdWords.v201809
Namespace Google.Api.Ads.AdWords.Examples.VB.v201809
''' <summary>
''' This code example illustrates how to use BatchJobService to create multiple
''' complete campaigns, including ad groups and keywords.
''' </summary>
Public Class AddCompleteCampaignsUsingBatchJob
Inherits ExampleBase
''' <summary>
''' The last ID that was automatically generated.
''' </summary>
Private Shared LAST_ID As Long = - 1
''' <summary>
''' The number of campaigns to be added.
''' </summary>
Private Const NUMBER_OF_CAMPAIGNS_TO_ADD As Long = 2
''' <summary>
''' The number of ad groups to be added per campaign.
''' </summary>
Private Const NUMBER_OF_ADGROUPS_TO_ADD As Long = 2
''' <summary>
''' The number of keywords to be added per campaign.
''' </summary>
Private Const NUMBER_OF_KEYWORDS_TO_ADD As Long = 5
''' <summary>
''' The maximum milliseconds to wait for completion.
''' </summary>
Private Const TIME_TO_WAIT_FOR_COMPLETION As Integer = 15*60*1000 ' 15 minutes
''' <summary>
''' Create a temporary ID generator that will produce a sequence of descending
''' negative numbers.
''' </summary>
''' <returns></returns>
Private Shared Function NextId() As Long
Return Interlocked.Decrement(LAST_ID)
End Function
''' <summary>
''' Main method, to run this code example as a standalone application.
''' </summary>
''' <param name="args">The command line arguments.</param>
Public Shared Sub Main(ByVal args As String())
Dim codeExample As New AddCompleteCampaignsUsingBatchJob
Console.WriteLine(codeExample.Description)
Try
codeExample.Run(New AdWordsUser)
Catch e As Exception
Console.WriteLine("An exception occurred while running this code example. {0}",
ExampleUtilities.FormatException(e))
End Try
End Sub
''' <summary>
''' Returns a description about the code example.
''' </summary>
Public Overrides ReadOnly Property Description() As String
Get
Return _
"This code example illustrates how to use BatchJobService to create multiple" &
" complete campaigns, including ad groups and keywords."
End Get
End Property
''' <summary>
''' Runs the code example.
''' </summary>
''' <param name="user">The AdWords user.</param>
Public Sub Run(ByVal user As AdWordsUser)
Using batchJobService As BatchJobService = CType(
user.GetService(
AdWordsService.v201809.BatchJobService),
BatchJobService)
Try
' Create a BatchJob.
Dim addOp As New BatchJobOperation()
addOp.operator = [Operator].ADD
addOp.operand = New BatchJob()
Dim batchJob As BatchJob = batchJobService.mutate(
New BatchJobOperation() {addOp}).value(0)
' Get the upload URL from the new job.
Dim uploadUrl As String = batchJob.uploadUrl.url
Console.WriteLine(
"Created BatchJob with ID {0}, status '{1}' and upload URL {2}.",
batchJob.id, batchJob.status, batchJob.uploadUrl.url)
' Create the mutate request that will be sent to the upload URL.
Dim operations As New List(Of Operation)()
' Create and add an operation to create a new budget.
Dim budgetOperation As BudgetOperation = BuildBudgetOperation()
operations.Add(budgetOperation)
' Create and add operations to create new campaigns.
Dim campaignOperations As List(Of CampaignOperation) =
BuildCampaignOperations(budgetOperation.operand.budgetId)
operations.AddRange(campaignOperations.ToArray())
Dim adGroupOperations As New List(Of AdGroupOperation)()
' Create and add operations to create new ad groups.
For Each campaignOperation As CampaignOperation In campaignOperations
adGroupOperations.AddRange(
BuildAdGroupOperations(campaignOperation.operand.id))
Next
operations.AddRange(adGroupOperations.ToArray())
' Create and add operations to create new ad group ads (expanded text ads).
For Each adGroupOperation As AdGroupOperation In adGroupOperations
operations.AddRange(
BuildAdGroupAdOperations(adGroupOperation.operand.id).ToArray())
Next
' Create and add operations to create new ad group criteria (keywords).
For Each adGroupOperation As AdGroupOperation In adGroupOperations
operations.AddRange(BuildAdGroupCriterionOperations(
adGroupOperation.operand.id).ToArray())
Next
Dim batchJobUploadHelper As New BatchJobUtilities(user)
' Create a resumable Upload URL to upload the operations.
Dim resumableUploadUrl As String =
batchJobUploadHelper.GetResumableUploadUrl(uploadUrl)
' Use the BatchJobUploadHelper to upload all operations.
batchJobUploadHelper.Upload(resumableUploadUrl, operations.ToArray())
Dim waitHandler As WaitHandler
' Create a wait handler.
waitHandler = New WaitHandler(batchJob, False)
Dim isComplete As Boolean = batchJobUploadHelper.WaitForPendingJob(
batchJob.id,
TIME_TO_WAIT_FOR_COMPLETION,
AddressOf waitHandler.OnJobWaitForCompletion)
' Restore the latest value for batchJob from waithandler.
batchJob = waitHandler.Job
If Not isComplete Then
Throw _
New TimeoutException(
"Job is still in pending state after waiting for " &
TIME_TO_WAIT_FOR_COMPLETION & " seconds.")
End If
If Not (batchJob.processingErrors Is Nothing) Then
For Each processingError As BatchJobProcessingError In _
batchJob.processingErrors
Console.WriteLine(" Processing error: {0}, {1}, {2}, {3}, {4}",
processingError.ApiErrorType,
processingError.trigger,
processingError.errorString,
processingError.fieldPath,
processingError.reason)
Next
End If
If (Not (batchJob.downloadUrl Is Nothing)) AndAlso
(Not (batchJob.downloadUrl.url Is Nothing)) Then
Dim mutateResponse As BatchJobMutateResponse =
batchJobUploadHelper.Download(batchJob.downloadUrl.url)
Console.WriteLine("Downloaded results from {0}.", batchJob.downloadUrl.url)
For Each mutateResult As MutateResult In mutateResponse.rval
Dim outcome As String = ""
If mutateResult.errorList Is Nothing Then
outcome = "SUCCESS"
Else
outcome = "FAILURE"
End If
Console.WriteLine(" Operation [{0}] - {1}",
mutateResult.index,
outcome)
Next
End If
Catch e As Exception
Throw _
New System.ApplicationException("Failed to add campaigns using batch job.",
e)
End Try
End Using
End Sub
''' <summary>
''' A class that handles wait callbacks for the batch job.
''' </summary>
Class WaitHandler
''' <summary>
''' The batch job to wait for.
''' </summary>
Private batchJob As BatchJob
''' <summary>
''' A flag to determine if the job was requested to be cancelled. This
''' typically comes from the user.
''' </summary>
Private cancelRequested As Boolean
''' <summary>
''' Initializes a new instance of the <see cref="WaitHandler"/> class.
''' </summary>
''' <param name="batchJob">The batch job to wait for.</param>
''' <param name="wasCancelRequested">A flag to determine if the job was
''' requested to be cancelled. This typically comes from the user.</param>
Sub New(ByVal batchJob As BatchJob, ByVal wasCancelRequested As Boolean)
Me.batchJob = batchJob
Me.WasCancelRequested = wasCancelRequested
End Sub
''' <summary>
''' Gets or sets the batch job to wait for.
''' </summary>
Public Property Job As BatchJob
Get
Return Me.batchJob
End Get
Set(value As BatchJob)
Me.batchJob = value
End Set
End Property
''' <summary>
''' Gets or sets a flag to determine if the job was requested to be
''' cancelled. This typically comes from the user.
''' </summary>
Public Property WasCancelRequested As Boolean
Get
Return Me.cancelRequested
End Get
Set(value As Boolean)
Me.cancelRequested = value
End Set
End Property
''' <summary>
''' Callback method when the job is waiting for cancellation.
''' </summary>
''' <param name="waitBatchJob">The updated batch job being waited for.</param>
''' <param name="timeElapsed">The time elapsed.</param>
''' <returns>True, if the wait loop should be cancelled, false otherwise.
'''</returns>
Public Function OnJobWaitForCancellation(ByVal waitBatchJob As BatchJob,
ByVal timeElapsed As Long) As Boolean
Console.WriteLine("[{0} seconds]: Batch job ID {1} has status '{2}'.",
timeElapsed/1000, waitBatchJob.id, waitBatchJob.status)
batchJob = waitBatchJob
Return False
End Function
''' <summary>
''' Callback method when the job is waiting for completion.
''' </summary>
''' <param name="waitBatchJob">The updated batch job being waited for.</param>
''' <param name="timeElapsed">The time elapsed.</param>
''' <returns>True, if the wait loop should be cancelled, false otherwise.
'''</returns>
Public Function OnJobWaitForCompletion(ByVal waitBatchJob As BatchJob,
ByVal timeElapsed As Long) As Boolean
Console.WriteLine("[{0} seconds]: Batch job ID {1} has status '{2}'.",
timeElapsed/1000, waitBatchJob.id, waitBatchJob.status)
batchJob = waitBatchJob
Return Me.WasCancelRequested
End Function
End Class
''' <summary>
''' Builds the operation for creating an ad within an ad group.
''' </summary>
''' <param name="adGroupId">ID of the ad group for which ads are created.</param>
''' <returns>A list of operations for creating ads.</returns>
Private Shared Function BuildAdGroupAdOperations(ByVal adGroupId As Long) _
As List(Of AdGroupAdOperation)
Dim operations As New List(Of AdGroupAdOperation)()
Dim adGroupAd As New AdGroupAd()
adGroupAd.adGroupId = adGroupId
Dim expandedTextAd As New ExpandedTextAd
expandedTextAd.headlinePart1 = "Luxury Cruise to Mars"
expandedTextAd.headlinePart2 = "Visit the Red Planet in style."
expandedTextAd.description = "Low-gravity fun for everyone!"
expandedTextAd.finalUrls = New String() {"http://www.example.com/1"}
adGroupAd.ad = expandedTextAd
Dim operation As New AdGroupAdOperation()
operation.operand = adGroupAd
operation.operator = [Operator].ADD
operations.Add(operation)
Return operations
End Function
''' <summary>
''' Builds the operations for creating keywords within an ad group.
''' </summary>
''' <param name="adGroupId">ID of the ad group for which keywords are
''' created.</param>
''' <returns>A list of operations for creating keywords.</returns>
Private Shared Function BuildAdGroupCriterionOperations(ByVal adGroupId As Long) _
As List(Of AdGroupCriterionOperation)
Dim adGroupCriteriaOperations As New List(Of AdGroupCriterionOperation)()
' Create AdGroupCriterionOperations to add keywords.
For i As Integer = 0 To NUMBER_OF_KEYWORDS_TO_ADD
' Create Keyword.
Dim text As String = String.Format("mars{0}", i)
' Make 50% of keywords invalid to demonstrate error handling.
If (i Mod 2) = 0 Then
text = text & "!!!"
End If
' Create AdGroupCriterionOperation.
Dim operation As New AdGroupCriterionOperation()
operation.operand = New BiddableAdGroupCriterion()
operation.operand.adGroupId = adGroupId
Dim keyword As New Keyword
keyword.text = text
keyword.matchType = KeywordMatchType.BROAD
operation.operand.criterion = keyword
operation.operator = [Operator].ADD
' Add to list.
adGroupCriteriaOperations.Add(operation)
Next
Return adGroupCriteriaOperations
End Function
''' <summary>
''' Builds the operations for creating ad groups within a campaign.
''' </summary>
''' <param name="campaignId">ID of the campaign for which ad groups are
''' created.</param>
''' <returns>A list of operations for creating ad groups.</returns>
Private Shared Function BuildAdGroupOperations(ByVal campaignId As Long) As _
List(Of AdGroupOperation)
Dim operations As New List(Of AdGroupOperation)()
For i As Integer = 0 To NUMBER_OF_ADGROUPS_TO_ADD
Dim adGroup As New AdGroup()
adGroup.campaignId = campaignId
adGroup.id = NextId()
adGroup.name = "Batch Ad Group # " & ExampleUtilities.GetRandomString()
Dim cpcBid As New CpcBid
cpcBid.bid = New Money()
cpcBid.bid.microAmount = 10000000L
Dim biddingStrategyConfiguration As New BiddingStrategyConfiguration()
biddingStrategyConfiguration.bids = New Bids() {cpcBid}
adGroup.biddingStrategyConfiguration = biddingStrategyConfiguration
Dim operation As New AdGroupOperation()
operation.operand = adGroup
operation.operator = [Operator].ADD
operations.Add(operation)
Next
Return operations
End Function
''' <summary>
''' Builds the operations for creating new campaigns.
''' </summary>
''' <param name="budgetId">ID of the budget to be used for the campaign.
''' </param>
''' <returns>A list of operations for creating campaigns.</returns>
Private Shared Function BuildCampaignOperations(ByVal budgetId As Long) _
As List(Of CampaignOperation)
Dim operations As New List(Of CampaignOperation)()
For i As Integer = 0 To NUMBER_OF_CAMPAIGNS_TO_ADD
Dim campaign As New Campaign()
campaign.name = "Batch Campaign " + ExampleUtilities.GetRandomString()
' Recommendation: Set the campaign to PAUSED when creating it to prevent
' the ads from immediately serving. Set to ENABLED once you've added
' targeting and the ads are ready to serve.
campaign.status = CampaignStatus.PAUSED
campaign.id = NextId()
campaign.advertisingChannelType = AdvertisingChannelType.SEARCH
Dim budget As New Budget()
budget.budgetId = budgetId
campaign.budget = budget
Dim biddingStrategyConfiguration As New BiddingStrategyConfiguration()
biddingStrategyConfiguration.biddingStrategyType = BiddingStrategyType.MANUAL_CPC
' You can optionally provide a bidding scheme in place of the type.
Dim biddingScheme As New ManualCpcBiddingScheme()
biddingStrategyConfiguration.biddingScheme = biddingScheme
campaign.biddingStrategyConfiguration = biddingStrategyConfiguration
Dim operation As New CampaignOperation()
operation.operand = campaign
operation.operator = [Operator].ADD
operations.Add(operation)
Next
Return operations
End Function
''' <summary>
''' Builds an operation for creating a budget.
''' </summary>
''' <returns>The operation for creating a budget.</returns>
Private Shared Function BuildBudgetOperation() As BudgetOperation
Dim budget As New Budget()
budget.budgetId = NextId()
budget.name = "Interplanetary Cruise #" & ExampleUtilities.GetRandomString()
Dim amount As New Money()
amount.microAmount = 50000000L
budget.amount = amount
budget.deliveryMethod = BudgetBudgetDeliveryMethod.STANDARD
Dim budgetOperation As New BudgetOperation()
budgetOperation.operand = budget
budgetOperation.operator = [Operator].ADD
Return budgetOperation
End Function
End Class
End Namespace