forgejo-tickets/docs/forgejo-integration.md

4.0 KiB

Forgejo Integration

The application syncs support tickets with Forgejo issues, providing a bridge between the customer-facing UI and internal issue tracking.

Configuration

Two environment variables are required for the integration:

Variable Description
FORGEJO_URL Base URL of your Forgejo instance (e.g. https://forgejo.example.com)
FORGEJO_API_TOKEN Personal access token with permission to create issues and comments

See Configuration for the full reference.

Ticket-to-Issue Sync

When a customer creates a ticket:

  1. The ticket is saved to the database immediately.
  2. A goroutine asynchronously calls the Forgejo API to create a corresponding issue:
    • Endpoint: POST /api/v1/repos/{owner}/{repo}/issues
    • Title: Same as the ticket title
    • Body: Ticket description + a footer line identifying the submitting user's email
  3. On success, the Forgejo issue number is stored on the ticket (forgejo_issue_number).

If the API call fails, the error is logged but the ticket remains valid. The issue number will be NULL, meaning no further syncing occurs for that ticket.

Comment Sync

When a customer adds a comment to a ticket that has a linked Forgejo issue:

  1. The comment is saved to the database immediately.
  2. A goroutine asynchronously calls the Forgejo API to create a comment on the issue:
    • Endpoint: POST /api/v1/repos/{owner}/{repo}/issues/{number}/comments
    • Body: Comment text + a footer line identifying the commenting user's email
  3. On success, the Forgejo comment ID is stored on the ticket comment (forgejo_comment_id).

Comments are only synced if forgejo_issue_number is set on the ticket.

Webhook Setup

To receive events from Forgejo (e.g. issue closed), configure a webhook in each Forgejo repository:

1. Get the Webhook URL

The URL follows the pattern:

{BASE_URL}/webhooks/forgejo/{slug}

Where {slug} is the repo slug configured in the admin panel. For example:

https://tickets.example.com/webhooks/forgejo/my-product

2. Configure in Forgejo

In the Forgejo repository settings, go to Webhooks and add a new webhook:

  • Target URL: The webhook URL from step 1
  • HTTP Method: POST
  • Content Type: application/json
  • Secret: Must match the webhook secret configured for this repo in the admin panel
  • Events: Select "Issues" (or use "Custom Events" and check "Issues")

3. Signature Verification

All webhook requests are verified using HMAC-SHA256. The signature is read from the X-Forgejo-Signature header and compared against the computed HMAC of the request body using the repo's webhook secret.

Requests with missing or invalid signatures are rejected with 401 Unauthorized.

Auto-Close Flow

When an issue is closed in Forgejo, the following happens:

  1. Forgejo sends a webhook POST to {BASE_URL}/webhooks/forgejo/{slug}.
  2. The app verifies the HMAC-SHA256 signature against the repo's webhook secret.
  3. The payload is parsed. Only "action": "closed" events are processed; all others return 200 OK with no action.
  4. The app looks up the ticket by repo_id and forgejo_issue_number.
  5. If found, the ticket status is updated to closed.
  6. A notification email is sent asynchronously to the ticket owner informing them their ticket has been resolved.

This enables the internal team to close issues directly in Forgejo and have the status reflected in the customer-facing UI automatically.

Architecture Notes

  • All Forgejo API calls (issue creation, comment creation) are asynchronous — they run in goroutines and don't block the HTTP response.
  • The API client uses a 30-second HTTP timeout.
  • Authentication uses the Authorization: token {api_token} header.
  • Webhook processing is synchronous — the ticket status update happens before returning the response to Forgejo.

See Admin Guide for managing repos through the admin UI and Deployment for webhook URL configuration in production.