codebar-ag / laravel-zammad
Zammad integration with Laravel
Installs: 3 469
Dependents: 0
Suggesters: 0
Security: 0
Stars: 8
Watchers: 4
Forks: 0
Open Issues: 3
Requires
- php: ^8.2
- guzzlehttp/guzzle: ^7.8.1
- illuminate/contracts: ^10.0
- saloonphp/laravel-plugin: ^3.3
- saloonphp/saloon: ^3.6
- spatie/laravel-package-tools: ^1.16
Requires (Dev)
- laravel/pint: ^1.13
- nunomaduro/collision: ^7.10
- nunomaduro/larastan: ^2.8
- orchestra/testbench: ^8.20
- pestphp/pest: ^2.3
- pestphp/pest-plugin-arch: ^2.6
- pestphp/pest-plugin-laravel: ^2.2
- phpstan/extension-installer: ^1.3
- phpstan/phpstan-deprecation-rules: ^1.1
- phpstan/phpstan-phpunit: ^1.3
- spatie/laravel-ray: ^1.33
README
This package was developed to give you a quick start to communicate with the Zammad REST API. It is used to query the most common endpoints.
โ ๏ธ This package is not designed as a replacement of the official Zammad REST API. See the documentation if you need further functionality. โ ๏ธ
๐ก What is Zammad?
Zammad is a web-based open source helpdesk/customer support system with many features to manage customer communication.
๐ Requirements
โ๏ธ Installation
You can install the package via composer:
composer require codebar-ag/laravel-zammad
Add the following environment variables to your .env
file:
ZAMMAD_URL=https://domain.zammad.com ZAMMAD_TOKEN=token
๐ Where can I find the token?
Go to your profile page in your Zammad application. In the tab Token Access you can create your token. Be sure to activate all rights you need.
๐ Make sure to activate HTTP Token Authentication in your system settings.
๐ How to add dynamic ticket attributes?
- Publish your configuration file (see chapter
๐ง Configuration file
). - Add attributes to the ticket key:
'ticket' => [ 'note' => 'string', 'additional_id' => 'integer', ],
๐ Usage
๐ถ User Resource
use CodebarAg\Zammad\Facades\Zammad;
/** * Get the current authenticated user. */ $user = Zammad::user()->me();
/** * Show a list of users. */ $users = Zammad::user()->list();
/** * Search a single user. */ $term = 'email:sebastian.fix@codebar.ch'; $user = Zammad::user()->search($term);
/** * Show a user by id. */ $user = Zammad::user()->show(20);
/** * Create a new user. */ $data = [ 'firstname' => 'Max', 'lastname' => 'Mustermann', 'email' => 'max.mustermann@codebar.ch', ]; $user = (new Zammad())->user()->create($data);
/** * Update a existing user. */ $data = [ 'firstname' => 'Max', 'lastname' => 'Mustermann', ]; $user = (new Zammad())->user()->update($id, $data);
/** * Delete a user by id. */ (new Zammad())->user()->delete(20);
/** * Search a user by email. If not found create a new user. */ $user = (new Zammad())->user()->searchOrCreateByEmail('max.mustermann@codebar.ch');
/** * Search a user by email. If not found create a new user with custom $data */ $data = [ 'firstname' => 'Max', 'lastname' => 'Mustermann', 'email' => 'max.mustermann@codebar.ch', ]; $user = (new Zammad())->user()->searchOrCreateByEmail('max.mustermann@codebar.ch', $data);
๐ซ Ticket Resource
use CodebarAg\Zammad\Facades\Zammad;
/** * Show a list of tickets. */ $tickets = Zammad::ticket()->list();
/** * Search tickets which include following term. */ $term = 'Max Mustermann'; $tickets = Zammad::ticket()->search($term);
/** * Show a ticket by id (empty comments). */ $ticket = Zammad::ticket()->show(20);
/** * Show a ticket by id with comments. */ $ticket = Zammad::ticket()->showWithComments(20);
/** * Create a new ticket. */ $data = [ 'title' => 'The application is not working', 'group' => 'Inbox', 'customer_id' => 20, // 'customer' => 'bob@domain.test', // or use the customer e-mail address 'article' => [ 'body' => 'It just crashes if I visit the page', 'attachments' => [ [ 'filename' => 'log.txt', 'data' => 'V2FzdGUgbm8gbW9yZSB0aW1lIGFyZ3Vpbmcgd2hhdCBhIGdvb2QgbWFuIHNob3VsZCBiZSwgYmUgb25l', 'mime-type' => 'text/plain' ], ], ], ]; $ticket = (new Zammad())->ticket()->create($data);
/** * Delete a ticket by id. */ (new Zammad())->user()->delete(20);
๐ฌ Comment Resource
use CodebarAg\Zammad\Facades\Zammad;
/** * Show comments by ticket id */ $comments = Zammad::comment()->showByTicket(20);
/** * Show a comment by id. */ $comment = Zammad::comment()->show(20);
/** * Create a new comment. */ $data = [ 'ticket_id' => 42, 'subject' => 'Login still not working', 'body' => 'Somehow the login is not working<br>Could you check that?', 'content_type' => 'text/html', 'attachments' => [ [ 'filename' => 'log.txt', 'data' => 'WW91IGFyZSBhIPCfjoEgZm9yIHRoZSDwn4yN', 'mime-type' => 'text/plain', ], ], ]; $comment = (new Zammad())->comment()->create($data);
/** * Delete a comment by id. */ (new Zammad())->comment()->delete(20);
๐ Object Resource
use CodebarAg\Zammad\Facades\Zammad;
/** * Show a list of objects. */ $objects = Zammad::object()->list();
/** * Create a object */ $data = [ 'title' => 'sample_boolean', 'object' => 'Ticket', 'display' => 'Sample Boolean', 'active' => true, 'position' => 1500, 'data_type' => 'select', 'data_option' => [ 'options' => [ 'key-one' => 'First Key', 'key-two' => 'Second Key', 'key-three' => 'Third Key', ], 'default' => 'key-one' ], ]; $object = Zammad::object()->create($data);
/** * Update a object */ $object = Zammad::object()->update($id, $data);
/** * Show a object by id. */ $object = Zammad::object()->show(20);
/** * Execute database migrations */ (new Zammad())->object()->executeMigrations();
๐งท Attachment Resource
use CodebarAg\Zammad\Facades\Zammad;
/** * Download attachment. */ $content = Zammad::attachment()->download( ticketId: 32, commentId: 111, attachmentId: 42, );
Expanding response payloads
You can use the expand()
method to expand the response with additional data.
See documentation on this in the Zammad API Docs.
$ticket = Zammad::ticket()->expand()->show(20); $user = Zammad::user()->expand()->show(20); $me = Zammad::user()->expand()->me();
Limit search response payloads
You can use the limit(int $limit = 1)
method to expand the response with additional data.
See documentation on this in the Zammad API Docs.
$ticket = Zammad::ticket()->limit(1)->search(); $user = Zammad::user()->limit(1)->search();
Paginate list response payloads
You can use the perPage(int $perPage)
and page(int $page)
methods to set the page and per page values for the
response
Alternatively you can use the paginate(int $page, int $perPage):
method to set both at once.
See documentation on this in the Zammad API Docs.
$ticket = Zammad::ticket()->perPage(1)->page(1)->list(); $user = Zammad::user()->perPage(1)->page(1)->list(); $ticket = Zammad::ticket()->paginate(1, 1)->list(); $user = Zammad::user()->paginate(1, 1)->list();
๐๏ธ DTO showcase
CodebarAg\Zammad\DTO\User { +id: 20 // int +first_name: "Max" // string +last_name: "Mustermann" // string +login: "max.mustermann@codebar.ch" // string +email: "max.mustermann@codebar.ch" // string +last_login_at: Carbon\Carbon // Carbon +updated_at: Carbon\Carbon // Carbon +created_at: Carbon\Carbon // Carbon
CodebarAg\Zammad\DTO\Ticket { +id: 32 // int +number: 69032 // int +customer_id: 20 // int +group_id: 3 // int +state_id: 1 // int +subject: "Login is not working" // string +comments_count: 3 // int +updated_at: Carbon\Carbon // Carbon +created_at: Carbon\Carbon // Carbon +comments: Illuminate\Support\Collection // Collection|Comment[] }
CodebarAg\Zammad\DTO\Comment { +id: 66 // int +type_id: 10 // int +ticket_id: 32 // int +sender_id: 2 // int +sender: "Customer" // string +subject: "App Subject" // string +body: "We have fixed your issue! Have a great day<br><span class=\"js-signatureMarker\"></span><blockquote type=\"cite\"><div>It is not working</div></blockquote>" +body_without_blockquote: "We have fixed your issue! Have a great day<br>" +body_only_blockquote: "<blockquote type=\"cite\"><div>It is not working</div></blockquote>" +content_type: "text/plain" // string +from: "Max Mustermann" // string +to: null // ?string +internal: false // boolean +created_by_id: 20 // int +updated_by_id: 20 // int +origin_by_id: 4 // ?int +attachments: Illuminate\Support\Collection // Collection|Attachment[] +updated_at: Carbon\Carbon // Carbon +created_at: Carbon\Carbon // Carbon }
CodebarAg\Zammad\DTO\Attachment { +id: 313 // int +size: 30 // int +name: "log.txt" // string +type: "text/plain" // string }
CodebarAg\Zammad\DTO\ObjectAttribute { +id: 313 // int +name: "sample_object" // string +object_lookup_id: 2 // int +display: "Sample Object" // string +data_type: "select" // string +position: 1500 // int +data_option: [] // array +data_option_new: [] // ?array }
๐ง Configuration file
You can publish the config file with:
php artisan vendor:publish --tag="zammad-config"
This is the contents of the published config file:
<?php return [ /* |-------------------------------------------------------------------------- | Zammad URL |-------------------------------------------------------------------------- | | This URL is used to properly communicate with the Zammad REST-API for | every request that is made. Please make sure to include the scheme | and the hostname in it. Otherwise we can't find the destination. | */ 'url' => env('ZAMMAD_URL'), /* |-------------------------------------------------------------------------- | Zammad Access Token |-------------------------------------------------------------------------- | | The access token is used to authenticate with the Zammad REST-API. You | should make sure to activate the "HTTP Token Authentication" in the | configuration. Afterwards generate a token in your settings page. | */ 'token' => env('ZAMMAD_TOKEN'), /* |-------------------------------------------------------------------------- | HTTP Retry Values |-------------------------------------------------------------------------- | | If you would like HTTP client to automatically retry the request if a client or server error occurs, | you may specify the retry values. The maximum retry value specifies the number of times the request should be attempted, | and the retry delay value is the number of milliseconds Laravel should wait between attempts. | */ 'http_retry_maximum' => env('ZAMMAD_HTTP_RETRY_MAXIMUM', 3), 'http_retry_delay' => env('ZAMMAD_HTTP_RETRY_DELAY', 1500), /* |-------------------------------------------------------------------------- | Object reference error on delete request |-------------------------------------------------------------------------- | | Please note that removing data cannot be undone. Zammad will also remove references - thus potentially tickets! | Removing data with references in e.g. activity streams is not possible via API - this will be indicated by "error": | "Can't delete, object has references." (Status 422). This is not a bug. | Consider using Data Privacy via UI for more control instead. https://docs.zammad.org/en/latest/api/user.html#delete | */ 'object_reference_error_ignore' => env('ZAMMAD_OBJECT_REFERENCE_ERROR_IGNORE', false), 'objet_reference_error' => env('ZAMMAD_OBJECT_REFERENCE_ERROR', 'Can't delete, object has references.'), /* |-------------------------------------------------------------------------- | Comment Object HTML Parsing |-------------------------------------------------------------------------- | */ 'filter_images' => true, 'filter_tables' => true, 'filter_signature_marker' => true, 'filter_signature_marker_value' => '<span class="js-signatureMarker"></span>', 'filter_data_signature' => true, 'filter_data_signature_value' => '<div data-signature="true" data-signature-id="1">', /* |-------------------------------------------------------------------------- | Dynamic Ticket Attributes with Casts |-------------------------------------------------------------------------- | | You should define a list of all your dynamic ticket attributes here to | ensure that they are correctly converted into the native types. The | only limitation you have is to include following supported types. | | Supported: "string", "integer", "float", "boolean", "datetime" | */ 'ticket' => [ // 'note' => 'string', ], /* |-------------------------------------------------------------------------- | Ticket States |-------------------------------------------------------------------------- | | The ticket states are used to determine if a ticket is open, closed, | active or inactive. You can use this information to filter tickets | by their state. The following states are supported by default. | https://docs.zammad.org/en/latest/api/ticket/states.html | */ 'ticket_states' => [ 'open' => [1, 2, 3, 7], 'closed' => [4], 'active' => [1, 2, 3, 4, 7], 'inactive' => [5, 6], ], ];
๐ง Testing
Copy your own phpunit.xml-file.
cp phpunit.xml.dist phpunit.xml
Modify environment variables in the phpunit.xml-file:
<env name="ZAMMAD_URL" value="https://domain.zammad.com"/> <env name="ZAMMAD_TOKEN" value="token"/>
Run the tests:
./vendor/bin/pest
๐ Changelog
Please see CHANGELOG for more information on what has changed recently.
โ๏ธ Contributing
Please see CONTRIBUTING for details.
composer test
Code Style
./vendor/bin/pint
๐งโ๐ป Security Vulnerabilities
Please review our security policy on how to report security vulnerabilities.
๐ Credits
- Sebastian Fix
- Ruslan Steiger
- All Contributors
- Skeleton Repository from Spatie
- Laravel Package Training from Spatie
๐ญ License
The MIT License (MIT). Please see License File for more information.