Migration Samples

The code samples below provide examples of common migration functions using the AdWords API. Client Library.

Migrate feed-based campaign level sitelinks to extension settings

' 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 Google.Api.Ads.AdWords.Lib
Imports Google.Api.Ads.AdWords.v201809

Namespace Google.Api.Ads.AdWords.Examples.VB.v201809
    ''' <summary>
    ''' This code example migrates your feed based sitelinks at campaign level to
    ''' use extension settings. To learn more about extensionsettings, see
    ''' https://developers.google.com/adwords/api/docs/guides/extension-settings.
    ''' To learn more about migrating Feed based extensions to extension
    ''' settings, see
    ''' https://developers.google.com/adwords/api/docs/guides/migrate-to-extension-settings.
    ''' </summary>
    ''' <remarks>This code example doesn't migrate scheduling or feeditem-level campaign, adgroup,
    ''' keyword, Or geo targeting settings.</remarks>
    Public Class MigrateToExtensionSettings
        Inherits ExampleBase

        ''' <summary>
        ''' The placeholder type for sitelinks. See
        ''' https://developers.google.com/adwords/api/docs/appendix/placeholders for
        ''' the list of all supported placeholder types.
        ''' </summary>
        Private Const PLACEHOLDER_TYPE_SITELINKS As Integer = 1

        ''' <summary>
        ''' Holds the placeholder field IDs for sitelinks. See
        ''' https://developers.google.com/adwords/api/docs/appendix/placeholders for
        ''' the list of all supported placeholder types.
        ''' </summary>
        Private Class SiteLinkFields
            Public Const TEXT As Long = 1
            Public Const URL As Long = 2
            Public Const LINE2 As Long = 3
            Public Const LINE3 As Long = 4
            Public Const FINAL_URLS As Long = 5
            Public Const FINAL_MOBILE_URLS As Long = 6
            Public Const TRACKING_URL_TEMPLATE As Long = 7
        End Class

        ''' <summary>
        ''' A sitelink object read from a feed.
        ''' </summary>
        Private Class SiteLinkFromFeed
            ''' <summary>
            ''' The feed ID.
            ''' </summary>
            Private feedIdField As Long

            ''' <summary>
            ''' The feed item ID.
            ''' </summary>
            Private feedItemIdField As Long

            ''' <summary>
            ''' The sitelink text.
            ''' </summary>
            Private textField As String

            ''' <summary>
            ''' The sitelink URL.
            ''' </summary>
            Private urlField As String

            ''' <summary>
            ''' The sitelink final URLs.
            ''' </summary>
            Private finalUrlsField As String()

            ''' <summary>
            ''' The sitelink final Mobile URLs.
            ''' </summary>
            Private finalMobileUrlsField As String()

            ''' <summary>
            ''' The sitelink tracking URL template.
            ''' </summary>
            Private trackingUrlTemplateField As String

            ''' <summary>
            ''' The sitelink line2 details.
            ''' </summary>
            Private line2Field As String

            ''' <summary>
            ''' The sitelink line3 details.
            ''' </summary>
            Private line3Field As String

            ''' <summary>
            ''' Gets or sets the feed ID.
            ''' </summary>
            Public Property FeedId As Long
                Get
                    Return feedIdField
                End Get
                Set(ByVal value As Long)
                    feedIdField = value
                End Set
            End Property

            ''' <summary>
            ''' Gets or sets the feed item ID.
            ''' </summary>
            Public Property FeedItemId As Long
                Get
                    Return feedItemIdField
                End Get
                Set(ByVal value As Long)
                    feedItemIdField = value
                End Set
            End Property

            ''' <summary>
            ''' Gets or sets the sitelink text.
            ''' </summary>
            Public Property Text As String
                Get
                    Return textField
                End Get
                Set(ByVal value As String)
                    textField = value
                End Set
            End Property

            ''' <summary>
            ''' Gets or sets the sitelink URL.
            ''' </summary>
            Public Property Url As String
                Get
                    Return urlField
                End Get
                Set(ByVal value As String)
                    urlField = value
                End Set
            End Property

            ''' <summary>
            ''' Gets or sets the sitelink final URLs.
            ''' </summary>
            Public Property FinalUrls As String()
                Get
                    Return finalUrlsField
                End Get
                Set(ByVal value As String())
                    finalUrlsField = value
                End Set
            End Property

            ''' <summary>
            ''' Gets or sets the sitelink final Mobile URLs.
            ''' </summary>
            Public Property FinalMobileUrls As String()
                Get
                    Return finalMobileUrlsField
                End Get
                Set(ByVal value As String())
                    finalMobileUrlsField = value
                End Set
            End Property

            ''' <summary>
            ''' Gets or sets the tracking URL template.
            ''' </summary>
            Public Property TrackingUrlTemplate As String
                Get
                    Return trackingUrlTemplateField
                End Get
                Set(ByVal value As String)
                    trackingUrlTemplateField = value
                End Set
            End Property

            ''' <summary>
            ''' Gets or sets the sitelink line2 details.
            ''' </summary>
            Public Property Line2 As String
                Get
                    Return line2Field
                End Get
                Set(ByVal value As String)
                    line2Field = value
                End Set
            End Property

            ''' <summary>
            ''' Gets or sets the sitelink line3 details.
            ''' </summary>
            Public Property Line3 As String
                Get
                    Return line3Field
                End Get
                Set(ByVal value As String)
                    line3Field = value
                End Set
            End Property
        End Class

        ''' <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 MigrateToExtensionSettings
            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 migrates your feed based sitelinks at campaign level to " &
                    "use extension settings. To learn more about extensionsettings, see " &
                    "https://developers.google.com/adwords/api/docs/guides/extension-settings. " &
                    "To learn more about migrating Feed based extensions to extension settings, " &
                    "see https://developers.google.com/adwords/api/docs/guides/migrate-to-extension-settings."
            End Get
        End Property

        ''' <summary>
        ''' Runs the code example.
        ''' </summary>
        ''' <param name="user">The AdWords user.</param>
        Public Sub Run(ByVal user As AdWordsUser)
            ' Get all the feeds from the user account.
            Dim feeds As Feed() = GetFeeds(user)

            For Each feed As Feed In feeds
                ' Retrieve all the sitelinks from the current feed.
                Dim feedItems As Dictionary(Of Long, SiteLinkFromFeed) =
                        GetSiteLinksFromFeed(user, feed.id)

                ' Get all the instances where a sitelink from this feed has been added
                ' to a campaign.
                Dim campaignFeeds As CampaignFeed() = GetCampaignFeeds(user, feed,
                                                                       PLACEHOLDER_TYPE_SITELINKS)

                If Not campaignFeeds Is Nothing Then
                    Dim allFeedItemsToDelete As New HashSet(Of Long)()

                    For Each campaignFeed As CampaignFeed In campaignFeeds
                        ' Retrieve the sitelinks that have been associated with this
                        ' campaign.
                        Dim feedItemIds As List(Of Long) = GetFeedItemsForCampaign(campaignFeed)
                        Dim platformRestrictions As ExtensionSettingPlatform =
                                GetPlatformRestrictionsForCampaign(campaignFeed)

                        If feedItemIds.Count = 0 Then
                            Console.WriteLine(
                                "Migration skipped for campaign feed with campaign ID {0} " &
                                "and feed ID {1} because no mapped feed item IDs were found in " &
                                "the campaign feed's matching function.", campaignFeed.campaignId,
                                campaignFeed.feedId)
                        Else
                            ' Delete the campaign feed that associates the sitelinks from the
                            ' feed to the campaign.
                            DeleteCampaignFeed(user, campaignFeed)

                            ' Create extension settings instead of sitelinks.
                            CreateExtensionSetting(user, feedItems, campaignFeed.campaignId,
                                                   feedItemIds,
                                                   platformRestrictions)

                            ' Mark the sitelinks from the feed for deletion.
                            allFeedItemsToDelete.UnionWith(feedItemIds)
                        End If
                    Next
                    ' Delete all the sitelinks from the feed.
                    DeleteOldFeedItems(user, New List(Of Long)(allFeedItemsToDelete), feed.id)
                End If
            Next
        End Sub

        ''' <summary>
        ''' Gets the site links from a feed.
        ''' </summary>
        ''' <param name="user">The user that owns the feed.</param>
        ''' <param name="feedId">The feed ID.</param>
        ''' <returns>A dictionary of sitelinks from the feed, with key as the feed
        ''' item ID, and value as the sitelink.</returns>
        Private Function GetSiteLinksFromFeed(ByVal user As AdWordsUser, ByVal feedId As Long) As _
            Dictionary(Of Long, SiteLinkFromFeed)
            Dim siteLinks As New Dictionary(Of Long, SiteLinkFromFeed)()

            ' Retrieve all the feed items from the feed.
            Dim feedItems As FeedItem() = GetFeedItems(user, feedId)

            ' Retrieve the feed's attribute mapping.
            Dim feedMappings As Dictionary(Of Long, HashSet(Of Long)) =
                    GetFeedMapping(user, feedId, PLACEHOLDER_TYPE_SITELINKS)

            If Not feedItems Is Nothing Then
                For Each feedItem As FeedItem In feedItems
                    Dim sitelinkFromFeed As New SiteLinkFromFeed()
                    sitelinkFromFeed.FeedId = feedItem.feedId
                    sitelinkFromFeed.FeedItemId = feedItem.feedItemId

                    For Each attributeValue As FeedItemAttributeValue In feedItem.attributeValues
                        ' This attribute hasn't been mapped to a field.
                        If Not feedMappings.ContainsKey(attributeValue.feedAttributeId) Then
                            Continue For
                        End If
                        ' Get the list of all the fields to which this attribute has been mapped.
                        For Each fieldId As Long In feedMappings(attributeValue.feedAttributeId)
                            ' Read the appropriate value depending on the ID of the mapped
                            ' field.
                            Select Case fieldId
                                Case SiteLinkFields.TEXT
                                    sitelinkFromFeed.Text = attributeValue.stringValue

                                Case SiteLinkFields.URL
                                    sitelinkFromFeed.Url = attributeValue.stringValue

                                Case SiteLinkFields.FINAL_URLS
                                    sitelinkFromFeed.FinalUrls = attributeValue.stringValues

                                Case SiteLinkFields.FINAL_MOBILE_URLS
                                    sitelinkFromFeed.FinalMobileUrls = attributeValue.stringValues

                                Case SiteLinkFields.TRACKING_URL_TEMPLATE
                                    sitelinkFromFeed.TrackingUrlTemplate =
                                        attributeValue.stringValue

                                Case SiteLinkFields.LINE2
                                    sitelinkFromFeed.Line2 = attributeValue.stringValue

                                Case SiteLinkFields.LINE3
                                    sitelinkFromFeed.Line3 = attributeValue.stringValue
                            End Select
                        Next
                    Next
                    siteLinks.Add(feedItem.feedItemId, sitelinkFromFeed)
                Next
            End If
            Return siteLinks
        End Function

        ''' <summary>
        ''' Gets the feed mapping for a feed.
        ''' </summary>
        ''' <param name="user">The user that owns the feed.</param>
        ''' <param name="feedId">The feed ID.</param>
        ''' <param name="placeHolderType">Type of the place holder for which feed
        ''' mappings should be retrieved.</param>
        ''' <returns>A dictionary, with key as the feed attribute ID, and value as
        ''' the set of all fields which the attribute has a mapping to.</returns>
        Private Function GetFeedMapping(ByVal user As AdWordsUser, ByVal feedId As Long,
                                        ByVal placeHolderType As Long) _
            As Dictionary(Of Long, HashSet(Of Long))
            Using feedMappingService As FeedMappingService = DirectCast(
                user.GetService(
                    AdWordsService.v201809.FeedMappingService),
                FeedMappingService)
                Dim page As FeedMappingPage = feedMappingService.query(
                    String.Format(
                        "SELECT FeedMappingId, AttributeFieldMappings where FeedId='{0}' and " &
                        "PlaceholderType={1} and Status='ENABLED'", feedId, placeHolderType))

                Dim attributeMappings As New Dictionary(Of Long, HashSet(Of Long))()

                If Not (page.entries Is Nothing) Then
                    ' Normally, a feed attribute is mapped only to one field. However,
                    ' you may map it to more than one field if needed.
                    For Each feedMapping As FeedMapping In page.entries
                        For Each attributeMapping As AttributeFieldMapping In _
                            feedMapping.attributeFieldMappings
                            If Not attributeMappings.ContainsKey(attributeMapping.feedAttributeId) _
                                Then
                                attributeMappings(attributeMapping.feedAttributeId) =
                                    New HashSet(Of Long)()
                            End If
                            attributeMappings(attributeMapping.feedAttributeId).Add(
                                attributeMapping.fieldId)
                        Next
                    Next
                End If
                Return attributeMappings
            End Using
        End Function

        ''' <summary>
        ''' Gets the feeds.
        ''' </summary>
        ''' <param name="user">The user for which feeds are retrieved.</param>
        ''' <returns>The list of feeds.</returns>
        Private Function GetFeeds(ByVal user As AdWordsUser) As Feed()
            ' TODO(b/67949201): This needs to handle paging
            Using feedService As FeedService = DirectCast(
                user.GetService(
                    AdWordsService.v201809.FeedService),
                FeedService)
                Dim page As FeedPage = feedService.query("SELECT Id, Name, Attributes where " &
                                                         "Origin='USER' and FeedStatus='ENABLED'")
                Return page.entries
            End Using
        End Function

        ''' <summary>
        ''' Gets the feed items in a feed.
        ''' </summary>
        ''' <param name="user">The user that owns the feed.</param>
        ''' <param name="feedId">The feed ID.</param>
        ''' <returns>The list of feed items in the feed.</returns>
        Private Function GetFeedItems(ByVal user As AdWordsUser, ByVal feedId As Long) As FeedItem()
            ' TODO(b/67949201): This needs to handle paging
            Using FeedItemService As FeedItemService = DirectCast(
                user.GetService(
                    AdWordsService.v201809.FeedItemService),
                FeedItemService)
                Dim page As FeedItemPage =
                        FeedItemService.query(String.Format("SELECT FeedItemId, AttributeValues " &
                                                            "WHERE Status = 'ENABLED'" &
                                                            " AND FeedId = '{0}'",
                                                            feedId))
                Return page.entries
            End Using
        End Function

        ''' <summary>
        ''' Deletes the old feed items for which extension settings have been
        ''' created.
        ''' </summary>
        ''' <param name="user">The user that owns the feed items.</param>
        ''' <param name="feedItemIds">IDs of the feed items to be removed.</param>
        ''' <param name="feedId">ID of the feed that holds the feed items.</param>
        Private Sub DeleteOldFeedItems(ByVal user As AdWordsUser,
                                       ByVal feedItemIds As List(Of Long),
                                       ByVal feedId As Long)
            If feedItemIds.Count = 0 Then
                Return
            End If
            Dim operations As New List(Of FeedItemOperation)()
            For Each feedItemId As Long In feedItemIds
                Dim operation As New FeedItemOperation()
                operation.operator = [Operator].REMOVE

                operation.operand = New FeedItem()
                operation.operand.feedItemId = feedItemId
                operation.operand.feedId = feedId

                operations.Add(operation)
            Next
            Using feedItemService As FeedItemService = DirectCast(
                user.GetService(
                    AdWordsService.v201809.FeedItemService),
                FeedItemService)
                feedItemService.mutate(operations.ToArray())
                Return
            End Using
        End Sub

        ''' <summary>
        ''' Creates the extension setting fo a list of feed items.
        ''' </summary>
        ''' <param name="user">The user for which extension settings are created.
        ''' </param>
        ''' <param name="feedItems">The list of all feed items.</param>
        ''' <param name="campaignId">ID of the campaign to which extension settings
        ''' are added.</param>
        ''' <param name="feedItemIds">IDs of the feed items for which extension
        ''' settings should be created.</param>
        ''' <param name="platformRestrictions">The platform restrictions for the
        ''' extension setting.</param>
        Private Sub CreateExtensionSetting(ByVal user As AdWordsUser, ByVal feedItems As _
                                              Dictionary(Of Long, SiteLinkFromFeed),
                                           ByVal campaignId As Long,
                                           ByVal feedItemIds As List(Of Long),
                                           ByVal platformRestrictions As ExtensionSettingPlatform)
            Dim extensionSetting As New CampaignExtensionSetting()
            extensionSetting.campaignId = campaignId
            extensionSetting.extensionType = FeedType.SITELINK
            extensionSetting.extensionSetting = New ExtensionSetting()

            Dim extensionFeedItems As New List(Of ExtensionFeedItem)()

            For Each feedItemId As Long In feedItemIds
                Dim feedItem As SiteLinkFromFeed = feedItems(feedItemId)

                Dim newFeedItem As New SitelinkFeedItem()
                newFeedItem.sitelinkText = feedItem.Text
                newFeedItem.sitelinkUrl = feedItem.Url
                newFeedItem.sitelinkFinalUrls = New UrlList()
                newFeedItem.sitelinkFinalUrls.urls = feedItem.FinalUrls
                newFeedItem.sitelinkFinalMobileUrls = New UrlList()
                newFeedItem.sitelinkFinalMobileUrls.urls = feedItem.FinalMobileUrls
                newFeedItem.sitelinkTrackingUrlTemplate = feedItem.TrackingUrlTemplate
                newFeedItem.sitelinkLine2 = feedItem.Line2
                newFeedItem.sitelinkLine3 = feedItem.Line3

                extensionFeedItems.Add(newFeedItem)
            Next
            extensionSetting.extensionSetting.extensions = extensionFeedItems.ToArray()
            extensionSetting.extensionSetting.platformRestrictions = platformRestrictions
            extensionSetting.extensionType = FeedType.SITELINK

            Using campaignExtensionSettingService As CampaignExtensionSettingService =
                DirectCast(user.GetService(AdWordsService.v201809.CampaignExtensionSettingService),
                           CampaignExtensionSettingService)

                Dim operation As New CampaignExtensionSettingOperation()
                operation.operand = extensionSetting
                operation.operator = [Operator].ADD

                campaignExtensionSettingService.mutate(
                    New CampaignExtensionSettingOperation() {operation})

                Return
            End Using
        End Sub

        ''' <summary>
        ''' Deletes a campaign feed.
        ''' </summary>
        ''' <param name="user">The AdWords user.</param>
        ''' <param name="campaignFeed">The campaign feed.</param>
        ''' <returns></returns>
        Private Function DeleteCampaignFeed(ByVal user As AdWordsUser,
                                            ByVal campaignFeed As CampaignFeed) As CampaignFeed
            Using campaignFeedService As CampaignFeedService = DirectCast(
                user.GetService(
                    AdWordsService.v201809.CampaignFeedService),
                CampaignFeedService)

                Dim operation As New CampaignFeedOperation()
                operation.operand = campaignFeed
                operation.operator = [Operator].REMOVE

                Return campaignFeedService.mutate(New CampaignFeedOperation() {operation}).value(0)
            End Using
        End Function

        ''' <summary>
        ''' Gets the platform restrictions for sitelinks in a campaign.
        ''' </summary>
        ''' <param name="campaignFeed">The campaign feed.</param>
        ''' <returns>The platform restrictions.</returns>
        Private Function GetPlatformRestrictionsForCampaign(ByVal campaignFeed As CampaignFeed) As _
            ExtensionSettingPlatform
            Dim platformRestrictions As String = "NONE"

            If campaignFeed.matchingFunction.operator = FunctionOperator.AND Then

                For Each argument As FunctionArgumentOperand In _
                    campaignFeed.matchingFunction.lhsOperand
                    ' Check if matchingFunction is of the form EQUALS(CONTEXT.DEVICE, 'Mobile').
                    If TypeOf argument Is FunctionOperand Then
                        Dim operand As FunctionOperand = CType(argument, FunctionOperand)
                        If operand.value.operator = FunctionOperator.EQUALS Then
                            Dim requestContextOperand As RequestContextOperand =
                                    CType(operand.value.lhsOperand(0), RequestContextOperand)
                            If (Not requestContextOperand Is Nothing) AndAlso
                               (requestContextOperand.contextType =
                                RequestContextOperandContextType.DEVICE_PLATFORM) Then
                                platformRestrictions = DirectCast(operand.value.rhsOperand(0),
                                                                  ConstantOperand).stringValue
                            End If
                        End If
                    End If
                Next
            End If

            Return _
                CType([Enum].Parse(GetType(ExtensionSettingPlatform), platformRestrictions, True),
                      ExtensionSettingPlatform)
        End Function

        ''' <summary>
        ''' Gets the list of feed items that are used by a campaign through a given
        ''' campaign feed.
        ''' </summary>
        ''' <param name="campaignFeed">The campaign feed.</param>
        ''' <returns>The list of feed items.</returns>
        Private Function GetFeedItemsForCampaign(ByVal campaignFeed As CampaignFeed) _
            As List(Of Long)
            Dim feedItems As New List(Of Long)()

            Select Case campaignFeed.matchingFunction.operator
                Case FunctionOperator.IN
                    ' Check if matchingFunction is of the form IN(FEED_ITEM_ID,{xxx,xxx}).
                    ' Extract feedItems if applicable.
                    feedItems.AddRange(GetFeedItemsFromArgument(campaignFeed.matchingFunction))

                Case FunctionOperator.AND
                    ' Check each condition.

                    For Each argument As FunctionArgumentOperand In _
                        campaignFeed.matchingFunction.lhsOperand
                        ' Check if matchingFunction is of the form IN(FEED_ITEM_ID,{xxx,xxx}).
                        ' Extract feedItems if applicable.
                        If TypeOf argument Is FunctionOperand Then
                            Dim operand As FunctionOperand = CType(argument, FunctionOperand)
                            If operand.value.operator = FunctionOperator.IN Then
                                feedItems.AddRange(GetFeedItemsFromArgument(operand.value))
                            End If
                        End If
                    Next

                Case Else
                    ' There are no other matching functions involving feeditem ids.
            End Select

            Return feedItems
        End Function

        Private Function GetFeedItemsFromArgument(ByVal func As [Function]) As List(Of Long)
            Dim feedItems As New List(Of Long)()

            If func.lhsOperand.Length = 1 Then
                Dim requestContextOperand As RequestContextOperand =
                        CType(func.lhsOperand(0), RequestContextOperand)
                If Not (requestContextOperand Is Nothing) AndAlso
                   (requestContextOperand.contextType =
                    RequestContextOperandContextType.FEED_ITEM_ID) Then
                    For Each argument As ConstantOperand In func.rhsOperand
                        feedItems.Add(argument.longValue)
                    Next
                End If
            End If

            Return feedItems
        End Function

        ''' <summary>
        ''' Gets the campaignfeeds that use a particular feed.
        ''' </summary>
        ''' <param name="user">The user that owns the feed.</param>
        ''' <param name="feed">The feed for which campaign feeds should be
        ''' retrieved.</param>
        ''' <param name="placeholderType">The type of placeholder to restrict
        ''' search.</param>
        ''' <returns>The list of campaignfeeds.</returns>
        Private Function GetCampaignFeeds(ByVal user As AdWordsUser, ByVal feed As Feed,
                                          ByVal placeholderType As Integer) As CampaignFeed()
            Using campaignFeedService As CampaignFeedService = DirectCast(
                user.GetService(
                    AdWordsService.v201809.CampaignFeedService),
                CampaignFeedService)

                Dim page As CampaignFeedPage = campaignFeedService.query(
                    String.Format(
                        "SELECT CampaignId, MatchingFunction, PlaceholderTypes " &
                        "WHERE Status='ENABLED' " &
                        "AND FeedId = '{0}' AND PlaceholderTypes CONTAINS_ANY[{1}]", feed.id,
                        placeholderType))
                Return page.entries
            End Using
        End Function
    End Class
End Namespace

Feedback geben zu...