You are not logged in.
Pages: 1
Topic closed
Bonjour tout le monde
étant donné la difficulté de trouver de la doc, j'ai décidé de placer le code que j'utilise pour :
créer un ticket
trouver une machine à partir de son numéro d'inventaire
associer une machine
affecter le ticket à un tech
ajouter un document et l'associer au ticket
J'utilise Laravel (version 8 ; la 9 est trop fraîche), et Guzzlehttp.
Ce qui a été difficile était :
trouver les paramètres à fournir
paramétrer correctement Guzzle car passer de cUrl à lui n'est pas si simple : GLPI est exigeant sur ce qu'il reçoit
Pour trouver j'ai dû :
parvenir à faire la manip via cUrl
passer cUrl en verbose et utiliser l'option --trace-ascii
connecter Guzzle à netcat (mais cela aurait été possible avec Wireshark) pour voir ce qui est réellement envoyé
@+
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use GuzzleHttp\Client;
use GuzzleHttp\RequestOptions;
use GuzzleHttp\Psr7;
class SignalementController extends Controller
{
public function root(Request &$request) {
return view('layouts.signalements.welcome', ['path' => '']);
}
private function request(Client &$client, string $type, string $url, array $params, int $expectedCode = 200) {
$response = $client->request($type, $url, $params);
if ($response->getStatusCode() != $expectedCode)
throw new \Exception('Request failed; request='.$url.', statusCode='.$response->getStatusCode().', body='.$response->getBody().'; stack: '.(new \Exception)->getTraceAsString());
return json_decode($response->getBody(), true);
}
public function createTicket(Request &$request, string $numinventaire) {
// as input:
// - numinventaire => it is an inventory number; that allows to know the computer that is faulty
// - an optional picture of the material
$request->validate(['problem' => 'required', 'comment'=> 'required', 'latitude' => 'required|numeric', 'longitude' => 'required|numeric', 'geoErrorType' => 'required', 'geoError' => 'nullable']);
try {
// the credentials
$endpoint = config('app.glpiendpoint');
$client = new Client;
$app_token = config('app.glpiapptoken');
// Session creation
$session_token = $this->request($client, 'GET', $endpoint.'/initSession', [
'headers' => [
'Content-Type' => 'application/json',
'Authorization' => 'user_token '.config('app.glpiusrtoken'),
'App-Token' => $app_token
]
])['session_token'];
$headers = [
'Content-Type' => 'application/json',
'Session-Token' => $session_token,
'App-Token' => $app_token
];
// Ticket creation
$params = [
RequestOptions::HEADERS => array_merge($headers, []),
RequestOptions::JSON => [
'input' => [
'name' => $request->get('problem'),
'content' => $request->get('comment')
."\nCoordonnée: ".$request->get('longitude').' '.$request->get('latitude')
]
]
];
$ticket_id = $this->request($client,'POST', $endpoint.'/Ticket', $params, 201)['id'];
// Search the computer associated to the given inventory number
$params = [
\GuzzleHttp\RequestOptions::QUERY => [
'criteria' => [
[
'link' => 'AND',
'itemtype' => 'Computer',
'field' => 6,
'searchtype' => 'equals',
'value' => $numinventaire
]
],
'forcedisplay' => [2] // force display of the computer's id
],
\GuzzleHttp\RequestOptions::HEADERS => array_merge($headers, []),
];
$response = $this->request($client, 'GET', $endpoint.'/search/Computer', $params);
if (count($response['data']) == 0)
throw new Exception('Incorrect data structure in response; statusCode='.$response->getStatusCode().', body='.$response->getBody().'; stack: '.(new \Exception)->getTraceAsString());
$materiel_id = $response['data'][0][2];
// Associate the computer to the ticket
$params = [
RequestOptions::HEADERS => array_merge($headers, []),
RequestOptions::JSON => [
'input' => ['tickets_id' => $ticket_id, 'itemtype' => 'Computer', 'items_id' => $materiel_id]
]
];
$this->request($client, 'POST', $endpoint.'/Item_Ticket', $params, 201);
// Assign the technician to the ticket
$params = [
RequestOptions::HEADERS => array_merge($headers, []),
RequestOptions::JSON => [
'input' => ['_users_id_assign' => 4]
]
];
$this->request($client, 'PUT', $endpoint.'/Ticket/'.$ticket_id, $params);
if ($request->has('photo_jpg')) {//If there is a picture
$storePath = storage_path('app'); //Laravel retrieving and storing mecanism
$path = $request->file('photo_jpg')->store('signalementphoto'); //Laravel retrieving and storing mecanism
// create the document and associate it to the ticket
$boundary = 'COUCOU_XX_UNIQ_BOUNDARY_kjhkjhkjhjkhUHU75'; //the tricky part as GLPI accepts but only "correctly" formated request; the defaut Guzzle behaviour is not supported
$this->request($client, 'POST', $endpoint.'/Document/', [
'body' => new Psr7\MultipartStream([
[
'contents' => json_encode([
'input' => ['name' => "Uploaded document", "_filename" => ["photo.jpg"], 'itemtype'=>'Ticket', 'items_id'=>$ticket_id]
]),
'name' => 'uploadManifest',
RequestOptions::HEADERS => [
'Content-Type' => 'application/json'
]
],
[
'name' => 'filename[0]',
'filename' => 'photo.jpg',
'contents' => Psr7\Utils::tryFopen($storePath.'/'.$path, 'r')
],
], $boundary),
RequestOptions::HEADERS => array_merge($headers, ['Content-Type' => 'multipart/form-data; boundary='.$boundary])
], 201);
}
}
catch(\Exception $ex) {
\Log::warning($ex->getMessage());
return response()->json(['status' => false, 'message' => '', 'result' => ''], 500);
}
return response()->json(['status' => true, 'message' => '', 'result' => ''], 200);;
}
}
Subject: How add ticket, assign a tech and computer, add a document
Hi everyone !
as it is difficult to find docs, I decided to provide the code that I use in order to:
create a ticket
find a computer after its inventory number
associate a computer to the ticket
assign a tech to the ticket
create a document and asssociate it to the ticket
I use Laravel (release 8 ; the 9 is too new), and Guzzlehttp.
It was difficult to:
find the right parameters
tweak Guzzle as it is not easy to come from cUrl: GLPI is really strict
To succeed I had to:
firstly succeed via command line and cUrl
use the flags verbose and --trace-ascii with cUrl
connect Guzzle to netcat (but it would have been possible to do it with Wireshark) in order to see what was really sent
@+
Offline
Comment fait-on pour fermer le ticket ?
Offline
pour fermer on change le titre avec [resolu] et un modérateur ferme la discussion. (fait)
Trouver la panne avant de réparer...
GLPI10.0.16 (ubuntu 22.04 PHP8.1 Mariadb10.6 ) plugins : comportements 2.7.3 reports 1.16.0 formcreator 2.13.9, datainjection 2.13.5 fields 1.21.9
Offline
Pages: 1
Topic closed