특가 업데이트

다음 방법을 사용하여 거래를 개별적으로 업데이트할 수 있습니다. 또는 일괄 처리할 수 있습니다. 협상 중에 거래를 업데이트할 수 있으며, 기존에 수락한 인벤토리 재협상을 시작하거나 제안을 참조하세요.

거래 패치

buyers.proposals.deals.patch 드림 메서드를 사용하여 해당 인벤토리와 연결된 특정 거래를 제안서 구매자 계정 또는 클라이언트입니다.

patch을(를) 사용하여 제안된 거래를 초기에 변경할 수 있습니다. 확정된 거래의 재협상을 시작할 수 있습니다

다음 샘플은 patch를 사용하여 거래를 업데이트하는 방법을 보여줍니다. 메서드를 사용하여 축소하도록 요청합니다.

REST

요청

PATCH https://authorizedbuyersmarketplace.googleapis.com/v1/buyers/12345678/proposals/MP21673270/deals/52404updateMask=flightStartTime%2CflightEndTime%2CprogrammaticGuaranteedTerms.fixedPrice.amount.units%2CprogrammaticGuaranteedTerms.fixedPrice.amount.nanos&alt=json
Authorization: Bearer ACCESS_TOKEN
Content-Type: application/json

{
 "proposalRevision": "4",
 "flightStartTime": "2037-04-02T20:15:59.584739+00:00",
 "flightEndTime": "2037-04-03T20:15:59.584739+00:00",
 "programmaticGuaranteedTerms": {
   "fixedPrice": {
     "amount": {
       "units": 1,
       "nanos": 500000000
     }
   }
 }
}

응답

{
 "name": "buyers/12345678/proposals/MP21673270/deals/52404",
 "createTime": "2036-12-27T04:02:39.731Z",
 "updateTime": "2037-03-31T20:12:40.875Z",
 "proposalRevision": "5",
 "displayName": "test_deal_7435251",
 "buyer": "buyers/12345678",
 "publisherProfile": "buyers/12345678/publisherProfiles/PP54321",
 "flightStartTime": "2037-04-02T20:12:39.038Z",
 "flightEndTime": "2037-04-03T20:12:39.038Z",
 "targeting": {
   "inventorySizeTargeting": {
     "targetedInventorySizes": [
       {
         "width": "1024",
         "height": "768",
         "type": "PIXEL"
       }
     ]
   }
 },
 "creativeRequirements": {
   "creativePreApprovalPolicy": "SELLER_PRE_APPROVAL_NOT_REQUIRED",
   "creativeSafeFrameCompatibility": "COMPATIBLE",
   "programmaticCreativeSource": "ADVERTISER",
   "creativeFormat": "DISPLAY"
 },
 "deliveryControl": {
   "deliveryRateType": "EVENLY"
 },
 "billedBuyer": "buyers/12345678",
 "dealType": "PROGRAMMATIC_GUARANTEED",
 "programmaticGuaranteedTerms": {
   "guaranteedLooks": "100",
   "fixedPrice": {
     "type": "CPM",
     "amount": {
       "currencyCode": "CNY",
       "units": "1",
       "nanos": 500000000
     }
   },
   "reservationType": "STANDARD"
 },
 "sellerTimeZone": {
   "id": "Asia/Shanghai"
 }
}

C#

/* Copyright 2022 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.
 */

using Google.Apis.AuthorizedBuyersMarketplace.v1;
using Google.Apis.AuthorizedBuyersMarketplace.v1.Data;
using Mono.Options;

using System;
using System.Collections.Generic;

namespace Google.Apis.AuthorizedBuyersMarketplace.Examples.v1.Buyers.Proposals.Deals
{
    /// <summary>
    /// Patches a programmatic guaranteed deal at the given revision number.
    ///
    /// This will modify the deal's flightStartTime, flightEndTime, and
    /// programmaticGuaranteedDealTerms.
    ///
    /// Note: If the revision number is lower than what is stored for the deal server-side, the
    /// operation will be deemed obsolete and an error will be returned.
    /// </summary>
    public class PatchProgrammaticGuaranteedDeals : ExampleBase
    {
        private AuthorizedBuyersMarketplaceService mkService;

        /// <summary>
        /// Constructor.
        /// </summary>
        public PatchProgrammaticGuaranteedDeals()
        {
            mkService = Utilities.GetAuthorizedBuyersMarketplaceService();
        }

        /// <summary>
        /// Returns a description about the code example.
        /// </summary>
        public override string Description
        {
            get => "This code example patches a programmatic guaranteed deal at the given " +
                "revision number.";
        }

        /// <summary>
        /// Parse specified arguments.
        /// </summary>
        protected override Dictionary<string, object> ParseArguments(List<string> exampleArgs) {
            string[] requiredOptions = new string[] {"account_id", "proposal_id", "deal_id",
                "proposal_revision"};
            bool showHelp = false;

            string accountId = null;
            string dealId = null;
            string proposalId = null;
            long? proposalRevision = null;
            long? fixedPriceUnits = null;
            int? fixedPriceNanos = null;
            OptionSet options = new OptionSet {
                "Patches a programmatic guaranteed deal at the given revision number.",
                {
                    "h|help",
                    "Show help message and exit.",
                    h => showHelp = h != null
                },
                {
                    "a|account_id=",
                    ("[Required] The resource ID of the buyers resource under which the deal is " +
                     "being patched. This will be used to construct the name used as a path " +
                     "parameter for the deals.patch request."),
                    a => accountId = a
                },
                {
                    "d|deal_id=",
                    ("[Required] The resource ID of the buyers.proposals.deals resource that is " +
                     "being patched. This will be used to construct the name used as a path " +
                     "parameter for the deals.patch request."),
                    d => dealId = d
                },
                {
                    "p|proposal_id=",
                    ("[Required] The resource ID of the buyers.proposals resource under which " +
                     "the deal is being patched. This will be used to construct the name used " +
                     "as a path parameter for the deals.patch request."),
                    p => proposalId = p
                },
                {
                    "r|proposal_revision=",
                    ("[Required] The revision number for the corresponding proposal of the deal " +
                     "being modified. Each update to the proposal or its deals causes the " +
                     "number to increment. The revision number specified must match the value " +
                     "stored server-side in order for the operation to be performed."),
                    (long? r) => proposalRevision = r
                },
                {
                    "u|fixed_price_units=",
                    "Whole units of the currency specified for the programmatic guaranteed deal.",
                    (long? u) => fixedPriceUnits = u
                },
                {
                    "n|fixed_price_nanos=",
                    ("Number of nano units of the currency specified for the programmatic " +
                     "guaranteed deal."),
                    (int? u) => fixedPriceNanos = u
                },
            };

            List<string> extras = options.Parse(exampleArgs);
            var parsedArgs = new Dictionary<string, object>();

            // Show help message.
            if (showHelp == true)
            {
                options.WriteOptionDescriptions(Console.Out);
                Environment.Exit(0);
            }
            // Set arguments.
            parsedArgs["account_id"] = accountId;
            parsedArgs["deal_id"] = dealId;
            parsedArgs["proposal_id"] = proposalId;
            parsedArgs["proposal_revision"] = proposalRevision;
            parsedArgs["fixed_price_units"] = fixedPriceUnits ?? 1L;
            parsedArgs["fixed_price_nanos"] = fixedPriceNanos ?? 500000000;

            // Validate that options were set correctly.
            Utilities.ValidateOptions(options, parsedArgs, requiredOptions, extras);

            return parsedArgs;
        }

        /// <summary>
        /// Run the example.
        /// </summary>
        /// <param name="parsedArgs">Parsed arguments for the example.</param>
        protected override void Run(Dictionary<string, object> parsedArgs)
        {
            string accountId = (string) parsedArgs["account_id"];
            string dealId = (string) parsedArgs["deal_id"];
            string proposalId = (string) parsedArgs["proposal_id"];
            string name = $"buyers/{accountId}/proposals/{proposalId}/deals/{dealId}";
            long? proposalRevision = (long?) parsedArgs["proposal_revision"];
            DateTime startTime = DateTime.Now.AddDays(1);

            Deal programmaticGuaranteedDeal = new Deal()
            {
                ProposalRevision = proposalRevision,
                // Patch new start and end flight times in RFC3339 UTC "Zulu" format.
                FlightStartTime = startTime.ToUniversalTime().ToString("o"),
                FlightEndTime = startTime.AddDays(1).ToUniversalTime().ToString("o"),
                ProgrammaticGuaranteedTerms = new ProgrammaticGuaranteedTerms()
                {
                    FixedPrice = new Price()
                    {
                        Amount = new Money()
                        {
                            Units = (long?) parsedArgs["fixed_price_units"],
                            Nanos = (int?) parsedArgs["fixed_price_nanos"]
                        }
                    }
                }
            };

            string updateMask = "flightStartTime,flightEndTime," +
                "programmaticGuaranteedTerms.fixedPrice.amount.units," +
                "programmaticGuaranteedTerms.fixedPrice.amount.nanos";

            BuyersResource.ProposalsResource.DealsResource.PatchRequest request =
                mkService.Buyers.Proposals.Deals.Patch(programmaticGuaranteedDeal, name);
            request.UpdateMask = updateMask;
            Deal response = null;

            Console.WriteLine("Patching deal with name: {0}", name);

            try
            {
                response = request.Execute();
            }
            catch (Exception exception)
            {
                throw new ApplicationException(
                    $"Real-time Bidding API returned error response:\n{exception.Message}");
            }

            Utilities.PrintDeal(response);
        }
    }
}

Java

/*
 * Copyright 2022 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
 *
 *    https://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.
 */

package com.google.api.services.samples.authorizedbuyers.marketplace.v1.buyers.proposals.deals;

import com.google.api.services.authorizedbuyersmarketplace.v1.AuthorizedBuyersMarketplace;
import com.google.api.services.authorizedbuyersmarketplace.v1.model.Deal;
import com.google.api.services.authorizedbuyersmarketplace.v1.model.Money;
import com.google.api.services.authorizedbuyersmarketplace.v1.model.Price;
import com.google.api.services.authorizedbuyersmarketplace.v1.model.ProgrammaticGuaranteedTerms;
import com.google.api.services.samples.authorizedbuyers.marketplace.Utils;
import java.io.IOException;
import java.security.GeneralSecurityException;
import net.sourceforge.argparse4j.ArgumentParsers;
import net.sourceforge.argparse4j.inf.ArgumentParser;
import net.sourceforge.argparse4j.inf.ArgumentParserException;
import net.sourceforge.argparse4j.inf.Namespace;
import org.joda.time.DateTime;
import org.joda.time.format.ISODateTimeFormat;

/**
 * Patches a programmatic guaranteed deal at the given revision number.
 *
 * <p>This will modify the deal's flightStartTime, flightEndTime, and programmaticGuaranteedTerms.
 *
 * <p>Note: If the revision number is lower than what is stored for the deal server-side, the
 * operation will be deemed obsolete and an error will be returned.
 */
public class PatchProgrammaticGuaranteedDeals {

  public static void execute(AuthorizedBuyersMarketplace marketplaceClient, Namespace parsedArgs) {
    Long accountId = parsedArgs.getLong("account_id");
    String proposalId = parsedArgs.getString("proposal_id");
    Long dealId = parsedArgs.getLong("deal_id");
    String name = String.format("buyers/%d/proposals/%s/deals/%d", accountId, proposalId, dealId);
    Long proposalRevision = parsedArgs.getLong("proposal_revision");

    Deal patchedProgrammaticGuaranteedDeal = new Deal();
    patchedProgrammaticGuaranteedDeal.setProposalRevision(proposalRevision);

    // Patch new start and end flight times in RFC3339 UTC "Zulu" format.
    DateTime startTime = DateTime.now().plusDays(1);
    DateTime endTime = startTime.plusDays(1);
    patchedProgrammaticGuaranteedDeal.setFlightStartTime(
        startTime.toString(ISODateTimeFormat.dateTime()));
    patchedProgrammaticGuaranteedDeal.setFlightEndTime(
        endTime.toString(ISODateTimeFormat.dateTime()));

    Money fixedPriceAmount = new Money();
    fixedPriceAmount.setUnits(parsedArgs.getLong("fixed_price_units"));
    fixedPriceAmount.setNanos(parsedArgs.getInt("fixed_price_nanos"));

    Price fixedPrice = new Price();
    fixedPrice.setAmount(fixedPriceAmount);

    ProgrammaticGuaranteedTerms programmaticGuaranteedTerms = new ProgrammaticGuaranteedTerms();
    programmaticGuaranteedTerms.setFixedPrice(fixedPrice);
    patchedProgrammaticGuaranteedDeal.setProgrammaticGuaranteedTerms(programmaticGuaranteedTerms);

    String updateMask =
        "flightStartTime,flightEndTime,"
            + "programmaticGuaranteedTerms.fixedPrice.amount.units,"
            + "programmaticGuaranteedTerms.fixedPrice.amount.nanos";

    Deal deal = null;
    try {
      deal =
          marketplaceClient
              .buyers()
              .proposals()
              .deals()
              .patch(name, patchedProgrammaticGuaranteedDeal)
              .setUpdateMask(updateMask)
              .execute();
    } catch (IOException ex) {
      System.out.printf("Marketplace API returned error response:%n%s", ex);
      System.exit(1);
    }

    System.out.printf("Patching deal with name \"%s\":%n", name);
    Utils.printDeal(deal);
  }

  public static void main(String[] args) {
    ArgumentParser parser =
        ArgumentParsers.newFor("PatchProgrammaticGuaranteedDeals")
            .build()
            .defaultHelp(true)
            .description(("Patches a programmatic guaranteed deal at the given revision number."));
    parser
        .addArgument("-a", "--account_id")
        .help(
            "The resource ID of the buyers resource under which the deal is being patched. "
                + "This will be used to construct the name used as a path parameter for the "
                + "deals.patch request.")
        .required(true)
        .type(Long.class);
    parser
        .addArgument("-d", "--deal_id")
        .help(
            "The resource ID of the buyers.proposals.deals resource that is being patched. "
                + "This will be used to construct the name used as a path parameter for the "
                + "deals.patch request.")
        .required(true)
        .type(Long.class);
    parser
        .addArgument("-p", "--proposal_id")
        .help(
            "The resource ID of the buyers.proposals resource under which the deal is being"
                + " patched. This will be used to construct the name used as a path parameter for"
                + " the deals.patch request.")
        .required(true)
        .type(String.class);
    parser
        .addArgument("-r", "--proposal_revision")
        .help(
            "The revision number for the proposal being modified. Each update to the proposal "
                + "or its deals causes the number to increment. The revision number specified must "
                + "match the value stored server-side in order for the operation to be performed.")
        .required(true)
        .type(Long.class);
    parser
        .addArgument("-u", "--fixed_price_units")
        .help("Whole units of the currency specified for the programmatic guaranteed deal.")
        .type(Long.class)
        .setDefault(1L);
    parser
        .addArgument("-n", "--fixed_price_nanos")
        .help(
            "Number of nano units of the currency specified for the programmatic guaranteed "
                + "deal.")
        .type(Integer.class)
        .setDefault(500000000);

    Namespace parsedArgs = null;
    try {
      parsedArgs = parser.parseArgs(args);
    } catch (ArgumentParserException ex) {
      parser.handleError(ex);
      System.exit(1);
    }

    AuthorizedBuyersMarketplace client = null;
    try {
      client = Utils.getMarketplaceClient();
    } catch (IOException ex) {
      System.out.printf("Unable to create Marketplace API service:%n%s", ex);
      System.out.println("Did you specify a valid path to a service account key file?");
      System.exit(1);
    } catch (GeneralSecurityException ex) {
      System.out.printf("Unable to establish secure HttpTransport:%n%s", ex);
      System.exit(1);
    }

    execute(client, parsedArgs);
  }
}

Python

#!/usr/bin/python
#
# Copyright 2021 Google Inc. All Rights Reserved.
#
# 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.

"""Patches a programmatic guaranteed deal at the given revision number.

This will modify the deal's flightStartTime, flightEndTime, and
programmaticGuaranteedDealTerms.

Note: if the revision number is lower than what is stored for the proposal
server-side, the operation will be deemed obsolete and an error will be
returned. The revision number can be found at the proposal level.
"""


import argparse
import datetime
import os
import pprint
import sys

sys.path.insert(0, os.path.abspath('../../../..'))

from googleapiclient.errors import HttpError

import util


_DEALS_NAME_TEMPLATE = 'buyers/%s/proposals/%s/deals/%s'

DEFAULT_BUYER_RESOURCE_ID = 'ENTER_BUYER_RESOURCE_ID_HERE'
DEFAULT_PROPOSAL_RESOURCE_ID = 'ENTER_PROPOSAL_RESOURCE_ID_HERE'
DEFAULT_DEAL_RESOURCE_ID = 'ENTER_DEAL_RESOURCE_ID_HERE'


def main(marketplace, args):
    deal_name = _DEALS_NAME_TEMPLATE % (
        args.account_id, args.proposal_id, args.deal_id)

    flight_start_time = (datetime.datetime.now(datetime.timezone.utc) +
                         datetime.timedelta(days=2))
    flight_end_time = flight_start_time + datetime.timedelta(days=1)

    body = {
        'proposalRevision': args.proposal_revision,
        'flightStartTime': flight_start_time.isoformat(),
        'flightEndTime': flight_end_time.isoformat(),
        'programmaticGuaranteedTerms': {
            'fixedPrice': {
                'amount': {
                    'units': args.fixed_price_units,
                    'nanos': args.fixed_price_nanos
                }
            }
        }
    }

    update_mask = ('flightStartTime,flightEndTime,'
                   'programmaticGuaranteedTerms.fixedPrice.amount.units,'
                   'programmaticGuaranteedTerms.fixedPrice.amount.nanos')

    print(f'Patching programmatic guaranteed deal with name "{deal_name}":')
    try:
        # Construct and execute the request.
        response = marketplace.buyers().proposals().deals().patch(
            name=deal_name, body=body, updateMask=update_mask).execute()
    except HttpError as e:
        print(e)
        sys.exit(1)

    pprint.pprint(response)


if __name__ == '__main__':
    try:
        service = util.get_service(version='v1')
    except IOError as ex:
        print(f'Unable to create marketplace service - {ex}')
        print('Did you specify the key file in util.py?')
        sys.exit(1)

    parser = argparse.ArgumentParser(
        description=('Patch a programmatic guaranteed deal at the given '
                     'revision number.'))
    # Required fields.
    parser.add_argument(
        '-a', '--account_id', default=DEFAULT_BUYER_RESOURCE_ID,
        help=('The resource ID of the buyers resource under which the parent '
              'proposal was created. This will be used to construct the '
              'name used as a path parameter for the deals.patch request.'))
    parser.add_argument(
        '-p', '--proposal_id', default=DEFAULT_PROPOSAL_RESOURCE_ID,
        help=('The resource ID of the buyers.proposals resource for which the '
              'deal was created. This will be used to construct the '
              'name used as a path parameter for the deals.patch request.'))
    parser.add_argument(
        '-d', '--deal_id', default=DEFAULT_DEAL_RESOURCE_ID,
        help=('The resource ID of the buyers.proposals.deals resource that is '
              'being patched. This will be used to construct the name used as '
              'a path parameter for the deals.patch request.'))
    parser.add_argument(
        '-r', '--proposal_revision', required=True,
        help=('The revision number for the proposal associated with the deal '
              'being modified. Each update to the proposal or its deals causes '
              'the number to increment. The revision number specified must '
              'match the value stored server-side in order for the operation '
              'to be performed.'))
    # Optional fields.
    parser.add_argument(
        '-u', '--fixed_price_units', default=1,
        help=('Whole units of the currency specified for the programmatic '
              'guaranteed deal.'))
    parser.add_argument(
        '-n', '--fixed_price_nanos', default=500000000,
        help=('Number of nano units of the currency specified for the '
              'programmatic guaranteed deal.'))
    main(service, parser.parse_args())

일괄 업데이트 거래

buyers.proposals.deals.batchUpdate 드림 구매자를 위해 제안서와 관련된 하나 이상의 거래를 업데이트하는 방법 연결할 수 있습니다.

예를 들어 포함된 여러 거래를 업데이트하여 재협상을 시작할 수 있습니다. 제안서에 포함할 수 있습니다.

batchUpdate 메서드의 본문에 포함된 거래가 동일해야 합니다. 상위 제안서에서 찾을 수 있습니다.

다음 샘플은 batchUpdate 메서드를 사용하여 제안서의 거래를 처리할 수 있습니다.

REST

요청

POST https://authorizedbuyersmarketplace.googleapis.com/v1/buyers/12345678/proposals/MP21673270/deals:batchUpdate?alt=json
Authorization: Bearer ACCESS_TOKEN
Content-Type: application/json

{
 "requests": [
   {
     "deal": {
       "name": "buyers/12345678/proposals/MP21673270/deals/52404",
       "proposalRevision": "6",
       "targeting": {
         "userListTargeting": {
           "targetedCriteriaIds": [
             "111111"
           ]
         }
       }
     },
     "updateMask": "targeting.userListTargeting.targetedCriteriaIds"
   }
 ]
}

응답

{
 "deals": [
   {
     "name": "buyers/12345678/proposals/MP21673270/deals/52404",
     "createTime": "2036-12-27T04:02:39.731Z",
     "updateTime": "2037-03-31T20:33:04.773Z",
     "proposalRevision": "7",
     "displayName": "test_deal_7435251",
     "buyer": "buyers/12345678",
     "publisherProfile": "buyers/12345678/publisherProfiles/PP54321",
     "flightStartTime": "2037-04-02T20:12:39.038Z",
     "flightEndTime": "2037-04-03T20:12:39.038Z",
     "targeting": {
       "inventorySizeTargeting": {
         "targetedInventorySizes": [
           {
             "width": "1024",
             "height": "768",
             "type": "PIXEL"
           }
         ]
       },
        "userListTargeting": {
         "targetedCriteriaIds": [
           "111111"
         ]
       }
     },
     "creativeRequirements": {
       "creativePreApprovalPolicy": "SELLER_PRE_APPROVAL_NOT_REQUIRED",
       "creativeSafeFrameCompatibility": "COMPATIBLE",
       "programmaticCreativeSource": "ADVERTISER",
       "creativeFormat": "DISPLAY"
     },
     "deliveryControl": {
         "deliveryRateType": "EVENLY"
     },
     "billedBuyer": "buyers/12345678",
     "dealType": "PROGRAMMATIC_GUARANTEED",
     "programmaticGuaranteedTerms": {
       "guaranteedLooks": "100",
       "fixedPrice": {
         "type": "CPM",
         "amount": {
           "currencyCode": "CNY",
           "units": "1",
           "nanos": 500000000
         }
       },
       "reservationType": "STANDARD"
     },
     "sellerTimeZone": {
       "id": "Asia/Shanghai"
     }
   }
 ]
}

C#

/* Copyright 2022 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.
 */

using Google.Apis.AuthorizedBuyersMarketplace.v1;
using Google.Apis.AuthorizedBuyersMarketplace.v1.Data;
using Mono.Options;

using System;
using System.Collections.Generic;

namespace Google.Apis.AuthorizedBuyersMarketplace.Examples.v1.Buyers.Proposals.Deals
{
    /// <summary>
    /// Patches the user list targeting of one or more deals for the given buyer's proposal.
    ///
    /// This operation requires that the deals all exist under the same proposal.
    ///
    /// The user list targeting of the given deals will be modified to target the specified
    /// user lists. User lists can be retrieved via the Real-time Bidding API's
    /// buyers.userLists resource. You can learn more about buyers.userLists in the reference
    /// documentation:
    /// https://developers.google.com/authorized-buyers/apis/realtimebidding/reference/rest/v1/buyers.userLists
    ///
    /// Note: Only preferred and programmatic guaranteed deals can be modified by the buyer;
    /// attempting to modify a private auction deal will result in an error response.
    /// </summary>
    public class BatchUpdateDeals : ExampleBase
    {
        private AuthorizedBuyersMarketplaceService mkService;

        /// <summary>
        /// Constructor.
        /// </summary>
        public BatchUpdateDeals()
        {
            mkService = Utilities.GetAuthorizedBuyersMarketplaceService();
        }

        /// <summary>
        /// Returns a description about the code example.
        /// </summary>
        public override string Description
        {
            get => "This code example patches the user list targeting of one or more deals for " +
                "the given buyer's proposal.";
        }

        /// <summary>
        /// Parse specified arguments.
        /// </summary>
        protected override Dictionary<string, object> ParseArguments(List<string> exampleArgs) {
            string[] requiredOptions = new string[] {"account_id", "proposal_id", "deal_ids",
                "proposal_revision", "user_list_ids"};
            bool showHelp = false;

            string accountId = null;
            IList<string> dealIds = new List<string>();
            string proposalId = null;
            long? proposalRevision = null;
            IList<long?> userListIds = new List<long?>();

            OptionSet options = new OptionSet {
                "Patches the user list targeting of one or more deals for the given buyer's " +
                "proposal.",
                {
                    "h|help",
                    "Show help message and exit.",
                    h => showHelp = h != null
                },
                {
                    "a|account_id=",
                    ("[Required] The resource ID of the buyers resource under which one or more " +
                     "deals are being patched. This will be used to construct the proposal " +
                     "name used as a path parameter for the deals.batchUpdate request, and each " +
                     "deal name included in the request body."),
                    a => accountId = a
                },
                {
                    "d|deal_id=",
                    ("[Required] The resource ID of one or more buyers.proposals.deals " +
                     "resources that will be patch in a batch update operation. These will be " +
                     "used to construct the deal names included in the request body. Specify " +
                     "this argument for each deal you intend to patch with this example."),
                    d => dealIds.Add(d)
                },
                {
                    "p|proposal_id=",
                    ("[Required] The resource ID of the buyers.proposals resource under which " +
                     "one or more deals are being patched. This will be used to construct the " +
                     "name used as a path parameter for the deals.batchUpdate request, and each " +
                     "deal name included in the request body."),
                    p => proposalId = p
                },
                {
                    "r|proposal_revision=",
                    ("[Required] The revision number for the corresponding proposal of the " +
                     "deals being modified. Each update to the proposal or its deals causes the " +
                     "number to increment. The revision number specified must match the value " +
                     "stored server-side in order for the operation to be performed."),
                    (long? r) => proposalRevision = r
                },
                {
                    "u|user_list_id=",
                    ("[Required] The resource ID of one or more buyers.userLists resources that " +
                     "are to be targeted by the given deals. Specify this argument for each " +
                     "user list you intend to target."),
                    (long? u) => userListIds.Add(u)
                },
            };

            List<string> extras = options.Parse(exampleArgs);
            var parsedArgs = new Dictionary<string, object>();

            // Show help message.
            if (showHelp == true)
            {
                options.WriteOptionDescriptions(Console.Out);
                Environment.Exit(0);
            }
            // Set arguments.
            parsedArgs["account_id"] = accountId;
            parsedArgs["deal_ids"] = dealIds;
            parsedArgs["proposal_id"] = proposalId;
            parsedArgs["proposal_revision"] = proposalRevision;
            parsedArgs["user_list_ids"] = userListIds.Count > 0 ? userListIds : null;

            // Validate that options were set correctly.
            Utilities.ValidateOptions(options, parsedArgs, requiredOptions, extras);

            return parsedArgs;
        }

        /// <summary>
        /// Run the example.
        /// </summary>
        /// <param name="parsedArgs">Parsed arguments for the example.</param>
        protected override void Run(Dictionary<string, object> parsedArgs)
        {
            string accountId = (string) parsedArgs["account_id"];
            IList<string> dealIds = (List<string>) parsedArgs["deal_ids"];
            string proposalId = (string) parsedArgs["proposal_id"];
            string parent = $"buyers/{accountId}/proposals/{proposalId}";
            long? proposalRevision = (long?) parsedArgs["proposal_revision"];
            IList<long?> userListIds = (List<long?>) parsedArgs["user_list_ids"];

            IList<UpdateDealRequest> updateDealRequests = new List<UpdateDealRequest>();

            // Populate the request body based on the deals specified.
            foreach (string dealId in dealIds)
            {
                UpdateDealRequest updateDealRequest = new UpdateDealRequest()
                {
                    Deal = new Deal()
                    {
                        Name = $"buyers/{accountId}/proposals/{proposalId}/deals/{dealId}",
                        ProposalRevision = proposalRevision,
                        Targeting = new MarketplaceTargeting()
                        {
                            UserListTargeting = new CriteriaTargeting()
                            {
                                TargetedCriteriaIds = userListIds
                            }
                        }
                    },
                    UpdateMask = "targeting.userListTargeting.targetedCriteriaIds"
                };

                updateDealRequests.Add(updateDealRequest);
            }

            BatchUpdateDealsRequest batchUpdateDealsRequest = new BatchUpdateDealsRequest()
            {
                Requests = updateDealRequests
            };

            BuyersResource.ProposalsResource.DealsResource.BatchUpdateRequest request =
                mkService.Buyers.Proposals.Deals.BatchUpdate(batchUpdateDealsRequest, parent);
            BatchUpdateDealsResponse response = null;

            Console.WriteLine("Batch updating deals for proposal with name: {0}", parent);

            try
            {
                response = request.Execute();
            }
            catch (Exception exception)
            {
                throw new ApplicationException(
                    $"Real-time Bidding API returned error response:\n{exception.Message}");
            }

            foreach (Deal deal in response.Deals)
            {
                Utilities.PrintDeal(deal);
            }
        }
    }
}

Java

/*
 * Copyright 2022 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
 *
 *    https://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.
 */

package com.google.api.services.samples.authorizedbuyers.marketplace.v1.buyers.proposals.deals;

import com.google.api.services.authorizedbuyersmarketplace.v1.AuthorizedBuyersMarketplace;
import com.google.api.services.authorizedbuyersmarketplace.v1.model.BatchUpdateDealsRequest;
import com.google.api.services.authorizedbuyersmarketplace.v1.model.BatchUpdateDealsResponse;
import com.google.api.services.authorizedbuyersmarketplace.v1.model.CriteriaTargeting;
import com.google.api.services.authorizedbuyersmarketplace.v1.model.Deal;
import com.google.api.services.authorizedbuyersmarketplace.v1.model.MarketplaceTargeting;
import com.google.api.services.authorizedbuyersmarketplace.v1.model.UpdateDealRequest;
import com.google.api.services.samples.authorizedbuyers.marketplace.Utils;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.List;
import net.sourceforge.argparse4j.ArgumentParsers;
import net.sourceforge.argparse4j.inf.ArgumentParser;
import net.sourceforge.argparse4j.inf.ArgumentParserException;
import net.sourceforge.argparse4j.inf.Namespace;

/**
 * Patches the user list targeting of one or more deals for the given buyer's proposal.
 *
 * <p>This operation requires that the deals all exist under the same proposal.
 *
 * <p>The user list targeting of the given deals will be modified to target the specified user
 * lists. User lists can be retrieved via the Real-time Bidding API's buyers.userLists resource. You
 * can learn more about buyers.userLists in the reference documentation:
 * https://developers.google.com/authorized-buyers/apis/realtimebidding/reference/rest/v1/buyers.userLists
 *
 * <p>Note: Only preferred and programmatic guaranteed deals can be modified by the buyer;
 * attempting to modify a private auction deal will result in an error response.
 */
public class BatchUpdateDeals {

  public static void execute(AuthorizedBuyersMarketplace marketplaceClient, Namespace parsedArgs) {
    Long accountId = parsedArgs.getLong("account_id");
    List<Long> dealIds = parsedArgs.getList("deal_ids");
    String proposalId = parsedArgs.getString("proposal_id");
    String parent = String.format("buyers/%d/proposals/%s", accountId, proposalId);
    Long proposalRevision = parsedArgs.getLong("proposal_revision");
    List<Long> userListIds = parsedArgs.getList("user_list_ids");

    List<UpdateDealRequest> updateDealRequests = new ArrayList<>();

    // Populate the request body based on the deals specified.
    for (Long dealId : dealIds) {
      Deal deal = new Deal();
      deal.setName(String.format("buyers/%d/proposals/%s/deals/%d", accountId, proposalId, dealId));
      deal.setProposalRevision(proposalRevision);

      CriteriaTargeting userListTargeting = new CriteriaTargeting();
      userListTargeting.setTargetedCriteriaIds(userListIds);

      MarketplaceTargeting marketplaceTargeting = new MarketplaceTargeting();
      marketplaceTargeting.setUserListTargeting(userListTargeting);
      deal.setTargeting(marketplaceTargeting);

      UpdateDealRequest updateDealRequest = new UpdateDealRequest();
      updateDealRequest.setDeal(deal);
      updateDealRequest.setUpdateMask("targeting.userListTargeting.targetedCriteriaIds");

      updateDealRequests.add(updateDealRequest);
    }

    BatchUpdateDealsRequest batchUpdateDealsRequest = new BatchUpdateDealsRequest();
    batchUpdateDealsRequest.setRequests(updateDealRequests);

    BatchUpdateDealsResponse response = null;
    try {
      response =
          marketplaceClient
              .buyers()
              .proposals()
              .deals()
              .batchUpdate(parent, batchUpdateDealsRequest)
              .execute();
    } catch (IOException ex) {
      System.out.printf("Marketplace API returned error response:%n%s", ex);
      System.exit(1);
    }

    System.out.printf("Batch updating deals for proposal with name \"%s\":%n", parent);

    for (Deal deal : response.getDeals()) {
      Utils.printDeal(deal);
    }
  }

  public static void main(String[] args) {
    ArgumentParser parser =
        ArgumentParsers.newFor("BatchUpdateDeals")
            .build()
            .defaultHelp(true)
            .description(
                ("Patches the user list targeting of one or more deals for the given "
                    + "buyer's proposal."));
    parser
        .addArgument("-a", "--account_id")
        .help(
            "The resource ID of the buyers resource under which one or more deals are being"
                + " patched. This will be used to construct the proposal name used as a path"
                + " parameter for the deals.batchUpdate request, and each deal name included in the"
                + " request body.")
        .required(true)
        .type(Long.class);
    parser
        .addArgument("-d", "--deal_ids")
        .help(
            "The resource ID of one or more buyers.proposals.deals resources that will be patched"
                + " in a batch update operation. These will be used to construct the deal names"
                + " included in the request body. Specify each client ID separated by a space.")
        .required(true)
        .type(Long.class)
        .nargs("+");
    parser
        .addArgument("-p", "--proposal_id")
        .help(
            "The resource ID of the buyers.proposals resource under which one or more deals is"
                + " being patched. This will be used to construct the name used as a path parameter"
                + " for the deals.batchUpdate request, and each deal name included in the request"
                + " body")
        .required(true);
    parser
        .addArgument("-r", "--proposal_revision")
        .help(
            "The revision number for the corresponding proposal of the deals being modified. Each"
                + " update to the proposal or its deals causes the number to increment. The"
                + " revision number specified must match the value stored server-side in order for"
                + " the operation to be performed.")
        .required(true)
        .type(Long.class);
    parser
        .addArgument("-u", "--user_list_ids")
        .help(
            "The resource ID of one or more buyers.userLists resources that are to be targeted "
                + "by the given deals. Specify each client ID separated by a space.")
        .required(true)
        .type(Long.class)
        .nargs("+");

    Namespace parsedArgs = null;
    try {
      parsedArgs = parser.parseArgs(args);
    } catch (ArgumentParserException ex) {
      parser.handleError(ex);
      System.exit(1);
    }

    AuthorizedBuyersMarketplace client = null;
    try {
      client = Utils.getMarketplaceClient();
    } catch (IOException ex) {
      System.out.printf("Unable to create Marketplace API service:%n%s", ex);
      System.out.println("Did you specify a valid path to a service account key file?");
      System.exit(1);
    } catch (GeneralSecurityException ex) {
      System.out.printf("Unable to establish secure HttpTransport:%n%s", ex);
      System.exit(1);
    }

    execute(client, parsedArgs);
  }
}

Python

#!/usr/bin/python
#
# Copyright 2021 Google Inc. All Rights Reserved.
#
# 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.

"""Patch the user list targeting of one or more deals for the given proposal.

This operation requires that the deals all exist under the same proposal.

The user list targeting of the given deals will be modified to target the
specified user lists. User lists can be retrieved via the Real-time Bidding
API's buyers.userLists resource. You can learn more about buyers.userLists in
the reference documentation:
https://developers.google.com/authorized-buyers/apis/realtimebidding/reference/rest/v1/buyers.userLists

Note: Only preferred and programmatic guaranteed deals an be modified by the
buyer; attempting to modify a private auction deal will result in an error
response.
"""


import argparse
import os
import pprint
import sys

sys.path.insert(0, os.path.abspath('../../../..'))

from googleapiclient.errors import HttpError

import util


_PROPOSALS_NAME_TEMPLATE = 'buyers/%s/proposals/%s'
_DEALS_NAME_TEMPLATE = 'buyers/%s/proposals/%s/deals/%s'


DEFAULT_BUYER_RESOURCE_ID = 'ENTER_BUYER_RESOURCE_ID_HERE'
DEFAULT_PROPOSAL_RESOURCE_ID = 'ENTER_PROPOSAL_RESOURCE_ID_HERE'


def main(marketplace, args):
    account_id = args.account_id
    proposal_id = args.proposal_id
    proposal_name = _PROPOSALS_NAME_TEMPLATE % (account_id, proposal_id)

    # This will create a update deal request for each given deal for the
    # specified proposal revision. Each request will patch userListTargeting
    # for the deal such that the given user list IDs are targeted.
    body = {
        'requests': [{
            'deal': {
                'name': _DEALS_NAME_TEMPLATE % (
                    account_id, proposal_id, deal_id),
                'proposalRevision': args.proposal_revision,
                'targeting': {
                    'userListTargeting': {
                        'targetedCriteriaIds': [
                            user_list_id for user_list_id in args.user_list_ids]
                    }
                },
            },
            'updateMask': 'targeting.userListTargeting.targetedCriteriaIds'
        } for deal_id in args.deal_ids],
    }

    print(f'Batch updating deals for proposal "{proposal_name}":')
    try:
        # Construct and execute the request.
        response = marketplace.buyers().proposals().deals().batchUpdate(
            parent=proposal_name, body=body).execute()
    except HttpError as e:
        print(e)
        sys.exit(1)

    pprint.pprint(response)


if __name__ == '__main__':
    try:
        service = util.get_service(version='v1')
    except IOError as ex:
        print(f'Unable to create marketplace service - {ex}')
        print('Did you specify the key file in util.py?')
        sys.exit(1)

    parser = argparse.ArgumentParser(
        description=('Batch update user list targeting for multiple deals '
                     'associated with a given buyer\'s proposal.'))
    # Required fields.
    parser.add_argument(
        '-a', '--account_id', default=DEFAULT_BUYER_RESOURCE_ID,
        help=('The resource ID of the buyers resource under which the '
              'proposal was created. This will be used to construct the '
              'name used as a path parameter for the deals.batchUpdate '
              'request.'))
    parser.add_argument(
        '-p', '--proposal_id', default=DEFAULT_PROPOSAL_RESOURCE_ID,
        help=('The resource ID of the buyers.proposals resource under which '
              'one or more deals were created. This will be used to construct '
              'the name used as a path parameter for the deals.batchUpdate '
              'request.'))
    parser.add_argument(
        '-d', '--deal_ids', required=True, nargs='+',
        help=('One or more resource IDs for the buyers.proposals.deals '
              'resource that will be patched in a batch update operation. This '
              'will be used to construct the deal name that is included in the '
              'update request for each deal in the deals.batchUpdate request.'))
    parser.add_argument(
        '-r', '--proposal_revision', required=True,
        help=('The revision number for the proposal associated with the deals '
              'being modified. Each update to the proposal or its deals causes '
              'the number to increment. The revision number specified must '
              'match the value stored server-side in order for the operation '
              'to be performed.'))
    parser.add_argument(
        '-u', '--user_list_ids', nargs='+',
        help=('One or more resource IDs for the buyers.userLists resources '
              'that are to be targeted by the given deals. Specify each user '
              'list ID separated by a space.'))

    main(service, parser.parse_args())