const config = input.config({
title: 'DocuGenerate - Single pdf for single record',
description: 'A script that lets you automate document generation from a template using DocuGenerate',
items: [
input.config.table('table', {
label: 'Record table',
//description: 'The table in which you store your records'
}),
input.config.text('APIKey', {
label: 'DocuGenerate API Key ',
description: "(get it from https://app.docugenerate.com/settings)"
}),
input.config.text('templateId', {
label: 'DocuGenerate ID of the template ',
description: "(get it from the URL of your template on DocuGenerate which looks like https://app.docugenerate.com/templates/xxxxxxxxxxxxxxxxxxxx, xxxxxxxxxxxxxxxxxxxx being your template's ID)"
}),
input.config.field('docuField', {
label: 'DocuGenerate config field (must be a text type field)',
description: "the field used to store the cofig of relationships between your template and your fields",
parentTable: 'table',
}),
input.config.field('storageField', {
label: 'Document storage field (either URL or File type field)',
parentTable: 'table',
}),
input.config.select('outputFormat', {
label: 'Output format',
description: 'output format of the generated document. Options are .docx, .pdf, .doc, .odt, .txt or .html ',
options: [
{label: '.docx', value: '.docx'},
{label: '.pdf', value: '.pdf'},
{label: '.doc', value: '.doc'},
{label: '.odt', value: '.odt'},
{label: '.txt', value: '.txt'},
{label: '.html', value: '.html'},
]
})
]
});
async function chooseFieldFill(tagName) {
let match = false;
let foundField = null;
let res = null;
for (let f=0; f
looking for every items");
let multifound = true;
for (let k=1;k {
const reader = new FileReader();
reader.readAsDataURL(blob);
reader.onloadend = () => {
const base64data = reader.result;
resolve(base64data);
};
reader.onerror = reject;
});
};
async function displayTagRule(record,obj,verbose = false) {
let ruleStr = "";
let rules = [];
switch (obj.filltype) {
case 'basename' :
ruleStr = base.name;
if (verbose) { ruleStr += " (name of the base)";}
break;
case 'tablename' :
ruleStr = table.name;
if (verbose) { ruleStr += " (name of the table)";}
break;
case 'today':
ruleStr = new Date(Date.now()).toLocaleDateString(obj.filldata);
if (verbose) { ruleStr += " (today's date)";}
break;
case 'now':
ruleStr = new Date(Date.now()).toLocaleTimeString(obj.filldata);
if (verbose) { ruleStr += " (time now)";}
break;
case 'field':
for (let field of table.fields) {
if (field.id == obj.filldata) {
if (obj.type == "string") {
let data = record.getCellValue(field.name);
if (data.constructor == Array) {
for(let i=0;i-1) {
tagRules[Object.keys(storedOptions)[o]].push(data[i]['name']);
}
else { tagRules[Object.keys(storedOptions)[o]].push(data[i]); }
}
else {
tagRules[Object.keys(storedOptions)[o]].push(data[i]);
}
}
break;
}
}
}
}
else {
tagRules[Object.keys(storedOptions)[o]] = [];
let obj = {};
//let objs = [];
for (let i=1;i {
status = response.status;
return response.json()
})
.catch(err => console.log(err));
////// Inspect templateResponse for debug purpose //////
//output.inspect(templateResponse);
if (status< 200 || status >= 300){
output.text(status + " error : "+templateResponse.message)
}
else {
/////// Tag error in the template //////
if ('tags' in templateResponse && 'invalid' in templateResponse.tags && templateResponse.tags.invalid.length>0) {
output.text("Tag error in your template, the following tags are invalid. Please modify your template.");
output.table(templateResponse.tags.invalid);
}
else if ('tags' in templateResponse && 'valid' in templateResponse.tags){
////// No tags //////
if (templateResponse.tags.valid.length==0) {
output.text("Error : no tag found in your template, please modify your template.");
}
else {
////// Template analysis summary //////
output.text("Name of the template : "+templateResponse.name);
for (let t=0; t-1) {
tags.push({type: typeof(validTag), name: Object.keys(validTag)[0].split('.')[0], items: [Object.keys(validTag)[0].split('.')[1],Object.values(validTag)[0]].filter(onlyUnique)});
}
else {
tags.push({type: typeof(validTag), name: Object.keys(validTag)[0], items: Object.values(validTag)[0]});
}
}
}
}
output.text("List of available tags :")
output.table(tags);
}
}
//////// End of template analysis //////
//////// Tags analysis //////
var record = await input.recordAsync('Pick a record', table);
if (record) {
output.markdown("# Tags analysis");
let storedOptionsField = record.getCellValueAsString(docuField);
if (storedOptionsField != "") {
var storedOptions = JSON.parse(storedOptionsField);
var error = false;
//TODO : keep valid settings and reset options only for invalid or missing tags
if (tags.length != Object.keys(storedOptions).length) {
error = true;
}
else {
for (let k=0;k0) {
const nFirst = updateOptions.splice(0,Math.min(50,updateOptions.length));
await table.updateRecordsAsync(nFirst);
}
}
}
//////// End of tags analysis ////////
//////// Document generation ////////
output.clear();
if (storageField.type =="url" || storageField.type == "multipleAttachments"){
output.markdown("# Document generation");
output.markdown("_Please wait while the document is being generated..._")
let missingFields = checkFieldsData(record);
if (missingFields.length==0) {
//console.log(JSON.stringify([await displayTagRules()]));
const options = {
method: 'POST',
headers: {
accept: 'application/json',
'content-type': 'application/json',
authorization: APIKey
},
body: JSON.stringify({
template_id: templateId,
data: [await displayTagRules(record)],
//name: "Attestation d'entrée en formation",
//output_name: "Attestation_entree_formation",
output_format: outputFormat,
output_quality: 100
})
};
var status = -1;
let docResponse = await fetch('https://api.docugenerate.com/v1/document', options)
.then(response => {
status = response.status;
return response.json()
})
.catch(err => console.log(err));
if (status< 200 || status >= 300){
console.log("Erreur "+docResponse.statusCode+": "+docResponse.message)
}
else {
if (storageField.type == 'url') {
await table.updateRecordsAsync([
{
id: record.id,
fields: { [storageField.name]: docResponse.document_uri }
}
]);
}
else if (storageField.type == 'multipleAttachments'){
await table.updateRecordsAsync([
{
id: record.id,
fields: { [storageField.name] : [{url:docResponse.document_uri}] }
}
]);
}
output.markdown("**✅ Document successfully generated !**");
output.markdown("If you're in Free plan, please check the number of generated documents on [https://app.docugenerate.com/settings](https://app.docugenerate.com/settings)");
output.markdown("_Script completed successfully_");
}
} else {
output.markdown("**⚠ Error, the document has not been generated!**");
output.markdown("List of the missing data :")
output.table(missingFields);
}
}
else {
output.text("Please verify the type of your storage field : it should be URL or File (current : "+storageField.type+")");
}
}
}