Destek Talepleri
Destek talebi açan, yanıtlayan, kapatan ve puanlayan on bir uç.
Genel Bakış
Destek talebi bir konuşmadır: müşteri açar, personel yanıtlar, konuşma kapanır. On bir uç bu konuşmanın her adımını kapsar.
Talep açmadan önce iki sözlüğü okumak gerekir: hangi departmanların hangi alanları sorduğu ve hangi erişim gruplarının şifreli bilgi kabul ettiği.
Şifre gibi bilgiler mesaj gövdesine yazılmaz. Erişim grupları için ayrı bir alan vardır ve oradaki parola tipli değerler şifreli saklanır.
Referans
Departmanları Listeleme
Talep açılabilecek departmanları kendi alan şemalarıyla döndürür.
curl 'https://panel.ornek.com/api/v1/client/tickets/departments' \
-H "Authorization: Bearer $CLIENT_KEY"const res = await fetch('https://panel.ornek.com/api/v1/client/tickets/departments', {
headers: { Authorization: `Bearer ${clientKey}` },
});
const { data } = await res.json();
renderDepartmentForm(data[0].custom_fields);$ch = curl_init('https://panel.ornek.com/api/v1/client/tickets/departments');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $clientKey],
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// Alan semasi DEPARTMAN BASINA degisir: formu secilen departmanin semasindan kurun.
$deps = Kernel::internal('client:Tickets/GetTicketDepartments', ['owner_id' => $uid])['data'];
$schema = array_column($deps, 'custom_fields', 'id')[$did] ?? [];Erişim Gruplarını Listeleme
Mesaja eklenebilecek erişim bilgisi gruplarını şemalarıyla döndürür.
curl 'https://panel.ornek.com/api/v1/client/tickets/access-groups' \
-H "Authorization: Bearer $CLIENT_KEY"const res = await fetch('https://panel.ornek.com/api/v1/client/tickets/access-groups', {
headers: { Authorization: `Bearer ${clientKey}` },
});
const { data } = await res.json();
const server = data.find((g) => g.name.includes('Server'));$ch = curl_init('https://panel.ornek.com/api/v1/client/tickets/access-groups');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $clientKey],
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// Parola tipli alanlar SIFRELI saklanir; duz metin mesaj govdesine yazmak yerine bunu kullanin.
$groups = Kernel::internal('client:Tickets/GetTicketAccessGroups', ['owner_id' => $uid])['data'];
$creds = [['group_id' => $groups[0]['id'], 'fields' => $values]];Talepleri Listeleme
Hesabın destek taleplerini durum sırasıyla döndürür.
curl 'https://panel.ornek.com/api/v1/client/tickets?status=answered' \
-H "Authorization: Bearer $CLIENT_KEY"const res = await fetch('https://panel.ornek.com/api/v1/client/tickets?status=answered', {
headers: { Authorization: `Bearer ${clientKey}` },
});
const { data } = await res.json();
const waiting = data.filter((t) => t.unread);$ch = curl_init('https://panel.ornek.com/api/v1/client/tickets?status=answered');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $clientKey],
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// Okunmamis isareti YALNIZ listede gorunur: detayi okumak onu temizler, once listeden sayin.
$rows = Kernel::internal('client:Tickets/GetTickets', ['owner_id' => $uid])['data'];
$badge = count(array_filter($rows, fn ($t) => $t['unread']));Talep Açma
Yeni bir destek talebi açar.
curl -X POST 'https://panel.ornek.com/api/v1/client/tickets' \
-H "Authorization: Bearer $CLIENT_KEY" \
-H 'Content-Type: application/json' \
-d '{"department_id":4,"subject":"Cannot reach my server","message":"SSH times out since this morning.","priority":3}'const res = await fetch('https://panel.ornek.com/api/v1/client/tickets', {
method: 'POST',
headers: {
Authorization: `Bearer ${clientKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
department_id: 4,
subject,
message,
credentials: [{ group_id: 1, fields: { 30: ip, 32: password } }],
}),
});
const { data } = await res.json();$ch = curl_init('https://panel.ornek.com/api/v1/client/tickets');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $clientKey,
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode($ticket),
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// Ekler talep KAYDEDILMEDEN once dogrulanir: bozuk dosya yarim bir talep birakmaz.
Kernel::internal('client:Tickets/CreateTicket', ['owner_id' => $uid] + $ticket);Talebi ve Mesajları Okuma
Talebin üst bilgilerini ve bütün mesaj dizisini döndürür.
curl 'https://panel.ornek.com/api/v1/client/tickets/429' \
-H "Authorization: Bearer $CLIENT_KEY"const res = await fetch(`https://panel.ornek.com/api/v1/client/tickets/${id}`, {
headers: { Authorization: `Bearer ${clientKey}` },
});
const { data } = await res.json();
renderThread(data.messages, data.can_reply);$ch = curl_init('https://panel.ornek.com/api/v1/client/tickets/' . $id);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $clientKey],
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// Bu okuma OKUNDU isaretler: bildirim sayaci kuran bir is bunu cagirdiginda rozet duser.
$t = Kernel::internal('client:Tickets/GetTicket', ['owner_id' => $uid, 'id' => $id])['data'];
$html = array_filter($t['messages'], fn ($m) => $m['is_html']);Yanıt Yazma
Açık bir talebe yanıt ekler.
curl -X POST 'https://panel.ornek.com/api/v1/client/tickets/429/reply' \
-H "Authorization: Bearer $CLIENT_KEY" \
-H 'Content-Type: application/json' \
-d '{"message":"The firewall rule is back, thank you."}'const res = await fetch(`https://panel.ornek.com/api/v1/client/tickets/${id}/reply`, {
method: 'POST',
headers: {
Authorization: `Bearer ${clientKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ message }),
});
const { data } = await res.json();
appendMessage(data.message);$ch = curl_init('https://panel.ornek.com/api/v1/client/tickets/' . $id . '/reply');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $clientKey,
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode(['message' => $text]),
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// Yanit talebi BEKLIYOR durumuna ceker: kapali bir talebe yanit yazilamaz, once yeniden acin.
$t = Kernel::internal('client:Tickets/GetTicket', ['owner_id' => $uid, 'id' => $id])['data'];
if (! $t['can_reply']) Kernel::internal('client:Tickets/ReopenTicket', ['owner_id' => $uid, 'id' => $id]);Talebi Kapatma
Talebi çözüldü olarak kapatır.
curl -X POST 'https://panel.ornek.com/api/v1/client/tickets/429/close' \
-H "Authorization: Bearer $CLIENT_KEY" \
-H 'Content-Type: application/json' \
-d '{"rating":5}'const res = await fetch(`https://panel.ornek.com/api/v1/client/tickets/${id}/close`, {
method: 'POST',
headers: {
Authorization: `Bearer ${clientKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ rating: 5 }),
});
const { data } = await res.json();$ch = curl_init('https://panel.ornek.com/api/v1/client/tickets/' . $id . '/close');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $clientKey,
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode(['rating' => 5]),
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// Kapatirken puan vermek TEK SANSTIR: talep zaten puanliysa gonderilen puan sessizce atlanir.
Kernel::internal('client:Tickets/CloseTicket', ['owner_id' => $uid, 'id' => $id, 'rating' => 5]);Talebi Yeniden Açma
Kapalı bir talebi yeniden açar.
curl -X POST 'https://panel.ornek.com/api/v1/client/tickets/429/reopen' \
-H "Authorization: Bearer $CLIENT_KEY"const res = await fetch(`https://panel.ornek.com/api/v1/client/tickets/${id}/reopen`, {
method: 'POST',
headers: { Authorization: `Bearer ${clientKey}` },
});
const { data } = await res.json();$ch = curl_init('https://panel.ornek.com/api/v1/client/tickets/' . $id . '/reopen');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $clientKey],
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// KILITLI talep yeniden acilamaz: bu durumda yeni bir talep acmak tek yoldur.
$t = Kernel::internal('client:Tickets/GetTicket', ['owner_id' => $uid, 'id' => $id])['data'];
if ($t['locked']) $openNewTicket();Talebi Puanlama
Talebe bir ile beş arasında puan verir.
curl -X POST 'https://panel.ornek.com/api/v1/client/tickets/429/rating' \
-H "Authorization: Bearer $CLIENT_KEY" \
-H 'Content-Type: application/json' \
-d '{"rating":5}'const res = await fetch(`https://panel.ornek.com/api/v1/client/tickets/${id}/rating`, {
method: 'POST',
headers: {
Authorization: `Bearer ${clientKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ rating }),
});
if (res.status === 422) hideRatingWidget();$ch = curl_init('https://panel.ornek.com/api/v1/client/tickets/' . $id . '/rating');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $clientKey,
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode(['rating' => $n]),
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// Puan KESINDIR: bir kez verildikten sonra degistirilemez, arayuzde onay isteyin.
$t = Kernel::internal('client:Tickets/GetTicket', ['owner_id' => $uid, 'id' => $id])['data'];
if ($t['rating'] === null) Kernel::internal('client:Tickets/RateTicket',
['owner_id' => $uid, 'id' => $id, 'rating' => $n]);Personel Yanıtını Puanlama
Tek bir personel yanıtına puan verir.
curl -X POST 'https://panel.ornek.com/api/v1/client/tickets/429/replies/878/rating' \
-H "Authorization: Bearer $CLIENT_KEY" \
-H 'Content-Type: application/json' \
-d '{"rating":4}'const res = await fetch(`https://panel.ornek.com/api/v1/client/tickets/${id}/replies/${rid}/rating`, {
method: 'POST',
headers: {
Authorization: `Bearer ${clientKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ rating }),
});
const { data } = await res.json();$ch = curl_init('https://panel.ornek.com/api/v1/client/tickets/' . $id . '/replies/' . $rid . '/rating');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $clientKey,
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode(['rating' => $n]),
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// Yalniz PERSONEL yanitlari puanlanir: kendi mesajinizin numarasi bulunamadi doner.
$t = Kernel::internal('client:Tickets/GetTicket', ['owner_id' => $uid, 'id' => $id])['data'];
$staff = array_filter($t['messages'], fn ($m) => $m['author']['kind'] === 'staff');Eki İndirme
Bir mesaj ekini içeriğiyle birlikte döndürür.
curl 'https://panel.ornek.com/api/v1/client/tickets/429/attachments/55' \
-H "Authorization: Bearer $CLIENT_KEY"const res = await fetch(`https://panel.ornek.com/api/v1/client/tickets/${id}/attachments/${aid}`, {
headers: { Authorization: `Bearer ${clientKey}` },
});
const { data } = await res.json();
const blob = await (await fetch(`data:${data.mime};base64,${data.content}`)).blob();$ch = curl_init('https://panel.ornek.com/api/v1/client/tickets/' . $id . '/attachments/' . $aid);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $clientKey],
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// Icerik JSON icinde KODLU gelir: buyuk dosyalarda bellek kullanimini hesaba katin.
$a = Kernel::internal('client:Tickets/GetTicketAttachment',
['owner_id' => $uid, 'id' => $id, 'aid' => $aid])['data'];
file_put_contents($a['name'], base64_decode($a['content']));Tuzaklar
Talep detayını okumak hesabın okunmamış işaretini temizler. Bildirim rozeti kuran bir iş bu ucu çağırdığında rozet müşteri görmeden düşer. Sayımı liste ucundan yapın; detayı yalnız müşteri gerçekten açtığında çağırın.
Personel bir talebi kilitlediyse ne yanıt yazılabilir ne de yeniden açılabilir. Bu durum kapalı olmaktan farklıdır: kapalı bir talep yeniden açılır, kilitli olan açılmaz. Detaydaki kilit alanını okuyup arayüzde yeni talep açma yolunu gösterin.
Hem talep puanı hem personel yanıtı puanı bir kez verilir; ikinci deneme reddedilir. Kapatırken puan göndermek de aynı hakkı kullanır ve talep zaten puanlıysa o değer sessizce atlanır. Arayüzde onay isteyin.
Parola ve anahtar gibi bilgiler için ayrı bir yapı vardır: erişim grubu satırları. Oradaki parola tipli değerler şifreli saklanır ve yalnız sahibiyle personele çözülür. Aynı bilgiyi mesaj metnine yazmak onu düz metin olarak bırakır.
Ekler kodlanmış içerik olarak gönderilir; bir adres vermek reddedilir. Ekler talep kaydedilmeden önce doğrulanır, yani bozuk bir dosya yarım bir talep bırakmaz. İndirme de aynı biçimdedir: içerik kodlanmış olarak JSON içinde gelir.
Personelin kendi arasında yazdığı notlar mesaj dizisinde hiç yer almaz ve o notlardaki ekler indirilemez. Yani müşteri arayüzünde eksik görünen bir mesaj numarası hata değil, tasarımdır.
İlgili Makaleler
Geri bildiriminiz için teşekkürler!
Yukarıda bulamadığınız her şey için destek ekibimiz her zaman yanınızda.