HTTP berichten inkomend

  • 3 minutes to read

Het is mogelijk om connected apps (externe toepassingen) toe te laten om data te wijzigen binnen Business Central. ​
Bv. Via C#, Postman, PowerShell, ...​

REST API calls​

  • Verschillende soorten:
    • Insert = POST​
    • Read = GET (vergelijkbaar met URL intikken in browser) ​
    • Modify = PUT/PATCH​
    • Delete = DELETE
  • Via page van type API, specifiek per datatype
  • met versiebeheer
  • via ODATA poort automatisch beschikbaar

Voorbeeld:

Invoke-RestMethod ​
  -Method Get  ​
  -Uri "https://<server>:<port>/<nst>/api/v2.0/companies(<companyid>)/customers" ​
  -Credential (Get-Credential) 

Probleem

Probleem hierbij is dat er voor elk proces een specifieke REST API dient gemaakt te worden. Bij elke wijziging, nieuwe versie te maken. En elke API apart te ontwikkelen/testen/valideren.
Tevens is er geen logging van de calls.

Oplossing

HTTP berichten zijn hierop een antwoord. Deze voorzien een API met 1 tekstveld (contentstring) om bericht door te sturen naar BC.
Je kan zelf instaan voor de structuur van het bericht (json, xml, tekst,...).
Je kan zelf instaan voor de afhandeling van het bericht.

Voorbeeld

Bericht

$Message = @{ ContentString = '{"Type":"API","Method":"HelloWorld","Params":"Bart"}' }​
Invoke-RestMethod ​
  -Method Post​
  -Uri "https://<server>:<port>/<nst>/api/christiaens/bocountdynamics/v1.0/companies(<id>)/HttpMessages" ​
  -Credential (Get-Credential)​
  -ContentType 'application/json' ​
  -Body ($message | ConvertTo-Json)​

Afhandeling

[EventSubscriber(ObjectType::Table, Database::"CFL HttpMessage", 'CFLOnCFLProcess', '', true, true)]​
local procedure Process(var Sender: Record "CFL HttpMessage")​
var​
    JsonObject: JsonObject;​
begin​
    if JsonObject.ReadFrom(Sender.CFLGetContent()) then begin​
        if (JsonValue(JsonObject, 'Type') = 'API') and (JsonValue(JsonObject, 'Method') = 'HelloWorld') then begin​
            Sender.CFLSetResponse(StrSubstNo('Hello %1 !', JsonValue(JsonObject, 'Params')));​
            Sender.Modify(true);​
            exit;​
        end;​
    end;​
end;
TIP

Zie technische informatie voor de procedures en events die het mogelijk maken te integreren met deze componenten.

BoCount Azure Functions API

Azure Function: GET ipv POST

Probleem van een POST functie is dat dit programmatie vereist aan de aanroepende kant.
De url bevat de omgeving en bedrijf. Credentials bevatten inloggegevens. De Body bevat het bericht.

Via een Azure function is het binnen BoCount mogelijk een GET om te zetten in een POST.
Dit maakt het mogelijk om met een eenvoudige url (bvb. hyperlink in mail, QR-code op document,...) een actie uit te voeren in Business Central, zonder dat men moet inloggen in Business Central.

De uit te voeren actie, credentials,... zitten vervat in de query-string parameters.
Bijkomend probleem hierbij is dat de querystring manipuleerbaar is door de gebruiker.

  • Url met omgeving + bedrijf wijzigbaar ​
  • Credential leesbaar?​
  • Body moeilijk als querystring door te geven (vreemde tekens in xml, json) ​
  • Body manipuleerbaar

Oplossing hiervoor is dat we de querystring gaan omzetten naar een Base64-sting met encryptie. Voorbeeld: https://azurefunction? apidata=XG0pc8....​ De 'XG0pc8....​' bevat dan alle informatie omtrent wat dient te gebeuren.

{ ​
  "Username" : "SERVICEUSER" , ​
  "Password" : "******" , ​
  "Url":"https://<server>:<port>/<nst>/api/christiaens/bocountdynamics/v1.0/companies(<id>)/HttpMessages",​
  "ContentString" : "{\"Type\":\"API\",\"Method\":\"HelloWorld\",\"Params\":\"Bart\"}",​
  "ResultType": "String"​
}​

De authenticatie in bovenstaand voorbeeld gebeurt door gebruiker en passwoord. In SAAS is dit niet mogelijk, alsook is dit in OnPrem obsolete. Dus we maken beter gebruik van OAUTH.

{ ​
  "AadTenantId": "9d73024c-******",​
  "ClientId": "c3a2bc67-******",​
  "ClientSecret": "PHg6O_******",​
  "Scope": "api://c3a2bc67-*******/.default",  ​
  "Url":"https://<server>:<port>/<nst>/api/christiaens/bocountdynamics/v1.0/companies(<id>)/HttpMessages",​
  "ContentString" : "{\"Type\":\"API\",\"Method\":\"HelloWorld\",\"Params\":\"Bart\"}",​
  "ResultType": "String"​
}

Hiervoor kan in Business Central een Azure Active Directory toepassing worden geconfigureerd.

procedure CFLCallBoCountAPIUrl

Deze procedure implementeert het bovenstaande.
Voert een uitgaande http-call uit op de bocount azure function om een encoded base64string te krijgen waarmee dan een inkomende httpcall kan gedaan worden.

procedure CFLCallBoCountApiUrl(ContentString: Text; ResultType: Enum "CFL Call Api ResultType"): Text

Returnvalue is URL (GET) met alle informatie om BoCount REST API call uit te voeren​

Afhankelijk van scenario kan antwoordvorm verschillen​

  • String​
  • Pdf (pdf tonen in browser) ​
  • Html (zelf website opbouwen adhv bv. mailsjabloon) ​
  • Url (redirect naar andere URL) ​
  • File (downloaden van bestand) ​

Scenario's

Mogelijke scenario's voor deze werkwijze zijn:

  • Factuurgoedkeuring via mail​
  • Incl. gekoppelde pdf van factuur bekijken/downloaden​
  • Eigen rapport genereren door klant, bv. openstaande facturen, prijslijst, ... ​​
  • Levering boeken door QR code te scannen op leveringsbon​
  • Verkoopfactuur doormailen met downloadlink als Proof of Delivery​
  • Productieorder starten/stoppen zonder toegang tot BC​
  • ...​

HTTPinvoiceapproval

TIP

Zie technische informatie voor de procedures en events die het mogelijk maken te integreren met deze componenten.