Skip to content

Plugin Development with OPM Packages

In this section, you will learn how to create, install, and distribute your own plugins as OPM packages for OTOBO.


The SOPM file (*.sopm) contains all metadata for your package:

<?xml version="1.0" encoding="utf-8"?>
<otobo_package version="1.0">
<Name>MyExtension</Name>
<Version>1.0.0</Version>
<Framework>10.0.x</Framework> <!-- Minimum OTOBO version -->
<Vendor>YourName GmbH</Vendor>
<URL>https://github.com/your-user/otobo-mypackage</URL>
<License>GPL-3.0</License>
<Description Lang="en">Extension for special functions</Description>
<ChangeLog Version="1.0.0" Date="13.06.2025 12:00:00">Initial release</ChangeLog>
<Filelist>
<File Location="Kernel/Config/Files/XML/MyExtension.xml" Permission="644"></File>
<File Location="Kernel/System/MyExtension.pm" Permission="644"></File>
<File Location="Kernel/Modules/AgentMyPage.pm" Permission="644"></File>
<File Location="Kernel/Output/HTML/Standard/AgentMyPage.tt" Permission="644"></File>
<File Location="Kernel/Language/en_MyExtension.pm" Permission="644"></File>
</Filelist>
</otobo_package>
  • Name/Version/Framework: Unique package identifier and compatible OTOBO version.
  • Filelist: All files that are copied during installation.

Create your package in its own directory, e.g., MyExtension/:

MyExtension/
├─ MyExtension.sopm
├─ Kernel/
│ ├─ Config/Files/XML/MyExtension.xml
│ ├─ System/MyExtension.pm
│ ├─ Modules/AgentMyPage.pm
│ ├─ Output/HTML/Standard/AgentMyPage.tt
│ └─ Language/en_MyExtension.pm
└─ sql/
└─ create_tables.sql # optional, for DB migrations
  • Kernel/Config/Files/XML/: Registers modules, menus, or Dynamic Fields.
  • Kernel/System/: Business logic class.
  • Kernel/Modules/: Frontend controller.
  • Templates & Language: TT files + translation .pm files.

Use the CLI tool to build an OPM from your SOPM:

Terminal window
cd /path/to/MyExtension
bin/otobo.Console.pl Dev::Package::Build \
--sopm-file MyExtension.sopm \
--output /tmp/MyExtension.opm

Admin UI: Upload the package under Admin → Settings → Package Manager. Console:

Terminal window
bin/otobo.Console.pl Admin::Package::Install /tmp/MyExtension.opm

To uninstall or upgrade:

Terminal window
bin/otobo.Console.pl Admin::Package::Uninstall /tmp/MyExtension.opm
bin/otobo.Console.pl Admin::Package::Upgrade /tmp/MyExtension.opm

In Kernel/Config/Files/XML/MyExtension.xml, you register a new Dynamic Field driver:

<Setting Name="DynamicFields::Driver###MyCustomField" Required="0" Valid="1">
<Navigation>DynamicFields::Driver</Navigation>
<Value>
<Array>
<Item><Hash>
<Item Key="DriverName">MyCustomField</Item>
<Item Key="Module">Kernel::System::DynamicField::Driver::MyCustomField</Item>
</Hash></Item>
</Array>
</Value>
</Setting>

Implement the driver in Kernel/System/DynamicField/Driver/MyCustomField.pm.

Register your event handler:

<Setting Name="Event::EventHandler###MyHandler" Required="0" Valid="1">
<Navigation>Event::EventHandler</Navigation>
<Value>
<Array>
<Item><Hash>
<Item Key="Module">Kernel::System::Event::Handler::MyHandler</Item>
</Hash></Item>
</Array>
</Value>
</Setting>

Implement the handler in Kernel/System/Event/Handler/MyHandler.pm (the Run() method).

<Setting Name="Output::Filter###MyFilter" Required="0" Valid="1">
<Navigation>Output::Filter</Navigation>
<Value>
<Array>
<Item><Hash>
<Item Key="Module">Kernel::System::Output::Filter::MyFilter</Item>
</Hash></Item>
</Array>
</Value>
</Setting>

Filter in Kernel/System/Output/Filter/MyFilter.pm.


  • Repository Index: Generate Packages.xml for your own repo:

    Terminal window
    bin/otobo.Console.pl Dev::Package::RepositoryIndex \
    --directory /var/www/otobo-packages
  • Add your repo URL under SysConfig Package::RepositoryList.

  • OTOpar: Upload your OPM to https://otopar.perl-services.de so that others can install it directly.


  1. Create SOPM with the name MyCalendar.
  2. DB script sql/create_calendar.sql for table calendar_events.
  3. Config XML defines a new ticket field “Appointment”.
  4. Core module Kernel/System/CalendarEvent.pm with CRUD methods.
  5. Frontend module Kernel/Modules/AgentCalendar.pm, template AgentCalendar.tt.
  6. Build package and upload to OTOpar.

  • Update the version number in the sopm (SemVer).
  • Version DB migrations in sql/ cleanly.
  • Create unit tests for system and module classes.
  • Include documentation in the README plus POD in Perl modules.
  • Translations in Language/de_*.pm and en_*.pm.

With this, you have a solid foundation to develop, distribute, and maintain your own OTOBO plugins in customer projects. Have fun!