diff --git a/packages/backend/src/apps/jotform/assets/favicon.svg b/packages/backend/src/apps/jotform/assets/favicon.svg
new file mode 100644
index 00000000..99500044
--- /dev/null
+++ b/packages/backend/src/apps/jotform/assets/favicon.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/packages/backend/src/apps/jotform/auth/index.js b/packages/backend/src/apps/jotform/auth/index.js
new file mode 100644
index 00000000..baf817e1
--- /dev/null
+++ b/packages/backend/src/apps/jotform/auth/index.js
@@ -0,0 +1,32 @@
+import verifyCredentials from './verify-credentials.js';
+import isStillVerified from './is-still-verified.js';
+
+export default {
+ fields: [
+ {
+ key: 'instanceUrl',
+ label: 'Jotform instance URL',
+ type: 'string',
+ required: false,
+ readOnly: false,
+ value: null,
+ placeholder: 'https://${subdomain}.jotform.com',
+ description: 'If you have an enterprise plan, you can use your api url.',
+ clickToCopy: true,
+ },
+ {
+ key: 'apiKey',
+ label: 'API Key',
+ type: 'string',
+ required: true,
+ readOnly: false,
+ value: null,
+ placeholder: null,
+ description: 'Jotform API key of your account.',
+ clickToCopy: false,
+ },
+ ],
+
+ verifyCredentials,
+ isStillVerified,
+};
diff --git a/packages/backend/src/apps/jotform/auth/is-still-verified.js b/packages/backend/src/apps/jotform/auth/is-still-verified.js
new file mode 100644
index 00000000..39867547
--- /dev/null
+++ b/packages/backend/src/apps/jotform/auth/is-still-verified.js
@@ -0,0 +1,8 @@
+import getCurrentUser from '../common/get-current-user.js';
+
+const isStillVerified = async ($) => {
+ const user = await getCurrentUser($);
+ return !!user.username;
+};
+
+export default isStillVerified;
diff --git a/packages/backend/src/apps/jotform/auth/verify-credentials.js b/packages/backend/src/apps/jotform/auth/verify-credentials.js
new file mode 100644
index 00000000..c99fae89
--- /dev/null
+++ b/packages/backend/src/apps/jotform/auth/verify-credentials.js
@@ -0,0 +1,14 @@
+import getCurrentUser from '../common/get-current-user.js';
+
+const verifyCredentials = async ($) => {
+ const user = await getCurrentUser($);
+
+ const screenName = [user.username, user.email].filter(Boolean).join(' @ ');
+
+ await $.auth.set({
+ screenName,
+ apiKey: $.auth.data.apiKey,
+ });
+};
+
+export default verifyCredentials;
diff --git a/packages/backend/src/apps/jotform/common/add-auth-header.js b/packages/backend/src/apps/jotform/common/add-auth-header.js
new file mode 100644
index 00000000..4d6296fb
--- /dev/null
+++ b/packages/backend/src/apps/jotform/common/add-auth-header.js
@@ -0,0 +1,9 @@
+const addAuthHeader = ($, requestConfig) => {
+ if ($.auth.data?.apiKey) {
+ requestConfig.headers['APIKEY'] = `${$.auth.data.apiKey}`;
+ }
+
+ return requestConfig;
+};
+
+export default addAuthHeader;
diff --git a/packages/backend/src/apps/jotform/common/get-current-user.js b/packages/backend/src/apps/jotform/common/get-current-user.js
new file mode 100644
index 00000000..e0cf0186
--- /dev/null
+++ b/packages/backend/src/apps/jotform/common/get-current-user.js
@@ -0,0 +1,7 @@
+const getCurrentUser = async ($) => {
+ const response = await $.http.get('/user');
+ const currentUser = response.data.content;
+ return currentUser;
+};
+
+export default getCurrentUser;
diff --git a/packages/backend/src/apps/jotform/common/set-base-url.js b/packages/backend/src/apps/jotform/common/set-base-url.js
new file mode 100644
index 00000000..135149b1
--- /dev/null
+++ b/packages/backend/src/apps/jotform/common/set-base-url.js
@@ -0,0 +1,11 @@
+const setBaseUrl = ($, requestConfig) => {
+ if ($.auth.data.instanceUrl) {
+ requestConfig.baseURL = $.auth.data.instanceUrl;
+ } else if ($.app.apiBaseUrl) {
+ requestConfig.baseURL = $.app.apiBaseUrl;
+ }
+
+ return requestConfig;
+};
+
+export default setBaseUrl;
diff --git a/packages/backend/src/apps/jotform/index.js b/packages/backend/src/apps/jotform/index.js
new file mode 100644
index 00000000..697a024b
--- /dev/null
+++ b/packages/backend/src/apps/jotform/index.js
@@ -0,0 +1,17 @@
+import defineApp from '../../helpers/define-app.js';
+import addAuthHeader from './common/add-auth-header.js';
+import auth from './auth/index.js';
+import setBaseUrl from './common/set-base-url.js';
+
+export default defineApp({
+ name: 'Jotform',
+ key: 'jotform',
+ iconUrl: '{BASE_URL}/apps/jotform/assets/favicon.svg',
+ authDocUrl: 'https://automatisch.io/docs/apps/jotform/connection',
+ supportsConnections: true,
+ baseUrl: 'https://www.jotform.com',
+ apiBaseUrl: 'https://api.jotform.com',
+ primaryColor: 'FF6100',
+ beforeRequest: [setBaseUrl, addAuthHeader],
+ auth,
+});
diff --git a/packages/docs/pages/.vitepress/config.js b/packages/docs/pages/.vitepress/config.js
index 0912d90b..c83c75e6 100644
--- a/packages/docs/pages/.vitepress/config.js
+++ b/packages/docs/pages/.vitepress/config.js
@@ -252,6 +252,12 @@ export default defineConfig({
{ text: 'Connection', link: '/apps/invoice-ninja/connection' },
],
},
+ {
+ text: 'Jotform',
+ collapsible: true,
+ collapsed: true,
+ items: [{ text: 'Connection', link: '/apps/jotform/connection' }],
+ },
{
text: 'Mailchimp',
collapsible: true,
diff --git a/packages/docs/pages/apps/jotform/connection.md b/packages/docs/pages/apps/jotform/connection.md
new file mode 100644
index 00000000..0b49f8f9
--- /dev/null
+++ b/packages/docs/pages/apps/jotform/connection.md
@@ -0,0 +1,12 @@
+# Jotform
+
+:::info
+This page explains the steps you need to follow to set up the Jotform
+connection in Automatisch. If any of the steps are outdated, please let us know!
+:::
+
+1. Login to your Jotform account: [https://www.jotform.com/](https://www.jotform.com/).
+2. Click on your account image and go to **Settings**.
+3. Click on the **API** tab on the left.
+4. Copy **API key** from the page to the `API Key` field on Automatisch.
+5. Now, you can start using the Jotform connection with Automatisch.
diff --git a/packages/docs/pages/public/favicons/jotform.svg b/packages/docs/pages/public/favicons/jotform.svg
new file mode 100644
index 00000000..99500044
--- /dev/null
+++ b/packages/docs/pages/public/favicons/jotform.svg
@@ -0,0 +1 @@
+
\ No newline at end of file