Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] Async generation #84

Draft
wants to merge 25 commits into
base: main
Choose a base branch
from

Conversation

maelanleborgne
Copy link
Contributor

@maelanleborgne maelanleborgne commented Jun 25, 2024

Closes #46

Gotenberg allows async generation of files by passing webhooks urls in dedicated headers. Doing this, the request to Gotenberg server returns a 204 immediately, and once the file is generated, a call will be made by Gotenberg server on the specified endpoint to upload the generated file. This PR aims at enabling easy integration of this feature with the bundle.

The base of the feature is a new interface AsyncBuilderInterface that defines a generateAsync method. The AbstractPdfBuilder and AbstractScreenshotBuilder now implement this interface.
Another important addition is the webhookUrls(string $successWebhook, string|null $errorWebhook) that allows directly setting the webhooks url to use with the builders.

To make things easier when not working directly with urls (if you'd like to generate the url from a route, or if using the Webhook component), a some new configuration options are available :

# packages/sensiolabs_gotenberg.yaml

sensiolabs_gotenberg:  
    # ...
    webhook:  
        # Here you can define any number of webhook configuration so that you can reuse them in builder configs or to switch configuration at runtime
        my_config_name:  
            success:  
                url: 'http://example.com/webhook'
                # route: ['my_route_name', ['param1', 'param2']]
            # This "error" entry is optional. If not set, the "success" configuration will be used for both success and error.
            error:  
                url: 'http://example.com/webhook-error'
                # route: ['my_route_name', ['param1', 'param2']]
    default_options:
        # Here you can define which webhook config to use by default
        webhook: 'my_config_name'
        pdf:
            html:
                webhook: 'my_config_name'
                # Or you can define a specific configuration directly from here
                # webhook:
                #    success:
                #	    url: 'http://example.com/custom-webhook'
    #...

TODO:

  • Write documentation
  • Add example config to flex recipe
  • Change icon in profiler
  • Add default webhook configuration in profiler
  • Add/fix tests

@maelanleborgne maelanleborgne changed the title Feature/webhook integration [Feature] Async generation Jun 25, 2024
@maelanleborgne maelanleborgne marked this pull request as draft June 25, 2024 07:40
@Neirda24
Copy link
Contributor

After discussing this with @ConstantBqt we have another usecase to take into account : If we generate the PDF but the webhook is not setup in our own app but is external. We should be able to declare such case. WDYT @maelanleborgne ?

@maelanleborgne
Copy link
Contributor Author

After discussing this with @ConstantBqt we have another usecase to take into account : If we generate the PDF but the webhook is not setup in our own app but is external. We should be able to declare such case. WDYT @maelanleborgne ?

This is already present in the PR :

// ...
$this->gotenberg->html()
  ->webhookUrls('https://external.service/webhook', 'https://external.service/webhook-error')
  ->webhookExtraHeaders(['X-ExternalService-Secret' => 'a_secret'])
  ->generateAsync()
;

or via the configuration :

sensiolabs_gotenberg:  
    # ...
    webhook:  
        external_service:  
            success:  
                url: 'https://external.service/webhook'
            error:  
                url: 'https://external.service/webhook-error'
    default_options:
        pdf:
            html:
                webhook: 'external_service'

Or maybe I'm missing the point.

@Jean-Beru
Copy link
Contributor

This is already present in the PR :

Could this part be done in a dedicated PR ?

  • allow defining a webhook to add as a header
  • make "internal" webhook easier to developer using the component

composer.json Outdated Show resolved Hide resolved
composer.json Outdated Show resolved Hide resolved
config/builder_pdf.php Outdated Show resolved Hide resolved
src/Builder/Pdf/AbstractPdfBuilder.php Outdated Show resolved Hide resolved
src/DependencyInjection/Configuration.php Show resolved Hide resolved
src/Builder/Pdf/AbstractPdfBuilder.php Outdated Show resolved Hide resolved
src/DependencyInjection/SensiolabsGotenbergExtension.php Outdated Show resolved Hide resolved
config/builder_pdf.php Outdated Show resolved Hide resolved
config/builder_pdf.php Outdated Show resolved Hide resolved
src/Builder/AsyncBuilderTrait.php Outdated Show resolved Hide resolved
src/Builder/AsyncBuilderTrait.php Outdated Show resolved Hide resolved
src/Builder/AsyncBuilderTrait.php Outdated Show resolved Hide resolved
src/Builder/AsyncBuilderTrait.php Outdated Show resolved Hide resolved
src/Builder/Pdf/AbstractChromiumPdfBuilder.php Outdated Show resolved Hide resolved
src/Builder/AsyncBuilderTrait.php Outdated Show resolved Hide resolved
src/Debug/Builder/TraceableScreenshotBuilder.php Outdated Show resolved Hide resolved
src/DependencyInjection/Configuration.php Outdated Show resolved Hide resolved
src/DependencyInjection/Configuration.php Outdated Show resolved Hide resolved
Copy link
Contributor

@Jean-Beru Jean-Beru left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Quick review

src/Builder/AsyncBuilderTrait.php Outdated Show resolved Hide resolved
'time' => $swEvent?->getDuration(),
'memory' => $swEvent?->getMemory(),
'size' => null,
'fileName' => null,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can add a mention/icon to distinguish sync and async calls in the profiler?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Implements the Webhook features
3 participants