If you can not, or do not want to generate a custom client (e.g. like for PHP), e.g. because you target low code platforms like Node Red, you can actually get quite far with the following node.js’s / npm packages in your package.json
{
"dependencies": {
"axios": "^1.7.9",
"file-saver": "^2.0.5",
"string-to-file-stream": "^2.0.0"
}
}
After a “npm install” and obtaining an access token for client_credentials as described via
axios.post('https://gw.usegroup.de:9443/oauth2/token',
null,
{
params: {'grant_type':'client_credentials'},
auth: {
username: '<client id/>',
password: '<client secret/>'
}
}
).then(function (response) {
// handle success
const msg={};
msg.payload =response.data.access_token;
console.log("done", msg.payload);
})
.catch(function (error) {
// handle error
console.warn(error);
})
.finally(function () {
// always executed
console.log("finished");
});
A simple request will then work as follows after inserting the obtained access_token below:
const axios = require('axios');
axios.get('https://gw.usegroup.de:8243/mustang/1.5.1/mustang/ping',
{
headers: {
'accept': '*/*',
'Authorization': 'Bearer <access_token/>'
}
}
).then(function (response) {
// handle success
console.log("done: ",response.data);
})
.catch(function (error) {
// handle error
console.warn(error);
})
.finally(function () {
// always executed
console.log("finished");
});
And a more complex operation with a file request and a file response may work like
const stringToFileStream = require('string-to-file-stream');
const axios = require('axios');
const bufStr='<rsm:CrossIndustryInvoice...';// rest of XML goes in here!
const stream=stringToFileStream(bufStr);
const FormData = require('form-data');
const fsPromises = require('fs').promises;
const form = new FormData();
form.append("file", stream);
axios.post('https://gw.usegroup.de:8243/mustang/1.5.1/mustang/xmltopdf',
form,
{
responseType: 'arraybuffer',
headers: {
'accept': '*/*',
'Content-Type': 'multipart/form-data',
'Authorization': 'Bearer <access_token/>'
}
}
).then(function (response) {
// handle success
fsPromises.writeFile('response.pdf', response.data, { encoding: 'binary' });
console.log("done");
})
.catch(function (error) {
// handle error
console.warn(error);
})
.finally(function () {
// always executed
console.log("finished");
});
Node Red
This is a Node Red flow which watches a directory (/tmp/incoming), converts newly placed UBL files into CII, additionally converts them into PDF and adds the CII contents to create a Factur-X file from a XRechnung:

The custom function UBL2CII has the setup

and is defined as
axios.post('https://gw.usegroup.de:8243/eigor/v1.6.0/eeisi/eigor?sourceFormat=ubl&destFormat=cii',
msg.payload,
{
"responseType": 'arraybuffer',
headers: {
'Content-Type': 'text/plain',
'accept': '*/*',
'apikey': 'eyJ4N...=='
}
}
).then(function (response) {
msg.payload=response.data;
node.send(msg);
})
XML2PDF is defined as
flow.set("read",msg.payload);
const form=new FormData();
form.append("file", stringToFileStream(msg.payload))
axios.post('https://gw.usegroup.de:8243/mustang/1.6.1/mustang/xmltopdf?returnJSON=false',
form,
{
"responseType": 'arraybuffer',
headers: {
'Content-Type': 'multipart/form-data',
'accept': '*/*',
'apikey': 'eyJ4N...=='
}
}
).then(function (response) {
msg.payload=response.data;
flow.set("pdf",response.data);
node.send(msg);
})
and PDF2FX is defined as
const form=new FormData();
form.append("file", stringToFileStream(flow.get('pdf')))
form.append("XML", flow.get('read'))
axios.post('https://gw.usegroup.de:8243/mustang/1.6.1/mustang/combineXML?format=fx&version=2&profile=EN16931',
form,
{
"responseType": 'arraybuffer',
headers: {
'Content-Type': 'multipart/form-data',
'accept': '*/*',
'apikey': 'eyJ4N...=='
}
}
).then(function (response) {
msg.payload=response.data;
node.send(msg);
})
Have fun!