Przejdź do głównej zawartości

Pliki do zamówienia

Dla: Programista

Sklep albo portal klienta dołącza do zamówienia pliki do druku, a drukarnia sprawdza je w Prynt. Ten przepis wysyła plik do produktu albo do całego zamówienia i pobiera pliki zamówienia z powrotem, np. żeby pokazać je klientowi.

  • Zakres files:write do wysyłania plików i files:read do ich odczytu i pobierania.
  • Zakres orders:read. Plik dołączasz do zamówienia albo produktu, które klucz widzi, a listę plików czytasz w zapytaniach order i product.
  • Klienta API z przepisu Obsługa błędów i ponowień. Kod niżej wysyła żądania przez niego.

Treść pliku nie przechodzi przez API GraphQL: idzie prosto do magazynu plików, pod podpisany adres od Prynt.

  1. Rozpocznij wysyłkę mutacją initiateFileUpload. Podaj, do czego dołączasz plik (entityType: PRODUCT dla pliku do druku produktu albo ORDER dla pliku całego zamówienia, i entityId), nazwę pliku, jego typ (mimeType) i dokładny rozmiar w bajtach (sizeBytes). Prynt zwraca fileId, adres uploadUrl, metodę method, nagłówki requiredHeaders i czas expiresAt.

  2. Wyślij treść pliku jednym żądaniem metodą method na uploadUrl, z nagłówkami z requiredHeaders i dokładnie sizeBytes bajtami. Nie wysyłaj klucza API: adres jest podpisany i działa bez niego, a nagłówek Authorization psuje podpis.

  3. Zakończ wysyłkę mutacją completeFileUpload z fileId. Prynt mierzy plik w magazynie i dopiero wtedy pokazuje go w zamówieniu. Plik produktu, który nie jest jeszcze w produkcji (NO_FILES, FILES_TO_CHECK, WAITING_FOR_ADMIN_RESPONSE, WAITING_FOR_CLIENT_RESPONSE, FILES_ACCEPTED), trafia do sprawdzenia: produkt przechodzi w status FILES_TO_CHECK, a jego pliki mają verificationStatus: TO_CHECK. Produkt w produkcji i dalej zostaje w swoim statusie.

  • Adres wysyłki działa do expiresAt (domyślnie godzinę). Nieudane wysłanie treści możesz powtórzyć pod ten sam adres przed tym czasem. Później zacznij od nowa od initiateFileUpload: niezakończona wysyłka nie pojawi się w Prynt.
  • Zakończenie z kluczem idempotencji. Plik kończy się raz: drugie completeFileUpload bez klucza kończy się błędem. Kod wysyła je z kluczem zakoncz-<fileId>, więc ponowienie zwraca zapisaną odpowiedź.
  • Typy i rozmiar. Prynt domyślnie przyjmuje formaty do druku i biurowe, do 5 GB w jednym żądaniu. W mimeType podaj jeden z typów: application/pdf, image/png, image/jpeg, image/tiff, image/webp, image/svg+xml, application/postscript, application/illustrator, application/x-indesign, application/vnd.adobe.photoshop, application/zip, application/x-rar-compressed, text/csv albo typ pliku XLSX lub DOCX. Inny typ API odrzuca błędem walidacji, a komunikat błędu podaje listę typów, które przyjmuje Twoja drukarnia.
  • Nowy plik cofa akceptację. Plik dodany do produktu z zaakceptowanymi plikami (FILES_ACCEPTED) przestawia go z powrotem na FILES_TO_CHECK: drukarnia sprawdza pliki jeszcze raz. Poprawki wysyłaj tylko wtedy, gdy drukarnia o nie prosi.
  • Tylko zamówienia i produkty, bez archiwum. Klucz API dołącza pliki wyłącznie do ORDER i PRODUCT, a nie do zarchiwizowanego zamówienia ani jego produktów.
  • Pobieranie przez podpisany adres. downloadUrl działa bez klucza API przez ograniczony czas (domyślnie godzinę). Nie zapisuj go na później: po nowy adres zapytaj ponownie o plik. Plik bez downloadUrl (pole może być puste) kod pomija, a katalog docelowy zakłada sam.

Przykłady pokazują adres zastępczy. Wpisz adres swojej drukarni, żeby go podmienić.

Wymaga curl, jq, uuidgen i skryptu prynt-call.sh z przepisu Obsługa błędów i ponowień w tym samym katalogu.

order-files.sh
#!/usr/bin/env bash
# order-files.sh — pliki zamówienia (curl, jq; prynt-call.sh z przepisu „Obsługa błędów i ponowień”).
# Wysyłka: ./order-files.sh upload PRODUCT <id produktu> ulotka-a5.pdf application/pdf
# Pobranie: ./order-files.sh download <id zamówienia> <katalog>
set -euo pipefail
body=$(mktemp) result=$(mktemp)
trap 'rm -f "$body" "$result"' EXIT
upload() {
local entity_type=$1 entity_id=$2 path=$3 mime_type=$4
jq -n --arg type "$entity_type" --arg id "$entity_id" --arg name "$(basename "$path")" \
--arg mime "$mime_type" --argjson size "$(wc -c <"$path" | tr -d ' ')" '{
query: "mutation StartUpload($input: InitiateUploadInput!) { initiateFileUpload(input: $input) { fileId uploadUrl method requiredHeaders expiresAt } }",
variables: { input: { entityType: $type, entityId: $id, filename: $name, mimeType: $mime, sizeBytes: $size } }
}' >"$body"
IDEMPOTENCY_KEY=$(uuidgen) ./prynt-call.sh "$body" >"$result"
local file_id url method
file_id=$(jq -r '.data.initiateFileUpload.fileId' "$result")
url=$(jq -r '.data.initiateFileUpload.uploadUrl' "$result")
method=$(jq -r '.data.initiateFileUpload.method' "$result")
# Bez klucza API i dokładnie z nagłówkami od Prynt.
local headers=()
while IFS= read -r header; do headers+=(-H "$header"); done < <(
jq -r '.data.initiateFileUpload.requiredHeaders // "{}" | fromjson | to_entries[] | "\(.key): \(.value)"' "$result"
)
curl -sS --fail -X "$method" "${headers[@]}" --upload-file "$path" "$url"
jq -n --arg id "$file_id" '{
query: "mutation CompleteUpload($input: CompleteUploadInput!) { completeFileUpload(input: $input) { id originalFilename sizeBytes uploadStatus verificationStatus } }",
variables: { input: { fileId: $id } }
}' >"$body"
IDEMPOTENCY_KEY="zakoncz-$file_id" ./prynt-call.sh "$body" | jq '.data.completeFileUpload'
}
download() {
local order_id=$1 directory=$2
jq -n --arg id "$order_id" '{
query: "query OrderFiles($id: ID!) { order(id: $id) { files { id originalFilename mimeType sizeBytes downloadUrl } products { number name files { id originalFilename mimeType sizeBytes downloadUrl } } } }",
variables: { id: $id }
}' >"$body"
./prynt-call.sh "$body" >"$result"
mkdir -p "$directory"
# Podpisany adres działa bez klucza API przez ograniczony czas: pobieraj od razu. Plik bez
# zapisanej treści nie ma adresu: nie ma czego pobrać.
jq -r '.data.order | (.files // []) + ([.products[]?.files // []] | add // []) | .[] |
select(.downloadUrl != null) | "\(.id)-\(.originalFilename)\t\(.downloadUrl)"' "$result" |
while IFS=$'\t' read -r name url; do
curl -sS --fail -o "$directory/$name" "$url"
echo "$directory/$name"
done
}
case ${1:-} in
upload | download) "$@" ;;
*) echo "Użycie: $0 upload <ORDER|PRODUCT> <id> <plik> <typ MIME> | download <id zamówienia> <katalog>" >&2; exit 2 ;;
esac
Okno terminala
./order-files.sh upload PRODUCT "$PRODUCT_ID" ulotka-a5.pdf application/pdf
./order-files.sh download "$ORDER_ID" pliki-zamowienia
  • Nowy plik zmienia Order.updatedAt, więc zamówienie z nowym plikiem, także dodanym przez drukarnię, znajdziesz synchronizacją przyrostową. Zobacz Zamówienia do księgowości.
  • Nowej wersji pliku nie wyślesz przez API, a listy files zamówienia i produktu pokazują tylko pierwszą wersję każdego pliku (versionNumber: 1, parentFileId: null). Gdy drukarnia doda w Prynt nową wersję, klucz dalej widzi i pobiera pierwszą. Poprawiony plik wysyłaj jako nowy plik.