Usage of TotalumApiSdk
Totalum allows you to use the SDK to perform actions such as creating users, creating items, creating pdfs, read, filter, delete, etc.
Basically the Totalum sdk is a wrapper for javascript of the Totalum api, so if you want you can use the api directly if you prefer.
What happens if you are not programming in javascript?
If you are not programming in javascript, you can use the api directly, see TOTALUM API DOCUMENTATION
Authentication
Note: If you use totalumSdk inside a totalum plugin, you don't need to authenticate, you can start using totalum like this: modules.totalumSdk.your.function();-> example: modules.totalumSdk.crud.getItems('your_item', {})
You can choose to use one of the two authentication methods offered by Totalum Sdk:
Token: You can use an access token to authenticate. This token can be obtained from the localStorage of your browser from the web https://web.totalum.app
ApiKey: (RECOMMENDED OPTION) You can use an ApiKey to authenticate. This ApiKey can be obtained in the Api Keys section of the Configuration section of Totalum.
ES Module Import:
import {AuthOptions, TotalumApiSdk} from 'totalum-api-sdk';
// CHOICE FROM USE accessToken OR apiKey (API KEY IS RECOMMENDED)
// the auth using token
const options: AuthOptions = {
token:{
accessToken: 'YOUR TOKEN' // get it from totalum project web localStorage
}
}
// the auth using api key
const options: AuthOptions = {
apiKey:{
'api-key': 'your_api_key', //the api key secret that is shown only once, example: sk-234fgrw4t3w...
}
}
const totalumClient = new TotalumApiSdk(options);
// execute some TotalumApiSdk function
const result = await totalumClient.crud.getItems('your_element_table_name', {});
CommonJS Require:
const totalum = require('totalum-api-sdk');
// CHOICE FROM USE accessToken OR apiKey (API KEY IS RECOMMENDED)
// the auth using token
const options = {
token:{
accessToken: 'YOUR TOKEN' // get it from totalum project web localStorage
}
}
// the auth using api key
const options = {
apiKey:{
'api-key': 'your_api_key', //the api key secret that is shown only once, example: sk-234fgrw4t3w...
}
}
const totalumClient = new totalum.TotalumApiSdk(options);
// execute some TotalumApiSdk function
const result = await totalumClient.crud.getItems('your_element_table_name', {});
HTML script import: (Use this way if you are using standalone html, and you cannot import npm packages)
<head>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/totalum-sdk.min.js"></script>
</head>
<script>
//Example of use TotalumSdk in your custom html page
const token=localStorage.getItem('token');
var totalumClient = new totalumSdk.TotalumApiSdk({
token:{
accessToken: token
}
});
const tableElementName = 'your-table-name'; // replace with your table name
//example of endpoint execution
const result = totalumClient.crud.getItems(tableElementName, {}).then((result) => {
const items = result.data.data;
console.log("THE ITEMS", items);
});
</script>
Functions for create, read, filter, update, delete. (CRUD)
Get item by id
// get item by id from your_element_table_name
const tableElementName = 'your_element_table_name'; // replace 'your_element_table_name' with the name of your element table
let your_item_id = 'your_item_id'; // replace 'your_item_id' with the id of the item object
const result = await totalumClient.crud.getItemById(tableElementName, your_item_id);
const item = result.data.data;
Get items
// get items from your_element_table_name (for default 50 items per page)
const tableElementName = 'your_element_table_name'; // replace 'your_element_table_name' with the name of your element table
const result = await totalumClient.crud.getItems(tableElementName, {});
const items = result.data.data;
delete item by id
// delete item by id from your_element_table_name
const tableElementName = 'your_element_table_name'; // replace 'your_element_table_name' with the name of your element table
let your_item_id = 'your_item_id'; // replace 'your_item_id' with the id of the item object
const result = await totalumClient.crud.deleteItemById(tableElementName, your_item_id);
Get nested items
// imagine that you have 3 tables, client, order and product, and you want to get some clients with all orders and the products of the orders
const nestedQuery: NestedQuery = {
client: {
order: {
product: {}
},
}
}
const result = await totalumClient.crud.getNestedData(nestedQuery);
Get nested items and filter
// As before you have client, order, and product tables, but you now want to only get the client with name 'Jhon' and limit to 10 results
const nestedQuery: NestedQuery = {
client: {
tableFilter: {
filter: [{
name: 'Jhon'
}],
sort: {
name: 1
},
pagination: {
limit: 10,
page: 0,
}
},
order: {
product: {}
},
}
}
const result = await totalumClient.crud.getNestedData(nestedQuery);
edit item by id
// edit item by id from your_element_table_name, you can edit 1 or multiple properties at the same time (like a patch)
const tableElementName = 'your_element_table_name'; // replace 'your_element_table_name' with the name of your element table
let your_item_id = 'your_item_id'; // replace 'your_item_id' with the id of the item object
const result = await totalumClient.crud.editItemById(tableElementName, your_item_id, {your_item_property: 'new value'});
create item
// create item from your_element_table_name, you need to pass at least the required properties
const tableElementName = 'your_element_table_name'; // replace 'your_element_table_name' with the name of your element table
const result = await totalumClient.crud.createItem(tableElementName, {your_item_property: 'new value'});
add many to many reference item (add a reference to another item that have a many to many relationship)
const tableElementName = 'your_element_table_name'; // replace 'your_element_table_name' with the name of your element table
let your_item_id = 'your_item_id'; // replace 'your_item_id' with the id of the item
const propertyName = 'your_property_name'; // replace 'your_property_name' with the name of the property that have a many to many relationship
const referenceId = 'your_reference_item_id'; // replace 'your_reference_item_id' with the id of the item that you want to add as a many to many reference
const result = await totalumClient.crud.addManyToManyReferenceItem(tableElementName, your_item_id, propertyName, referenceId);
drop many to many reference item (drop a reference to another item that have a many to many relationship)
const tableElementName = 'your_element_table_name'; // replace 'your_element_table_name' with the name of your element table
let your_item_id = 'your_item_id'; // replace 'your_item_id' with the id of the item
const propertyName = 'your_property_name'; // replace 'your_property_name' with the name of the property that have a many to many relationship
const referenceId = 'your_reference_item_id'; // replace 'your_reference_item_id' with the id of the item that you want to drop as a many to many reference
const result = await totalumClient.crud.dropManyToManyReferenceItem(tableElementName, your_item_id, propertyName, referenceId);
get many to many references items (get all items that have a many to many relationship with the item)
const tableElementName = 'your_element_table_name'; // replace 'your_element_table_name' with the name of your element table
let your_item_id = 'your_item_id'; // replace 'your_item_id' with the id of the item
const propertyName = 'your_property_name'; // replace 'your_property_name' with the name of the property that have a many to many relationship
// the query is optional, you can use it to filter and sort the results
const query = {
filter: [
{
'your_property_name': 'value' // add your custom filters here
},
],
sort:{
'your_property_name': 1 // 1 for asc, -1 for desc
},
pagination: {
limit: 50,
page: 0,
}
};
const result = await totalumClient.crud.getManyToManyReferencesItems(tableElementName, your_item_id, propertyName, query);
Functions for filter data
Filter data using totalum AND filter
const tableElementName = 'your_element_table_name'; // replace 'your_element_table_name' with the name of your element table
// get items from your_element_table_name (for default 50 items per page) applying a filter AND query (all conditions must be true)
const filter: FilterSearchQueryI = {
filter: [
{
'your_property_name': 'value' // it matches the value exactly
},
{
'your_other_property_name': {regex: 'your regex query', options: 'i'} // it matches a value using a regex query and options: i for case insensitive (ignore if it is uppercase or lowercase)
},
// PD: gte and lte operators are only allowed for properties of type date or number
{
'your_other_property_name': {gte: new Date('your date')} // it matches a value greater than or equal to the date
},
{
'your_other_property_name': {lte: new Date('your date')} // it matches a value less than or equal to the date
},
{
'your_other_property_name': {gte: 10} // it matches a value greater than or equal to 10
},
{
'your_other_property_name': {lte: 100} // it matches a value less than or equal to 100
}
],
sort:{
'your_property_name': 1 // 1 for asc, -1 for desc
},
pagination: {
limit: 50,
page: 0,
}
};
const result = await totalumClient.crud.getItems(tableElementName, filter);
const items = result.data.data;
Filter data using totalum OR filter
// get items from your_element_table_name (for default 50 items per page) applying a filter OR query (at least one condition must be true)
const filter: FilterSearchQueryI = {
filter: [
{
or: [
{
'your_property_name': 'value' // it matches the value exactly
},
{
'your_other_property_name': {regex: 'your regex query', options: 'i'} // it matches a value using a regex query and options: i for case insensitive (ignore if it is uppercase or lowercase)
},
{
'your_other_property_name': {gte: new Date('your date')} // it matches a value greater than or equal to the date
},
]
}
],
sort: {
'your_property_name': 1 // 1 for asc, -1 for desc
},
pagination: {
limit: 50,
page: 0,
}
};
const result = await totalumClient.crud.getItems(tableElementName, filter);
const items = result.data.data;
Filter data using totalum AND and OR filter
// get items from your_element_table_name (for default 50 items per page) applying a filter OR and AND
const filter: FilterSearchQueryI = {
filter: [
{
or: [
{
'your_property_name_in_or': 'value' // it matches the value exactly
},
{
'your_other_property_name_in_or': {regex: 'your regex query', options: 'i'} // it matches a value using a regex query and options: i for case insensitive (ignore if it is uppercase or lowercase)
},
],
},
{
'your_other_property_name': 'value' // it matches the value exactly
}
],
sort: {
'your_property_name': 1 // 1 for asc, -1 for desc
},
pagination: {
limit: 50,
page: 0,
}
};
const result = await totalumClient.crud.getItems(tableElementName, filter);
const items = result.data.data;
Filter using your custom mongoDb aggregation query
// filter results from your_element_table_name applying a filter query (a custom mongodb aggregation query)
const customMongoDbAggregationQueryInString = `
your custom mongo aggregation query in string, for more info:
https://docs.mongodb.com/manual/aggregation/
or ask to chatgpt, he is very good writing mongo aggregation queries ;)
`;
const result = await totalumClient.filter.runCustomMongoAggregationQuery(tableElementName, customMongoDbAggregationQueryInString);
Functions for create download and manipulate files
Upload a file to Totalum (you can upload any file type)
1. Upload the file to Totalum
To scan a document, first you need to upload the file to Totalum. You can do this using the Totalum API directly or using the Totalum SDK.
1.1 Transform the file to a blob
If you are not using javascript, you will need to do this step using the language you are using. Search on internet how to transform a file to a blob in your language. Or also you can ask chatgpt to transform the following examples to your language.
Depending on the platform you are using, you will need to transform the file to a blob. Here are some examples:
From a file input (Frontend)
const fileInput = document.getElementById('fileInput');
const fileBlob = fileInput.files[0];
From a file in storage (Backend)
const fs = require('fs');
const yourFilePath = 'your_file_path'; // example: /user/your_file.pdf
const fileBlob = fs.readFileSync(yourFilePath);
From a remote file (Backend)
const response = await axios.get('your_file_url', { responseType: 'stream' });
const fileBlob = response.data;
From a base64 string (Frontend/Backend)
// Convert base64 to binary
const binaryStr = atob(base64String);
const len = binaryStr.length;
const bytes = new Uint8Array(len);
for (let i = 0; i < len; i++) {
bytes[i] = binaryStr.charCodeAt(i);
}
let fileBlob;
// Environment check: Node.js or Browser
if (typeof process === 'object' && process.version) {
// Node.js environment
// Convert Uint8Array to Buffer for Node.js usage
const buffer = Buffer.from(bytes.buffer);
// Here, 'buffer' can be used similarly to how you'd use a Blob in the browser
// Note: Direct Blob emulation isn't possible in Node.js, but Buffer is a close alternative for file handling
fileBlob = buffer;
} else {
// Browser environment
// Create a Blob from the Uint8Array
const blob = new Blob([bytes], { type: fileType });
fileBlob = blob;
}
1.2 Upload the file to Totalum
Using Totalum SDK
const FormData = require('form-data'); // if you are using node.js
const fileName = 'your_file_name.png'; // replace 'your_file_name' with the name of your file, replace .png with the extension of your file
const file = yourFileBlob // your blob file created in the previous step
const formData = new FormData();
formData.append('file', file, fileName);
const result = await totalumClient.files.uploadFile(formData);
const fileNameId = result.data.data;
Using Totalum API
const FormData = require('form-data'); // if you are using node.js
const fileName = 'your_file_name.png'; // replace 'your_file_name' with the name of your file, replace .png with the extension of your file
const file = yourFileBlob // your blob file created in the previous step
const formData = new FormData();
formData.append('file', file, fileName);
const result = await axios.post('https://api.totalum.app/files/upload', formData, {
headers: {
'Content-Type': 'multipart/form-data',
'api-key': 'your api key here', // replace 'your api key here' with your api key
}
});
const fileNameId = result.data.data;
//if you want to link this file to an item, you need to add the fileNameId to the item property of type file
const result2 = await totalumClient.crud.editItemById('your_element_table_name', 'your_item_id', {'your_file_property_name': {name: fileNameId}});
// now the file is linked to the item property, and you can see it in the totalum panel.
Get the download url of a file
// you can get the fileNameId from the result of the upload file function
const fileNameId = 'your_file_name.png'; // replace 'your_file_name' with the name id of your file, replace .png with the extension of your file
//optional options
const options = {
// the default expiration time is 128 hours, but you can set it to whatever you want, after the expiration time the url will not return the file
expirationTime: Date.now() + (128 * 60 * 60 * 1000); // Set to expire in 128 hours, how it works is, set the current date in milliseconds + the milliseconds you want the url to expire
}
const result = await totalumClient.files.getDownloadUrl(fileNameId, options);
let [fileUrl] = result.data.data;
// the result will be a full url that you can use to download the file
Generate a pdf from a template
const templateId = 'your_template_id'; // replace 'your_template_id' with the id of your template id, go to totalum -> configuration -> pdf templates
// the variables will be replaced in your template with handlebars
const variablesExample = { // replace the variables with your variables, can contain nested objects of n deep, can contain strings, numbers, dates, etc.
'your_variable_name': 'your_variable_value',
'your_other_variable_name': {
'your_other_variable_name': 'your_other_variable_value'
'your_other_variable_name': 10,
'your_other_variable_name': new Date('your date'),
},
}
const fileName = 'your_pdf_name.pdf'; // replace 'your_pdf_name' with the name of your pdf
//CAUTION: if you use the same name for multiple pdfs, the pdfs will be overwritten
const result = await totalumClient.files.generatePdfByTemplate(templateId, variablesExample, name);
const fileResult = result.data.data;
// with the fileUrl you can download the pdf
//if you want to link this pdf to an item, you need to add the fileName to the item property of type file
const result2 = await totalumClient.crud.editItemById('your_element_table_name', 'your_item_id', {'your_pdf_property_name': {name: fileResult.fileName}});
get OCR of an image (get the text of an image)
// you can only do ocr of a file that is previously uploaded to totalum (see the upload file function)
// then you can do ocr of the file using the file name of the file uploaded
const fileNameId = 'your_file_name_id.png'; // replace 'your_file_name' with the name of your file, replace .png with the extension of your image
const result = await totalumClient.files.ocrOfImage(fileNameId);
const ocrResult = result.data.data;
// ocrResult.text will contain all text of the image
// ocrResult.fullDetails will contain all details of the image, like the language, the position of the text, etc.
get OCR of a pdf (get the text of a pdf)
// you can only do ocr of a file that is previously uploaded to totalum (see the upload file function)
// then you can do ocr of the file using the file name of the file uploaded
const fileName = 'your_file_name_id.pdf'; // replace 'your_file_name' with the name of your file
const result = await totalumClient.files.ocrOfPdf(fileName);
const ocrResult = result.data.data;
// ocrResult.text will contain all text of the pdf
// ocrResult.fullDetails will contain all details of the pdf, like the language, in which page is the text, the position of the text, etc.
scan an invoice (get the details of an invoice)
// you can only do scan of a file that is previously uploaded to totalum (see the upload file function)
// then you can do scan of the file using the file name of the file uploaded
const fileName = 'your_file_name.png'; // replace 'your_file_name' with the name of your file, replace .png with the extension of your file
const file = yourFileBlob // replace yourFile with your file object binary blob (in blob format)
const formData = new FormData();
formData.append('file', file, fileName);
const result = await totalumClient.files.uploadFile(formData);
const fileNameId = result.data.data;
const result = await totalumClient.files.scanInvoice(fileNameId);
const invoiceResult = result.data.data;
scan a document (get the details of a document)
// first upload the file to totalum
const fileName = 'your_file_name.png'; // replace 'your_file_name' with the name of your file, replace .png with the extension of your file
const file = yourFileBlob // replace yourFile with your file object binary blob (in blob format)
const formData = new FormData();
formData.append('file', file, fileName);
const result = await totalumClient.files.uploadFile(formData);
const fileNameId = result.data.data;
// define the json properties that you want to extract from the document
// this is just an example, you can define your own properties following the JSON schema format, the api will return a json with the properties that you define here
const properties = {
"fecha": {
"type": "string",
"format": "date",
"description": "introduce here your description for help api to extract this value"
},
"import": {
"type": "number",
"description": "the import"
},
"currency": {
"type": "string",
"enum": ["EUR", "USD", "GBP", "OTHER"],
"description": "if currency is not EUR, USD or GBP set OTHER"
}
}
const result = await totalumClient.files.scanDocument(fileNameId, properties);
const documentResult = result.data.data;
Functions for call OpenAI API without need to have an OpenAI account
Create a completion (deprecated, use createChatCompletion instead)
//body the openai completion body, more info here: https://platform.openai.com/docs/api-reference/completions/create
const body={
// see the openai api docs for more info
}
const result = await totalumClient.openai.createCompletion(body);
const gptCompletion = result.data.data;
// returns the completion provided by openai api
Create a chat completion
//body the openai chat completion body, more info here: https://platform.openai.com/docs/api-reference/chat/create
const bodyExample={
// see the openai api docs for more info
messages: [
{content: 'You are a math specialist assistant', role: 'system'},
{content: 'how I can resolve a matrix', role: 'user'}
//etc...
],
model: 'gpt-3.5-turbo',
max_tokens: 30,
}
const result = await totalumClient.openai.createChatCompletion(bodyExample);
const chatCompletion = result.data.data;
// returns the completion provided by openai api
Generate an image
//body the openai chat completion body, more info here: https://platform.openai.com/docs/api-reference/chat/create
const bodyExample={
prompt:'your prompt',
size: '256x256' | '512x512' | '1024x1024',
fileName: 'file-name-of-file-saved.png' // CAUTION: if you use the same name for multiple images, the images will be overwritten
}
const result = await totalumClient.openai.generateImage(bodyExample);
const imageCompletion = result.data.data;
// returns the file name with the file generated by openai, if is not an url, you can download it using files.getDownloadUrl(imageCompletion);