squish
X-Api-Key; restano aperti
/health, la pagina di test e i link condivisi. Il servizio è raggiungibile da Internet
senza TLS: non ci sono password o dati riservati negli URL, ma i documenti viaggiano in
chiaro.1) In ingresso il contenuto (immagine, PDF, XML) va sempre referenziato da una variabile —
--data-binary @$var — mai incollato dentro la stringa delle opzioni
cURL. FileMaker spezza le opzioni sugli spazi, e un < subito dopo un =
viene letto come "leggi da file". Un XML o un binario incollati inline non arriveranno mai interi.
2) In uscita, se il Target dell'Insert from URL è una variabile (non un campo container), va aggiunta l'opzione
--FM-return-container-variable: senza,
FileMaker tratta la risposta binaria come testo e dà errore 507. Con un campo container
come Target non serve. Vale per tutti gli endpoint che restituiscono un file (immagini, PDF, PNG).squish
Ottimizzazione immagini (imgservice, porta 3002) · http://squish.cmisolutions.it:3002
Comprime e ridimensiona immagini. In ingresso: BMP, JPEG, PNG, WebP,
AVIF e HEIC/HEIF (le foto iPhone). In uscita: JPEG, WebP, AVIF (il più
compresso), PNG. Nasce per aggirare il limite di GetThumbnail di FileMaker, che sa
solo ridimensionare producendo JPEG e non sa ricomprimere a qualità controllata mantenendo la
risoluzione. Usa Pillow (+ pillow-heif per l'HEIC): nessuna dipendenza di sistema, tutto dentro
/app.
POST/fontsX-Api-Key
Carica un font (TTF/OTF)
Aggiunge un font per la filigrana di testo (wm_font=nome), oltre
a quelli preinstallati. Via programmatica con la chiave normale, o a mano dal pannello
di amministrazione. Il file va nel corpo grezzo, il nome nella query.
Input accettati. corpo grezzo = il .ttf/.otf • oppure multipart file
| parametro | valori | default | note |
|---|---|---|---|
nome | testo | obbligatorio | lettere/cifre/-/_; stesso nome = sovrascrive |
cURL
curl -X POST -H "X-Api-Key: LA_TUA_CHIAVE" \ --data-binary @MioFont.ttf "http://squish.cmisolutions.it:3002/fonts?nome=aziendale" curl -H "X-Api-Key: LA_TUA_CHIAVE" "http://squish.cmisolutions.it:3002/fonts" # elenco (nome, formato, bytes)
Risposta
JSON {"ok": true, "nome": "aziendale"}. GET /fonts/<nome> scarica il font; DELETE /fonts/<nome> lo elimina.
Da sapere
- ~57 font già preinstallati da Google Fonts (OFL/Apache): elenco con
GET /fonts. Coprono sans, serif, titoli/display, monospace e script. - Solo TTF/OTF, max 10 MB. Carica font di cui hai la licenza d'uso: il servizio non può verificarlo.
POST/optimizeX-Api-Key
Ottimizza un'immagine
Alias: /optimize/image
Riceve l'immagine come binario grezzo nel corpo della richiesta e restituisce la versione ottimizzata, sempre binaria, pronta per un campo container. Accetta anche i HEIC/HEIF delle foto iPhone (trasparente: mandi il .heic e scegli il formato di uscita). Gestisce l'orientamento EXIF, converte CMYK in RGB e appiattisce la trasparenza su bianco quando l'uscita è JPEG (l'AVIF invece la conserva). Guardia anti decompression-bomb a 120 megapixel.
| parametro | valori | default | note |
|---|---|---|---|
format | jpeg | webp | avif | png | auto | jpeg | auto = png se c'è trasparenza, altrimenti jpeg. avif = più compresso (~−49% vs jpeg) |
quality | 1-100 | 82 | ignorato per png, che è lossless |
maxw | px | — | larghezza massima; mantiene le proporzioni e non ingrandisce mai |
maxh | px | — | altezza massima |
strip | 0 | 1 | 1 | rimuove i metadati EXIF/ICC |
filename | testo | (nome originale) | nome del file restituito; l'estensione la mette il servizio in base al formato |
wm | testo | — | filigrana di testo: se presente, sovrappone questo testo |
wm_font | nome font | (default) | font per il testo: un preinstallato o uno caricato nel pannello (vedi sotto) |
wm_image | nome preset | — | filigrana logo PNG: usa un PNG caricato nel pannello di amministrazione. Ha priorità sul testo |
wm_pos | br | bl | tr | tl | center | tile | br | angoli, centro, o tile = ripetuto su tutta l'immagine |
wm_size | 1-50 | 6 | altezza del testo in % della larghezza dell'immagine |
wm_color | #rrggbb o nome CSS | #ffffff | colore del testo |
wm_opacity | 0-100 | 50 | 0 = invisibile, 100 = pieno |
wm_rotate | gradi | 0 | 45 per la classica diagonale |
cURL
# comprimi e ridimensiona curl -X POST \ -H "X-Api-Key: LA_TUA_CHIAVE" \ --data-binary @foto.bmp \ "http://squish.cmisolutions.it:3002/optimize?format=jpeg&quality=80&maxw=1600" \ -o ottimizzata.jpg # filigrana diagonale al centro, con un font preinstallato (Oswald) curl -X POST -H "X-Api-Key: LA_TUA_CHIAVE" --data-binary @foto.jpg \ "http://squish.cmisolutions.it:3002/optimize?wm=COPIA+NON+VALIDA&wm_font=oswald&wm_pos=center&wm_rotate=25&wm_size=11&wm_opacity=55" \ -o filigranata.jpg # foto iPhone HEIC -> AVIF (doppia compressione: formato di uscita moderno) curl -X POST -H "X-Api-Key: LA_TUA_CHIAVE" --data-binary @foto.heic \ "http://squish.cmisolutions.it:3002/optimize?format=avif&quality=55&maxw=2000" -o foto.avif # logo PNG trasparente (caricato prima nel pannello di amministrazione come "logo_cmi") curl -X POST -H "X-Api-Key: LA_TUA_CHIAVE" --data-binary @foto.jpg \ "http://squish.cmisolutions.it:3002/optimize?wm_image=logo_cmi&wm_pos=br&wm_size=22&wm_opacity=80" \ -o con_logo.jpg
FileMaker
Set Variable [ $img ; value: Immagini::ContainerOriginale ]
Insert from URL [
Select ; With dialog: Off ;
Target: Immagini::ContainerOttimizzato ; // campo container: nessuna opzione extra
"http://squish.cmisolutions.it:3002/optimize?format=jpeg&quality=80&maxw=1600" ;
cURL options:
"--data-binary @$img "
& "-H \"X-Api-Key: " & $$API_KEY & "\" "
& "-H \"Content-Type: application/octet-stream\""
// Se il Target è una VARIABILE (es. $risultato) invece di un campo container,
// aggiungi questa opzione, altrimenti FileMaker dà errore 507:
// & " --FM-return-container-variable"
]
Risposta
L'immagine binaria. Header: X-Original-Bytes,
X-Optimized-Bytes, X-Ratio, X-Dimensions,
X-Source-Format. Il Content-Disposition dà il nome al file nel container
(vedi sotto per conservarlo).
Da sapere
- Destinazione a variabile → errore 507: se il Target dell'Insert from URL è una variabile (non un campo container), aggiungi
--FM-return-container-variablealle cURL options, altrimenti FileMaker interpreta il binario come testo e dà 507. Con un campo container come Target non serve. - Conservare il nome del file: con
--data-binaryil nome NON viaggia (arrivano solo i byte) → l'uscita èoptimized.<ext>. Per mantenerlo hai due strade: usa-F "file=@$img"(il container porta con sé il nome, preservato in automatico), oppure passa?filename=nome. In entrambi i casi cambia solo l'estensione secondo il formato. - Accetta sia il corpo grezzo (
--data-binary, consigliato) sia il multipart (-F file=@...). Quest'ultimo serve proprio a portare il nome del file. - Un BMP è non compresso: convertirlo in JPEG è il caso con più guadagno (misurato: 18 MB → 1,5 MB, −91%).
- Su un JPEG a parità di risoluzione conta solo
quality(misurato: q95 3,3 MB → q75 1,27 MB, −62%). - Filigrana e compressione si fanno in un colpo solo: sono parametri dello stesso endpoint, non due chiamate. Con le immagini il costo vero è il trasferimento.
- La filigrana testuale usa il font incorporato in Pillow (sull'appbox non c'è alcun font di sistema, e
/usrè effimero): un solo carattere, ma funziona sempre. - La filigrana a logo (
wm_image) usa un PNG trasparente caricato una volta nel pannello di amministrazione (sezione Filigrane) e richiamato per nome: il logo non viaggia a ogni chiamata.wm_opacitymodula la trasparenza già presente nel PNG,wm_colorviene ignorato (il logo ha i suoi colori). - Font (
wm_font): la filigrana di testo può usare un font diverso dal default. Ci sono ~57 font preinstallati da Google Fonts (OFL/Apache) — elenco completo conGET /fontso nel pannello. Qualche esempio per categoria: sans roboto/poppins/inter/lato/montserrat/raleway; titoli/timbri anton/bebasneue/oswald/archivoblack/bungee/staatliches; serif merriweather/playfairdisplay/lora/ebgaramond; mono robotomono/jetbrainsmono/spacemono; script pacifico/dancingscript/caveat/lobster. Puoi aggiungerne altri (TTF/OTF) dal pannello di amministrazione o viaPOST /fonts. - Se il testo è troppo lungo o
wm_sizetroppo alto, la filigrana viene rimpicciolita per stare dentro invece di essere tagliata dal bordo (verificato).tilefa eccezione: lì deve uscire dai bordi. mozjpegnon è disponibile senza dipendenze di sistema: si usa libjpeg-turbo con optimize+progressive.
POST/watermarksX-Api-Key
Carica un logo/filigrana PNG
Salva un PNG trasparente come preset, richiamabile poi con
?wm_image=nome. Via programmatica (chiave normale, anche da FileMaker); la
stessa cosa si fa a mano dal pannello di amministrazione. Il PNG va nel corpo grezzo, il nome
nella query.
Input accettati. corpo grezzo = il PNG • oppure multipart file
| parametro | valori | default | note |
|---|---|---|---|
nome | testo | obbligatorio | lettere, cifre, - e _; caricare lo stesso nome sovrascrive |
cURL
curl -X POST -H "X-Api-Key: LA_TUA_CHIAVE" \ --data-binary @logo.png \ "http://squish.cmisolutions.it:3002/watermarks?nome=logo_cmi"
FileMaker
Set Variable [ $png ; value: Loghi::LogoPNG ]
Insert from URL [
Select ; With dialog: Off ; Target: $risposta ;
"http://squish.cmisolutions.it:3002/watermarks?nome=logo_cmi" ;
cURL options: "--data-binary @$png -H \"X-Api-Key: " & $$API_KEY & "\""
]
Risposta
JSON {"ok": true, "nome": "logo_cmi"}.
Da sapere
- Solo PNG (serve la trasparenza), max 5 MB, fino a 50 filigrane totali.
- Le filigrane sono condivise fra tutti i soggetti: con la chiave normale chiunque può sovrascriverle o eliminarle. Nel contesto CMI (database tutti interni) è accettabile.
GET/watermarksX-Api-Key
Elenca le filigrane
Nomi e dimensioni delle filigrane caricate. GET /watermarks/<nome> scarica il PNG.
cURL
curl -H "X-Api-Key: LA_TUA_CHIAVE" "http://squish.cmisolutions.it:3002/watermarks" curl -H "X-Api-Key: LA_TUA_CHIAVE" "http://squish.cmisolutions.it:3002/watermarks/logo_cmi" -o logo.png
Risposta
JSON con watermarks[] (nome, bytes). Il singolo restituisce il PNG.
Da sapere
- Per eliminare:
DELETE /watermarks/<nome>con la chiave.
Comuni
Autenticazione e stato del servizio
Valgono per ogni endpoint di questo servizio.
GET/healthsenza chiave
Stato del servizio
Sonda di vita, aperta e non contabilizzata: un check ogni minuto non sporca le statistiche.
cURL
curl http://squish.cmisolutions.it:3002/health
Risposta
JSON con status, service, la versione della libreria e auth (se l'obbligo di chiave è attivo).
—Autenticazionesenza chiave
Come funzionano le chiavi
Una chiave = un soggetto (un database FileMaker, uno script, n8n). Ogni chiave porta l'elenco dei servizi su cui è abilitata, quindi la stessa chiave può valere su più servizi — ed è quello che vuoi: così le statistiche attribuiscono tutto il consumo a un'unica riga. Non condividere una chiave fra due soggetti: perderesti proprio l'informazione per cui l'hai creata. Le chiavi le gestisce l'amministratore: se te ne serve una, o la tua non funziona più, chiedila a lui.
cURL
# su ogni POST di lavoro -H "X-Api-Key: cmi_xxxxxxxxxxxx" # in FileMaker, tenendo la chiave in una variabile globale sola: "-H \"X-Api-Key: " & $$API_KEY & "\""
Risposta
Se la chiave manca o è errata: 401 con un messaggio esplicito (mancante, non riconosciuta, revocata, non abilitata per questo servizio).
Da sapere
- Restano aperti senza chiave:
/healthe la pagina di test su/. - Revoche e nuove chiavi hanno effetto immediato, senza riavviare i servizi.
- Oltre ai servizi, una chiave può essere ristretta ai singoli endpoint. Se è abilitata al servizio ma non a quella rotta la risposta è 403 (non 401: la chiave è valida, manca il permesso). Le restrizioni si impostano dal pannello di amministrazione e valgono subito.
- Ogni risposta porta
X-Esito: ok|erroreeX-Status. Servono da FileMaker:Insert from URLNON fallisce sugli errori HTTP —Get(LastError)resta 0 e il corpo dell'errore finisce nel contenitore, sovrascrivendo l'allegato buono. Con--dump-header $hsi controlla l'esito prima di scrivere sul campo. Regola d'oro: mandare il risultato in una variabile, verificare, e solo allora fareSet Field. - Nome del file restituito: gli endpoint che restituiscono un file accettano
?filename=. Senza, si usa il nome originale se l'invio è multipart (che lo porta con sé); con--data-binaryil nome si perde, quindi lì il parametro serve. L'estensione è sempre quella d'uscita, sostituita e non appesa. Il nome è anche nell'headerX-Filename.