Monday, August 2, 2021

Running Puppeteer inside .NET Azure Function

I wanted to check whether Puppeteer can run inside a .NET Azure Function as code and not in a Docker Container (because with Docker it's definitely possible).

Puppeteer is a Node library that provides a high-level API to control Chrome or Chromium over the DevTools Protocol. Puppeteer runs headless by default, but can be configured to run full (non-headless) Chrome or Chromium.

I have created an Azure Function Project with a single HTTP trigger function. So to make sure Puppeteer can run inside a .NET Azure Function App, I am going to call my function with a query parameter of a URL, and I am expecting my function to run Puppeteer, navigate to that URL, download its content and return. So it proves my requirement.

First, we need to install PuppeteerSharp NuGet package, which is the official .NET port of the official Puppeteer. And it's depending on .NETStandard 2.0, so we are all good for .NET Core 2.x, 3.x, and .NET 5 compatibility.

using PuppeteerSharp;

public static class Function1
{
    [FunctionName("Function1")]
    public static async Task<IActionResult> Run(
        [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)] HttpRequest req,
        ILogger log)
    {
        log.LogInformation("C# HTTP trigger function processed a request.");

        string url = req.Query["url"];
        if (string.IsNullOrEmpty(url))
        {
            return new BadRequestObjectResult($"Missing 'url' query parameter.");
        }

        var browserFetcher = new BrowserFetcher(new BrowserFetcherOptions
        {
            Path = Path.GetTempPath()
        });

        await browserFetcher.DownloadAsync(BrowserFetcher.DefaultChromiumRevision);

        Browser browser = await Puppeteer.LaunchAsync(new LaunchOptions
        {
            Headless = true,
            ExecutablePath = browserFetcher.RevisionInfo(BrowserFetcher.DefaultChromiumRevision.ToString()).ExecutablePath
        });

        using Page page = await browser.NewPageAsync();
        await page.GoToAsync(url);

        string responseMessage = await page.GetContentAsync();

        return new OkObjectResult(responseMessage);
    }
}

Here the code itself is self-descriptive, I am downloading the chromium browser, launching that through Puppeteer, navigating to the URL, reading the content, and finally returning the content.

I ran the function app locally and the results looked promising.
Working Locally

Then I have deployed this to an Azure Function App with following configuration.
Azure Function App Configuration: Publish, Runtime stack and Version
Azure Function App Configuration: Operating System
Once deployed, tested whether it's working.
Working on Azure
Works like a charm.

Hope this helps.

Happy Coding.

Regards,
Jaliya

No comments:

Post a Comment