hudhaifas/silverstripe-gpt-actions

Expose secure server-side actions to ChatGPT via OpenAPI and expirable API keys.

Installs: 63

Dependents: 0

Suggesters: 0

Security: 0

Stars: 0

Watchers: 0

Forks: 0

Open Issues: 0

Type:silverstripe-vendormodule

dev-master 2025-08-01 01:17 UTC

This package is not auto-updated.

Last update: 2025-08-01 01:18:08 UTC


README

Expose your custom server-side logic to GPTs and AI clients via secure, structured endpoints.

The silverstripe-gpt-actions module allows you to define and expose server-side actions through a secure HTTP interface for integration with custom GPTs (ChatGPT plugins) or other AI tools.

It supports:

  • Custom GET endpoints per action
  • OpenAPI schema generation (/gpt/openapi) for easy GPT integration
  • Secure access using expirable API keys
  • CMS management of API keys
  • Google Analytics 4 (GA4) usage tracking (optional)
  • Developer-friendly action registration and manifest system

โœ… Requires SilverStripe 4.10+ or 5.x

๐Ÿ“ฆ Installation

composer require hudhaifas/silverstripe-gpt-actions

Enable the module in your SilverStripe project, then run:

vendor/bin/sake dev/build flush=1

๐Ÿง  Use Cases

This module is ideal for:

  • Enabling GPTs to access domain-specific actions directly
  • Exposing structured data and tools to AI models
  • Creating secure and discoverable AI endpoints
  • Tracking GPT usage analytics via GA4

๐Ÿงฉ Defining Actions

Create a PHP class implementing a run() static function and a describe() static method:

namespace MyApp\GPTActions;

use Exception;

class GetEntityByIDAction {
    public static function run(array $parameters) {
        if (!isset($parameters['EntityID'])) {
            throw new Exception("Missing parameter: EntityID");
        }
        
        $entity = MyEntity::get_by_id($parameters['EntityID']);

        return [
            'ID' => $entity->ID,
            'Name' => $entity->Name,
            'Details' => $entity->Details
        ];
    }

    public static function describe(): array {
        return [
            'name' => 'GetEntityByID',
            'description' => 'Retrieve an entity by its unique ID.',
            'parameters' => [
                'EntityID' => [
                    'type' => 'integer',
                    'required' => true,
                    'description' => 'The numeric ID of the entity'
                ],
            ],
        ];
    }
}

The describe() method is used to auto-generate OpenAPI documentation.

โš™๏ธ Registering Actions

Register actions in your YAML config (e.g., app/_config/gpt-actions.yml):

GptActions\Util\GPTActionRegistry:
  available_actions:
    GetEntityByID: MyApp\GPTActions\GetEntityByIDAction
    SearchEntities: MyApp\GPTActions\SearchEntitiesAction

๐ŸŒ Available Endpoints

GET /gpt/action/{ActionName}?param1=value1&...

Invokes a specific action. Example:

GET /gpt/action/GetEntityByID?EntityID=123
Authorization: Bearer YOUR_API_KEY

GET /gpt/openapi

Returns a dynamic OpenAPI 3.1 JSON schema for all registered actions.

๐Ÿ” API Key Authentication

Manage API keys from the CMS under the GPT Keys section.

Each key:

  • Is a 64-character token
  • Can be linked to a Member
  • Can expire and/or be deactivated
  • Inherits the same permissions and access scope as the linked Member

Authentication Methods:

  • โœ… Recommended: Authorization: Bearer YOUR_KEY
  • ๐Ÿงช Testing only: ?key=YOUR_KEY

๐Ÿ›ก๏ธ Request Authentication

The module uses the GPTAuthenticator class to validate incoming requests.

Internally, each request to /gpt/* is authenticated via the controllerโ€™s init() method:

if (!GPTAuthenticator::authenticate($this->getRequest())) {
    return $this->httpError(401, 'Unauthorized GPT access');
}

You may reuse the GPTAuthenticator::authenticate() method anywhere in your project.

โš™๏ธ SiteConfig Integration

To customize OpenAPI schema metadata and enable analytics, the module extends SiteConfig with:

Field Purpose
GPTActionTitle Appears in OpenAPI info.title
GPTActionDescription Appears in OpenAPI info.description
GPTAnalyticsMeasurementID GA4 Measurement ID
GPTAnalyticsAPISecret GA4 API Secret

All can be set from the CMS Settings UI.

๐Ÿ“ˆ GPT Usage Analytics (Optional)

If configured via SiteConfig, the module will send usage events to Google Analytics 4 (GA4) using the [Measurement Protocol].

Tracked event: gpt_action_called

Event parameters:

Param Example Description
action_name GetEntityByID Name of the called action
success true/false Whether the action succeeded

๐Ÿ“‹ Example OpenAPI Output

{
  "openapi": "3.1.0",
  "info": {
    "title": "My Custom GPT",
    "description": "Custom actions exposed for GPT integration.",
    "version": "1.0.0"
  },
  "paths": {
    "/gpt/action/GetEntityByID": {
      "get": {
        "summary": "Retrieve an entity by ID.",
        "parameters": [
          {
            "name": "EntityID",
            "in": "query",
            "required": true,
            "schema": { "type": "integer" }
          }
        ]
      }
    }
  }
}

๐Ÿงช Testing Endpoints

fetch('https://yourdomain.com/gpt/action/GetEntityByID?EntityID=123', {
  headers: {
    Authorization: 'Bearer YOUR_KEY'
  }
})
  .then(res => res.json())
  .then(console.log);

๐Ÿค– Creating a Custom GPT

You can easily create a ChatGPT plugin (Custom GPT) that consumes the OpenAPI spec exposed at /gpt/openapi.

๐Ÿ‘‰ See docs/CustomGPT.md for a walkthrough on publishing your GPT on ChatGPT.com.

๐Ÿ“œ License

MIT

โœ๏ธ Maintainer

Hudhaifa โ€“ amlineage.com