Skip to content

Commit

Permalink
fix(KoBoToolbox Node): Fix query and sort + use question name in atta…
Browse files Browse the repository at this point in the history
…chments (#3017)

* Fix query,sort + use question name in attachments

* Change Menu structure

* kobo: Clearer webhook name

* [kobo]: fix when no json filter
  • Loading branch information
Yann-J authored May 14, 2022
1 parent a7d960c commit c885115
Show file tree
Hide file tree
Showing 5 changed files with 165 additions and 33 deletions.
27 changes: 19 additions & 8 deletions packages/nodes-base/nodes/KoBoToolbox/GenericFunctions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,10 +173,14 @@ export async function downloadAttachments(this: IExecuteFunctions | IWebhookFunc
for (const [index, attachment] of attachmentList.entries()) {
// look for the question name linked to this attachment
const filename = attachment.filename;
Object.keys(submission).forEach(question => {
if (filename.endsWith('/' + _.toString(submission[question]).replace(/\s/g, '_'))) {
}
});
let relatedQuestion = null;
if('question' === options.binaryNamingScheme) {
Object.keys(submission).forEach(question => {
if (filename.endsWith('/' + _.toString(submission[question]).replace(/\s/g, '_'))) {
relatedQuestion = question;
}
});
}

// Download attachment
// NOTE: this needs to follow redirects (possibly across domains), while keeping Authorization headers
Expand Down Expand Up @@ -209,11 +213,18 @@ export async function downloadAttachments(this: IExecuteFunctions | IWebhookFunc
}
}

const dataPropertyAttachmentsPrefixName = options.dataPropertyAttachmentsPrefixName || 'attachment_';
const fileName = filename.split('/').pop();

if (response && response.body) {
binaryItem.binary![`${dataPropertyAttachmentsPrefixName}${index}`] = await this.helpers.prepareBinaryData(response.body, fileName);
// Use the provided prefix if any, otherwise try to use the original question name
let binaryName;
if('question' === options.binaryNamingScheme && relatedQuestion) {
binaryName = relatedQuestion;
}
else {
binaryName = `${options.dataPropertyAttachmentsPrefixName || 'attachment_'}${index}`;
}
const fileName = filename.split('/').pop();

binaryItem.binary![binaryName] = await this.helpers.prepareBinaryData(response.body, fileName);
}
}
} else {
Expand Down
5 changes: 3 additions & 2 deletions packages/nodes-base/nodes/KoBoToolbox/KoBoToolbox.node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,13 +194,14 @@ export class KoBoToolbox implements INodeType {
// ----------------------------------

const submissionQueryOptions = this.getNodeParameter('options', i) as IDataObject;
const filterJson = this.getNodeParameter('filterJson', i, null) as string;

responseData = await koBoToolboxApiRequest.call(this, {
url: `/api/v2/assets/${formId}/data/`,
qs: {
limit: this.getNodeParameter('limit', i, 1000) as number,
...(submissionQueryOptions.query && { query: submissionQueryOptions.query }),
//...(submissionQueryOptions.sort && { sort: submissionQueryOptions.sort }),
...(filterJson && { query: filterJson }),
...(submissionQueryOptions.sort && { sort: submissionQueryOptions.sort }),
...(submissionQueryOptions.fields && { fields: JSON.stringify(parseStringList(submissionQueryOptions.fields as string)) }),
},
scroll: this.getNodeParameter('returnAll', i) as boolean,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
} from './GenericFunctions';

import {
options,
options,
} from './Options';

export class KoBoToolboxTrigger implements INodeType {
Expand Down Expand Up @@ -98,13 +98,14 @@ export class KoBoToolboxTrigger implements INodeType {
async create(this: IHookFunctions): Promise<boolean> {
const webhookData = this.getWorkflowStaticData('node');
const webhookUrl = this.getNodeWebhookUrl('default');
const workflow = this.getWorkflow();
const formId = this.getNodeParameter('formId') as string; //tslint:disable-line:variable-name

const response = await koBoToolboxApiRequest.call(this, {
method: 'POST',
url: `/api/v2/assets/${formId}/hooks/`,
body: {
name: `n8n-webhook:${webhookUrl}`,
name: `n8n webhook id ${workflow.id}: ${workflow.name}`,
endpoint: webhookUrl,
email_notification: true,
},
Expand Down
40 changes: 33 additions & 7 deletions packages/nodes-base/nodes/KoBoToolbox/Options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,36 @@ export const options = {
type: 'collection',
default: {},
options: [
{
displayName: 'Download Attachments',
name: 'download',
type: 'boolean',
default: false,
description: 'Download submitted attachments',
},
{
displayName: 'Attachments Naming Scheme',
name: 'binaryNamingScheme',
type: 'options',
default: 'sequence',
displayOptions: {
show: {
download: [
true,
],
},
},
options: [
{
name: 'Sequence (e.g. attachment_N)',
value: 'sequence',
},
{
name: 'Use Original Form Question ID',
value: 'question',
},
],
},
{
displayName: 'Attachments Prefix',
name: 'dataPropertyAttachmentsPrefixName',
Expand All @@ -18,18 +48,14 @@ export const options = {
download: [
true,
],
binaryNamingScheme: [
'sequence',
],
},
},
default: 'attachment_',
description: 'Prefix for name of the binary property to which to write the attachments. An index starting with 0 will be added. So if name is "attachment_" the first attachment is saved to "attachment_0"',
},
{
displayName: 'Download Attachments',
name: 'download',
type: 'boolean',
default: false,
description: 'Download submitted attachments',
},
{
displayName: 'File Size',
name: 'version',
Expand Down
121 changes: 107 additions & 14 deletions packages/nodes-base/nodes/KoBoToolbox/SubmissionDescription.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,73 @@ export const submissionFields: INodeProperties[] = [
default: 100,
description: 'Max number of results to return',
},
{
displayName: 'Filter',
name: 'filterType',
type: 'options',
default: 'none',
displayOptions: {
show: {
resource: [
'submission',
],
operation: [
'getAll',
],
},
},
options: [
{
name: 'None',
value: 'none',
},
{
name: 'JSON',
value: 'json',
},
],
},
{
displayName: 'See <a href="https://github.com/SEL-Columbia/formhub/wiki/Formhub-Access-Points-(API)#api-parameters" target="_blank">Formhub API docs</a> to creating filters, using the MongoDB JSON format - e.g. {"_submission_time":{"$lt":"2021-10-01T01:02:03"}}',
name: 'jsonNotice',
type: 'notice',
displayOptions: {
show: {
resource: [
'submission',
],
operation: [
'getAll',
],
filterType: [
'json',
],
},
},
default: '',
},
{
displayName: 'Filters (JSON)',
name: 'filterJson',
type: 'string',
default: '',
typeOptions: {
// alwaysOpenEditWindow: true,
},
displayOptions: {
show: {
resource: [
'submission',
],
operation: [
'getAll',
],
filterType: [
'json',
],
},
},
},
{
displayName: 'Options',
name: 'options',
Expand All @@ -210,6 +277,36 @@ export const submissionFields: INodeProperties[] = [
default: {},
placeholder: 'Add Option',
options: [
{
displayName: 'Download Attachments',
name: 'download',
type: 'boolean',
default: false,
description: 'Download submitted attachments',
},
{
displayName: 'Attachments Naming Scheme',
name: 'binaryNamingScheme',
type: 'options',
default: 'sequence',
displayOptions: {
show: {
download: [
true,
],
},
},
options: [
{
name: 'Sequence (e.g. attachment_N)',
value: 'sequence',
},
{
name: 'Use Original Form Question ID',
value: 'question',
},
],
},
{
displayName: 'Attachments Prefix',
name: 'dataPropertyAttachmentsPrefixName',
Expand All @@ -219,18 +316,14 @@ export const submissionFields: INodeProperties[] = [
download: [
true,
],
binaryNamingScheme: [
'sequence',
],
},
},
default: 'attachment_',
description: 'Prefix for name of the binary property to which to write the attachments. An index starting with 0 will be added. So if name is "attachment_" the first attachment is saved to "attachment_0"',
},
{
displayName: 'Download Attachments',
name: 'download',
type: 'boolean',
default: false,
description: 'Download submitted attachments',
},
{
displayName: 'Fields to Retrieve',
name: 'fields',
Expand Down Expand Up @@ -291,13 +384,13 @@ export const submissionFields: INodeProperties[] = [
default: false,
description: 'Apply some reformatting to the submission data, such as parsing GeoJSON coordinates',
},
// {
// displayName: 'Sort',
// name: 'sort',
// type: 'json',
// default: '',
// description: 'Sort predicates, in Mongo JSON format (e.g. {"_submission_time":1})',
// },
{
displayName: 'Sort',
name: 'sort',
type: 'json',
default: '',
description: 'Sort predicates, in MongoDB JSON format (e.g. {"_submission_time":1})',
},
],
},
];

0 comments on commit c885115

Please sign in to comment.