codebar-ag/laravel-zammad

Laravel与Zammad集成

v4.0 2024-02-09 10:11 UTC

This package is auto-updated.

Last update: 2024-09-15 12:47:10 UTC


README

Latest Version on Packagist Total Downloads run-tests PHPStan

本包旨在快速帮助您与Zammad REST API进行通信。它用于查询最常见的端点。

⚠️ 此包不是官方 Zammad REST API 的替代品。如需进一步功能,请参阅文档。⚠️

💡 什么是Zammad?

Zammad是一个基于Web的开源帮助台/客户支持系统,具有许多管理客户通信的功能。

🛠 要求

⚙️ 安装

您可以通过composer安装此包

composer require codebar-ag/laravel-zammad

将以下环境变量添加到您的 .env 文件中

ZAMMAD_URL=https://domain.zammad.com
ZAMMAD_TOKEN=token

🔑 哪里可以找到令牌?

转到您的Zammad应用程序中的个人资料页面。在 令牌访问 标签页中,您可以创建令牌。确保激活您需要的所有权限。

👉 确保在系统设置中激活 HTTP令牌身份验证

📝 如何添加动态工单属性?

  • 发布您的配置文件(请参阅 🔧 配置文件 章节)。
  • ticket 键添加属性
'ticket' => [
    'note' => 'string',
    'additional_id' => 'integer',
],

🏗 使用方法

👶 用户资源

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);

🎫 工单资源

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);

💬 评论资源

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);

🏠 对象资源

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();

🧷 附件资源

use CodebarAg\Zammad\Facades\Zammad;
/**
 * Download attachment.
 */
$content = Zammad::attachment()->download(
    ticketId: 32,
    commentId: 111,
    attachmentId: 42,
);

扩展响应负载

您可以使用 expand() 方法通过附加数据扩展响应。

有关详细信息,请参阅 Zammad API 文档

$ticket = Zammad::ticket()->expand()->show(20);
$user = Zammad::user()->expand()->show(20);
$me = Zammad::user()->expand()->me();

限制搜索响应负载

您可以使用 limit(int $limit = 1) 方法通过附加数据扩展响应。

有关详细信息,请参阅 Zammad API 文档

$ticket = Zammad::ticket()->limit(1)->search();
$user = Zammad::user()->limit(1)->search();

分页列表响应负载

您可以使用 perPage(int $perPage)page(int $page) 方法设置响应的页面和每页值。或者,您也可以使用 paginate(int $page, int $perPage): 方法同时设置两者。

有关详细信息,请参阅 Zammad API 文档

$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 展示

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
}

🔧 配置文件

您可以使用以下命令发布配置文件

php artisan vendor:publish --tag="zammad-config"

这是已发布配置文件的内容

<?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&#39;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],
    ],

];

🚧 测试

复制您的 own phpunit.xml 文件。

cp phpunit.xml.dist phpunit.xml

在 phpunit.xml 文件中修改环境变量

<env name="ZAMMAD_URL" value="https://domain.zammad.com"/>
<env name="ZAMMAD_TOKEN" value="token"/>

运行测试

./vendor/bin/pest

📝 更新日志

有关最近更改的更多信息,请参阅 更新日志

✏️ 贡献

有关详细信息,请参阅 贡献指南

composer test

代码风格

./vendor/bin/pint

🧑‍💻 安全漏洞

有关如何报告安全漏洞,请参阅 我们的安全策略

🙏 致谢

🎭 许可证

MIT许可证(MIT)。有关更多信息,请参阅 许可证文件