CommentThreads: list

Returns a list of comment threads that match the API request parameters. Try it now.

Quota impact: A call to this method has a quota cost of 1 unit in addition to the costs of the specified resource parts.

Usage

Request

HTTP request

GET https://www.googleapis.com/youtube/v3/commentThreads

Parameters

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

Parameters
Required parameters
part string
The part parameter specifies a comma-separated list of one or more commentThread resource properties that the API response will include.

The following list contains the part names that you can include in the parameter value and the quota cost for each part:
  • id: 0
  • replies: 2
  • snippet: 2
Filters (specify exactly one of the following parameters)
allThreadsRelatedToChannelId string
The allThreadsRelatedToChannelId parameter instructs the API to return all comment threads associated with the specified channel. The response can include comments about the channel or about the channel's videos.
channelId string
The channelId parameter instructs the API to return comment threads containing comments about the specified channel. (The response will not include comments left on videos that the channel uploaded.)
id string
The id parameter specifies a comma-separated list of comment thread IDs for the resources that should be retrieved.
videoId string
The videoId parameter instructs the API to return comment threads associated with the specified video ID.
Optional parameters
maxResults unsigned integer
The maxResults parameter specifies the maximum number of items that should be returned in the result set.

Note: This parameter is not supported for use in conjunction with the id parameter. Acceptable values are 1 to 100, inclusive. The default value is 20.
moderationStatus string
This parameter can only be used in a properly authorized request. Set this parameter to limit the returned comment threads to a particular moderation state.

Note: This parameter is not supported for use in conjunction with the id parameter. The default value is published.

Acceptable values are:
  • heldForReview – Retrieve comment threads that are awaiting review by a moderator. A comment thread can be included in the response if the top-level comment or at least one of the replies to that comment are awaiting review.
  • likelySpam – Retrieve comment threads classified as likely to be spam. A comment thread can be included in the response if the top-level comment or at least one of the replies to that comment is considered likely to be spam.
  • published – Retrieve threads of published comments. This is the default value. A comment thread can be included in the response if its top-level comment has been published.
order string
The order parameter specifies the order in which the API response should list comment threads. Valid values are:
  • time - Comment threads are ordered by time. This is the default behavior.
  • relevance - Comment threads are ordered by relevance.
Note: This parameter is not supported for use in conjunction with the id parameter.
pageToken string
The pageToken parameter identifies a specific page in the result set that should be returned. In an API response, the nextPageToken property identifies the next page of the result that can be retrieved.

Note: This parameter is not supported for use in conjunction with the id parameter.
searchTerms string
The searchTerms parameter instructs the API to limit the API response to only contain comments that contain the specified search terms.

Note: This parameter is not supported for use in conjunction with the id parameter.
textFormat string
Set this parameter's value to html or plainText to instruct the API to return the comments left by users in html formatted or in plain text. The default value is html.

Acceptable values are:
  • html – Returns the comments in HTML format. This is the default value.
  • plainText – Returns the comments in plain text format.

Request body

Do not provide a request body when calling this method.

Response

If successful, this method returns a response body with the following structure:

{
  "kind": "youtube#commentThreadListResponse",
  "etag": etag,
  "nextPageToken": string,
  "pageInfo": {
    "totalResults": integer,
    "resultsPerPage": integer
  },
  "items": [
    commentThread Resource
  ]
}

Properties

The following table defines the properties that appear in this resource:

Properties
kind string
Identifies the API resource's type. The value will be youtube#commentThreadListResponse.
etag etag
The Etag of this resource.
nextPageToken string
The token that can be used as the value of the pageToken parameter to retrieve the next page in the result set.
pageInfo object
The pageInfo object encapsulates paging information for the result set.
pageInfo.totalResults integer
The total number of results in the result set.
pageInfo.resultsPerPage integer
The number of results included in the API response.
items[] list
A list of comment threads that match the request criteria.

Examples

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

Java #1

This sample demonstrates how to use the following API methods to create and manage comments:
  • It calls the commentThreads.list method with the videoId parameter set to retrieve comments for a video.
  • It calls the comments.insert method with the parentId parameter set to reply to an existing comment.
  • It calls the comments.list method with the parentId parameter to retrieve the comments in the thread.
  • It calls the comments.update method with comment in the request body to update a comment.
  • It calls the comments.setModerationStatus method to set the moderation status of the comment, the comments.markAsSpam method to mark the comment as spam, and the comments.delete method to delete the comment, using the id parameter to identify the comment.

This example uses the Java client library.

/*
 * Copyright (c) 2013 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 java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;

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.Comment;
import com.google.api.services.youtube.model.CommentSnippet;
import com.google.api.services.youtube.model.CommentThread;
import com.google.api.services.youtube.model.CommentListResponse;
import com.google.api.services.youtube.model.CommentThreadListResponse;
import com.google.common.collect.Lists;

/**
 * This sample creates and manages comments by:
 *
 * 1. Retrieving the top-level comments for a video via "commentThreads.list" method.
 * 2. Replying to a comment thread via "comments.insert" method.
 * 3. Retrieving comment replies via "comments.list" method.
 * 4. Updating an existing comment via "comments.update" method.
 * 5. Sets moderation status of an existing comment via "comments.setModerationStatus" method.
 * 6. Marking a comment as spam via "comments.markAsSpam" method.
 * 7. Deleting an existing comment via "comments.delete" method.
 *
 * @author Ibrahim Ulukaya
 */
public class CommentHandling {

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

    /**
     * List, reply to comment threads; list, update, moderate, mark and delete
     * replies.
     *
     * @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 and requires requests to use an SSL connection.
        List<String> scopes = Lists.newArrayList("https://www.googleapis.com/auth/youtube.force-ssl");

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

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

            // Prompt the user for the ID of a video to comment on.
            // Retrieve the video ID that the user is commenting to.
            String videoId = getVideoId();
            System.out.println("You chose " + videoId + " to subscribe.");

            // Prompt the user for the comment text.
            // Retrieve the text that the user is commenting.
            String text = getText();
            System.out.println("You chose " + text + " to subscribe.");

            // All the available methods are used in sequence just for the sake
            // of an example.

            // Call the YouTube Data API's commentThreads.list method to
            // retrieve video comment threads.
            CommentThreadListResponse videoCommentsListResponse = youtube.commentThreads()
                    .list("snippet").setVideoId(videoId).setTextFormat("plainText").execute();
            List<CommentThread> videoComments = videoCommentsListResponse.getItems();

            if (videoComments.isEmpty()) {
                System.out.println("Can't get video comments.");
            } else {
                // Print information from the API response.
                System.out
                        .println("\n================== Returned Video Comments ==================\n");
                for (CommentThread videoComment : videoComments) {
                    CommentSnippet snippet = videoComment.getSnippet().getTopLevelComment()
                            .getSnippet();
                    System.out.println("  - Author: " + snippet.getAuthorDisplayName());
                    System.out.println("  - Comment: " + snippet.getTextDisplay());
                    System.out
                            .println("\n-------------------------------------------------------------\n");
                }
                CommentThread firstComment = videoComments.get(0);

                // Will use this thread as parent to new reply.
                String parentId = firstComment.getId();

                // Create a comment snippet with text.
                CommentSnippet commentSnippet = new CommentSnippet();
                commentSnippet.setTextOriginal(text);
                commentSnippet.setParentId(parentId);

                // Create a comment with snippet.
                Comment comment = new Comment();
                comment.setSnippet(commentSnippet);

                // Call the YouTube Data API's comments.insert method to reply
                // to a comment.
                // (If the intention is to create a new top-level comment,
                // commentThreads.insert
                // method should be used instead.)
                Comment commentInsertResponse = youtube.comments().insert("snippet", comment)
                        .execute();

                // Print information from the API response.
                System.out
                        .println("\n================== Created Comment Reply ==================\n");
                CommentSnippet snippet = commentInsertResponse.getSnippet();
                System.out.println("  - Author: " + snippet.getAuthorDisplayName());
                System.out.println("  - Comment: " + snippet.getTextDisplay());
                System.out
                        .println("\n-------------------------------------------------------------\n");

                // Call the YouTube Data API's comments.list method to retrieve
                // existing comment
                // replies.
                CommentListResponse commentsListResponse = youtube.comments().list("snippet")
                        .setParentId(parentId).setTextFormat("plainText").execute();
                List<Comment> comments = commentsListResponse.getItems();

                if (comments.isEmpty()) {
                    System.out.println("Can't get comment replies.");
                } else {
                    // Print information from the API response.
                    System.out
                            .println("\n================== Returned Comment Replies ==================\n");
                    for (Comment commentReply : comments) {
                        snippet = commentReply.getSnippet();
                        System.out.println("  - Author: " + snippet.getAuthorDisplayName());
                        System.out.println("  - Comment: " + snippet.getTextDisplay());
                        System.out
                                .println("\n-------------------------------------------------------------\n");
                    }
                    Comment firstCommentReply = comments.get(0);
                    firstCommentReply.getSnippet().setTextOriginal("updated");
                    Comment commentUpdateResponse = youtube.comments()
                            .update("snippet", firstCommentReply).execute();
                    // Print information from the API response.
                    System.out
                            .println("\n================== Updated Video Comment ==================\n");
                    snippet = commentUpdateResponse.getSnippet();
                    System.out.println("  - Author: " + snippet.getAuthorDisplayName());
                    System.out.println("  - Comment: " + snippet.getTextDisplay());
                    System.out
                            .println("\n-------------------------------------------------------------\n");

                    // Call the YouTube Data API's comments.setModerationStatus
                    // method to set moderation
                    // status of an existing comment.
                    youtube.comments().setModerationStatus(firstCommentReply.getId(), "published");
                    System.out.println("  -  Changed comment status to published: "
                            + firstCommentReply.getId());

                    // Call the YouTube Data API's comments.markAsSpam method to
                    // mark an existing comment as spam.
                    youtube.comments().markAsSpam(firstCommentReply.getId());
                    System.out.println("  -  Marked comment as spam: " + firstCommentReply.getId());

                    // Call the YouTube Data API's comments.delete method to
                    // delete an existing comment.
                    youtube.comments().delete(firstCommentReply.getId());
                    System.out
                            .println("  -  Deleted comment as spam: " + firstCommentReply.getId());
                }
            }
        } catch (GoogleJsonResponseException e) {
            System.err.println("GoogleJsonResponseException code: " + e.getDetails().getCode()
                    + " : " + e.getDetails().getMessage());
            e.printStackTrace();

        } catch (IOException e) {
            System.err.println("IOException: " + e.getMessage());
            e.printStackTrace();
        } catch (Throwable t) {
            System.err.println("Throwable: " + t.getMessage());
            t.printStackTrace();
        }
    }

    /*
     * Prompt the user to enter a video ID. Then return the ID.
     */
    private static String getVideoId() throws IOException {

        String videoId = "";

        System.out.print("Please enter a video id: ");
        BufferedReader bReader = new BufferedReader(new InputStreamReader(System.in));
        videoId = bReader.readLine();

        return videoId;
    }

    /*
     * Prompt the user to enter text for a comment. Then return the text.
     */
    private static String getText() throws IOException {

        String text = "";

        System.out.print("Please enter a comment text: ");
        BufferedReader bReader = new BufferedReader(new InputStreamReader(System.in));
        text = bReader.readLine();

        if (text.length() < 1) {
            // If nothing is entered, defaults to "YouTube For Developers."
            text = "YouTube For Developers.";
        }
        return text;
    }
}

Java #2

This sample demonstrates how to use the following API methods to create and manage top-level comments:
  • It calls the commentThreads.insert method once with the channelId parameter to create a channel comment and once with the videoId parameter to create a video comment.
  • It calls the commentThreads.list method once with the channelId parameter to retrieve channel comments and once with the videoId parameter to retrieve video comments.
  • It calls the commentThreads.update method once to update a video comment and then again to update a channel comment. In each case, the request body contains the comment resource being updated.

This example uses the Java client library.

/*
 * Copyright (c) 2013 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 java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;

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.Comment;
import com.google.api.services.youtube.model.CommentSnippet;
import com.google.api.services.youtube.model.CommentThread;
import com.google.api.services.youtube.model.CommentThreadSnippet;
import com.google.api.services.youtube.model.CommentThreadListResponse;
import com.google.common.collect.Lists;

/**
 * This sample creates and manages top-level comments by:
 *
 * 1. Creating a top-level comments for a video and a channel via "commentThreads.insert" method.
 * 2. Retrieving the top-level comments for a video and a channel via "commentThreads.list" method.
 * 3. Updating an existing comments via "commentThreads.update" method.
 *
 * @author Ibrahim Ulukaya
 */
public class CommentThreads {

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

    /**
     * Create, list and update top-level channel and video comments.
     *
     * @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 and requires requests to use an SSL connection.
        List<String> scopes = Lists.newArrayList("https://www.googleapis.com/auth/youtube.force-ssl");

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

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

            // Prompt the user for the ID of a channel to comment on.
            // Retrieve the channel ID that the user is commenting to.
            String channelId = getChannelId();
            System.out.println("You chose " + channelId + " to subscribe.");

            // Prompt the user for the ID of a video to comment on.
            // Retrieve the video ID that the user is commenting to.
            String videoId = getVideoId();
            System.out.println("You chose " + videoId + " to subscribe.");

            // Prompt the user for the comment text.
            // Retrieve the text that the user is commenting.
            String text = getText();
            System.out.println("You chose " + text + " to subscribe.");


            // Insert channel comment by omitting videoId.
            // Create a comment snippet with text.
            CommentSnippet commentSnippet = new CommentSnippet();
            commentSnippet.setTextOriginal(text);

            // Create a top-level comment with snippet.
            Comment topLevelComment = new Comment();
            topLevelComment.setSnippet(commentSnippet);

            // Create a comment thread snippet with channelId and top-level
            // comment.
            CommentThreadSnippet commentThreadSnippet = new CommentThreadSnippet();
            commentThreadSnippet.setChannelId(channelId);
            commentThreadSnippet.setTopLevelComment(topLevelComment);

            // Create a comment thread with snippet.
            CommentThread commentThread = new CommentThread();
            commentThread.setSnippet(commentThreadSnippet);

            // Call the YouTube Data API's commentThreads.insert method to
            // create a comment.
            CommentThread channelCommentInsertResponse = youtube.commentThreads()
                    .insert("snippet", commentThread).execute();
            // Print information from the API response.
            System.out
                    .println("\n================== Created Channel Comment ==================\n");
            CommentSnippet snippet = channelCommentInsertResponse.getSnippet().getTopLevelComment()
                    .getSnippet();
            System.out.println("  - Author: " + snippet.getAuthorDisplayName());
            System.out.println("  - Comment: " + snippet.getTextDisplay());
            System.out
                    .println("\n-------------------------------------------------------------\n");


            // Insert video comment
            commentThreadSnippet.setVideoId(videoId);
            // Call the YouTube Data API's commentThreads.insert method to
            // create a comment.
            CommentThread videoCommentInsertResponse = youtube.commentThreads()
                    .insert("snippet", commentThread).execute();
            // Print information from the API response.
            System.out
                    .println("\n================== Created Video Comment ==================\n");
            snippet = videoCommentInsertResponse.getSnippet().getTopLevelComment()
                    .getSnippet();
            System.out.println("  - Author: " + snippet.getAuthorDisplayName());
            System.out.println("  - Comment: " + snippet.getTextDisplay());
            System.out
                    .println("\n-------------------------------------------------------------\n");


            // Call the YouTube Data API's commentThreads.list method to
            // retrieve video comment threads.
            CommentThreadListResponse videoCommentsListResponse = youtube.commentThreads()
                    .list("snippet").setVideoId(videoId).setTextFormat("plainText").execute();
            List<CommentThread> videoComments = videoCommentsListResponse.getItems();

            if (videoComments.isEmpty()) {
                System.out.println("Can't get video comments.");
            } else {
                // Print information from the API response.
                System.out
                        .println("\n================== Returned Video Comments ==================\n");
                for (CommentThread videoComment : videoComments) {
                    snippet = videoComment.getSnippet().getTopLevelComment()
                            .getSnippet();
                    System.out.println("  - Author: " + snippet.getAuthorDisplayName());
                    System.out.println("  - Comment: " + snippet.getTextDisplay());
                    System.out
                            .println("\n-------------------------------------------------------------\n");
                }
                CommentThread firstComment = videoComments.get(0);
                firstComment.getSnippet().getTopLevelComment().getSnippet()
                        .setTextOriginal("updated");
                CommentThread videoCommentUpdateResponse = youtube.commentThreads()
                        .update("snippet", firstComment).execute();
                // Print information from the API response.
                System.out
                        .println("\n================== Updated Video Comment ==================\n");
                snippet = videoCommentUpdateResponse.getSnippet().getTopLevelComment()
                        .getSnippet();
                System.out.println("  - Author: " + snippet.getAuthorDisplayName());
                System.out.println("  - Comment: " + snippet.getTextDisplay());
                System.out
                        .println("\n-------------------------------------------------------------\n");

            }

            // Call the YouTube Data API's commentThreads.list method to
            // retrieve channel comment threads.
            CommentThreadListResponse channelCommentsListResponse = youtube.commentThreads()
                    .list("snippet").setChannelId(channelId).setTextFormat("plainText").execute();
            List<CommentThread> channelComments = channelCommentsListResponse.getItems();

            if (channelComments.isEmpty()) {
                System.out.println("Can't get channel comments.");
            } else {
                // Print information from the API response.
                System.out
                        .println("\n================== Returned Channel Comments ==================\n");
                for (CommentThread channelComment : channelComments) {
                    snippet = channelComment.getSnippet().getTopLevelComment()
                            .getSnippet();
                    System.out.println("  - Author: " + snippet.getAuthorDisplayName());
                    System.out.println("  - Comment: " + snippet.getTextDisplay());
                    System.out
                            .println("\n-------------------------------------------------------------\n");
                }
                CommentThread firstComment = channelComments.get(0);
                firstComment.getSnippet().getTopLevelComment().getSnippet()
                        .setTextOriginal("updated");
                CommentThread channelCommentUpdateResponse = youtube.commentThreads()
                        .update("snippet", firstComment).execute();
                // Print information from the API response.
                System.out
                        .println("\n================== Updated Channel Comment ==================\n");
                snippet = channelCommentUpdateResponse.getSnippet().getTopLevelComment()
                        .getSnippet();
                System.out.println("  - Author: " + snippet.getAuthorDisplayName());
                System.out.println("  - Comment: " + snippet.getTextDisplay());
                System.out
                        .println("\n-------------------------------------------------------------\n");

            }

        } catch (GoogleJsonResponseException e) {
            System.err.println("GoogleJsonResponseException code: " + e.getDetails().getCode()
                    + " : " + e.getDetails().getMessage());
            e.printStackTrace();

        } catch (IOException e) {
            System.err.println("IOException: " + e.getMessage());
            e.printStackTrace();
        } catch (Throwable t) {
            System.err.println("Throwable: " + t.getMessage());
            t.printStackTrace();
        }
    }

    /*
     * Prompt the user to enter a channel ID. Then return the ID.
     */
    private static String getChannelId() throws IOException {

        String channelId = "";

        System.out.print("Please enter a channel id: ");
        BufferedReader bReader = new BufferedReader(new InputStreamReader(System.in));
        channelId = bReader.readLine();

        return channelId;
    }

    /*
     * Prompt the user to enter a video ID. Then return the ID.
     */
    private static String getVideoId() throws IOException {

        String videoId = "";

        System.out.print("Please enter a video id: ");
        BufferedReader bReader = new BufferedReader(new InputStreamReader(System.in));
        videoId = bReader.readLine();

        return videoId;
    }

    /*
     * Prompt the user to enter text for a comment. Then return the text.
     */
    private static String getText() throws IOException {

        String text = "";

        System.out.print("Please enter a comment text: ");
        BufferedReader bReader = new BufferedReader(new InputStreamReader(System.in));
        text = bReader.readLine();

        if (text.length() < 1) {
            // If nothing is entered, defaults to "YouTube For Developers."
            text = "YouTube For Developers.";
        }
        return text;
    }
}

PHP #1

The following code sample demonstrates how to use the following API methods to create and manage comments:
  • It calls the commentThreads.list method with the videoId parameter set to retrieve comments for a video.
  • It calls the comments.insert method with the parentId parameter set to reply to an existing comment.
  • It calls the comments.list method with the parentId parameter to retrieve the comments in the thread.
  • It calls the comments.update method with comment in the request body to update a comment.
  • It calls the comments.setModerationStatus method to set the moderation status of the comment, the comments.markAsSpam method to mark the comment as spam, and the comments.delete method to delete the comment, using the id parameter to identify the comment.

This example uses the PHP client library.

<?php

/**
 * This sample creates and manages comments by:
 *
 * 1. Getting the top-level comments for a video via "commentThreads.list" method.
 * 2. Replying to a comment thread via "comments.insert" method.
 * 3. Getting comment replies via "comments.list" method.
 * 4. Updating an existing comment via "comments.update" method.
 * 5. Sets moderation status of an existing comment via "comments.setModerationStatus" method.
 * 6. Marking a comment as spam via "comments.markAsSpam" method.
 * 7. Deleting an existing comment via "comments.delete" method.
 *
 * @author Ibrahim Ulukaya
 */

/**
 * Library Requirements
 *
 * 1. Install composer (https://getcomposer.org)
 * 2. On the command line, change to this directory (api-samples/php)
 * 3. Require the google/apiclient library
 *    $ composer require google/apiclient:~2.0
 */
if (!file_exists(__DIR__ . '/vendor/autoload.php')) {
  throw new \Exception('please run "composer require google/apiclient:~2.0" in "' . __DIR__ .'"');
}

require_once __DIR__ . '/vendor/autoload.php';
session_start();


/*
 * You can acquire an OAuth 2.0 client ID and client secret from the
 * {{ Google Cloud Console }} <{{ https://cloud.google.com/console }}>
 * For more information about using OAuth 2.0 to access Google APIs, please see:
 * <https://developers.google.com/youtube/v3/guides/authentication>
 * Please ensure that you have enabled the YouTube Data API for your project.
 */
$OAUTH2_CLIENT_ID = 'REPLACE_ME';
$OAUTH2_CLIENT_SECRET = 'REPLACE_ME';

/* You can replace $VIDEO_ID with one of your videos' id, and text with the
 *  comment you want to be added.
 */
$VIDEO_ID = 'REPLACE_ME';
$TEXT = 'REPLACE_ME';

$client = new Google_Client();
$client->setClientId($OAUTH2_CLIENT_ID);
$client->setClientSecret($OAUTH2_CLIENT_SECRET);

/*
 * This OAuth 2.0 access scope allows for full read/write access to the
 * authenticated user's account and requires requests to use an SSL connection.
 */
$client->setScopes('https://www.googleapis.com/auth/youtube.force-ssl');
$redirect = filter_var('http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'],
    FILTER_SANITIZE_URL);
$client->setRedirectUri($redirect);

// Define an object that will be used to make all API requests.
$youtube = new Google_Service_YouTube($client);

// Check if an auth token exists for the required scopes
$tokenSessionKey = 'token-' . $client->prepareScopes();
if (isset($_GET['code'])) {
  if (strval($_SESSION['state']) !== strval($_GET['state'])) {
    die('The session state did not match.');
  }

  $client->authenticate($_GET['code']);
  $_SESSION[$tokenSessionKey] = $client->getAccessToken();
  header('Location: ' . $redirect);
}

if (isset($_SESSION[$tokenSessionKey])) {
  $client->setAccessToken($_SESSION[$tokenSessionKey]);
}

// Check to ensure that the access token was successfully acquired.
if ($client->getAccessToken()) {
  try {
    # All the available methods are used in sequence just for the sake of an example.

    // Call the YouTube Data API's commentThreads.list method to retrieve video comment threads.
    $videoCommentThreads = $youtube->commentThreads->listCommentThreads('snippet', array(
    'videoId' => $VIDEO_ID,
    'textFormat' => 'plainText',
    ));

    $parentId = $videoCommentThreads[0]['id'];

    # Create a comment snippet with text.
    $commentSnippet = new Google_Service_YouTube_CommentSnippet();
    $commentSnippet->setTextOriginal($TEXT);
    $commentSnippet->setParentId($parentId);

    # Create a comment with snippet.
    $comment = new Google_Service_YouTube_Comment();
    $comment->setSnippet($commentSnippet);

    # Call the YouTube Data API's comments.insert method to reply to a comment.
    # (If the intention is to create a new top-level comment, commentThreads.insert
    # method should be used instead.)
    $commentInsertResponse = $youtube->comments->insert('snippet', $comment);


    // Call the YouTube Data API's comments.list method to retrieve existing comment replies.
    $videoComments = $youtube->comments->listComments('snippet', array(
        'parentId' => $parentId,
        'textFormat' => 'plainText',
    ));

    if (empty($videoComments)) {
      $htmlBody .= "<h3>Can\'t get video comments.</h3>";
    } else {
      $videoComments[0]['snippet']['textOriginal'] = 'updated';

      // Call the YouTube Data API's comments.update method to update an existing comment.
      $videoCommentUpdateResponse = $youtube->comments->update('snippet', $videoComments[0]);

      // Call the YouTube Data API's comments.setModerationStatus method to set moderation
      // status of an existing comment.
      $youtube->comments->setModerationStatus($videoComments[0]['id'], 'published');

      // Call the YouTube Data API's comments.markAsSpam method to mark an existing comment as spam.
      $youtube->comments->markAsSpam($videoComments[0]['id']);

      // Call the YouTube Data API's comments.delete method to delete an existing comment.
      $youtube->comments->delete($videoComments[0]['id']);
    }

    $htmlBody .= "<h3>Video Comment Replies</h3><ul>";
    foreach ($videoComments as $comment) {
      $htmlBody .= sprintf('<li>%s: "%s"</li>', $comment['snippet']['authorDisplayName'],
          $comment['snippet']['textOriginal']);
    }
    $htmlBody .= '</ul>';

    $htmlBody .= "<h2>Replied to a comment for</h2><ul>";
    $htmlBody .= sprintf('<li>%s: "%s"</li>',
        $commentInsertResponse['snippet']['authorDisplayName'],
        $commentInsertResponse['snippet']['textDisplay']);
    $htmlBody .= '</ul>';

    $htmlBody .= "<h2>Updated comment for</h2><ul>";
    $htmlBody .= sprintf('<li>%s: "%s"</li>',
        $videoCommentUpdateResponse['snippet']['authorDisplayName'],
        $videoCommentUpdateResponse['snippet']['textDisplay']);
    $htmlBody .= '</ul>';

  } catch (Google_Service_Exception $e) {
    $htmlBody .= sprintf('<p>A service error occurred: <code>%s</code></p>',
        htmlspecialchars($e->getMessage()));
  } catch (Google_Exception $e) {
    $htmlBody .= sprintf('<p>An client error occurred: <code>%s</code></p>',
        htmlspecialchars($e->getMessage()));
  }

  $_SESSION[$tokenSessionKey] = $client->getAccessToken();
} elseif ($OAUTH2_CLIENT_ID == 'REPLACE_ME') {
  $htmlBody = <<<END
  <h3>Client Credentials Required</h3>
  <p>
    You need to set <code>\$OAUTH2_CLIENT_ID</code> and
    <code>\$OAUTH2_CLIENT_ID</code> before proceeding.
  <p>
END;
} else {
  // If the user hasn't authorized the app, initiate the OAuth flow
  $state = mt_rand();
  $client->setState($state);
  $_SESSION['state'] = $state;

  $authUrl = $client->createAuthUrl();
  $htmlBody = <<<END
    <h3>Authorization Required</h3>
    <p>You need to <a href="$authUrl">authorize access</a> before proceeding.<p>
END;
}
?>

<!doctype html>
<html>
<head>
<title>Insert, list, update, moderate, mark and delete comments.</title>
</head>
<body>
  <?=$htmlBody?>
</body>
</html>

PHP #2

This sample demonstrates how to use the following API methods to create and manage top-level comments:
  • It calls the commentThreads.insert method once with the channelId parameter to create a channel comment and once with the videoId parameter to create a video comment.
  • It calls the commentThreads.list method once with the channelId parameter to retrieve channel comments and once with the videoId parameter to retrieve video comments.
  • It calls the commentThreads.update method once to update a video comment and then again to update a channel comment. In each case, the request body contains the comment resource being updated.

This example uses the PHP client library.

<?php

/**
 * This sample creates and manages top-level comments by:
 *
 * 1. Creating a top-level comments for a video and a channel via "commentThreads.insert" method.
 * 2. Getting the top-level comments for a video and a channel via "commentThreads.list" method.
 * 3. Updating an existing comments via "commentThreads.update" method.
 *
 * @author Ibrahim Ulukaya
 */

/**
 * Library Requirements
 *
 * 1. Install composer (https://getcomposer.org)
 * 2. On the command line, change to this directory (api-samples/php)
 * 3. Require the google/apiclient library
 *    $ composer require google/apiclient:~2.0
 */
if (!file_exists(__DIR__ . '/vendor/autoload.php')) {
  throw new \Exception('please run "composer require google/apiclient:~2.0" in "' . __DIR__ .'"');
}

require_once __DIR__ . '/vendor/autoload.php';
session_start();


/*
 * You can acquire an OAuth 2.0 client ID and client secret from the
 * {{ Google Cloud Console }} <{{ https://cloud.google.com/console }}>
 * For more information about using OAuth 2.0 to access Google APIs, please see:
 * <https://developers.google.com/youtube/v3/guides/authentication>
 * Please ensure that you have enabled the YouTube Data API for your project.
 */
$OAUTH2_CLIENT_ID = 'REPLACE_ME';
$OAUTH2_CLIENT_SECRET = 'REPLACE_ME';

/* You can replace $VIDEO_ID with one of your videos' id, channel id with your channel's id,
 * and text with the comment you want to be added.
 */
$VIDEO_ID = 'REPLACE_ME';
$CHANNEL_ID = 'REPLACE_ME';
$TEXT = 'REPLACE_ME';

$client = new Google_Client();
$client->setClientId($OAUTH2_CLIENT_ID);
$client->setClientSecret($OAUTH2_CLIENT_SECRET);

/*
 * This OAuth 2.0 access scope allows for full read/write access to the
 * authenticated user's account and requires requests to use an SSL connection.
 */
$client->setScopes('https://www.googleapis.com/auth/youtube.force-ssl');
$redirect = filter_var('http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'],
    FILTER_SANITIZE_URL);
$client->setRedirectUri($redirect);

// Define an object that will be used to make all API requests.
$youtube = new Google_Service_YouTube($client);

// Check if an auth token exists for the required scopes
$tokenSessionKey = 'token-' . $client->prepareScopes();
if (isset($_GET['code'])) {
  if (strval($_SESSION['state']) !== strval($_GET['state'])) {
    die('The session state did not match.');
  }

  $client->authenticate($_GET['code']);
  $_SESSION[$tokenSessionKey] = $client->getAccessToken();
  header('Location: ' . $redirect);
}

if (isset($_SESSION[$tokenSessionKey])) {
  $client->setAccessToken($_SESSION[$tokenSessionKey]);
}

// Check to ensure that the access token was successfully acquired.
if ($client->getAccessToken()) {
  try {
    # All the available methods are used in sequence just for the sake of an example.

    # Insert channel comment by omitting videoId.
    # Create a comment snippet with text.
    $commentSnippet = new Google_Service_YouTube_CommentSnippet();
    $commentSnippet->setTextOriginal($TEXT);

    # Create a top-level comment with snippet.
    $topLevelComment = new Google_Service_YouTube_Comment();
    $topLevelComment->setSnippet($commentSnippet);

    # Create a comment thread snippet with channelId and top-level comment.
    $commentThreadSnippet = new Google_Service_YouTube_CommentThreadSnippet();
    $commentThreadSnippet->setChannelId($CHANNEL_ID);
    $commentThreadSnippet->setTopLevelComment($topLevelComment);

    # Create a comment thread with snippet.
    $commentThread = new Google_Service_YouTube_CommentThread();
    $commentThread->setSnippet($commentThreadSnippet);

    // Call the YouTube Data API's commentThreads.insert method to create a comment.
    $channelCommentInsertResponse = $youtube->commentThreads->insert('snippet', $commentThread);


    # Insert video comment
    $commentThreadSnippet->setVideoId($VIDEO_ID);
    // Call the YouTube Data API's commentThreads.insert method to create a comment.
    $videoCommentInsertResponse = $youtube->commentThreads->insert('snippet', $commentThread);

    // Call the YouTube Data API's commentThreads.list method to retrieve video comment threads.
    $videoComments = $youtube->commentThreads->listCommentThreads('snippet', array(
        'videoId' => $VIDEO_ID,
        'textFormat' => 'plainText',
    ));

    if (empty($videoComments)) {
      $htmlBody .= "<h3>Can\'t get video comments.</h3>";
    } else {
      $videoComments[0]['snippet']['topLevelComment']['snippet']['textOriginal'] = 'updated';
      $videoCommentUpdateResponse = $youtube->commentThreads->update('snippet', $videoComments[0]);
    }

    // Call the YouTube Data API's commentThreads.list method to retrieve channel comment threads.
    $channelComments = $youtube->commentThreads->listCommentThreads('snippet', array(
        'channelId' => $CHANNEL_ID,
        'textFormat' => 'plainText',
    ));

    if (empty($channelComments)) {
      $htmlBody .= "<h3>Can\'t get channel comments.</h3>";
    } else {
      $channelComments[0]['snippet']['topLevelComment']['snippet']['textOriginal'] = 'updated';
      $channelCommentUpdateResponse = $youtube->commentThreads->update('snippet', $channelComments[0]);
    }

    $htmlBody .= "<h2>Inserted channel comment for</h2><ul>";
    $comment = $channelCommentInsertResponse['snippet']['topLevelComment'];
    $htmlBody .= sprintf('<li>%s: "%s"</li>',
        $comment['snippet']['authorDisplayName'], $comment['snippet']['textDisplay']);
    $htmlBody .= '</ul>';

    $htmlBody .= "<h2>Inserted video comment for</h2><ul>";
    $comment = $videoCommentInsertResponse['snippet']['topLevelComment'];
    $htmlBody .= sprintf('<li>%s: "%s"</li>',
        $comment['snippet']['authorDisplayName'], $comment['snippet']['textDisplay']);
    $htmlBody .= '</ul>';

    $htmlBody .= "<h3>Video Comments</h3><ul>";
    foreach ($videoComments as $comment) {
      $htmlBody .= sprintf('<li>%s</li>', $comment['snippet']['topLevelComment']['snippet']['textOriginal']);
    }
    $htmlBody .= '</ul>';

    $htmlBody .= "<h3>Channel Comments</h3><ul>";
    foreach ($channelComments as $comment) {
      $htmlBody .= sprintf('<li>%s</li>', $comment['snippet']['topLevelComment']['snippet']['textOriginal']);
    }
    $htmlBody .= '</ul>';

    $htmlBody .= "<h2>Updated channel comment for</h2><ul>";
    $comment = $videoCommentUpdateResponse['snippet']['topLevelComment'];
    $htmlBody .= sprintf('<li>%s: "%s"</li>',
        $comment['snippet']['authorDisplayName'], $comment['snippet']['textDisplay']);
    $htmlBody .= '</ul>';

    $htmlBody .= "<h2>Updated video comment for</h2><ul>";
    $comment = $channelCommentUpdateResponse['snippet']['topLevelComment'];
    $htmlBody .= sprintf('<li>%s: "%s"</li>',
        $comment['snippet']['authorDisplayName'], $comment['snippet']['textDisplay']);
    $htmlBody .= '</ul>';

  } catch (Google_Service_Exception $e) {
    $htmlBody .= sprintf('<p>A service error occurred: <code>%s</code></p>',
        htmlspecialchars($e->getMessage()));
  } catch (Google_Exception $e) {
    $htmlBody .= sprintf('<p>An client error occurred: <code>%s</code></p>',
        htmlspecialchars($e->getMessage()));
  }

  $_SESSION[$tokenSessionKey] = $client->getAccessToken();
} elseif ($OAUTH2_CLIENT_ID == 'REPLACE_ME') {
  $htmlBody = <<<END
  <h3>Client Credentials Required</h3>
  <p>
    You need to set <code>\$OAUTH2_CLIENT_ID</code> and
    <code>\$OAUTH2_CLIENT_ID</code> before proceeding.
  <p>
END;
} else {
  // If the user hasn't authorized the app, initiate the OAuth flow
  $state = mt_rand();
  $client->setState($state);
  $_SESSION['state'] = $state;

  $authUrl = $client->createAuthUrl();
  $htmlBody = <<<END
  <h3>Authorization Required</h3>
  <p>You need to <a href="$authUrl">authorize access</a> before proceeding.<p>
END;
}
?>

<!doctype html>
<html>
<head>
<title>Insert, list and update top-level comments</title>
</head>
<body>
  <?=$htmlBody?>
</body>
</html>

Python #1

This sample demonstrates how to use the following API methods to create and manage comments:
  • It calls the commentThreads.list method with the videoId parameter set to retrieve comments for a video.
  • It calls the comments.insert method with the parentId parameter set to reply to an existing comment.
  • It calls the comments.list method with the parentId parameter to retrieve the comments in the thread.
  • It calls the comments.update method with comment in the request body to update a comment.
  • It calls the comments.setModerationStatus method to set the moderation status of the comment, the comments.markAsSpam method to mark the comment as spam, and the comments.delete method to delete the comment, using the id parameter to identify the comment.

This example uses the Python client library.

#!/usr/bin/python

# Usage example:
# python comments.py --videoid='<video_id>' --text='<text>'

import httplib2
import os
import sys

from apiclient.discovery import build_from_document
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 Cloud Console }} at
# {{ https://cloud.google.com/console }}.
# 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 and requires requests to use an SSL connection.
YOUTUBE_READ_WRITE_SSL_SCOPE = "https://www.googleapis.com/auth/youtube.force-ssl"
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 APIs 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))

# Authorize the request and store authorization credentials.
def get_authenticated_service(args):
  flow = flow_from_clientsecrets(CLIENT_SECRETS_FILE, scope=YOUTUBE_READ_WRITE_SSL_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)

  # Trusted testers can download this discovery document from the developers page
  # and it should be in the same directory with the code.
  with open("youtube-v3-discoverydocument.json", "r") as f:
    doc = f.read()
    return build_from_document(doc, http=credentials.authorize(httplib2.Http()))


# Call the API's commentThreads.list method to list the existing comment threads.
def get_comment_threads(youtube, video_id):
  results = youtube.commentThreads().list(
    part="snippet",
    videoId=video_id,
    textFormat="plainText"
  ).execute()

  for item in results["items"]:
    comment = item["snippet"]["topLevelComment"]
    author = comment["snippet"]["authorDisplayName"]
    text = comment["snippet"]["textDisplay"]
    print "Comment by %s: %s" % (author, text)

  return results["items"]


# Call the API's comments.list method to list the existing comment replies.
def get_comments(youtube, parent_id):
  results = youtube.comments().list(
    part="snippet",
    parentId=parent_id,
    textFormat="plainText"
  ).execute()

  for item in results["items"]:
    author = item["snippet"]["authorDisplayName"]
    text = item["snippet"]["textDisplay"]
    print "Comment by %s: %s" % (author, text)

  return results["items"]


# Call the API's comments.insert method to reply to a comment.
# (If the intention is to create a new to-level comment, commentThreads.insert
# method should be used instead.)
def insert_comment(youtube, parent_id, text):
  insert_result = youtube.comments().insert(
    part="snippet",
    body=dict(
      snippet=dict(
        parentId=parent_id,
        textOriginal=text
      )
    )
  ).execute()

  author = insert_result["snippet"]["authorDisplayName"]
  text = insert_result["snippet"]["textDisplay"]
  print "Replied to a comment for %s: %s" % (author, text)


# Call the API's comments.update method to update an existing comment.
def update_comment(youtube, comment):
  comment["snippet"]["textOriginal"] = 'updated'
  update_result = youtube.comments().update(
    part="snippet",
    body=comment
  ).execute()

  author = update_result["snippet"]["authorDisplayName"]
  text = update_result["snippet"]["textDisplay"]
  print "Updated comment for %s: %s" % (author, text)


# Call the API's comments.setModerationStatus method to set moderation status of an
# existing comment.
def set_moderation_status(youtube, comment):
  youtube.comments().setModerationStatus(
    id=comment["id"],
    moderationStatus="published"
  ).execute()

  print "%s moderated succesfully" % (comment["id"])


# Call the API's comments.markAsSpam method to mark an existing comment as spam.
def mark_as_spam(youtube, comment):
  youtube.comments().markAsSpam(
    id=comment["id"]
  ).execute()

  print "%s marked as spam succesfully" % (comment["id"])


# Call the API's comments.delete method to delete an existing comment.
def delete_comment(youtube, comment):
  youtube.comments().delete(
    id=comment["id"]
  ).execute()

  print "%s deleted succesfully" % (comment["id"])


if __name__ == "__main__":
  # The "videoid" option specifies the YouTube video ID that uniquely
  # identifies the video for which the comment will be inserted.
  argparser.add_argument("--videoid",
    help="Required; ID for video for which the comment will be inserted.")
  # The "text" option specifies the text that will be used as comment.
  argparser.add_argument("--text", help="Required; text that will be used as comment.")
  args = argparser.parse_args()

  if not args.videoid:
    exit("Please specify videoid using the --videoid= parameter.")
  if not args.text:
    exit("Please specify text using the --text= parameter.")

  youtube = get_authenticated_service(args)
  # All the available methods are used in sequence just for the sake of an example.
  try:
    video_comment_threads = get_comment_threads(youtube, args.videoid)
    parent_id = video_comment_threads[0]["id"]
    insert_comment(youtube, parent_id, args.text)
    video_comments = get_comments(youtube, parent_id)
    update_comment(youtube, video_comments[0])
    set_moderation_status(youtube, video_comments[0])
    mark_as_spam(youtube, video_comments[0])
    delete_comment(youtube, video_comments[0])
  except HttpError, e:
    print "An HTTP error %d occurred:\n%s" % (e.resp.status, e.content)
  else:
    print "Inserted, listed, updated, moderated, marked and deleted comments."

Python #2

This sample demonstrates how to use the following API methods to create and manage top-level comments:
  • It calls the commentThreads.insert method once with the channelId parameter to create a channel comment and once with the videoId parameter to create a video comment.
  • It calls the commentThreads.list method once with the channelId parameter to retrieve channel comments and once with the videoId parameter to retrieve video comments.
  • It calls the commentThreads.update method once to update a video comment and then again to update a channel comment. In each case, the request body contains the comment resource being updated.

This example uses the Python client library.

#!/usr/bin/python

# Usage example:
# python comment_threads.py --channelid='<channel_id>' --videoid='<video_id>' --text='<text>'

import httplib2
import os
import sys

from apiclient.discovery import build_from_document
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 Cloud Console }} at
# {{ https://cloud.google.com/console }}.
# 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 and requires requests to use an SSL connection.
YOUTUBE_READ_WRITE_SSL_SCOPE = "https://www.googleapis.com/auth/youtube.force-ssl"
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 APIs 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))

# Authorize the request and store authorization credentials.
def get_authenticated_service(args):
  flow = flow_from_clientsecrets(CLIENT_SECRETS_FILE, scope=YOUTUBE_READ_WRITE_SSL_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)

  # Trusted testers can download this discovery document from the developers page
  # and it should be in the same directory with the code.
  with open("youtube-v3-discoverydocument.json", "r") as f:
    doc = f.read()
    return build_from_document(doc, http=credentials.authorize(httplib2.Http()))


# Call the API's commentThreads.list method to list the existing comments.
def get_comments(youtube, video_id, channel_id):
  results = youtube.commentThreads().list(
    part="snippet",
    videoId=video_id,
    channelId=channel_id,
    textFormat="plainText"
  ).execute()

  for item in results["items"]:
    comment = item["snippet"]["topLevelComment"]
    author = comment["snippet"]["authorDisplayName"]
    text = comment["snippet"]["textDisplay"]
    print "Comment by %s: %s" % (author, text)

  return results["items"]


# Call the API's commentThreads.insert method to insert a comment.
def insert_comment(youtube, channel_id, video_id, text):
  insert_result = youtube.commentThreads().insert(
    part="snippet",
    body=dict(
      snippet=dict(
        channelId=channel_id,
        videoId=video_id,
        topLevelComment=dict(
          snippet=dict(
            textOriginal=text
          )
        )
      )
    )
  ).execute()

  comment = insert_result["snippet"]["topLevelComment"]
  author = comment["snippet"]["authorDisplayName"]
  text = comment["snippet"]["textDisplay"]
  print "Inserted comment for %s: %s" % (author, text)


# Call the API's commentThreads.update method to update an existing comment.
def update_comment(youtube, comment):
  comment["snippet"]["topLevelComment"]["snippet"]["textOriginal"] = 'updated'
  update_result = youtube.commentThreads().update(
    part="snippet",
    body=comment
  ).execute()

  comment = update_result["snippet"]["topLevelComment"]
  author = comment["snippet"]["authorDisplayName"]
  text = comment["snippet"]["textDisplay"]
  print "Updated comment for %s: %s" % (author, text)


if __name__ == "__main__":
  # The "channelid" option specifies the YouTube channel ID that uniquely
  # identifies the channel for which the comment will be inserted.
  argparser.add_argument("--channelid",
    help="Required; ID for channel for which the comment will be inserted.")
  # The "videoid" option specifies the YouTube video ID that uniquely
  # identifies the video for which the comment will be inserted.
  argparser.add_argument("--videoid",
    help="Required; ID for video for which the comment will be inserted.")
  # The "text" option specifies the text that will be used as comment.
  argparser.add_argument("--text", help="Required; text that will be used as comment.")
  args = argparser.parse_args()

  if not args.channelid:
    exit("Please specify channelid using the --channelid= parameter.")
  if not args.videoid:
    exit("Please specify videoid using the --videoid= parameter.")
  if not args.text:
    exit("Please specify text using the --text= parameter.")

  youtube = get_authenticated_service(args)
  try:
    # All the available methods are used in sequence just for the sake of an example.
    # Insert channel comment by omitting videoId
    insert_comment(youtube, args.channelid, None, args.text)
    # Insert video comment
    insert_comment(youtube, args.channelid, args.videoid, args.text)
    video_comments = get_comments(youtube, args.videoid, None)
    if video_comments:
      update_comment(youtube, video_comments[0])
    channel_comments = get_comments(youtube, None, args.channelid)
    if channel_comments:
      update_comment(youtube, channel_comments[0])
  except HttpError, e:
    print "An HTTP error %d occurred:\n%s" % (e.resp.status, e.content)
  else:
    print "Inserted, listed and updated top-level comments."

Errors

The following table 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) operationNotSupported The id filter is only compatible with comments based on Google+.
badRequest (400) processingFailure The API server failed to successfully process the request. While this can be a transient error, it usually indicates that the request's input is invalid. Check the structure of the commentThread resource in the request body to ensure that it is valid.
forbidden (403) commentsDisabled The video identified by the videoId parameter has disabled comments.
forbidden (403) forbidden One or more of the requested comment threads cannot be retrieved due to insufficient permissions. The request might not be properly authorized.
notFound (404) channelNotFound The channel identified by either the channelId or the allThreadsRelatedToChannelId parameter could not be found.
notFound (404) commentThreadNotFound One or more of the specified comment threads cannot be found. Check the values of the request's id parameter to ensure that it is correct.
notFound (404) videoNotFound The video identified by the videoId parameter could not be found.