Create new ticket
createTicket()
This gets called when a customer creates a new ticket in the storefront. This gets called in the following file:
app/Http/Controllers/Storefront/Account/SupportTicketController.php Line 125Parameters
Type | Name | Description |
|---|---|---|
SalesChannel | salesChannel | The salesChannel |
Customer or null | customer | The Customer object. If null, then guestName and guestMail is filled. (The ticket was created without login using contact forms) |
string | subject | The ticket subject. |
string | message | The initial message. |
ProductHosting or Domain or null | product | The selected ProductHosting or Domain or null. Check with instanceof() |
TicketDepartment or null | department | The selected Department |
array | attachments | Array of ticket attachments |
String or null | guestName | If customer is null, this contains the guest name |
String or null | guestMail | If customer is null, this contains the guest email |
Response
TicketCreatedResponse() class.
Type | Name | Description |
|---|---|---|
mixed | $id | The ID of the ticked. Usually integer or UUID. |
mixed | $number | The number of the ticket which was created during generation. |
mixed | $messageId | The ID of the initial message. |
array | $attachmentFilePaths | Array of file paths in the same order as the files. |
Example Code
public function createTicket(
SalesChannel $salesChannel,
?Customer $customer,
string $subject,
string $message,
mixed $product,
?TicketDepartment $department = null,
array $attachments = [],
?string $guestName = null,
?string $guestMail = null,
): TicketCreatedResponse {
$mailboxId = $department->provider_department_id["freescout"] ?? $this->provider->default_department_id;
$customerId = $this->getCustomerId($customer, $guestName, $guestMail);
$additionalTexts = [];
if($customer !== null) {
$customerViewUrl = $salesChannel->url . route('admin.customer.edit', $customer->id, false);
$additionalTexts = [
"Ticket aus hostware in Freescout erstellt",
"Verkaufskanal: {$salesChannel->name}",
"<a href='{$customerViewUrl}'>Kunde ansehen (#{$customer->customer_number})</a>"
];
if ($product !== null) {
$productRoute = "N-A";
$productText = "N/A";
if ($product instanceof Domain) {
$productRoute = route('admin.domain.view', $product->fqdn, false);
$productText = "{$product->fqdn} (Domain)";
}
if ($product instanceof ProductHosting) {
$productRoute = route('admin.hosting.hostings.view', $product->id, false);
$productText = "{$product->product->name} #{$product->product_hosting_number} (Hosting)";
}
$completeUrl = $salesChannel->url . $productRoute;
$additionalTexts[] = '<a href="' . $completeUrl . '">Verlinktes Produkt ansehen (' . $productText . ')</a>';
}
}
$threadAttachments = [];
foreach ($attachments as $attachment) {
$threadAttachments[] = [
'fileName' => $attachment->getClientOriginalName(),
'mimeType' => $attachment->getMimeType(),
'data' => base64_encode($attachment->getContent()),
];
}
$response = $this->makeRequest("conversations", "POST", [
"type" => "email",
"mailboxId" => $mailboxId,
"subject" => $subject,
"customer" => [
'id' => $customerId,
],
"threads" => [[
'text' => $message,
'type' => 'customer',
'customer' => [
'id' => $customerId,
],
"attachments" => $threadAttachments
], [
'text' => implode("<br>", $additionalTexts),
'type' => 'note',
'user' => $this->_getFreescoutUserId()
]],
"createdAt" => now()->setTimezone("UTC")->toISOString(),
"status" => "active"
]);
/**
* Get the attachment IDs
*/
$attachmentResponse = [];
foreach ($response->_embedded->threads[0]->_embedded->attachments as $file) {
$attachmentResponse[] = $file->id;
}
Log::debug("Freescout ticket creation response", ["res" => $response]);
return new TicketCreatedResponse(
$response->id,
$response->number,
$response->_embedded->threads[0]->id,
$attachmentResponse
);
}
/**
The function below is not required by the interface, but it gets used in the createTicket() of Freescout.
This method searches or creates a customer / contact at the ticket api using the given customer.
*/
private function getCustomerId(?Customer $customer, ?string $guestName = null, ?string $guestMail = null,) {
if($customer === null) {
/**
* Create a guest in freescout
*/
$allCustomers = $this->makeRequest("customers", "GET", [
"email" => $guestMail
]);
if (count($allCustomers->_embedded->customers) === 1) {
return $allCustomers->_embedded->customers[0]->id;
}
$response = $this->makeRequest("customers", "POST", [
"firstName" => $guestName,
"lastName" => "-",
"notes" => "Aus hostware als Gast erstellt",
"emails" => [[
'value' => $guestMail,
'type' => 'home',
]]
]);
return $response->id;
}
/**
If the customer already has a contact saved in the hostware database, use that.
**/
if (isset($customer->support_ticket_providers['freescout'])) {
return $customer->support_ticket_providers['freescout'];
}
/**
* Search existing customers for the email
*/
$allCustomers = $this->makeRequest("customers", "GET", [
"email" => $customer->email
]);
if (count($allCustomers->_embedded->customers) === 1) {
$customer->addTicketProviderId("freescout", $allCustomers->_embedded->customers[0]->id);
return $allCustomers->_embedded->customers[0]->id;
}
/**
If no existing contact was found, create a new one.
*/
$firstAddress = $customer->firstAddress();
$customerViewUrl = $customer->salesChannel->url . route('admin.customer.edit', $customer->id, false);
$response = $this->makeRequest("customers", "POST", [
"firstName" => $customer->first_name,
"lastName" => $customer->last_name,
"phone" => $customer->phone,
"photoUrl" => null,
"jobTitle" => null,
"photoType" => null,
"address" => array(
'city' => $firstAddress->city,
'state' => '-',
'zip' => $firstAddress->zipcode,
'country' => $firstAddress->country,
'address' => $firstAddress->street_full,
),
"notes" => "Aus hostware importiert\n\n{$customerViewUrl}",
"company" => $customer->company,
"emails" => [[
'value' => $customer->email,
'type' => 'home',
]],
"phones" => [[
'value' => $customer->phone,
'type' => 'home',
]]
]);
// Save the contact id to customer in hostware.
$customer->addTicketProviderId("freescout", $response->id);
return $response->id;
}Testing
You can test this function by creating a ticket in the storefront.