Ticket Settings

9 vues Markdown

The six endpoints for the support area's settings, its e-mail setup and its custom statuses.

Overview

These six endpoints decide how the support area behaves. Two hold the general settings, two configure tickets arriving by e-mail, and two manage the statuses an installation defines for itself.

Among the general settings are three blocking switches: for the blacklisted, for those with no service, and for unverified accounts. Each stops a client opening a ticket, so this is the first place to look when the support queue falls unexpectedly quiet.

Custom statuses sit on top of the standard ones. A status such as "Awaiting parts" shows with its own colour and name, while for the workflow it behaves as whichever standard status it was built on.

Reference

Reading the Support Settings

get/api/v1/admin/tickets/settings
Tickets/GetTicketSettings admin

Returns the general settings of the support area.

Response fields data — 11
show_firstintWhich end of the conversation comes first.
member_groupintThe client group allowed to open support requests.
ticket_claimingboolWhether staff can take a ticket for themselves.
assigned_tickets_onlyboolWhether staff see only what is assigned to them.
block_blacklistedboolWhether a blacklisted client is kept from opening one.
block_without_serviceboolWhether a client with no service is kept from opening one.
verification_requiredboolWhether the account has to be verified first.
technical_departmentintThe department technical matters go to.
billing_departmentintThe department billing matters go to.
listing_countintHow many tickets a panel page shows.
refresh_timeintHow often the panel refreshes the list, in seconds.
Errors 1
insufficient_scope403The key lacks the required scope.
Request
curl 'https://panel.example.com/api/v1/admin/tickets/settings' \
  -H "Authorization: Bearer $API_KEY"
const res  = await fetch('https://panel.example.com/api/v1/admin/tickets/settings', {
  headers: { Authorization: `Bearer ${apiKey}` },
});
const body = await res.json();
$ch = curl_init('https://panel.example.com/api/v1/admin/tickets/settings');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $apiKey],
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
// Three blocking settings stop a CLIENT opening one; check these first when support goes quiet.
$s = Api::Tickets()->GetTicketSettings()['data'];

Writing the Support Settings

put/api/v1/admin/tickets/settings
Tickets/UpdateTicketSettings admin

Changes the general support settings.

Body 11
show_firstintWhich end of the conversation comes first.
member_groupintThe client group allowed to open support requests.
ticket_claimingboolWhether staff can take a ticket for themselves.
assigned_tickets_onlyboolWhether staff see only what is assigned to them.
block_blacklistedboolWhether a blacklisted client is kept from opening one.
block_without_serviceboolWhether a client with no service is kept from opening one.
verification_requiredboolWhether the account has to be verified first.
technical_departmentintThe department technical matters go to.
billing_departmentintThe department billing matters go to.
listing_countintTickets per page. Clamped between one and a hundred.
refresh_timeintThe refresh interval. Clamped between five and three hundred seconds.
Response fields data — 11
dataobjectThe settings as they now stand. Same shape as the read endpoint.
Errors 1
insufficient_scope403The key lacks the required scope.
Request
curl -X PUT 'https://panel.example.com/api/v1/admin/tickets/settings' \
  -H "Authorization: Bearer $API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"listing_count":25,"refresh_time":60,"ticket_claiming":true}'
const res = await fetch('https://panel.example.com/api/v1/admin/tickets/settings', {
  method: 'PUT',
  headers: {
    Authorization: `Bearer ${apiKey}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    listing_count: 25,
    refresh_time: 60,
    ticket_claiming: true,
  }),
});

const body = await res.json();
$ch = curl_init('https://panel.example.com/api/v1/admin/tickets/settings');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'listing_count'   => 25,
        'refresh_time'    => 60,
        'ticket_claiming' => true,
    ]),
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
// An out-of-range value is NOT refused but pulled to the limit; read back what returned.
$now = Api::Tickets()->UpdateTicketSettings(['refresh_time' => 1])['data'];
// $now['refresh_time'] === 5

Reading the Mail Settings

get/api/v1/admin/tickets/pipe-settings
Tickets/GetTicketPipeSettings admin

Returns how tickets arriving by e-mail are set up.

Response fields data — 5
enabledboolWhether tickets can arrive by e-mail.
methodintHow an incoming message is matched to a client.
spam_controlboolWhether incoming mail goes through a spam check.
prefixstringThe reference prefix in the subject line. This is what brings a reply back to the right ticket.
departmentsobjectThe mailbox settings per department: the sending address, the shown name and the provider.
Errors 1
insufficient_scope403The key lacks the required scope.
Request
curl 'https://panel.example.com/api/v1/admin/tickets/pipe-settings' \
  -H "Authorization: Bearer $API_KEY"
const res  = await fetch('https://panel.example.com/api/v1/admin/tickets/pipe-settings', {
  headers: { Authorization: `Bearer ${apiKey}` },
});
const body = await res.json();
$ch = curl_init('https://panel.example.com/api/v1/admin/tickets/pipe-settings');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $apiKey],
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
// This is configuration ONLY; authorising a mailbox does not happen through this endpoint.
$pipe = Api::Tickets()->GetTicketPipeSettings()['data'];

Writing the Mail Settings

put/api/v1/admin/tickets/pipe-settings
Tickets/UpdateTicketPipeSettings admin

Changes how tickets arriving by e-mail are set up.

Body 5
enabledboolLets tickets arrive by e-mail.
methodintHow a client is matched. An unknown value falls back to zero.
spam_controlboolTurns the spam check on.
prefixstringThe reference prefix. Left empty, the default prefix is used.
departmentsobjectThe mailbox per department: sending address, shown name and provider.
Response fields data — 5
dataobjectThe mail settings as they now stand.
Errors 1
insufficient_scope403The key lacks the required scope.
Request
curl -X PUT 'https://panel.example.com/api/v1/admin/tickets/pipe-settings' \
  -H "Authorization: Bearer $API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"enabled":true,"method":1,"spam_control":true,"prefix":"REF"}'
const res = await fetch('https://panel.example.com/api/v1/admin/tickets/pipe-settings', {
  method: 'PUT',
  headers: {
    Authorization: `Bearer ${apiKey}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    enabled: true,
    method: 1,
    spam_control: true,
    prefix: 'REF',
  }),
});

const body = await res.json();
$ch = curl_init('https://panel.example.com/api/v1/admin/tickets/pipe-settings');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'enabled'      => true,
        'method'       => 1,
        'spam_control' => true,
        'prefix'       => 'REF',
    ]),
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
// CHANGING the prefix leaves replies carrying the old subject unable to find their ticket.
Api::Tickets()->UpdateTicketPipeSettings(['prefix' => 'REF']);

Listing the Custom Statuses

get/api/v1/admin/tickets/custom-statuses
Tickets/GetTicketCustomStatuses admin

Returns the ticket statuses the installation defined for itself.

Response fields data[] — 5
idintThe status id.
typestringThe standard status it sits on: open, waiting, process, replied, solved.
colorstringThe badge colour.
namestringIts name in the current language.
langsobjectIts name per language.
Errors 1
insufficient_scope403The key lacks the required scope.
Request
curl 'https://panel.example.com/api/v1/admin/tickets/custom-statuses' \
  -H "Authorization: Bearer $API_KEY"
const res  = await fetch('https://panel.example.com/api/v1/admin/tickets/custom-statuses', {
  headers: { Authorization: `Bearer ${apiKey}` },
});
const body = await res.json();
$ch = curl_init('https://panel.example.com/api/v1/admin/tickets/custom-statuses');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $apiKey],
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
// A custom status sits ON TOP of a standard one: the workflow follows the base.
$custom = Api::Tickets()->GetTicketCustomStatuses()['data'];

Writing the Custom Statuses

put/api/v1/admin/tickets/custom-statuses
Tickets/UpdateTicketCustomStatuses admin wants the whole list

Replaces every custom status with the list you send.

Body 4
statusesarrayreqThe complete set of statuses. The old ones go and these are written.
statuses[].typestringThe standard status it sits on: open, waiting, process, replied, solved. An unknown value falls back to the in-process one.
statuses[].colorstringThe badge colour.
statuses[].langsobjectIts name per language. Languages left empty are skipped.
Response fields data[] — 5
dataobject[]The custom statuses as they now stand. Same shape as the listing endpoint.
Errors 2
invalid_statuses422What was sent is not a list.
insufficient_scope403The key lacks the required scope.
Request
curl -X PUT 'https://panel.example.com/api/v1/admin/tickets/custom-statuses' \
  -H "Authorization: Bearer $API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"statuses":[{"type":"process","color":"#3399ff","langs":{"tr":"Parca bekleniyor"}}]}'
const res = await fetch('https://panel.example.com/api/v1/admin/tickets/custom-statuses', {
  method: 'PUT',
  headers: {
    Authorization: `Bearer ${apiKey}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    statuses: [
      {
        type: 'process',
        color: '#3399ff',
        langs: { en: 'Awaiting parts', tr: 'Parca bekleniyor' },
      },
    ],
  }),
});

const body = await res.json();
$ch = curl_init('https://panel.example.com/api/v1/admin/tickets/custom-statuses');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'statuses' => [[
            'type'  => 'process',
            'color' => '#3399ff',
            'langs' => ['en' => 'Awaiting parts'],
        ]],
    ]),
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
// Even to add one, read the CURRENT list and append; the write is a full replacement.
$all   = Api::Tickets()->GetTicketCustomStatuses()['data'];
$all[] = ['type' => 'waiting', 'color' => '#999999', 'langs' => ['en' => 'On hold']];

Api::Tickets()->UpdateTicketCustomStatuses(['statuses' => $all]);

Pitfalls

Writing custom statuses replaces everything

The write endpoint replaces the whole set with what you send: the existing statuses go and yours are added in their place. Sending only the one you meant to add removes the rest. Read the current list first, append to it and send the whole thing back.

Rewriting changes the status ids

Because a full replacement removes the old rows and inserts new ones, custom statuses get new ids. If you keep the id assigned to a ticket on your side, that number may now point at a different status. Resolve from the list each time rather than storing ids.

Three switches quietly stop a client

With the blacklist, no-service and verification switches on, a client cannot open a ticket at all. Nothing shows as an error in the panel, the queue stays empty, and that is easy to read as a fault. When no tickets arrive on an installation, read these three fields first.

Changing the prefix cuts old replies loose

Which ticket an incoming e-mail belongs to is read from the reference prefix in the subject line. Change the prefix and replies still carrying the old subject cannot find their ticket, landing as new ones instead. Leave the prefix alone while conversations are in flight.

An out-of-range value is clipped rather than refused

The page size and the refresh interval are pulled into set ranges. Asking for a one-second refresh raises no error; the setting quietly lands on the lowest value allowed. Do not assume what you sent was written, and read the value that comes back.

Cet article vous a-t-il été utile ?

Merci pour votre retour !

Besoin d'aide supplémentaire ?

Notre équipe d'assistance est disponible 24h/24 pour tout ce que vous ne trouvez pas ci-dessus.