0

I'm working on my own ChatBot for YouTube in Winforms and C#. It already works on Twitch and I'm trying to replicate the functionality for Youtube using the C# API. I can download the Chat Messages no problem, but creating a chat message is causing me a headache as I'm getting a 403, Insufficient Permission error. The full error message is

Google.Apis.Requests.RequestError
Insufficient Permission [403]
Errors [
    Message[Insufficient Permission] Location[ - ] Reason[insufficientPermissions] Domain[global]
]

After some searching I've tried most things that I can find and have still come up empty as to what exactly is causing this. I get it's a permission issue and I obviously need to set something but I can't figure out what. My code is below and definitely works for reading data... but i don't know why it won't work for writing.

  public class YouTubeDataWrapper
    {
        private YouTubeService youTubeService;
        private string liveChatId;
        private bool updatingChat;
        private int prevResultCount;

        public List<YouTubeMessage> Messages { get; private set; }
        public bool Connected { get; private set; }
        public bool ChatUpdated { get; set; }
        //public Authorisation Authorisation { get; set; }
        //public AccessToken AccessToken { get; set; }

        public YouTubeDataWrapper()
        {
            this.Messages = new List<YouTubeMessage>();
        }

        public async void Connect()
        {
            Stream stream = new FileStream("client_secrets.json", FileMode.Open);
            UserCredential credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(GoogleClientSecrets.Load(stream).Secrets, new[] { YouTubeService.Scope.YoutubeForceSsl }, "user", CancellationToken.None, new FileDataStore(this.GetType().ToString()));
            stream.Close();
            stream.Dispose();

            this.youTubeService = new YouTubeService(new BaseClientService.Initializer()
            {
                HttpClientInitializer = credential,
                ApplicationName = this.GetType().ToString()
            });

            var res = this.youTubeService.LiveBroadcasts.List("id,snippet,contentDetails,status");
            res.BroadcastType = LiveBroadcastsResource.ListRequest.BroadcastTypeEnum.Persistent;
            res.Mine = true;

            //res.BroadcastStatus = LiveBroadcastsResource.ListRequest.BroadcastStatusEnum.Active;
            var resListResponse = await res.ExecuteAsync();

            IEnumerator<LiveBroadcast> ie = resListResponse.Items.GetEnumerator();
            while (ie.MoveNext() && string.IsNullOrEmpty(this.liveChatId))
            {
                LiveBroadcast livebroadcast = ie.Current;
                string id = livebroadcast.Snippet.LiveChatId;
                if (!string.IsNullOrEmpty(id))
                {
                    this.liveChatId = id;
                    this.Connected = true;
                }

                bool? def = livebroadcast.Snippet.IsDefaultBroadcast;
                string title = livebroadcast.Snippet.Title;
                LiveBroadcastStatus status = livebroadcast.Status;
            }
        }

        public async void UpdateChat()
        {
            if (!this.updatingChat)
            {
                if (!string.IsNullOrEmpty(this.liveChatId) && this.Connected)
                {
                    this.updatingChat = true;
                    var livechat = this.youTubeService.LiveChatMessages.List(this.liveChatId, "id,snippet,authorDetails");
                    var livechatResponse = await livechat.ExecuteAsync();

                    PageInfo pageInfo = livechatResponse.PageInfo;

                    this.ChatUpdated = false;

                    if (pageInfo.TotalResults.HasValue)
                    {
                        if (!this.prevResultCount.Equals(pageInfo.TotalResults.Value))
                        {
                            this.prevResultCount = pageInfo.TotalResults.Value;
                            this.ChatUpdated = true;
                        }
                    }

                    if (this.ChatUpdated)
                    {
                        this.Messages = new List<YouTubeMessage>();

                        foreach (var livemessage in livechatResponse.Items)
                        {
                            string id = livemessage.Id;
                            string displayName = livemessage.AuthorDetails.DisplayName;
                            string message = livemessage.Snippet.DisplayMessage;

                            YouTubeMessage msg = new YouTubeMessage(id, displayName, message);

                            string line = string.Format("{0}: {1}", displayName, message);
                            if (!this.Messages.Contains(msg))
                            {
                                this.Messages.Add(msg);
                            }
                        }
                    }
                    this.updatingChat = false;
                }
            }
        }

        public async void SendMessage(string message)
        {
            LiveChatMessage liveMessage = new LiveChatMessage();

            liveMessage.Snippet = new LiveChatMessageSnippet() { LiveChatId = this.liveChatId, Type = "textMessageEvent", TextMessageDetails = new LiveChatTextMessageDetails() { MessageText = message } };

            var insert = this.youTubeService.LiveChatMessages.Insert(liveMessage, "snippet");
            var response = await insert.ExecuteAsync();

            if (response != null)
            {

            }

        }

}

The main code in question is the Send Message method. I've tried changing the Scope of the UserCredentials to everything I can try to no avail. Any ideas?

mikelomaxxx14
  • 133
  • 12

2 Answers2

1

From the YouTube Data API - Error, your error 403 or insufficientPermissions is error in the OAuth 2.0 token provided for the request specifies scopes that are insufficient for accessing the requested data.

So make sure you use proper Scope in your application. Here is the example of scope that is needed in your application.

https://www.googleapis.com/auth/youtube.force-ssl

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

For more information about this error 403, you can check this related SO question.

Community
  • 1
  • 1
KENdi
  • 7,576
  • 2
  • 16
  • 31
  • As you can see from the code, I am using the proper scope. I've tried both YouTube and YouTubeForceSSL and neither work. Maybe, if I can figure out how, I'll revoke the access and redo it. – mikelomaxxx14 Jul 22 '16 at 18:07
  • 1
    Ok, revoking and retrying fixed it... don't know why! – mikelomaxxx14 Jul 22 '16 at 18:13
0

Turns out that revoking the access and then re-doing it fixed the issue. The error message was not very helpful.

mikelomaxxx14
  • 133
  • 12