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+")"); } } }