Gotenberg Sharp API Client

repository·develop·Indexed 41 days ago

https://github.com/changemakerstudios/gotenbergsharpapiclient

A .NET C# client for the Gotenberg API (v7 & v8) used for stateless conversion of HTML, Markdown, and Office documents to PDF. It supports PDF manipulation tasks such as merging, rotating, encrypting, and watermarking, as well as capturing screenshots of HTML or URLs. The client features integrated support for Dependency Injection, Polly-based retry policies, asynchronous webhook processing, and version-gated feature checks for Gotenberg instances.

Tokens
13.2K
Snippets
62
Records
68
Agent score
53%

What's inside Gotenberg Sharp

  1. Overview of GotenbergSharpApiClient features

    develop

    GotenbergSharpApiClient is a .NET C# client for the Gotenberg stateless API. It supports the following capabilities:

    • HTML/URL to PDF: Convert HTML content or URLs to PDF using Chromium.
    • Screenshots: Capture screenshots of HTML or URLs as PNG, JPEG, or WebP.
    • Office to PDF: Convert Word, Excel, PowerPoint (100+ formats) via LibreOffice.
    • PDF Manipulation: Merge, flatten, rotate, split, encrypt, watermark, stamp, and embed files.
    • PDF/A & PDF/UA: Generate archive-ready and accessible PDF output.
    • Metadata & Bookmarks: Read and write PDF metadata and document outlines.
    • Webhooks: Support for asynchronous PDF generation with callbacks.
    • DI-Ready: Built for dependency injection with Polly retry policies.
  2. How to write and read PDF bookmarks

    develop

    Bookmarks (document outlines) allow you to create a clickable table of contents in the PDF sidebar.

    Requirements: Requires Gotenberg 8.28.0 or higher. Older versions will throw a GotenbergVersionNotSupportedException.

    Writing Bookmarks:

    • Use PdfEngineBuilders.WriteBookmarks for a single document outline.
    • Use PdfEngineBuilders.WriteBookmarksPerFile if you are uploading multiple PDFs and want each to have its own outline. The keys in the builder must match the filenames used in .WithPdfs().
    • You can use a fluent builder or pass a list of Bookmark objects.

    Reading Bookmarks:

    • Use ReadPdfBookmarksAsync to get a typed collection of bookmarks.
    • Use ReadPdfBookmarksJsonAsync to get the raw JSON response.
    // Writing nested bookmarks
    using var result = await sharpClient.ExecutePdfEngineAsync(
        PdfEngineBuilders.WriteBookmarks(b => b
                .Add("Introduction", 1)
                .Add("Chapter 1", 2, c => c
                    .Add("Section 1.1", 3)
                    .Add("Section 1.2", 5))
                .Add("Appendix", 9))
            .WithPdfs(a => a.AddItem("doc.pdf", pdfBytes)));
    
    // Reading bookmarks
    var outlines = await sharpClient.ReadPdfBookmarksAsync(
        PdfEngineBuilders.ReadBookmarks()
            .WithPdfs(a => a.AddItem("doc.pdf", pdfBytes)));
    
    foreach (var bookmark in outlines["doc.pdf"])
    {
        Console.WriteLine($"{bookmark.Title} -> page {bookmark.Page}");
    }
  3. Use DDD Value Objects for validated configuration

    develop

    The client uses Domain-Driven Design (DDD) value objects to ensure configuration is valid before it is sent to the Gotenberg API. Invalid values will throw an exception immediately during construction.

    Key Value Objects:

    • CssSelector.Create("#app"): Non-empty string.
    • GotenbergStatusCode.Create(499): Must be between 100-599.
    • DomainName.Create("cdn.example.com"): Non-empty, trimmed.
    • EmulatedMediaFeature.PrefersColorScheme("dark"): Non-empty name and value.
    • PdfPassword.Create("secret"): Non-empty (redacted in ToString()).
    • ImageQuality.Create(85): Range 1-100.
    • ImageResolution.Dpi300: Supported values: 75, 150, 300, 600, 1200 DPI.
    • RotationAngle.Degrees90: Supported values: 90, 180, 270.
    • PageRanges.Create("1-3,5,8-10"): Validated format.
    • ScreenDimension.Create(1920): Positive integer.
    • CompressionQuality.Create(90): Range 0-100.
  4. Handle Gotenberg version compatibility

    develop

    The client performs version checking to prevent sending requests that use features not supported by your running Gotenberg instance. The client fetches and caches the version from the /version endpoint.

    Feature Gating

    • Split (PdfEngineBuilders.Split): Requires 8.15.0+
    • Flatten (PdfEngineBuilders.Flatten): Requires 8.16.0+
    • Embedded files (PdfEngineBuilders.Embed): Requires 8.25.0+
    • Bookmarks (ReadBookmarks / WriteBookmarks): Requires 8.28.0+

    Note: Rotate, metadata, watermark, stamp, merge, and screenshot routes are not gated as they predate 8.5.

    Checking support before executing

    You can check if a request is supported to avoid catching GotenbergVersionNotSupportedException.

    var request = PdfEngineBuilders.ReadBookmarks()
        .WithPdfs(a => a.AddItem("doc.pdf", pdfBytes))
        .Build();
    
    if (await sharpClient.SupportsAsync(request))
        outlines = await sharpClient.ReadPdfBookmarksAsync(request);

    Handling services without a version endpoint

    If your Gotenberg service is behind a proxy that hides the /version route, you can disable version enforcement:

    sharpClient.EnforceMinimumVersion = false;
  5. Convert URL to PDF

    develop

    Use UrlRequestBuilder to convert a web URL into a PDF. This allows you to specify page ranges, add asynchronous headers and footers, and configure page properties like orientation and paper size.

    var builder = new UrlRequestBuilder()
        .SetUrl("https://www.example.com")
        .ConfigureRequest(config => config.SetPageRanges("1-2"))
        .AddAsyncHeaderFooter(async doc =>
            doc.SetHeader(await File.ReadAllTextAsync(headerPath))
                .SetFooter(await File.ReadAllBytesAsync(footerPath)))
        .WithPageProperties(pp =>
        {
            pp.SetPaperSize(PaperSizes.A4)
                .SetMargins(Margins.None)
                .SetScale(.90)
                .SetLandscape();
        });
    
    var result = await sharpClient.UrlToPdfAsync(builder);
  6. Install and Setup Gotenberg Sharp API Client

    develop

    To use the client, you must first have a Gotenberg instance running (typically via Docker) and then install the NuGet package in your .NET project.

    1. Run Gotenberg via Docker:
    docker run --rm -p 3000:3000 gotenberg/gotenberg:latest
    1. Install the NuGet package:
    dotnet add package Gotenberg.Sharp.Api.Client
    1. Configure Dependency Injection (DI): In your Startup.cs or equivalent service configuration, bind your options from configuration and register the client:
    services.AddOptions<GotenbergSharpClientOptions>()
        .Bind(Configuration.GetSection("GotenbergSharpClient"));
    services.AddGotenbergSharpClient();
    // Startup.cs
    services.AddOptions<GotenbergSharpClientOptions>()
        .Bind(Configuration.GetSection("GotenbergSharpClient"));
    services.AddGotenbergSharpClient();
  7. Convert HTML to PDF

    develop

    Use HtmlRequestBuilder to convert HTML content into a PDF. You can include embedded assets (like images), headers, footers, and configure page properties such as paper size, margins, and scale. Assets can be added asynchronously using WithAsyncAssets.

    var builder = new HtmlRequestBuilder()
        .AddDocument(doc =>
            doc.SetBody(GetBody()).SetFooter(GetFooter()))
        .WithPageProperties(pp =>
        {
            pp.SetPaperSize(PaperSizes.A3)
                .SetMargins(Margins.None)
                .SetScale(.99);
        })
        .WithAsyncAssets(async assets =>
            assets.AddItem("some-image.jpg", await GetImageBytes()));
    
    var result = await sharpClient.HtmlToPdfAsync(builder);
  8. Add Cookies and Custom HTTP Headers to requests

    develop

    You can inject cookies and custom HTTP headers into the Chromium session using SetConversionBehaviors. This is useful for authenticated sessions or passing specific metadata to the target URL.

    // Adding Cookies
    builder.SetConversionBehaviors(b => b
        .AddCookie(new Cookie
        {
            Name = "session_token",
            Value = "abc123xyz",
            Domain = "example.com",
            Path = "/",
            Secure = true,
            HttpOnly = true,
            SameSite = "Lax"
        }));
    
    // Adding Custom HTTP Headers
    builder.SetConversionBehaviors(b => b
        .AddAdditionalHeaders("Authorization", "Bearer token123"));
  9. Convert and merge Office documents to PDF

    develop

    Use MergeOfficeBuilder to convert and merge various Office formats (Word, Excel, PowerPoint, and 100+ others) into a single PDF. You can provide assets asynchronously and configure the output PDF format using SetPdfOutputOptions.

    var builder = new MergeOfficeBuilder()
        .WithAsyncAssets(async a => a.AddItems(await GetDocsAsync(sourceDirectory)))
        .SetPdfOutputOptions(o => o.SetPdfFormat(PdfFormat.A2b));
    
    var result = await sharpClient.MergeOfficeDocsAsync(builder);
  10. Capture a screenshot from a URL

    develop

    Use ScreenshotUrlRequestBuilder to capture a screenshot of a specific web address. You can set the URL and configure properties such as size, format, quality, and clipping. The result is returned as a stream.

    var builder = new ScreenshotUrlRequestBuilder()
        .SetUrl("https://example.com")
        .WithScreenshotProperties(p => p
            .SetSize(1024, 768)
            .SetFormat(ScreenshotFormat.Jpeg)
            .SetQuality(90)
            .SetClip());
    
    var imageStream = await sharpClient.ScreenshotUrlAsync(builder);
  11. Run Gotenberg using Docker

    develop

    Before using the client, you must have a Gotenberg instance running. You can use Docker to pull and run the official image.

    To run a standard instance on port 3000 with an increased API timeout and debug logging, use the following command:

    docker pull gotenberg/gotenberg:latest
    docker run --name gotenberg --rm -p 3000:3000 gotenberg/gotenberg:latest gotenberg --api-timeout=1800s --log-level=debug