Il est possible d'accepter un dossier et d'y joindre le justificatif via les API GraphQL. Mais avant cela, voici un petit tour d'horizon du fonctionnement :
3 étapes :
1. Vous demandez a notre API une authorisation pour uploader un fichier sur notre object storage.
Cette requete implique de décrire le fichier que vous allez envoyer : le filename, byteSize, checksum (un digest md5, base64digesté) et son contenu. Ceci pour nous permettre de valider que nous echangeons le meme fichier, qu'il n'a pas été altéré etc.. Nous vous renvoyons :
les crédentials pour communiquer avec notre object storage
l'identifiant du fichier (blob_signed_id) a utiliser dans une autre requete pour le lier à une autre mutation
2. Vous uploadez le fichier sur notre object storage, en réutilisant les crédentials de la 1ere requete
3. Vous, client, faites une requete pour lier ce fichier (maintenant sur nos serveurs, identifié par le signed_blob_id) a un justificatif
1ere étape : demander les crédentials
Utiliser la mutation createDirectUpload. Voici un exemple complet de script que vous pouvez executer :
FILE=./file.txt\FILE_TYPE="text/plain" \API_TOKEN="VOTRE_TOKEN" \DOSSIER_ID="un identifiant de dossier, cf: dossiers.id (ce n'est pas le numero de dossier)" \ruby ./get_credentials.rb
get_credentials.rb
require'net/http'require'uri'require'json'require'byebug'require'digest'ENDPOINT=URI('https://www.demarches-simplifiees.fr/api/v2/graphql')QUERY_UPLOAD_REQUEST="mutation createDirectUpload($input: CreateDirectUploadInput!) { createDirectUpload(input: $input) { directUpload { url headers blobId signedBlobId } }}"### that's the HTTP part# open an http connexion to our GraphQL endpointdefopen_http_connection http =Net::HTTP.new(ENDPOINT.host,ENDPOINT.port)ifENDPOINT.scheme =='https' http.use_ssl =true http.verify_mode =OpenSSL::SSL::VERIFY_NONEend httpend# the headers of our http query, include authdefrequest_headers {"Content-Type"=>"application/json","Authorization"=>"Bearer #{ENV.fetch('API_TOKEN') { raise'missing env var API_TOKEN=xxx' }}" }enddefcompute_checksum_in_chunks(io)Digest::MD5.new.tap do|checksum|while (chunk = io.read(5242880)) checksum << chunkend io.rewindend.base64digestenddefrequest_direct_upload_credentials(http, file) data = {"query"=>QUERY_UPLOAD_REQUEST,"operationName"=>"createDirectUpload","variables"=> {"input"=> {"dossierId"=>ENV.fetch("DOSSIER_ID") { raise"missing env var DOSSIER_ID=xxx" },"filename"=> file.path,"byteSize"=> file.size,"checksum"=> compute_checksum_in_chunks(file),"contentType"=>ENV.fetch("FILE_TYPE") { raise'missing file type' } } } } pp "SENT DATA : #{data.inspect}" req =Net::HTTP::Post.new(ENDPOINT, request_headers) req.body = data.to_json http.request(req)endfp =ENV.fetch('FILE') { raise'missing env var FILE' }File.open(fp,'r') do|file| http = open_http_connection response = request_direct_upload_credentials(http, file) body =JSON.parse(response.body)puts body.inspect credentials = body['data']['createDirectUpload']['directUpload'] credentials_headers =JSON.parse(credentials['headers'])puts<<~CURL curl -vvv \ --data-binary @#{file.path} \ -X PUT \ -H "Content-Type: #{credentials_headers['Content-Type']}" \ -H "ETag: #{credentials_headers['ETag']}" \ "#{credentials['url']}" CURLend
La réponse HTTP de notre API sera de la forme suivante
{"data":{"createDirectUpload":{"directUpload":{ "url":"https://static.demarches-simplifiees.fr:443/v1/AUTH_XXX/ds_activestorage_backup/2023/12/21/We/We9FmNxKuJfzEr6QSmKWSrxP263Z?temp_url_sig=XXX\u0026temp_url_expires=XXX",
"headers":"{\"Content-Type\":\"image/png\",\"ETag\":\"d5d122f320e9d34faf716390a33429a7\"}","blobId":"a number in a string","signedBlobId":"a string" } } }}
Aussi notre script echo un exemple pour uploader le fichier via curl, il vous suffit de le copier/coller pour envoyer le même fichier sur notre object storage
2eme étape : Uploader le fichier en utilisant les crédentials
curl -vvv --data-binary @./file.txt -X PUT -H "Content-Type: LE type de votre fichier" -H "ETag: LAVALEUR PRESENTE DANS LA REPONSE, au niveau de headers.etag [attention, c'est un json a parser]" "data[createDirectUpload][directUpload][url]"
3eme étape : Associer ce fichier lors de l'acceptation du dossier.
En préambule, il vous faut envoyer ce message au nom d'un instructeur, nous vous renvoyons à la documentation pour lister les id des instructeurs.
Utiliser la mutation dossierAccepter. Voici un exemple complet de script que vous pouvez executer :
SIGNED_BLOB_ID="Le signed blob id de la 1ere requete" API_TOKEN="votre token d'api" DOSSIER_ID="l'id de votre dossier" INSTRUCTEUR_ID="l'id de l'instructeur" ruby ./accept_with_pj.rb
accept_with_pj.rb
require'net/http'require'uri'require'json'ENDPOINT=URI('https://www.demarches-simplifiees.fr/api/v2/graphql')QUERY="mutation dossierAccepter($input: DossierAccepterInput!) { dossierAccepter(input: $input) { dossier { id } errors { message } }}"### that's the HTTP part# open an http connexion to our GraphQL endpointdefopen_http_connection http =Net::HTTP.new(ENDPOINT.host,ENDPOINT.port)ifENDPOINT.scheme =='https' http.use_ssl =true http.verify_mode =OpenSSL::SSL::VERIFY_NONEend httpend# the headers of our http query, include authdefrequest_headers {"Content-Type"=>"application/json","Authorization"=>"Bearer #{ENV.fetch('API_TOKEN') { raise'missing env var API_TOKEN=xxx' }}" }enddefaccept_dossier_and_link_justificatif(http) data = {"query"=>QUERY,"operationName"=>"dossierAccepter","variables"=> {"input"=> {"dossierId"=>ENV.fetch('DOSSIER_ID') { raise'missing env var DOSSIER_ID' },"instructeurId"=>ENV.fetch('INSTRUCTEUR_ID') { raise'missing env var INSTRUCTEUR_ID' },"justificatif"=>ENV.fetch('SIGNED_BLOB_ID') { raise'missing SIGNED_BLOB_ID env var' } } } } req =Net::HTTP::Post.new(ENDPOINT, request_headers) req.body = data.to_json response = http.request(req) pp JSON.parse(response.body)endhttp = open_http_connectionputs accept_dossier_and_link_justificatif(http)