YouTube

Activities: insert

Posts a bulletin for a specific channel. (The user submitting the request must be authorized to act on the channel's behalf.)

Note: Even though an activity resource can contain information about actions like a user rating a video or marking a video as a favorite, you need to use other API methods to generate those activity resources. For example, you would use the API's videos.rate() method to rate a video and the playlistItems.insert() method to mark a video as a favorite.

Try it now or see an example.

Request

HTTP request

POST https://www.googleapis.com/youtube/v3/activities

Authorization

This request requires authorization with at least one of the following scopes (read more about authentication and authorization).

Scope
https://www.googleapis.com/auth/youtube

Parameters

The table below lists the parameters that this query supports. All of the parameters listed are query parameters.

Parameter name Value Description
Required parameters
part string The part parameter serves two purposes in this operation. It identifies the properties that the write operation will set as well as the properties that the API response will include.

The part names that you can include in the parameter value are snippet and contentDetails.

Request body

Provide an activity resource in the request body. For that resource:

  • You must specify a value for these properties:

    • snippet.description

  • You can set values for these properties:

    • snippet.description
    • contentDetails.bulletin.resourceId

Response

If successful, this method returns an activity resource in the response body.

Examples

Note: The code samples below may not represent all supported programming languages. See the client libraries documentation for a list of supported languages.

Apps Script

This function creates and posts a new channel bulletin, adding a video and message. Note that this will also accept a playlist ID. After completing the API call, logs the output to the log.
/**
 * This function creates and posts a new channel bulletin, adding a video and message. Note that this
 * will also accept a playlist ID. After completing the API call, logs the output to the log.
 */
function postChannelBulletin() {
  var message = 'Thanks for subscribing to my channel!  This posting is from Google Apps Script';
  var videoId = 'qZRsVqOIWms';
  var resource = {
    snippet: {
      description: message
    },
    contentDetails: {
      bulletin: {
        resourceId: {
          kind: 'youtube#video',
          videoId: videoId
        }
      }
    }
  };

  var response = YouTube.Activities.insert(resource, 'snippet,contentDetails');
  Logger.log(response);
}

Go

The code sample below calls the API's activities.insert method to post a bulletin to the channel associated with the request.

This example uses the Go client library.

package main

import (
	"flag"
	"fmt"
	"log"

	"code.google.com/p/google-api-go-client/youtube/v3"
)

var (
	message    = flag.String("message", "", "Text message to post")
	videoID    = flag.String("videoid", "", "ID of video to post")
	playlistID = flag.String("playlistid", "", "ID of playlist to post")
)

func main() {
	flag.Parse()

	// A bulletin must contain a message and may also contain a video or a
	// playlist. You can post a message with or without an accompanying video
	// or playlist, but you can't post a video and playlist at the same time.
	if *message == "" {
		log.Fatalf("Please provide a message.")
	}

	if *videoID != "" && *playlistID != "" {
		log.Fatalf("You cannot post a video and a playlist at the same time.")
	}

	client, err := buildOAuthHTTPClient(youtube.YoutubeScope)
	if err != nil {
		log.Fatalf("Error building OAuth client: %v", err)
	}

	service, err := youtube.New(client)
	if err != nil {
		log.Fatalf("Error creating YouTube client: %v", err)
	}

	// Start making YouTube API calls.
	parts := "snippet"
	bulletin := &youtube.Activity{
		Snippet: &youtube.ActivitySnippet{
			Description: *message,
		},
	}

	if *videoID != "" || *playlistID != "" {
		parts = "snippet,contentDetails"

		// The resource ID element value differs depending on
		// whether a playlist or a video is being posted.
		var resourceId *youtube.ResourceId
		switch {
		case *videoID != "":
			resourceId = &youtube.ResourceId{
				Kind:    "youtube#video",
				VideoId: *videoID,
			}
		case *playlistID != "":
			resourceId = &youtube.ResourceId{
				Kind:       "youtube#playlist",
				PlaylistId: *playlistID,
			}
		}

		bulletin.ContentDetails = &youtube.ActivityContentDetails{
			Bulletin: &youtube.ActivityContentDetailsBulletin{
				ResourceId: resourceId,
			},
		}
	}

	call := service.Activities.Insert(parts, bulletin)
	_, err = call.Do()
	if err != nil {
		log.Fatalf("Error making API call to post bulletin: %v", err.Error())
	}

	fmt.Println("The bulletin was posted to your channel.")
}

Java

This example uses the Java client library.

/*
 * Copyright (c) 2012 Google Inc.
 *
 * 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.
 */

package com.google.api.services.samples.youtube.cmdline.data;

import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.googleapis.json.GoogleJsonResponseException;
import com.google.api.services.samples.youtube.cmdline.Auth;
import com.google.api.services.youtube.YouTube;
import com.google.api.services.youtube.model.*;
import com.google.common.collect.Lists;

import java.util.Calendar;
import java.util.List;

/**
 * Create a video bulletin that is posted to the user's channel feed.
 *
 * @author Jeremy Walker
 */
public class ChannelBulletin {

    /**
     * Define a global instance of a Youtube object, which will be used
     * to make YouTube Data API requests.
     */
    private static YouTube youtube;

    /*
     * Define a global instance of the video ID that will be posted as a
     * bulletin into the user's channel feed. In practice, you will probably
     * retrieve this value from a search or your app.
     */
    private static String VIDEO_ID = "L-oNKK1CrnU";


    /**
     * Authorize the user, call the youtube.channels.list method to retrieve
     * information about the user's YouTube channel, and post a bulletin with
     * a video ID to that channel.
     *
     * @param args command line args (not used).
     */
    public static void main(String[] args) {

        // This OAuth 2.0 access scope allows for full read/write access to the
        // authenticated user's account.
        List<String> scopes = Lists.newArrayList("https://www.googleapis.com/auth/youtube");

        try {
            // Authorize the request.
            Credential credential = Auth.authorize(scopes, "channelbulletin");

            // This object is used to make YouTube Data API requests.
            youtube = new YouTube.Builder(Auth.HTTP_TRANSPORT, Auth.JSON_FACTORY, credential).setApplicationName(
                    "youtube-cmdline-channelbulletin-sample").build();

            // Construct a request to retrieve the current user's channel ID.
            // See https://developers.google.com/youtube/v3/docs/channels/list
            YouTube.Channels.List channelRequest = youtube.channels().list("contentDetails");
            channelRequest.setMine(true);

            // In the API response, only include channel information needed
            // for this use case.
            channelRequest.setFields("items/contentDetails");
            ChannelListResponse channelResult = channelRequest.execute();

            List<Channel> channelsList = channelResult.getItems();

            if (channelsList != null) {
                // The user's default channel is the first item in the list.
                String channelId = channelsList.get(0).getId();

                // Create the snippet for the activity resource that
                // represents the channel bulletin. Set its channel ID
                // and description.
                ActivitySnippet snippet = new ActivitySnippet();
                snippet.setChannelId(channelId);
                Calendar cal = Calendar.getInstance();
                snippet.setDescription("Bulletin test video via YouTube API on " + cal.getTime());

                // Create a resourceId that identifies the video ID. You could
                // set the kind to "youtube#playlist" and use a playlist ID
                // instead of a video ID.
                ResourceId resource = new ResourceId();
                resource.setKind("youtube#video");
                resource.setVideoId(VIDEO_ID);

                ActivityContentDetailsBulletin bulletin = new ActivityContentDetailsBulletin();
                bulletin.setResourceId(resource);

                // Construct the ActivityContentDetails object for the request.
                ActivityContentDetails contentDetails = new ActivityContentDetails();
                contentDetails.setBulletin(bulletin);

                // Construct the resource, including the snippet and content
                // details, to send in the activities.insert
                Activity activity = new Activity();
                activity.setSnippet(snippet);
                activity.setContentDetails(contentDetails);

                // The API request identifies the resource parts that are being
                // written (contentDetails and snippet). The API response will
                // also include those parts.
                YouTube.Activities.Insert insertActivities =
                        youtube.activities().insert("contentDetails,snippet", activity);
                // Return the newly created activity resource.
                Activity newActivityInserted = insertActivities.execute();

                if (newActivityInserted != null) {
                    System.out.println(
                            "New Activity inserted of type " + newActivityInserted.getSnippet().getType());
                    System.out.println(" - Video id "
                            + newActivityInserted.getContentDetails().getBulletin().getResourceId().getVideoId());
                    System.out.println(
                            " - Description: " + newActivityInserted.getSnippet().getDescription());
                    System.out.println(" - Posted on " + newActivityInserted.getSnippet().getPublishedAt());
                } else {
                    System.out.println("Activity failed.");
                }

            } else {
                System.out.println("No channels are assigned to this user.");
            }
        } catch (GoogleJsonResponseException e) {
            e.printStackTrace();
            System.err.println("There was a service error: " + e.getDetails().getCode() + " : "
                    + e.getDetails().getMessage());

        } catch (Throwable t) {
            t.printStackTrace();
        }
    }
}

Python

The code sample below calls the API's activities.insert method to post a bulletin to the channel associated with the request.

This example uses the Python client library.

#!/usr/bin/python

import httplib2
import os
import sys

from apiclient.discovery import build
from apiclient.errors import HttpError
from oauth2client.client import flow_from_clientsecrets
from oauth2client.file import Storage
from oauth2client.tools import argparser, run_flow


# The CLIENT_SECRETS_FILE variable specifies the name of a file that contains
# the OAuth 2.0 information for this application, including its client_id and
# client_secret. You can acquire an OAuth 2.0 client ID and client secret from
# the Google Developers Console at
# https://console.developers.google.com/.
# Please ensure that you have enabled the YouTube Data API for your project.
# For more information about using OAuth2 to access the YouTube Data API, see:
#   https://developers.google.com/youtube/v3/guides/authentication
# For more information about the client_secrets.json file format, see:
#   https://developers.google.com/api-client-library/python/guide/aaa_client_secrets
CLIENT_SECRETS_FILE = "client_secrets.json"

# This OAuth 2.0 access scope allows for full read/write access to the
# authenticated user's account.
YOUTUBE_READ_WRITE_SCOPE = "https://www.googleapis.com/auth/youtube"
YOUTUBE_API_SERVICE_NAME = "youtube"
YOUTUBE_API_VERSION = "v3"

# This variable defines a message to display if the CLIENT_SECRETS_FILE is
# missing.
MISSING_CLIENT_SECRETS_MESSAGE = """
WARNING: Please configure OAuth 2.0

To make this sample run you will need to populate the client_secrets.json file
found at:

   %s

with information from the Developers Console
https://console.developers.google.com/

For more information about the client_secrets.json file format, please visit:
https://developers.google.com/api-client-library/python/guide/aaa_client_secrets
""" % os.path.abspath(os.path.join(os.path.dirname(__file__),
                                   CLIENT_SECRETS_FILE))

def get_authenticated_service(args):
  flow = flow_from_clientsecrets(CLIENT_SECRETS_FILE,
    scope=YOUTUBE_READ_WRITE_SCOPE,
    message=MISSING_CLIENT_SECRETS_MESSAGE)

  storage = Storage("%s-oauth2.json" % sys.argv[0])
  credentials = storage.get()

  if credentials is None or credentials.invalid:
    credentials = run_flow(flow, storage, args)

  return build(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION,
    http=credentials.authorize(httplib2.Http()))

# This method calls the API's youtube.activities.insert method to post the
# channel bulletin.
def post_bulletin(youtube, args):
  body = dict(
    snippet=dict(
      description=args.message
    )
  )

  if args.video_id:
    body["contentDetails"] = dict(
      bulletin=dict(
        resourceId=dict(
          kind="youtube#video",
          videoId=args.video_id
        )
      )
    )

  if args.playlist_id:
    body["contentDetails"] = dict(
      bulletin=dict(
        resourceId=dict(
          kind="youtube#playlist",
          playlistId=args.playlist_id
        )
      )
    )

  youtube.activities().insert(
    part=",".join(body.keys()),
    body=body
  ).execute()

if __name__ == "__main__":
  argparser.add_argument("--message", required=True,
    help="Text of message to post.")
  argparser.add_argument("--video-id",
    help="Optional ID of video to post.")
  argparser.add_argument("--playlist-id",
    help="Optional ID of playlist to post.")
  args = argparser.parse_args()

  # You can post a message with or without an accompanying video or playlist.
  # However, you can't post a video and a playlist at the same time.
  if args.video_id and args.playlist_id:
    exit("You cannot post a video and a playlist at the same time.")

  youtube = get_authenticated_service(args)
  try:
    post_bulletin(youtube, args)
  except HttpError, e:
    print "An HTTP error %d occurred:\n%s" % (e.resp.status, e.content)
  else:
    print "The bulletin was posted to your channel."

Ruby

The code sample below calls the API's activities.insert method to post a bulletin to the channel associated with the request.

This example uses the Ruby client library.

#!/usr/bin/ruby

require 'rubygems'
gem 'google-api-client', '>0.7'
require 'google/api_client'
require 'google/api_client/client_secrets'
require 'google/api_client/auth/file_storage'
require 'google/api_client/auth/installed_app'
require 'trollop'

# This OAuth 2.0 access scope allows for full read/write access to the
# authenticated user's account.
YOUTUBE_SCOPE = 'https://www.googleapis.com/auth/youtube'
YOUTUBE_API_SERVICE_NAME = 'youtube'
YOUTUBE_API_VERSION = 'v3'

def get_authenticated_service
  client = Google::APIClient.new(
    :application_name => $PROGRAM_NAME,
    :application_version => '1.0.0'
  )
  youtube = client.discovered_api(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION)

  file_storage = Google::APIClient::FileStorage.new("#{$PROGRAM_NAME}-oauth2.json")
  if file_storage.authorization.nil?
    client_secrets = Google::APIClient::ClientSecrets.load
    flow = Google::APIClient::InstalledAppFlow.new(
      :client_id => client_secrets.client_id,
      :client_secret => client_secrets.client_secret,
      :scope => [YOUTUBE_SCOPE]
    )
    client.authorization = flow.authorize(file_storage)
  else
    client.authorization = file_storage.authorization
  end

  return client, youtube
end

def main
  opts = Trollop::options do
    opt :message, 'Required text of message to post.', :type => String
    opt :video_id, 'Optional ID of video to post.', :type => String
    opt :playlist_id, 'Optional ID of playlist to post.', :type => String
  end

  # You can post a message with or without an accompanying video or playlist.
  # However, you can't post a video and a playlist at the same time.
  if opts[:video_id] and opts[:playlist_id]
    Trollop::die 'You cannot post a video and a playlist at the same time'
  end
  Trollop::die :message, 'is required' unless opts[:message]

  client, youtube = get_authenticated_service

  begin
    body = {
      :snippet => {
        :description => opts[:message]
      }
    }

    if opts[:video_id]
      body[:contentDetails] = {
        :bulletin => {
          :resourceId => {
            :kind => 'youtube#video',
            :videoId => opts[:video_id]
          }
        }
      }
    end

    if opts[:playlist_id]
      body[:contentDetails] = {
        :bulletin => {
          :resourceId => {
            :kind => 'youtube#playlist',
            :playlistId => opts[:playlist_id]
          }
        }
      }
    end

    # Call the youtube.activities.insert method to post the channel bulletin.
    client.execute!(
      :api_method => youtube.activities.insert,
      :parameters => {
        :part => body.keys.join(',')
      },
      :body_object => body
    )

    puts "The bulletin was posted to your channel."
  rescue Google::APIClient::TransmissionError => e
    puts e.result.body
  end
end

main

Errors

The table below identifies error messages that the API could return in response to a call to this method. Please see the error message documentation for more detail.

Error type Error detail Description
badRequest (400) bulletinTextRequired The request must use the snippet object's description property to provide the text for the bulletin post.
notFound (404) playlistNotFound YouTube cannot find the video that you are trying to associate with the bulletin post. Check the value of the contentDetails.bulletinPosted.playlistId property.
notFound (404) videoNotFound YouTube cannot find the video that you are trying to associate with the bulletin post. Check the value of the contentDetails.bulletinPosted.videoId property.
userRateLimitExceeded (403) rateLimitExceeded The request cannot be completed because you have exceeded your quota.

Try it!

Use the API Explorer to call this method on live data and see the API request and response.

Authentication required

You need to be signed in with Google+ to do that.

Signing you in...

Google Developers needs your permission to do that.