I have this Azure function, which has the code to upload a video to my YouTube channel whenever there is a video file in the "video" container. The code I am using is from the YouTube API sample code: https://developers.google.com/youtube/v3/docs/videos/insert . I have taken this code, and I put it inside an Azure function(code below). When I compile and run the function locally, it runs fine and I am able to upload a video using Azure Storage Explorer(below is the console output log) and I see the videos get uploaded in my YouTube channel fine.
However, when I publish the function to Azure portal, and run the function, the function just TimeOuts because it is expecting a UI as it requires user interaction for sign-in. I am wondering how can I get over this OAuth issue? Is there a way to add workflow step in Azure app that prompts the user for credentials? I would like to be able to use my function on Azure without it timing out.
Error when I publish function to Azure:
Console Output when I run locally:
Now listening on: http://0.0.0.0:7071
Application started. Press Ctrl+C to shut down.
[3/26/2020 4:46:17 AM] Host lock lease acquired by instance ID '000000000000000000000000A74A8599'.
[3/26/2020 4:48:27 AM] Executing 'Function1' (Reason='New blob detected: video/Test.mp4', Id=62898b7f-878f-48b2-ace1-dee34a884652)
[3/26/2020 4:48:46 AM] test.mp4
[3/26/2020 4:48:46 AM] Getting client secrets.
[3/26/2020 4:48:46 AM] Done getting secrets.
[3/26/2020 4:48:46 AM] Creating youtube service
[3/26/2020 4:48:46 AM] Done creating service.
[3/26/2020 4:48:46 AM] Trying to upload video
[3/26/2020 4:49:21 AM] Done uploading video.
[3/26/2020 4:49:21 AM] Executed 'Function1' (Succeeded, Id=62898b7f-878f-48b2-ace1-dee34a884652)
Client_Secrets.json:
{
"installed": {
"client_id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com",
"project_id": "testindexer",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_secret": "xxxxxxxxxxxxxxxxxxxxxxxx",
"redirect_uris": [ "urn:ietf:wg:oauth:2.0:oob", "http://localhost" ]
}
}
using System;
using System.IO;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Services;
using Google.Apis.YouTube.v3;
using Google.Apis.YouTube.v3.Data;
using Microsoft.Azure.WebJobs;
using Microsoft.Extensions.Logging;
namespace AzureFunctionToUploadToYoutube
{
public static class Function1
{
[FunctionName("Function1")]
public static async Task Run([BlobTrigger("video/{name}", Connection = "AzureWebJobsStorage")]Stream myBlob, string name, Microsoft.Azure.WebJobs.ExecutionContext context, ILogger log)
{
log.LogInformation("Function triggered by blob." + name);
UserCredential credential;
log.LogInformation("Getting client secrets.");
using (var stream = new FileStream(System.IO.Path.Combine(context.FunctionAppDirectory, "client_secrets.json"), FileMode.Open, FileAccess.Read))
{
credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
new[] { YouTubeService.Scope.YoutubeUpload },
"user",
CancellationToken.None
new FileDataStore("Google.Apis.Auth.OAuth2.Responses.TokenResponse-use",true)
);
}
log.LogInformation("Done getting secrets.");
log.LogInformation("Creating youtube service");
var youtubeService = new YouTubeService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = Assembly.GetExecutingAssembly().GetName().Name
});
log.LogInformation("Done creating service.");
var video = new Video();
video.Snippet = new VideoSnippet();
video.Snippet.Title = name;
video.Snippet.Description = "Seattle Channel";
video.Snippet.Tags = new string[] { "tag1", "tag2" };
video.Snippet.CategoryId = "22";
video.Status = new VideoStatus();
video.Status.PrivacyStatus = "unlisted";
var VideoInsertRequest = youtubeService.Videos.Insert(video, "snippet,status", myBlob, "video/*");
log.LogInformation("Trying to upload video");
try
{
await VideoInsertRequest.UploadAsync();
log.LogInformation("Done uploading video.");
}
catch (Exception ex)
{
log.LogInformation("Error uploading video: " + ex.Message);
}
}
}
}