diff --git a/src/appmixer/activecampaign/tasks/CreateTask/component.json b/src/appmixer/activecampaign/tasks/CreateTask/component.json index 757bc71ec..e22a8f99d 100644 --- a/src/appmixer/activecampaign/tasks/CreateTask/component.json +++ b/src/appmixer/activecampaign/tasks/CreateTask/component.json @@ -40,6 +40,18 @@ "due", "duration", "durationUnits" + ], + "oneOf": [ + { + "required": [ + "contactId" + ] + }, + { + "required": [ + "dealId" + ] + } ] }, "inspector": { diff --git a/src/appmixer/aws/redshift/NewRow/NewRow.js b/src/appmixer/aws/redshift/NewRow/NewRow.js index 4662c0237..597d23fb0 100644 --- a/src/appmixer/aws/redshift/NewRow/NewRow.js +++ b/src/appmixer/aws/redshift/NewRow/NewRow.js @@ -14,15 +14,17 @@ module.exports = { const { query, compareField: field } = context.properties; let lastSeenValue = await context.stateGet('lastSeenValue'); + const sanitizedQuery = query.replace(/;$/, ''); + try { if (lastSeenValue === null) { // On the first run, query only the latest row to set the lastSeenValue - const latestRowQuery = `${query} ORDER BY ${field} DESC LIMIT 1`; + const latestRowQuery = `${sanitizedQuery} ORDER BY ${field} DESC LIMIT 1`; const latestRowResult = await runQuery({ context: context.auth, query: latestRowQuery }); lastSeenValue = latestRowResult.rows.length ? latestRowResult.rows[0][field] : 0; await context.stateSet('lastSeenValue', lastSeenValue); } else { - const newRows = await this.checkForNewRows(context, query, field, lastSeenValue); + const newRows = await this.checkForNewRows(context, sanitizedQuery, field, lastSeenValue); if (newRows.length) { const lastValue = newRows[newRows.length - 1][field]; for (const row of newRows) { diff --git a/src/appmixer/aws/redshift/NewRow/component.json b/src/appmixer/aws/redshift/NewRow/component.json index 79f6c4cbb..ee37b72bc 100644 --- a/src/appmixer/aws/redshift/NewRow/component.json +++ b/src/appmixer/aws/redshift/NewRow/component.json @@ -29,7 +29,7 @@ "type": "textarea", "index": 1, "label": "SQL Query", - "tooltip": "Enter the SQL query to fetch data from your database. This query should select from the table you want to monitor for new rows. Avoid including a WHERE clause for filtering by the compare field, as this will be handled automatically to detect new entries For example, if you want to monitor a table named 'orders', your query might be SELECT * FROM orders. The component will add necessary conditions to check for new rows." + "tooltip": "Enter the SQL query to fetch data from your database. This query should select from the table you want to monitor for new rows. Avoid including a WHERE clause for filtering by the compare field, as this will be handled automatically to detect new entries For example, if you want to monitor a table named 'orders', your query might be SELECT * FROM orders. The component will add necessary conditions to check for new rows. Semicolon will be ignored." }, "compareField": { "type": "text", @@ -52,4 +52,4 @@ } ], "icon": "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iMjY4cHgiIGhlaWdodD0iMzE0cHgiIHZpZXdCb3g9IjAgMCAyNjggMzE0IiB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPgogICAgPHRpdGxlPmFtYXpvbi1yZWRzaGlmdDwvdGl0bGU+CiAgICA8ZyBpZD0iUGFnZS0xIiBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj4KICAgICAgICA8ZyBpZD0iYW1hem9uLXJlZHNoaWZ0IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLjg0MDAwMCwgMC43MDIxMjgpIiBmaWxsLXJ1bGU9Im5vbnplcm8iPgogICAgICAgICAgICA8cG9seWdvbiBpZD0iU2hhcGUiIGZpbGw9IiM1Mjk0Q0YiIHBvaW50cz0iMjQ0LjkyNzk4OSA0My42MTcwMjEzIDI2NyA1NS4wODY0OTgzIDI2NyAyNTYuNTczOTIyIDI0NC45Mjc5ODkgMjY4LjA4NTEwNiAyMTAgMTU2LjE0MzAxNCI+PC9wb2x5Z29uPgogICAgICAgICAgICA8cG9seWdvbiBpZD0iU2hhcGUiIGZpbGw9IiMyMDVCOTkiIHBvaW50cz0iMjIuMjY4OTQxIDQzLjYxNzAyMTMgMCA1NS4wODY0OTgzIDAgMjU2LjU3MzkyMiAyMi4yNjg5NDEgMjY4LjA4NTEwNiA3OCAxNTYuMTQzMDE0Ij48L3BvbHlnb24+CiAgICAgICAgICAgIDxwb2x5Z29uIGlkPSJTaGFwZSIgZmlsbD0iIzIwNUI5OSIgcG9pbnRzPSIxMzQgMjM5LjE3MTI4IDI0NSAyNjguMDg1MTA2IDI0NSA0My42MTcwMjEzIDEzNCA3Mi41MzA4NDczIj48L3BvbHlnb24+CiAgICAgICAgICAgIDxwb2x5Z29uIGlkPSJTaGFwZSIgZmlsbD0iIzUyOTRDRiIgcG9pbnRzPSIxMzQgMjM5LjE3MTI4IDIyIDI2OC4wODUxMDYgMjIgNDMuNjE3MDIxMyAxMzQgNzIuNTMwODQ3MyI+PC9wb2x5Z29uPgogICAgICAgICAgICA8cG9seWdvbiBpZD0iU2hhcGUiIGZpbGw9IiM1Mjk0Q0YiIHBvaW50cz0iMTYwLjM0MzMxOCAzMTIuNzY1OTU3IDIwMyAyOTAuMTY5OTA3IDIwMyAyMi41OTYwNTA0IDE2MC4zNDMzMTggMCAxMTggMTQ4LjcyNjEyMiI+PC9wb2x5Z29uPgogICAgICAgICAgICA8cG9seWdvbiBpZD0iU2hhcGUiIGZpbGw9IiMyMDVCOTkiIHBvaW50cz0iMTA2Ljg2MzgxMyAzMTIuNzY1OTU3IDY0IDI5MC4xNjk5MDcgNjQgMjIuNTk2MDUwNCAxMDYuODYzODEzIDAgMTQ1IDE1Ni4zODI5NzgiPjwvcG9seWdvbj4KICAgICAgICAgICAgPHJlY3QgaWQ9IlJlY3RhbmdsZS1wYXRoIiBmaWxsPSIjMkU3M0I4IiB4PSIxMDciIHk9IjAiIHdpZHRoPSI1MyIgaGVpZ2h0PSIzMTIuNzY1OTU3Ij48L3JlY3Q+CiAgICAgICAgPC9nPgogICAgPC9nPgo8L3N2Zz4=" -} \ No newline at end of file +} diff --git a/src/appmixer/aws/redshift/UpdatedRow/UpdatedRow.js b/src/appmixer/aws/redshift/UpdatedRow/UpdatedRow.js index f02457306..f917ab91f 100644 --- a/src/appmixer/aws/redshift/UpdatedRow/UpdatedRow.js +++ b/src/appmixer/aws/redshift/UpdatedRow/UpdatedRow.js @@ -9,10 +9,12 @@ module.exports = { let { lastUpdated } = await context.stateGet('lastUpdated') || {}; let processedKeys = await context.stateGet('processedKeys') || {}; + const sanitizedQuery = query.replace(/;$/, ''); + try { if (!lastUpdated) { // On first tick, fetch only the most recent update to set lastUpdated - const latestRowQuery = `${query} ORDER BY ${updatedDateColumn} DESC LIMIT 1`; + const latestRowQuery = `${sanitizedQuery} ORDER BY ${updatedDateColumn} DESC LIMIT 1`; const latestRowResult = await runQuery({ context: context.auth, query: latestRowQuery }); lastUpdated = latestRowResult.rows.length ? latestRowResult.rows[0][updatedDateColumn] @@ -20,7 +22,12 @@ module.exports = { await context.stateSet('lastUpdated', { lastUpdated }); } else { - const updatedRows = await this.checkForUpdatedRows(context, query, updatedDateColumn, lastUpdated); + const updatedRows = await this.checkForUpdatedRows( + context, + sanitizedQuery, + updatedDateColumn, + lastUpdated + ); for (const row of updatedRows) { if (!primaryKey || !processedKeys[row[primaryKey]]) { diff --git a/src/appmixer/aws/redshift/UpdatedRow/component.json b/src/appmixer/aws/redshift/UpdatedRow/component.json index 278285405..dd85c5e90 100644 --- a/src/appmixer/aws/redshift/UpdatedRow/component.json +++ b/src/appmixer/aws/redshift/UpdatedRow/component.json @@ -32,7 +32,7 @@ "type": "textarea", "index": 1, "label": "SQL Query", - "tooltip": "Enter the SQL query to fetch data from your database. This query should select from the table you want to monitor for new rows. Avoid including a WHERE clause for filtering by the compare field, as this will be handled automatically to detect new entries For example, if you want to monitor a table named 'orders', your query might be SELECT * FROM orders. The component will add necessary conditions to check for new rows." + "tooltip": "Enter the SQL query to fetch data from your database. This query should select from the table you want to monitor for new rows. Avoid including a WHERE clause for filtering by the compare field, as this will be handled automatically to detect new entries For example, if you want to monitor a table named 'orders', your query might be SELECT * FROM orders. The component will add necessary conditions to check for new rows. Semicolon will be ignored." }, "updatedDateColumn": { "type": "text", @@ -61,4 +61,4 @@ } ], "icon": "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iMjY4cHgiIGhlaWdodD0iMzE0cHgiIHZpZXdCb3g9IjAgMCAyNjggMzE0IiB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPgogICAgPHRpdGxlPmFtYXpvbi1yZWRzaGlmdDwvdGl0bGU+CiAgICA8ZyBpZD0iUGFnZS0xIiBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj4KICAgICAgICA8ZyBpZD0iYW1hem9uLXJlZHNoaWZ0IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLjg0MDAwMCwgMC43MDIxMjgpIiBmaWxsLXJ1bGU9Im5vbnplcm8iPgogICAgICAgICAgICA8cG9seWdvbiBpZD0iU2hhcGUiIGZpbGw9IiM1Mjk0Q0YiIHBvaW50cz0iMjQ0LjkyNzk4OSA0My42MTcwMjEzIDI2NyA1NS4wODY0OTgzIDI2NyAyNTYuNTczOTIyIDI0NC45Mjc5ODkgMjY4LjA4NTEwNiAyMTAgMTU2LjE0MzAxNCI+PC9wb2x5Z29uPgogICAgICAgICAgICA8cG9seWdvbiBpZD0iU2hhcGUiIGZpbGw9IiMyMDVCOTkiIHBvaW50cz0iMjIuMjY4OTQxIDQzLjYxNzAyMTMgMCA1NS4wODY0OTgzIDAgMjU2LjU3MzkyMiAyMi4yNjg5NDEgMjY4LjA4NTEwNiA3OCAxNTYuMTQzMDE0Ij48L3BvbHlnb24+CiAgICAgICAgICAgIDxwb2x5Z29uIGlkPSJTaGFwZSIgZmlsbD0iIzIwNUI5OSIgcG9pbnRzPSIxMzQgMjM5LjE3MTI4IDI0NSAyNjguMDg1MTA2IDI0NSA0My42MTcwMjEzIDEzNCA3Mi41MzA4NDczIj48L3BvbHlnb24+CiAgICAgICAgICAgIDxwb2x5Z29uIGlkPSJTaGFwZSIgZmlsbD0iIzUyOTRDRiIgcG9pbnRzPSIxMzQgMjM5LjE3MTI4IDIyIDI2OC4wODUxMDYgMjIgNDMuNjE3MDIxMyAxMzQgNzIuNTMwODQ3MyI+PC9wb2x5Z29uPgogICAgICAgICAgICA8cG9seWdvbiBpZD0iU2hhcGUiIGZpbGw9IiM1Mjk0Q0YiIHBvaW50cz0iMTYwLjM0MzMxOCAzMTIuNzY1OTU3IDIwMyAyOTAuMTY5OTA3IDIwMyAyMi41OTYwNTA0IDE2MC4zNDMzMTggMCAxMTggMTQ4LjcyNjEyMiI+PC9wb2x5Z29uPgogICAgICAgICAgICA8cG9seWdvbiBpZD0iU2hhcGUiIGZpbGw9IiMyMDVCOTkiIHBvaW50cz0iMTA2Ljg2MzgxMyAzMTIuNzY1OTU3IDY0IDI5MC4xNjk5MDcgNjQgMjIuNTk2MDUwNCAxMDYuODYzODEzIDAgMTQ1IDE1Ni4zODI5NzgiPjwvcG9seWdvbj4KICAgICAgICAgICAgPHJlY3QgaWQ9IlJlY3RhbmdsZS1wYXRoIiBmaWxsPSIjMkU3M0I4IiB4PSIxMDciIHk9IjAiIHdpZHRoPSI1MyIgaGVpZ2h0PSIzMTIuNzY1OTU3Ij48L3JlY3Q+CiAgICAgICAgPC9nPgogICAgPC9nPgo8L3N2Zz4=" -} \ No newline at end of file +} diff --git a/src/appmixer/aws/redshift/bundle.json b/src/appmixer/aws/redshift/bundle.json index 35f16f25f..342ffed90 100644 --- a/src/appmixer/aws/redshift/bundle.json +++ b/src/appmixer/aws/redshift/bundle.json @@ -1,7 +1,12 @@ { "name": "appmixer.aws.redshift", - "version": "1.0.0", - "changelog": [ - "Initial version" - ] + "version": "1.0.1", + "changelog": { + "1.0.0": [ + "Initial version" + ], + "1.0.1": [ + "NewRow, UpdatedRow: query fields now ignores semicolon at the end of the query to avoid syntax error." + ] + } } diff --git a/src/appmixer/azuredocumentintelligence/bundle.json b/src/appmixer/azuredocumentintelligence/bundle.json index 520baa5ee..74f4d78f4 100644 --- a/src/appmixer/azuredocumentintelligence/bundle.json +++ b/src/appmixer/azuredocumentintelligence/bundle.json @@ -1,9 +1,13 @@ { "name": "appmixer.azuredocumentintelligence", - "version": "1.0.2", + "version": "2.0.0", "changelog": { "1.0.2": [ - "Initial version." - ] + "Initial version." + ], + "2.0.0": [ + "(breaking change) ClassifyDocument split into ClassifyDocument and ClassifyDocumentFromStream. ClassifyDocumentFromStream is using only the File ID parameter, ClassifyDocument is using either File URL or Base64Source.", + "ClassifyDocument and ClassifyDocumentFromStream: added supported file extensions to the tooltip of either File ID or File URL." + ] } } diff --git a/src/appmixer/azuredocumentintelligence/classifiers/ClassifyDocument/ClassifyDocument.js b/src/appmixer/azuredocumentintelligence/classifiers/ClassifyDocument/ClassifyDocument.js index f477ccfa8..25a78a5b9 100644 --- a/src/appmixer/azuredocumentintelligence/classifiers/ClassifyDocument/ClassifyDocument.js +++ b/src/appmixer/azuredocumentintelligence/classifiers/ClassifyDocument/ClassifyDocument.js @@ -8,30 +8,19 @@ module.exports = { async receive(context) { const { endpoint, apiKey } = context.config; - const { classifierId, fileId, fileUrl, base64Source } = context.messages.in.content; + const { classifierId, fileUrl, base64Source } = context.messages.in.content; const client = DocumentIntelligence(endpoint, { key: apiKey }); let options; - if (fileId) { - // Using "Classify Document From Stream" operation from "Document Classifiers" API - const fileInfo = await context.getFileInfo(fileId); - const fileStream = await context.getFileReadStream(fileId); - options = { - contentType: fileInfo.contentType || 'application/octet-stream', - body: fileStream - }; + if (fileUrl) { + options = { body: { urlSource: fileUrl } }; } else { - // Using "Classify Document" operation from "Document Classifiers" API - if (fileUrl) { - options = { body: { urlSource: fileUrl } }; - } else { - options = { body: { base64Source } }; - } + options = { body: { base64Source } }; } - await context.log({ step: 'Classifying document', endpoint, classifierId, fileId, fileUrl, base64Source }); + await context.log({ step: 'Classifying document', endpoint, classifierId, fileUrl, base64Source }); const initialResponse = await client .path('/documentClassifiers/{classifierId}:analyze', classifierId) .post(options); diff --git a/src/appmixer/azuredocumentintelligence/classifiers/ClassifyDocument/component.json b/src/appmixer/azuredocumentintelligence/classifiers/ClassifyDocument/component.json index 8086399a1..bb1cd4b44 100644 --- a/src/appmixer/azuredocumentintelligence/classifiers/ClassifyDocument/component.json +++ b/src/appmixer/azuredocumentintelligence/classifiers/ClassifyDocument/component.json @@ -1,7 +1,7 @@ { "name": "appmixer.azuredocumentintelligence.classifiers.ClassifyDocument", "author": "Appmixer ", - "description": "Classifies document with document classifier. Use one of the following input options: