L'YouTubeVideoUploadService
ti consente di caricare video direttamente su YouTube tramite l'API Google Ads. Questi video possono poi essere utilizzati per creare asset video in vari tipi di annunci, ad esempio campagne Performance Max o campagne Demand Gen.
Questo servizio semplifica il flusso di lavoro per la creazione di annunci video gestendo la procedura di caricamento su YouTube e garantendo che i video siano associati correttamente al tuo account.
Concetti fondamentali
Prima di iniziare, è importante capire come vengono gestiti i caricamenti dei video e i diversi stati che possono attraversare.
Workflow end-to-end
Il caricamento di un file video e la sua pubblicazione in un annuncio richiedono quattro passaggi sequenziali:
| Passaggio | Servizio e metodo | Riepilogo |
|---|---|---|
| 1. Avvia e carica i byte del video | CreateYouTubeVideoUpload su YouTubeVideoUploadService |
Carica i metadati e il file binario del video per creare una risorsa YouTubeVideoUpload (customers/{customer_id}/youTubeVideoUploads/{video_upload_id}). |
| 2. Esegui il polling dello stato di elaborazione | SearchStream su GoogleAdsService |
Esegui una query su you_tube_video_upload fino a state = 'PROCESSED' e l'video_id di YouTube di 11 caratteri viene compilato. |
| 3. Crea un asset video riutilizzabile | MutateAssets su AssetService |
Crea un YoutubeVideoAsset (youtube_video_id = video_id) per ottenere un nome della risorsa asset (customers/{customer_id}/assets/{asset_id}). |
| 4. Collega l'asset a campagne o annunci | MutateAssetGroupAssets il giorno AssetGroupAssetService o MutateAdGroupAds il giorno AdGroupAdService |
Collega l'asset a una campagna Performance Max AssetGroupAsset (field_type = YOUTUBE_VIDEO) o Demand Gen DemandGenVideoResponsiveAdInfo (videos[].asset). |
Proprietà del canale
Quando carichi un video, puoi specificare il canale YouTube di destinazione utilizzando il campo channel_id nella risorsa YouTubeVideoUpload:
- Canale di proprietà dell'inserzionista (brand):fornisci l'
channel_iddi un canale YouTube esistente di proprietà dell'inserzionista. Questa operazione è supportata solo con il flusso di autenticazione utente e non può essere utilizzata con i service account. - Canale gestito da Google: se
channel_idviene omesso, il video viene caricato su un canale YouTube gestito da Google associato all'account Google Ads.
Stati di caricamento
Il ciclo di vita di un caricamento di un video di YouTube viene monitorato dal campo state.
L'enum YouTubeVideoUploadState definisce i seguenti stati:
| Stato | Descrizione |
|---|---|
PENDING |
Il video è in fase di caricamento. |
UPLOADED |
Il video è stato caricato correttamente ed è in fase di elaborazione da parte di YouTube. |
PROCESSED |
Il video è stato elaborato ed è pronto per l'uso. |
FAILED |
Il caricamento o l'elaborazione non sono riusciti e non possono essere completati. |
REJECTED |
Il video è stato rifiutato per motivi di convalida o di norme. |
UNAVAILABLE |
Lo stato del video non è disponibile; potrebbe essere stato rimosso da YouTube. |
Impostazioni privacy
Il campo video_privacy controlla chi può vedere il video caricato. L'enum YouTubeVideoPrivacy supporta:
PUBLIC: il video è disponibile per chiunque su YouTube. (Consentito solo per i canali del brand).UNLISTED: il video non è disponibile per la ricerca, ma può essere visualizzato da chiunque abbia il link. Questa è l'opzione predefinita e l'unica disponibile per i canali gestiti da Google.
Requisiti per titolo e descrizione
Quando crei un caricamento di video, puoi specificare i metadati utilizzando i campi video_title
e video_description nella risorsa YouTubeVideoUpload:
video_title: obbligatorio. Il titolo non deve superare i 100 caratteri e non deve contenere caratteri non validi (parentesi angolari<o>). Può essere impostato solo durante la creazione del caricamento del video ed è immutabile dopo la creazione.video_description: facoltativo. La descrizione non deve contenere più di 5000 caratteri e non deve contenere caratteri non validi (parentesi angolari<o>). Può essere impostata solo durante la creazione del caricamento del video ed è immutabile dopo la creazione.
Entrambi i campi sono immutabili dopo la creazione. L'inclusione di video_title o video_description nella maschera di aggiornamento di una richiesta UpdateYouTubeVideoUpload non va a buon fine e genera un errore FieldError.IMMUTABLE_FIELD.
Per ulteriori informazioni sulla formattazione dei titoli e delle descrizioni di YouTube e sui caratteri non validi, consulta il Centro assistenza YouTube.
Informativa sui contenuti generativi
A partire dalla versione 26, ai sensi di normative come l'AI Act dell'Unione europea, gli inserzionisti possono divulgare se i contenuti video caricati includono contenuti multimediali sintetici o generati con l'AI.
Il campo video_content_metadata in YouTubeVideoUpload contiene VideoContentMetadata. Imposta il campo nidificato generative_content_disclosure utilizzando l'enum YouTubeVideoUploadGenerativeContentDisclosure:
| Valore | Descrizione |
|---|---|
NON_GENERATIVE_CONTENT |
L'inserzionista ha dichiarato che il video non è stato generato dall'AI. |
GENERATIVE_CONTENT |
L'inserzionista ha dichiarato che il video è stato generato dall'AI. |
Carica un video
Per caricare un video, devi utilizzare una richiesta in più parti per il metodo CreateYouTubeVideoUpload. La richiesta contiene sia i metadati per il caricamento sia il file video stesso.
1. Avvia il caricamento
Crea un CreateYouTubeVideoUploadRequest con i seguenti campi:
| Campo | Requisito | Descrizione e vincoli |
|---|---|---|
customer_id |
Obbligatorio | L'ID cliente Google Ads a 10 cifre (senza trattini). |
you_tube_video_upload.video_title |
Obbligatorio (INPUT_ONLY, IMMUTABLE) |
Titolo del video caricato su YouTube (fino a 100 caratteri; non può contenere < o >). |
you_tube_video_upload.video_description |
Facoltativo (INPUT_ONLY, IMMUTABLE) |
Descrizione del video su YouTube (fino a 5000 caratteri; non può contenere < o >). |
you_tube_video_upload.channel_id |
Facoltativo (IMMUTABLE) |
ID canale YouTube di destinazione di 24 caratteri (che inizia con UC) per un canale del brand di proprietà dell'inserzionista. Se omesso, il caricamento viene eseguito su un canale gestito da Google. |
you_tube_video_upload.video_privacy |
Facoltativo (modificabile sui canali del brand) | Impostazione YouTubeVideoPrivacy (UNLISTED predefinita o PUBLIC per i canali del brand di proprietà dell'inserzionista). |
you_tube_video_upload.video_content_metadata |
Facoltativo (INPUT_ONLY, IMMUTABLE) |
Disponibile a partire dalla versione 26: VideoContentMetadata con generative_content_disclosure impostato su un valore YouTubeVideoUploadGenerativeContentDisclosure (NON_GENERATIVE_CONTENT o GENERATIVE_CONTENT). |
Se utilizzi una libreria client, chiama il metodo CreateYouTubeVideoUpload, passando il file video, e il caricamento del video verrà gestito internamente.
Java
String videoUploadResourceName; try (YouTubeVideoUploadServiceClient youTubeVideoUploadServiceClient = googleAdsClient.getLatestVersion().createYouTubeVideoUploadServiceClient()) { YouTubeVideoUpload youTubeVideoUpload = YouTubeVideoUpload.newBuilder() .setVideoTitle("Test Video") .setVideoDescription("Test Video Description") .setVideoPrivacy(YouTubeVideoPrivacy.UNLISTED) .build(); CreateYouTubeVideoUploadRequest createUploadRequest = CreateYouTubeVideoUploadRequest.newBuilder() .setCustomerId(Long.toString(customerId)) .setYouTubeVideoUpload(youTubeVideoUpload) .build(); CreateYouTubeVideoUploadResponse response = youTubeVideoUploadServiceClient.createYouTubeVideoUpload( createUploadRequest, () -> new FileInputStream(videoFile), null); videoUploadResourceName = response.getResourceName(); System.out.printf("Created YouTube video upload: %s%n", videoUploadResourceName); }
C#
YouTubeVideoUploadServiceClient ytService = client.GetService( Services.V26.YouTubeVideoUploadService); CreateYouTubeVideoUploadRequest createUploadRequest = new CreateYouTubeVideoUploadRequest() { CustomerId = customerId.ToString(), YouTubeVideoUpload = new YouTubeVideoUpload() { VideoTitle = "Test Video", VideoDescription = "Test Video Description", VideoPrivacy = YouTubeVideoPrivacy.Unlisted } }; string videoUploadResourceName; using (FileStream stream = File.OpenRead(videoFilePath)) { ResumableUploadSession<CreateYouTubeVideoUploadRequest, CreateYouTubeVideoUploadResponse> session = ytService.CreateYouTubeVideoUpload(); CreateYouTubeVideoUploadResponse response = session.BeginUploadAsync(createUploadRequest, stream).Result; videoUploadResourceName = response.ResourceName; Console.WriteLine($"Created YouTube video upload: {videoUploadResourceName}"); }
PHP
$youTubeVideoUploadServiceClient = $googleAdsClient->getYouTubeVideoUploadServiceClient(); $youTubeVideoUpload = new YouTubeVideoUpload([ 'video_title' => 'Test Video', 'video_description' => 'Test Video Description', 'video_privacy' => YouTubeVideoPrivacy::UNLISTED ]); $createYouTubeVideoUploadRequest = CreateYouTubeVideoUploadRequest::build( $customerId, $youTubeVideoUpload ); /** @var ResumableUpload $resumableUpload */ $resumableUpload = $youTubeVideoUploadServiceClient->createYouTubeVideoUpload( $createYouTubeVideoUploadRequest ); $stream = Utils::streamFor(fopen($videoFilePath, 'rb')); /** @var CreateYouTubeVideoUploadResponse $response */ $response = $resumableUpload->startUpload($stream); $videoUploadResourceName = $response->getResourceName(); printf("Created YouTube video upload: '%s'%s", $videoUploadResourceName, PHP_EOL);
Python
yt_service: YouTubeVideoUploadServiceClient = client.get_service( "YouTubeVideoUploadService" ) create_upload_request: CreateYouTubeVideoUploadRequest = ( youtube_video_upload_service.CreateYouTubeVideoUploadRequest() ) create_upload_request.customer_id = customer_id create_upload_request.you_tube_video_upload.video_title = "Test Video" create_upload_request.you_tube_video_upload.video_description = ( "Test Video Description" ) create_upload_request.you_tube_video_upload.video_privacy = ( client.enums.YouTubeVideoPrivacyEnum.UNLISTED ) video_upload_resource_name: str with open(video_file_path, "rb") as stream: response: CreateYouTubeVideoUploadResponse = ( yt_service.create_you_tube_video_upload( stream=stream, request=create_upload_request, retry=None, ) ) video_upload_resource_name = response.resource_name print(f"Created YouTube video upload: {video_upload_resource_name}")
Ruby
video_upload = client.resource.you_tube_video_upload do |v| v.video_title = "Test Video" v.video_description = "Test Video Description" v.video_privacy = :UNLISTED end upload = client.service.you_tube_video_upload.create_you_tube_video_upload( customer_id: customer_id, you_tube_video_upload: video_upload, ) video_upload_resource_name = nil File.open(video_file_path, "rb") do |stream| response = upload.start( stream: stream, content_type: "application/octet-stream", ) video_upload_resource_name = response.resource_name puts "Created YouTube video upload: #{video_upload_resource_name}" end
Perl
This example is not yet available in Perl; you can take a look at the other languages.
curl
# # Use the --i curl parameter to capture response headers in the $RESPONSE # variable. FILE_SIZE=$(wc -c < "${VIDEO_FILE_NAME}" | tr -d '\r') RESPONSE=$(curl -i -f -v -s --request POST \ "https://googleads.googleapis.com/resumable/upload/v${API_VERSION}/customers/${CUSTOMER_ID}/youTubeVideoUploads:create" \ --header "Content-Type: application/json" \ --header "login-customer-id: ${MANAGER_CUSTOMER_ID}" \ --header "Authorization: Bearer ${OAUTH2_ACCESS_TOKEN}" \ --header "X-Goog-Upload-Protocol: resumable" \ --header "X-Goog-Upload-Command: start" \ --header "X-Goog-Upload-Header-Content-Length: ${FILE_SIZE}" \ --data @- <<EOF { "customer_id": "${CUSTOMER_ID}", "you_tube_video_upload": { "video_title": "${VIDEO_TITLE}", "video_description": "${VIDEO_DESCRIPTION}", "video_privacy": "UNLISTED" } } EOF ) # Extract the value of the "x-goog-upload-url" header from the HTTP response. UPLOAD_URL=$(echo "${RESPONSE}" \ | grep -i '^x-goog-upload-url' \ | awk '{print $2}' \ | tr -d '\r') CHUNK_SIZE=$(echo "${RESPONSE}" \ | grep -i '^x-goog-upload-chunk-granularity' \ | awk '{print $2}' \ | tr -d '\r')
Se utilizzi REST, la sezione seguente descrive come gestire il caricamento dei video.
2. Carica il video
Quando carichi con REST, CreateYouTubeVideoUpload utilizza un protocollo di caricamento ripristinabile in due passaggi:
- Avvia la sessione di caricamento: invia una richiesta
POSTiniziale all'endpoint di caricamentoCreateYouTubeVideoUpload(/upload/v26/customers/{customer_id}/youTubeVideoUploads:create) conx-goog-upload-command: start(e facoltativamentex-goog-upload-header-content-lengthper dichiarare le dimensioni del file). La risposta restituisce l'URL della sessione di caricamento nell'intestazione della risposta HTTPx-goog-upload-url, insieme ai metadati, ad esempio le dimensioni previste dei blocchi. - Trasmetti in streaming e finalizza i byte del video:invia il payload binario del video all'endpoint
x-goog-upload-urlconx-goog-upload-command: upload, finalize. Al termine del caricamento, la risposta restituisce l'oggettoresource_name(customers/{customer_id}/youTubeVideoUploads/{video_upload_id}) creato.
Per una descrizione completa delle intestazioni HTTP utilizzate nel protocollo di caricamento dei video, consulta il seguente esempio di codice:
# Take the first ${CHUNK_SIZE} bytes of the video file and upload them. head -c ${CHUNK_SIZE} ${VIDEO_FILE_NAME} | curl -i -v -X PUT "${UPLOAD_URL}" \ --header "Authorization: Bearer ${OAUTH2_ACCESS_TOKEN}" \ --header "X-Goog-Upload-Offset: 0" \ --header "X-Goog-Upload-Command: upload" \ --header "Content-Length: ${CHUNK_SIZE}" \ --data-binary @- # Query the status of the upload. QUERY_RESPONSE=$(curl -i -s -X POST "${UPLOAD_URL}" \ --header "Authorization: Bearer ${OAUTH2_ACCESS_TOKEN}" \ --header "X-Goog-Upload-Command: query") # Extract the value of the "x-goog-upload-size-received" header from the HTTP # response. UPLOADED_BYTES=$(echo "${QUERY_RESPONSE}" \ | grep -i '^x-goog-upload-size-received' \ | awk '{print $2}' \ | tr -d '\r') echo "Uploaded ${UPLOADED_BYTES} bytes." REMAINING_BYTES=$((FILE_SIZE - UPLOADED_BYTES)) echo "${REMAINING_BYTES} bytes remaining to upload." FINALIZE_RESPONSE=$(tail -c ${REMAINING_BYTES} ${VIDEO_FILE_NAME} | curl -v -X PUT "${UPLOAD_URL}" \ --header "Authorization: Bearer ${OAUTH2_ACCESS_TOKEN}" \ --header "X-Goog-Upload-Offset: ${UPLOADED_BYTES}" \ --header "X-Goog-Upload-Command: upload, finalize" \ --data-binary @-) UPLOADED_VIDEO_RESOURCE_NAME=$(echo $FINALIZE_RESPONSE | jq -r '.resourceName')
3. Recupera lo stato di caricamento del video
Dopo aver avviato il caricamento di un video, esegui il polling dello stato di elaborazione eseguendo una query sui campi selezionabili della risorsa you_tube_video_upload (resource_name, video_upload_id, channel_id, video_id, state e video_privacy) con GAQL fino a state = 'PROCESSED' (i campi INPUT_ONLY non possono essere selezionati in GAQL):
Java
// Retrieve the metadata of the newly uploaded video. String query = String.format( "SELECT " + "you_tube_video_upload.resource_name, " + "you_tube_video_upload.video_id, " + "you_tube_video_upload.state " + "FROM you_tube_video_upload " + "WHERE you_tube_video_upload.resource_name = '%s'", videoUploadResourceName); try (GoogleAdsServiceClient googleAdsServiceClient = googleAdsClient.getLatestVersion().createGoogleAdsServiceClient()) { SearchGoogleAdsStreamRequest request = SearchGoogleAdsStreamRequest.newBuilder() .setCustomerId(Long.toString(customerId)) .setQuery(query) .build(); ServerStream<SearchGoogleAdsStreamResponse> stream = googleAdsServiceClient.searchStreamCallable().call(request); for (SearchGoogleAdsStreamResponse response : stream) { for (GoogleAdsRow googleAdsRow : response.getResultsList()) { YouTubeVideoUpload video = googleAdsRow.getYouTubeVideoUpload(); System.out.printf( "Video with ID %s was found in state %s.%n", video.getVideoId(), video.getState()); } } }
C#
// Retrieve the metadata of the newly uploaded video. string query = $@" SELECT you_tube_video_upload.resource_name, you_tube_video_upload.video_id, you_tube_video_upload.state FROM you_tube_video_upload WHERE you_tube_video_upload.resource_name = '{videoUploadResourceName}'"; GoogleAdsServiceClient gaService = client.GetService( Services.V26.GoogleAdsService); gaService.SearchStream(customerId.ToString(), query, delegate (SearchGoogleAdsStreamResponse resp) { foreach (GoogleAdsRow row in resp.Results) { Console.WriteLine( $"Video with ID {row.YouTubeVideoUpload.VideoId} was found in " + $"state {row.YouTubeVideoUpload.State}."); } } );
PHP
// Retrieve the metadata of the newly uploaded video. $query = sprintf( "SELECT you_tube_video_upload.resource_name, " . "you_tube_video_upload.video_id, " . "you_tube_video_upload.state " . "FROM you_tube_video_upload " . "WHERE you_tube_video_upload.resource_name = '%s'", $videoUploadResourceName ); $googleAdsServiceClient = $googleAdsClient->getGoogleAdsServiceClient(); $stream = $googleAdsServiceClient->searchStream( SearchGoogleAdsStreamRequest::build($customerId, $query) ); foreach ($stream->iterateAllElements() as $googleAdsRow) { /** @var GoogleAdsRow $googleAdsRow */ printf( "Video with ID '%s' was found in state '%s'.%s", $googleAdsRow->getYouTubeVideoUpload()->getVideoId(), YouTubeVideoUploadState::name($googleAdsRow->getYouTubeVideoUpload()->getState()), PHP_EOL ); }
Python
# Retrieve the metadata of the newly uploaded video. query: str = f""" SELECT you_tube_video_upload.resource_name, you_tube_video_upload.video_id, you_tube_video_upload.state FROM you_tube_video_upload WHERE you_tube_video_upload.resource_name = '{video_upload_resource_name}'""" ga_service: GoogleAdsServiceClient = client.get_service("GoogleAdsService") stream: Iterator[SearchGoogleAdsStreamResponse] = ga_service.search_stream( customer_id=customer_id, query=query ) for row in itertools.chain.from_iterable(batch.results for batch in stream): video = row.you_tube_video_upload print( f"Video with ID {row.you_tube_video_upload.video_id} was found in state {row.you_tube_video_upload.state}." )
Ruby
# Retrieve the metadata of the newly uploaded video. query = <<~EOQ SELECT you_tube_video_upload.resource_name, you_tube_video_upload.video_id, you_tube_video_upload.state FROM you_tube_video_upload WHERE you_tube_video_upload.resource_name = '#{video_upload_resource_name}' EOQ responses = client.service.google_ads.search_stream( customer_id: customer_id, query: query, ) responses.each do |batch| batch.results.each do |row| puts "Video with ID #{row.you_tube_video_upload.video_id} was found in " \ "state #{row.you_tube_video_upload.state}." end end
Perl
This example is not yet available in Perl; you can take a look at the other languages.
curl
curl -i -v -X POST \ "https://qa-prod-googleads.sandbox.googleapis.com/v${API_VERSION}/customers/${CUSTOMER_ID}/googleAds:search" \ --header "Content-Type: application/json" \ --header "Developer-Token: ${DEVELOPER_TOKEN}" \ --header "login-customer-id: ${MANAGER_CUSTOMER_ID}" \ --header "Authorization: Bearer ${OAUTH2_ACCESS_TOKEN}" \ --data @- <<EOF { "query": "SELECT you_tube_video_upload.resource_name, you_tube_video_upload.video_id, you_tube_video_upload.state FROM you_tube_video_upload WHERE you_tube_video_upload.resource_name = '$UPLOADED_VIDEO_RESOURCE_NAME'" } EOF
Gestisci caricamenti
Una volta completato il caricamento di un video, puoi utilizzarlo come asset video.
Utilizza il video caricato
Quando un video raggiunge lo stato PROCESSED, puoi trovare il relativo ID video di YouTube di 11 caratteri nel campo video_id della risorsa YouTubeVideoUpload.
Utilizza questo video_id per creare un YoutubeVideoAsset con
MutateAssets e collega il nome della risorsa dell'asset risultante
(customers/{customer_id}/assets/{asset_id}) alle tue campagne o ai tuoi annunci:
Crea
YoutubeVideoAssetpassandoyoutube_video_idaAssetService.MutateAssets:POST https://googleads.googleapis.com/v26/customers/{customer_id}/assets:mutate { "operations": [ { "create": { "name": "Product Launch Video", "youtubeVideoAsset": { "youtubeVideoId": "dQw4w9WgXcQ" } } } ] }Collega
AssetaAssetGroupoAdGroupAd:Performance Max:crea un
AssetGroupAssetutilizzandoAssetGroupAssetService.MutateAssetGroupAssetsconfield_typeimpostato suYOUTUBE_VIDEO:POST https://googleads.googleapis.com/v26/customers/{customer_id}/assetGroupAssets:mutate { "operations": [ { "create": { "assetGroup": "customers/{customer_id}/assetGroups/{asset_group_id}", "asset": "customers/{customer_id}/assets/{asset_id}", "fieldType": "YOUTUBE_VIDEO" } } ] }Demand Gen:fai riferimento a
customers/{customer_id}/assets/{asset_id}nell'elencovideosdi un oggettoDemandGenVideoResponsiveAdInfoquando chiamiAdGroupAdService.MutateAdGroupAds:POST https://googleads.googleapis.com/v26/customers/{customer_id}/adGroupAds:mutate { "operations": [ { "create": { "adGroup": "customers/{customer_id}/adGroups/{ad_group_id}", "status": "PAUSED", "ad": { "name": "Demand Gen Video Ad", "finalUrls": ["https://www.example.com"], "demandGenVideoResponsiveAd": { "videos": [ { "asset": "customers/{customer_id}/assets/{asset_id}" } ], "logoImages": [ { "asset": "customers/{customer_id}/assets/{logo_asset_id}" } ], "headlines": [ { "text": "Example Headline" } ], "longHeadlines": [ { "text": "Example Long Headline" } ], "descriptions": [ { "text": "Example Description" } ], "businessName": { "text": "Example Business" } } } } } ] }
Esegui query sugli asset
YOUTUBE_VIDEOesistenti utilizzandoGoogleAdsService.SearchStream:SELECT asset.id, asset.resource_name, asset.name, asset.type, asset.youtube_video_asset.youtube_video_id, asset.youtube_video_asset.youtube_video_title FROM asset WHERE asset.type = 'YOUTUBE_VIDEO' AND asset.youtube_video_asset.youtube_video_id = '{video_id}'
Aggiorna metadati
Puoi aggiornare l'impostazione della privacy di un video caricato tramite questa API utilizzando il metodo UpdateYouTubeVideoUpload con update_mask impostato su "video_privacy". Solo il campo video_privacy (PUBLIC o
UNLISTED, per i video caricati su un canale del brand di proprietà dell'inserzionista) può essere
aggiornato dopo la creazione; video_title, video_description, channel_id e
video_content_metadata sono immutabili. L'inclusione di video_title o video_description nella maschera di aggiornamento non va a buon fine e genera un errore FieldError.IMMUTABLE_FIELD.
Rimuovi i caricamenti
Se devi eliminare i video caricati con l'API Google Ads, trasmetti i relativi
nomi delle risorse customers/{customer_id}/youTubeVideoUploads/{video_upload_id}
nel campo resource_names del
metodo RemoveYouTubeVideoUpload. In questo modo, il video viene rimosso sia dalla raccolta di asset di Google Ads sia da YouTube.