Skip to content

Latest commit

 

History

History
295 lines (251 loc) · 10.1 KB

File metadata and controls

295 lines (251 loc) · 10.1 KB

Bytedoc — Guide d'integration FileMaker

Comment utiliser l'API Bytedoc depuis FileMaker Pro / FileMaker Cloud

Prerequis

  • FileMaker Pro 16+ ou FileMaker Cloud
  • Un compte Bytedoc avec une cle API
  • Aucun plugin requis — tout est natif via Insert from URL

Concepts cles

Bytedoc FileMaker equivalent
Template Un modele de document (PDF form, HTML, DOCX) stocke sur le serveur
Document Le resultat genere apres remplissage d'un template
API Key Cle d'authentification (comme un mot de passe pour l'API)
Fill Remplir un formulaire PDF existant
Generate Generer un PDF a partir d'un template HTML
Webhook Notification automatique quand un document est pret

Script 1 : Remplir un formulaire PDF (Fill)

# --- Configuration ---
Set Variable [ $apiKey ; Value: GetValue ( Settings::APIKey ; 1 ) ]
Set Variable [ $baseUrl ; Value: "https://api.bytedoc.dev/v1" ]
Set Variable [ $templateId ; Value: Invoices::TemplateID ]

# --- Construire le JSON ---
Set Variable [ $json ; Value:
  JSONSetElement ( "{}" ;
    ["template_id" ; $templateId ; JSONString] ;
    ["data.client_name" ; Clients::Name ; JSONString] ;
    ["data.client_address" ; Clients::Address ; JSONString] ;
    ["data.invoice_number" ; Invoices::Number ; JSONString] ;
    ["data.invoice_date" ; Invoices::Date ; JSONString] ;
    ["data.total" ; Invoices::Total ; JSONString] ;
    ["options.flatten" ; True ; JSONBoolean] ;
    ["options.filename" ; "facture-" & Invoices::Number & ".pdf" ; JSONString]
  )
]

# --- Appel API ---
Set Variable [ $url ; Value: $baseUrl & "/documents/fill" ]
Insert from URL [ Select ; With dialog: Off ;
  Target: $response ;
  $url ;
  cURL options:
    "--request POST" &
    " --header \"Authorization: Bearer " & $apiKey & "\"" &
    " --header \"Content-Type: application/json\"" &
    " --data @$json"
]

# --- Verifier le resultat ---
If [ Get(LastError) = 0 ]
  Set Variable [ $docId ; Value: JSONGetElement ( $response ; "id" ) ]
  Set Variable [ $downloadUrl ; Value: JSONGetElement ( $response ; "download_url" ) ]

  # --- Telecharger le PDF dans un champ container ---
  Insert from URL [ Select ; With dialog: Off ;
    Target: Invoices::PDF_File ;
    $downloadUrl ;
    cURL options:
      "--header \"Authorization: Bearer " & $apiKey & "\""
  ]

  Set Field [ Invoices::DocumentID ; $docId ]
  Set Field [ Invoices::Status ; "Genere" ]
Else
  Show Custom Dialog [ "Erreur API" ;
    "Code: " & Get(LastError) & ¶ &
    "Detail: " & Get(LastExternalErrorDetail)
  ]
End If

Script 2 : Generer une facture PDF (Generate)

# --- Configuration ---
Set Variable [ $apiKey ; Value: GetValue ( Settings::APIKey ; 1 ) ]
Set Variable [ $baseUrl ; Value: "https://api.bytedoc.dev/v1" ]
Set Variable [ $templateId ; Value: Settings::InvoiceTemplateID ]

# --- Construire le tableau d'articles ---
Set Variable [ $items ; Value: "[]" ]
Go to Related Record [ From table: "InvoiceLines" ; Using layout: "InvoiceLines" ]
Go to Record/Request/Page [ First ]
Loop
  Set Variable [ $item ; Value:
    JSONSetElement ( "{}" ;
      ["description" ; InvoiceLines::Description ; JSONString] ;
      ["quantity" ; InvoiceLines::Quantity ; JSONNumber] ;
      ["unit_price" ; InvoiceLines::UnitPrice ; JSONNumber] ;
      ["line_total" ; InvoiceLines::LineTotal ; JSONNumber]
    )
  ]
  Set Variable [ $items ; Value: JSONSetElement ( $items ; "[" & (Get(RecordNumber) - 1) & "]" ; $item ; JSONObject ) ]
  Go to Record/Request/Page [ Next ; Exit after last: On ]
End Loop

# --- JSON complet ---
Set Variable [ $json ; Value:
  JSONSetElement ( "{}" ;
    ["template_id" ; $templateId ; JSONString] ;
    ["data.company.name" ; Settings::CompanyName ; JSONString] ;
    ["data.company.address" ; Settings::CompanyAddress ; JSONString] ;
    ["data.company.siret" ; Settings::CompanySIRET ; JSONString] ;
    ["data.client.name" ; Clients::Name ; JSONString] ;
    ["data.client.address" ; Clients::Address ; JSONString] ;
    ["data.client.email" ; Clients::Email ; JSONString] ;
    ["data.invoice_number" ; Invoices::Number ; JSONString] ;
    ["data.invoice_date" ; Invoices::Date ; JSONString] ;
    ["data.due_date" ; Invoices::DueDate ; JSONString] ;
    ["data.items" ; $items ; JSONArray] ;
    ["data.subtotal" ; Invoices::Subtotal ; JSONNumber] ;
    ["data.tax_rate" ; Invoices::TaxRate ; JSONNumber] ;
    ["data.tax_amount" ; Invoices::TaxAmount ; JSONNumber] ;
    ["data.total" ; Invoices::Total ; JSONNumber] ;
    ["options.format" ; "A4" ; JSONString] ;
    ["options.filename" ; "facture-" & Invoices::Number & ".pdf" ; JSONString]
  )
]

# --- Appel API ---
Set Variable [ $url ; Value: $baseUrl & "/documents/generate" ]
Insert from URL [ Select ; With dialog: Off ;
  Target: $response ;
  $url ;
  cURL options:
    "--request POST" &
    " --header \"Authorization: Bearer " & $apiKey & "\"" &
    " --header \"Content-Type: application/json\"" &
    " --data @$json"
]

# --- Telecharger le resultat ---
If [ Get(LastError) = 0 ]
  Set Variable [ $downloadUrl ; Value: JSONGetElement ( $response ; "download_url" ) ]
  Insert from URL [ Select ; With dialog: Off ;
    Target: Invoices::PDF_File ;
    $downloadUrl ;
    cURL options:
      "--header \"Authorization: Bearer " & $apiKey & "\""
  ]
  Set Field [ Invoices::DocumentID ; JSONGetElement ( $response ; "id" ) ]
  Set Field [ Invoices::Status ; "Genere" ]
Else
  Show Custom Dialog [ "Erreur API" ;
    "Code: " & Get(LastError) & ¶ &
    "Detail: " & Get(LastExternalErrorDetail)
  ]
End If

Script 3 : Lister les templates

# --- Configuration ---
Set Variable [ $apiKey ; Value: GetValue ( Settings::APIKey ; 1 ) ]
Set Variable [ $baseUrl ; Value: "https://api.bytedoc.dev/v1" ]

# --- Appel API ---
Insert from URL [ Select ; With dialog: Off ;
  Target: $response ;
  $baseUrl & "/templates" ;
  cURL options:
    "--header \"Authorization: Bearer " & $apiKey & "\""
]

# --- Parser la reponse ---
If [ Get(LastError) = 0 ]
  Set Variable [ $data ; Value: JSONGetElement ( $response ; "data" ) ]
  Set Variable [ $count ; Value: ValueCount ( JSONListKeys ( $data ; "" ) ) ]

  Set Variable [ $i ; Value: 0 ]
  Loop
    Exit Loop If [ $i >= $count ]
    Set Variable [ $template ; Value: JSONGetElement ( $data ; "[" & $i & "]" ) ]
    Set Variable [ $id ; Value: JSONGetElement ( $template ; "id" ) ]
    Set Variable [ $name ; Value: JSONGetElement ( $template ; "name" ) ]
    Set Variable [ $type ; Value: JSONGetElement ( $template ; "type" ) ]

    # Creer ou mettre a jour l'enregistrement template
    New Record/Request
    Set Field [ Templates::ID ; $id ]
    Set Field [ Templates::Name ; $name ]
    Set Field [ Templates::Type ; $type ]
    Commit Records/Requests

    Set Variable [ $i ; Value: $i + 1 ]
  End Loop
End If

Script 4 : PDF vers Template (IA)

# --- Configuration ---
Set Variable [ $apiKey ; Value: GetValue ( Settings::APIKey ; 1 ) ]
Set Variable [ $baseUrl ; Value: "https://api.bytedoc.dev/v1" ]

# --- Exporter le PDF du champ container ---
Set Variable [ $tempPath ; Value: Get(TemporaryPath) & "upload.pdf" ]
Export Field Contents [ Templates::SourcePDF ; "$tempPath" ]

# --- Upload multipart ---
Set Variable [ $url ; Value: $baseUrl & "/templates/from-pdf" ]
Insert from URL [ Select ; With dialog: Off ;
  Target: $response ;
  $url ;
  cURL options:
    "--request POST" &
    " --header \"Authorization: Bearer " & $apiKey & "\"" &
    " --form \"file=@" & $tempPath & "\"" &
    " --form \"name=" & Templates::Name & "\""
]

# --- Parser la reponse ---
If [ Get(LastError) = 0 ]
  Set Variable [ $templateId ; Value: JSONGetElement ( $response ; "id" ) ]
  Set Variable [ $fieldsCount ; Value: JSONGetElement ( $response ; "fields_count" ) ]

  Set Field [ Templates::BytedocID ; $templateId ]
  Set Field [ Templates::FieldsCount ; $fieldsCount ]
  Set Field [ Templates::Status ; "Processing" ]

  Show Custom Dialog [ "Succes" ;
    "Template cree: " & $templateId & ¶ &
    "Champs detectes: " & $fieldsCount & ¶ & ¶ &
    "Le template est en cours de traitement par l'IA." & ¶ &
    "Verifiez le statut dans quelques secondes."
  ]
Else
  Show Custom Dialog [ "Erreur API" ;
    "Code: " & Get(LastError) & ¶ &
    "Detail: " & Get(LastExternalErrorDetail)
  ]
End If

Astuces FileMaker

Stocker la cle API

Creez une table Settings avec un seul enregistrement :

Champ Type Description
APIKey Texte Votre cle pk_live_xxx
BaseURL Texte https://api.bytedoc.dev/v1
InvoiceTemplateID Texte ID du template de facture

Gestion des erreurs

Toujours verifier apres chaque Insert from URL :

If [ Get(LastError) <> 0 ]
  # Erreur reseau ou FileMaker
  Set Variable [ $fmError ; Value: Get(LastError) ]
  Set Variable [ $detail ; Value: Get(LastExternalErrorDetail) ]
  # Logger dans une table Logs
End If

# Verifier aussi les erreurs API
If [ not IsEmpty ( JSONGetElement ( $response ; "error.code" ) ) ]
  Set Variable [ $errorCode ; Value: JSONGetElement ( $response ; "error.code" ) ]
  Set Variable [ $errorMsg ; Value: JSONGetElement ( $response ; "error.message" ) ]
  # USAGE_LIMIT_EXCEEDED → afficher un message
  # UNAUTHORIZED → verifier la cle API
  # TEMPLATE_NOT_FOUND → verifier l'ID du template
End If

Compatibilite

Plateforme Support Notes
FileMaker Pro 16+ Oui Insert from URL avec cURL
FileMaker Pro 19+ Oui Meilleur support JSON natif
FileMaker Server Oui Scripts cote serveur (PSOS)
FileMaker Cloud Oui Fonctionne sans modification
FileMaker Go Oui iOS/iPadOS, meme syntaxe
FileMaker WebDirect Attention Insert from URL limite — utiliser un script cote serveur via PSOS

Bonnes pratiques

  1. Ne jamais coder la cle API en dur dans les scripts — utilisez la table Settings
  2. Loggez chaque appel API dans une table dediee pour le debugging
  3. Utilisez des scripts cote serveur (PSOS) pour les operations longues (Generate PDF)
  4. Testez d'abord avec une cle pk_test_ avant de passer en production
  5. Gerez le timeout : ajoutez --max-time 30 aux options cURL pour les generations PDF