제안서 보내기

구매자는 다음 거래 유형에 대한 제안 요청서 (RFP)를 보내 협상을 시작할 수 있습니다.

게시자만 비공개 입찰 거래를 시작할 수 있습니다.

buyers.proposals.sendRfp 메서드를 사용하여 게시자에게 RFP를 보낼 수 있습니다.

RFP를 보내려면 게시자를 PublisherProfile로 참조해야 합니다.

요청 본문에서 거래 유형을 preferredDealTerms 또는 programmaticGuaranteedTerms로 지정해야 합니다. 이러한 거래 유형에는 flightStartTimeflightEndTime 필드가 필요합니다.

게시자에게 RFP를 보내면 Proposal가 생성되고 게시자와 협상이 시작됩니다.

다음 샘플은 sendRfp 메서드를 사용하여 게시자에게 RFP를 전송하는 방법을 보여줍니다.

REST

요청

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

{
 "displayName": "Test PG Proposal #0ce643e9-5518-4e8e-b352-0cb45cc2eeb2",
 "publisherProfile": "buyers/12345678/publisherProfiles/PP111111",
 "buyerContacts": {
   "email": "testemail89319783@test.com",
   "displayName": "Joe"
 },
 "note": "Test programmatic guaranteed deal proposal.",
 "geoTargeting": {
   "targetedCriteriaIds": [
     "1023191"
   ]
 },
 "inventorySizeTargeting": {
   "targetedInventorySizes": [
     {
       "width": "300",
       "height": "260",
       "type": "PIXEL"
     }
   ]
 },
  "programmaticGuaranteedTerms": {
   "guaranteedLooks": 0,
   "fixedPrice": {
     "type": "CPM",
     "amount": {
       "currencyCode": "USD",
       "units": "1",
       "nanos": "500000"
     }
   },
   "minimumDailyLooks": 10000,
   "reservationType": "STANDARD",
   "impressionCap": 500000,
   "percentShareOfVoice": 40
 },
 "flightStartTime": "2022-03-27T04:03:18.939985+00:00",
 "flightEndTime": "2022-03-28T04:03:18.939985+00:00"
}

응답

{
 "name": "buyers/12345678/proposals/MP49876074",
 "updateTime": "2022-03-26T04:03:19.282Z",
 "proposalRevision": "1",
 "dealType": "PROGRAMMATIC_GUARANTEED",
 "displayName": "Test PG Proposal #0ce643e9-5518-4e8e-b352-0cb45cc2eeb2",
 "state": "SELLER_REVIEW_REQUESTED",
 "originatorRole": "BUYER",
 "publisherProfile": "buyers/12345678/publisherProfiles/PP111111",
 "buyer": "buyers/12345678",
 "billedBuyer": "buyers/12345678",
 "sellerContacts": [
   {
     "email": "jeff@hypersonicmedia.com"
   },
   {
     "email": "alex@hypersonicmedia.com"
   },
 ],
 "buyerContacts": [
   {
     "email": "testemail89319783@test.com",
     "displayName": "Joe"
   }
 ],
 "lastUpdaterOrCommentorRole": "BUYER",
  "notes": [
   {
     "createTime": "2022-03-26T04:03:19.548Z",
     "creatorRole": "BUYER",
     "note": "Test programmatic guaranteed deal proposal."
   }
 ]
}

자바

/*
 * 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;

import com.google.api.services.authorizedbuyersmarketplace.v1.AuthorizedBuyersMarketplace;
import com.google.api.services.authorizedbuyersmarketplace.v1.model.AdSize;
import com.google.api.services.authorizedbuyersmarketplace.v1.model.Contact;
import com.google.api.services.authorizedbuyersmarketplace.v1.model.CriteriaTargeting;
import com.google.api.services.authorizedbuyersmarketplace.v1.model.InventorySizeTargeting;
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.authorizedbuyersmarketplace.v1.model.Proposal;
import com.google.api.services.authorizedbuyersmarketplace.v1.model.SendRfpRequest;
import com.google.api.services.samples.authorizedbuyers.marketplace.v1.Utils;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
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;

/**
 * Sends a request for proposal to a publisher for a programmatic guaranteed deal.
 *
 * <p>The publisher will be sent an RFP that will initiate negotiation for a programmatic guaranteed
 * deal. For the buyer, this will create a corresponding proposal.
 *
 * <p>You must refer to the publisher using their publisher profile. These can be found with the
 * buyers.publisherProfiles resource.
 */
public class SendRfpForProgrammaticGuaranteedDealProposals {

  public static void execute(AuthorizedBuyersMarketplace marketplaceClient, Namespace parsedArgs) {
    Long accountId = parsedArgs.getLong("account_id");
    String publisherProfileId = parsedArgs.getString(("publisher_profile_id"));
    String parent = String.format("buyers/%d", accountId);
    String publisherProfileName =
        String.format("buyers/%d/publisherProfiles/%s", accountId, publisherProfileId);

    SendRfpRequest rfp = new SendRfpRequest();
    rfp.setDisplayName(parsedArgs.getString("display_name"));
    rfp.setPublisherProfile(publisherProfileName);
    rfp.setNote("Test preferred deal proposal created by Java sample.");
    // Specify the start and end flight times in RFC3339 UTC "Zulu" format.
    DateTime startTime = DateTime.now().plusDays(1);
    DateTime endTime = startTime.plusDays(1);
    rfp.setFlightStartTime(startTime.toString(ISODateTimeFormat.dateTime()));
    rfp.setFlightEndTime(endTime.toString(ISODateTimeFormat.dateTime()));

    Contact buyerContact = new Contact();
    buyerContact.setEmail(parsedArgs.getString("buyer_contacts_email"));
    buyerContact.setDisplayName((parsedArgs.getString("buyer_contacts_display_name")));
    List<Contact> buyerContacts = new ArrayList<>();
    buyerContacts.add(buyerContact);
    rfp.setBuyerContacts(buyerContacts);

    CriteriaTargeting geoTargeting = new CriteriaTargeting();
    List<Long> targetedCriteriaIds = new ArrayList<>();
    // Target New York, NY
    targetedCriteriaIds.add(1023191L);
    geoTargeting.setTargetedCriteriaIds(targetedCriteriaIds);
    rfp.setGeoTargeting(geoTargeting);

    AdSize adSize = new AdSize();
    adSize.setWidth(300L);
    adSize.setHeight(260L);
    adSize.setType("PIXEL");
    List<AdSize> targetedInventorySizes = new ArrayList<>();
    targetedInventorySizes.add(adSize);
    InventorySizeTargeting inventorySizeTargeting = new InventorySizeTargeting();
    inventorySizeTargeting.setTargetedInventorySizes(targetedInventorySizes);
    rfp.setInventorySizeTargeting(inventorySizeTargeting);

    Money fixedPriceAmount = new Money();
    fixedPriceAmount.setCurrencyCode("USD");
    fixedPriceAmount.setUnits(1L);
    fixedPriceAmount.setNanos(0);

    Price fixedPrice = new Price();
    fixedPrice.setType("CPM");
    fixedPrice.setAmount(fixedPriceAmount);

    ProgrammaticGuaranteedTerms programmaticGuaranteedTerms = new ProgrammaticGuaranteedTerms();
    programmaticGuaranteedTerms.setGuaranteedLooks(0L);
    programmaticGuaranteedTerms.setMinimumDailyLooks(0L);
    programmaticGuaranteedTerms.setReservationType("STANDARD");
    programmaticGuaranteedTerms.setImpressionCap(0L);
    programmaticGuaranteedTerms.setPercentShareOfVoice(0L);
    programmaticGuaranteedTerms.setFixedPrice(fixedPrice);
    rfp.setProgrammaticGuaranteedTerms(programmaticGuaranteedTerms);

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

    System.out.printf(
        "Sending programmatic guaranteed deal RFP for buyer Account ID '%d':%n", accountId);
    Utils.printProposal(proposal);
  }

  public static void main(String[] args) {
    ArgumentParser parser =
        ArgumentParsers.newFor("SendRfpForProgrammaticGuaranteedDealProposals")
            .build()
            .defaultHelp(true)
            .description(
                ("Sends a request for proposal for a programmatic guaranteed deal to a "
                    + "publisher for the given buyer account ID."));
    parser
        .addArgument("-a", "--account_id")
        .help(
            "The resource ID of the buyers resource for which the RFP is being sent to the"
                + " publisher. This will be used to construct the name used as a path parameter for"
                + " the proposals.sendRfp request.")
        .required(true)
        .type(Long.class);
    parser
        .addArgument("-d", "--buyer_contacts_display_name")
        .help("The display name of the buyer's contact, which will be visible to the publisher.")
        .required(true)
        .type(String.class);
    parser
        .addArgument("-e", "--buyer_contacts_email")
        .help("Email address for the buyer's contact, which will be visible to the publisher.")
        .required(true)
        .type(String.class);
    parser
        .addArgument("-p", "--publisher_profile_id")
        .help(
            "The resource ID of the publisher profiles resource representing the publisher "
                + "that the buyer wants to send the RFP.")
        .required(true)
        .type(String.class);
    parser
        .addArgument("-n", "--display_name")
        .help("The display name of the proposal being created by the RFP.")
        .type(String.class)
        .setDefault(String.format("Test PG Proposal %s", UUID.randomUUID()));

    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);
  }
}