Skip to main content

PyPI CI License

A ready-to-use repository demonstrating how to use Open edX Events for building workflows and automating integrations. It serves as a starting point for more advanced use cases. Explore Real-Life Use Cases for Open edX Events to see more complex implementations from the Open edX Community

Purpose

This repository demonstrates how to connect Open edX registration, enrollment, and grade change events to external tools via n8n, enabling easier automation workflows through this third-party service.

This project is based on the original Open edX Events 2 Zapier project and has been adapted by Abstract Technology to send events to n8n webhooks.

Open edX Events are a powerful feature that allows developers to listen to key events in the Open edX platform and trigger custom actions based on them. This can be useful for a variety of use cases, such as:

  • Sending welcome emails to new users

  • Logging new enrollments to external CRMs

  • Triggering events like email follow-ups for grade updates

By sending key event data to n8n, Open edX users can leverage the integration ecosystem of n8n without additional development effort.

Getting Started with Development

Please first see the Open edX documentation for guidance on Python development in this repo.

Then follow the steps below to set up your development environment:

# Clone the repository
git clone git@github.com:Abstract-Tech/openedx-events-2-n8n.git
# Mount it to lms container
tutor mounts add openedx-events-2-n8n
# Install dependencies
tutor dev exec lms bash
pip install -e /mnt/openedx-events-2-n8n
python manage.py lms migrate

Deploying

See the Usage section below for instructions on how to deploy this plugin. Also, see the Tutor documentation for more information on deploying extra requirements.

Getting Help

Documentation

Refer to the Open edX Events documentation to learn about implementing and working with events. This documentation details how to use the repository to integrate with third-party services, such as n8n Webhooks, through events.

You can review the rendered documentation at https://abstract-tech.github.io/openedx-events-2-n8n/.

Features

  • Event Handlers: Listen to Open edX Events using Django signals and send data to n8n.

  • Webhook Integration: Send event data to n8n webhooks for further processing.

  • Customizable: Easily extend the repository to handle additional events or integrate with other services.

  • Ready-to-Use: Install the package and configure webhooks to start sending events to n8n.

Supported Events

Event Name

Event Type

Description

STUDENT_REGISTRATION_COMPLETED

org.openedx.learning.student.registration.completed.v1

Triggered when a user completes registration in the LMS.

COURSE_ENROLLMENT_CREATED

org.openedx.learning.course.enrollment.created.v1

Triggered upon successful course enrollment.

PERSISTENT_GRADE_SUMMARY_CHANGED

org.openedx.learning.course.persistent_grade_summary.changed.v1

Triggered when a persistent grade summary is updated. This happens when a grade changes in a course.

How Does it Work?

Each of the above events is handled by Django Signal handlers. When these signals are emitted, they are intercepted by handlers defined in the repository, which transform and forward the event data to a n8n webhook.

Django Signal Handlers

In the file handlers.py, handlers listen to Django signals using the standard receiver decorator:

from django.dispatch import receiver
from openedx_events.signals import STUDENT_REGISTRATION_COMPLETED

@receiver(STUDENT_REGISTRATION_COMPLETED)
def send_user_data_to_webhook(signal, sender, user, metadata, **kwargs):
    n8n_payload = {
        "user": asdict(user),
        "event_metadata": asdict(metadata),
    }
    requests.post(
        settings.N8N_REGISTRATION_WEBHOOK,
        json=flatten_dict(n8n_payload),
        timeout=N8N_REQUEST_TIMEOUT,
    )
  • The receiver decorator listens to the STUDENT_REGISTRATION_COMPLETED signal.

  • The handler function send_user_data_to_webhook extracts the user and metadata from the signal.

  • The N8N_REGISTRATION_WEBHOOK URL is configured as a Django settings by using a Tutor plugin.

  • The extracted data is formatted into a payload and sent to the n8n webhook for further processing.

App Configuration (apps.py)

The Django app is configured using an AppConfig to automatically register handlers on startup.

class OpenedxEvents2N8nConfig(AppConfig):
    name = "openedx_events_2_n8n"

    def ready(self):
        from openedx_events_2_n8n import handlers

Usage

To use this plugin, follow these steps:

  1. Install the plugin in your Open edX image using Tutor’s OPENEDX_EXTRA_PIP_REQUIREMENTS configuration setting:

OPENEDX_EXTRA_PIP_REQUIREMENTS:
- git+https://github.com/Abstract-Tech/openedx-events-2-n8n.git@X.Y.Z
  1. Launch the Open edX platform to apply the changes:

tutor local launch
  1. Configure webhook URLs via the Django admin (/admin/openedx_events_2_n8n/webhookconfig/) by creating a WebhookConfig entry per event type.

    Alternatively, create and enable an Inline Tutor plugin to configure the n8n webhooks through Django settings:

# Location plugins/n8n.py
from tutor import hooks

hooks.Filters.ENV_PATCHES.add_item(
    (
        "openedx-lms-common-settings",
"""
N8N_REGISTRATION_WEBHOOK = "https://<your-n8n-domain>/webhook/<registration-path>"
N8N_ENROLLMENT_WEBHOOK = "https://<your-n8n-domain>/webhook/<enrollment-path>"
N8N_PERSISTENT_GRADE_COURSE_WEBHOOK = "https://<your-n8n-domain>/webhook/<grade-path>"
"""
    )
)
  tutor plugins enable n8n

You can use both the Django admin and the Tutor plugin settings at the same time. When a ``WebhookConfig`` entry exists, is active, and has a URL for an event, it takes priority over the settings value; the settings value is only used as a fallback.

Each ``WebhookConfig`` entry can also be configured with the authentication type used by the target n8n Webhook node's credential (matching `n8n's Webhook credentials <https://docs.n8n.io/integrations/builtin/credentials/webhook/>`_): ``None``, ``Basic Auth``, ``Header Auth``, or ``JWT Auth``. Fill in only the fields for the selected type.
Testing Each Auth Type

Set the n8n Webhook node’s credential to match, save a WebhookConfig with the same values, then trigger the event (e.g. enroll a user). Check /admin/openedx_events_2_n8n/webhookevent/ for the delivery result (status code, response body, error).

None

  • WebhookConfig: auth_type=none.

  • n8n Webhook node: credential set to None.

  • Verify directly with curl:

curl -X POST https://<your-n8n-domain>/webhook/<path> -H "Content-Type: application/json" -d '{"ping": "test"}'

Basic Auth

  • WebhookConfig: auth_type=basic, basic_auth_username, basic_auth_password.

  • n8n Webhook node: credential type Basic Auth with matching username/password.

  • Verify directly with curl:

curl -X POST https://<your-n8n-domain>/webhook/<path> -u "<username>:<password>" -H "Content-Type: application/json" -d '{"ping": "test"}'

Header Auth

  • WebhookConfig: auth_type=header, header_auth_name (e.g. X-Api-Key), header_auth_value.

  • n8n Webhook node: credential type Header Auth with the same header name/value.

  • Verify directly with curl:

curl -X POST https://<your-n8n-domain>/webhook/<path> -H "X-Api-Key: <header_auth_value>" -H "Content-Type: application/json" -d '{"ping": "test"}'

JWT Auth

  • WebhookConfig: auth_type=jwt, jwt_auth_secret (HS256 passphrase).

  • n8n Webhook node: credential type JWT Auth, algorithm HS256, same secret.

  • The plugin signs a short-lived token itself (60s TTL) and sends it as Authorization: Bearer <token>; to verify manually, mint a token with the same secret:

python -c "import jwt,time; print(jwt.encode({'iat': int(time.time()), 'exp': int(time.time())+60}, '<jwt_auth_secret>', algorithm='HS256'))"

curl -X POST https://<your-n8n-domain>/webhook/<path> -H "Authorization: Bearer <token-from-above>" -H "Content-Type: application/json" -d '{"ping": "test"}'
  1. Configure n8n webhooks to receive JSON event data, follow the instructions available in the n8n documentation.

  2. Trigger the events by registering a new user, enrolling in a course, or updating a grade in the Open edX platform.

To send event data to other services or APIs, simply configure more webhooks in the Django settings. The handlers are intentionally generic, ensuring they work seamlessly with different kinds of services. You can also add more event handlers to the handlers.py file to listen to additional events.

How to Extend this Repository

This repository is a starting point for Open edX developers:

  • You can add new event handlers by following the structure in handlers.py.

  • Custom logic can be implemented to fit your organization’s data flow requirements using n8n, third-party APIs, or internal services.

For details on extending Open edX with Open edX Events, see also:

The openedx-events-2-n8n repository is here to make integrations simple and sustainable, giving developers the tools to create effective Open edX workflows with external services like n8n.

More Help

If you’re having trouble, we have discussion forums at https://discuss.openedx.org where you can connect with others in the community.

Our real-time conversations are on Slack. You can request a Slack invitation, then join our community Slack workspace.

For anything non-trivial, the best path is to open an issue in this repository with as many details about the issue you are facing as you can provide.

https://github.com/Abstract-Tech/openedx-events-2-n8n/issues

For more information about these options, see the Getting Help page.

License

The code in this repository is licensed under the AGPL 3.0 unless otherwise noted.

Please see LICENSE.txt for details.

Contributing

Contributions are very welcome. Please read How To Contribute for details.

This project is currently accepting all types of contributions, bug fixes, security fixes, maintenance work, or new features. However, please make sure to discuss your new feature idea with the maintainers before beginning development to maximize the chances of your change being accepted. You can start a conversation by creating a new issue on this repo summarizing your idea.

The Open edX Code of Conduct

All community members are expected to follow the Open edX Code of Conduct.

People

This repository is currently being maintained by the Abstract Technology team. See the CODEOWNERS file for details.

Reporting Security Issues

Please do not report security issues in public. Contact the Abstract Technology maintainers privately before publishing details.

Change Log

Unreleased

[0.2.0] - 2024-01-24

Added

  • Modernize repo and readme with latest Open edX Events updates.

  • Make receivers trigger tasks to implement retry mechanism.

[0.1.0] - 2021-09-13

Added

  • First release on PyPI.

Metadata

Release files for openedx-events-2-n8n 0.5.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for openedx-events-2-n8n 0.5.0
File Size Uploaded
openedx_events_2_n8n-0.5.0.tar.gz 39.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for openedx-events-2-n8n 0.5.0
File Interpreter ABI Platform
openedx_events_2_n8n-0.5.0-py2.py3-none-any.whl Python 3, Python 2 none any Details

Total release size: 81.0 kB

Release files / openedx_events_2_n8n-0.5.0.tar.gz

Download URL openedx_events_2_n8n-0.5.0.tar.gz
Size 39.3 kB
Tags Source
SHA-256 checksum
How to use checksums
d70e5796f63492c673d00e07524665b9ceb4ba021c447b031cc1c121fc9a966e
BLAKE2b-256 checksum
How to use checksums
c7e31d52ab22714106115684112ee6a6be15c6b8aa519f0e1d27edd01cc7d102
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 19, 2026.

Transparency log

Release files / openedx_events_2_n8n-0.5.0-py2.py3-none-any.whl

Download URL openedx_events_2_n8n-0.5.0-py2.py3-none-any.whl
Size 41.7 kB
Tags Python 2 Python 3
SHA-256 checksum
How to use checksums
1d7eaaa7faa19c14fabb0a8ad7c895269c1eb2329ece795dc683ee237fa73051
BLAKE2b-256 checksum
How to use checksums
196896c97679a7a4ee15431596b3093592f6dc88649ade9c666b1b7688dd6905
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 19, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.5.0 This release

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page