Compare commits
	
		
			281 Commits
		
	
	
		
			test-docs-
			...
			changedete
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | c095d3138b | ||
|   | 9548c93b4c | ||
|   | 4144944ab2 | ||
|   | 46b85519c1 | ||
|   | 5a83fc33ec | ||
|   | c80791267f | ||
|   | b30f97db3e | ||
|   | 717c81fa2b | ||
|   | ae188bc563 | ||
|   | fc4561221d | ||
|   | 5aeb4f8809 | ||
|   | c6c900bc39 | ||
|   | c18ab67a25 | ||
|   | 55ae1470d0 | ||
|   | a1136fdfb2 | ||
|   | dfe56d3aa2 | ||
|   | 3da5e13ecd | ||
|   | 40d0fe0db6 | ||
|   | 029fd2d0b0 | ||
|   | 12905ad733 | ||
|   | d257f59a3e | ||
|   | c9281b4605 | ||
|   | e9d2ae5d67 | ||
|   | 0f8e05610b | ||
|   | 9ea2196e51 | ||
|   | 97327a9033 | ||
|   | 8bf11ba7d1 | ||
|   | 523833b015 | ||
|   | e25a651d26 | ||
|   | 92a8c1483d | ||
|   | 8da3448e9c | ||
|   | f2385d8916 | ||
|   | 17a8daa526 | ||
|   | 51e254f127 | ||
|   | feccf571cd | ||
|   | 9f8ce44c1b | ||
|   | a7cfe7f23b | ||
|   | 8eaf775ef2 | ||
|   | 7b4179a87f | ||
|   | 43281bcbfe | ||
|   | 8a35d47caf | ||
|   | 759e8b6c42 | ||
|   | a8b01244af | ||
|   | 6ffb16ac67 | ||
|   | 5b66cc6c8b | ||
|   | 9a96258265 | ||
|   | a6cc1566c7 | ||
|   | d8d6227125 | ||
|   | fbfa67e471 | ||
|   | ab897ada5a | ||
|   | 3bcd3f3cb7 | ||
|   | acbede8631 | ||
|   | fa8c7571d7 | ||
|   | a58575c5a1 | ||
|   | 51f7009a80 | ||
|   | ba24c77f06 | ||
|   | 6b712c9a90 | ||
|   | 033b15a158 | ||
|   | e398bb84d4 | ||
|   | 05e902ab0c | ||
|   | 36eee61cb5 | ||
|   | 2409ce6fce | ||
|   | 999d61e520 | ||
|   | 08d2418190 | ||
|   | 6c07faeaaf | ||
|   | 3f5cfbf5a2 | ||
|   | 28f7707c75 | ||
|   | dc8358f6ce | ||
|   | ffcda04677 | ||
|   | 64ef655abb | ||
|   | 67887b1220 | ||
|   | 07803d1263 | ||
|   | f5ff7f7e13 | ||
|   | 641d062b82 | ||
|   | bb28a06ee9 | ||
|   | 81338c60f2 | ||
|   | f47fa5d272 | ||
|   | 29e9e012a5 | ||
|   | f89ddb5847 | ||
|   | c721f063ef | ||
|   | a709565336 | ||
|   | 91e484aef1 | ||
|   | 6ba94dcc8e | ||
|   | 788530be45 | ||
|   | 7ed392e854 | ||
|   | 3932e554da | ||
|   | 1a21624618 | ||
|   | 9f292ff018 | ||
|   | dbb24b3a9b | ||
|   | 35b2639837 | ||
|   | 35951199cd | ||
|   | 79af909c51 | ||
|   | 3482aa7b76 | ||
|   | 5dbc1f59ef | ||
|   | 2166a3220e | ||
|   | 24a7d1ef10 | ||
|   | 18ffbb7317 | ||
|   | 363874de6a | ||
|   | 68d1719b11 | ||
|   | 1a75d81268 | ||
|   | 2163be4227 | ||
|   | b54afcd922 | ||
|   | 0a86641a0f | ||
|   | 18464c746a | ||
|   | ba92cddae1 | ||
|   | 2a4f8ed45f | ||
|   | 135a0028be | ||
|   | 4da6e8372f | ||
|   | 6a7cdf2570 | ||
|   | 73c929f25e | ||
|   | 754c2d41c2 | ||
|   | 7201e48111 | ||
|   | e4292815cd | ||
|   | ab37250d5d | ||
|   | e5be8d3ba7 | ||
|   | 96a421fa22 | ||
|   | 12f72401b1 | ||
|   | 7391a9eddc | ||
|   | 30dee27f72 | ||
|   | 51a9939034 | ||
|   | e03c6e0ca4 | ||
|   | bece5c6488 | ||
|   | d49bb4c52d | ||
|   | 73d0eec30c | ||
|   | 5c756b16ca | ||
|   | f482c2422c | ||
|   | 2e564c863f | ||
|   | d9917a81bb | ||
|   | 61dc431f92 | ||
|   | 7d2fb8d9d7 | ||
|   | 608b79b66f | ||
|   | 009754c18b | ||
|   | 5df07c289e | ||
|   | a36d10870b | ||
|   | b549ba3e39 | ||
|   | 897c96361f | ||
|   | e7693d8aa6 | ||
|   | 1fe755f836 | ||
|   | ea1a63f7dd | ||
|   | 85134722a5 | ||
|   | 5c9d3ed134 | ||
|   | 17fb935ea0 | ||
|   | 196642a1cf | ||
|   | 009cf63d8c | ||
|   | da399aacd6 | ||
|   | 3632ee77e5 | ||
|   | 2901f337cc | ||
|   | f0bd2f335b | ||
|   | acdd026448 | ||
|   | fb0a328ab0 | ||
|   | d2a7889fc9 | ||
|   | 88c50e014d | ||
|   | f0ef12f904 | ||
|   | 1827f5413f | ||
|   | 0609f30e25 | ||
|   | d4e4d95b6d | ||
|   | d74af4931e | ||
|   | bee043d10d | ||
|   | a65e48b98a | ||
|   | ee26b54d54 | ||
|   | 855ec53dc2 | ||
|   | 3e3e48110d | ||
|   | fc04a357c8 | ||
|   | c8147370de | ||
|   | 999426be89 | ||
|   | 91458f91ef | ||
|   | 4b9ed29cc0 | ||
|   | e3bcb673fb | ||
|   | bf4776ca4f | ||
|   | 9f7f30a92a | ||
|   | 5c29fff55e | ||
|   | a0160c2573 | ||
|   | 87d3ca287d | ||
|   | 526e093689 | ||
|   | 0930c9d8d6 | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | ec680a713d | ||
|   | 583f90d1e9 | ||
|   | 8ba95381bc | ||
|   | ec6d634b99 | ||
|   | bc082acbe7 | ||
|   | e474ba02cb | ||
|   | ea922aaf10 | ||
|   | 766e6e20d8 | ||
|   | 8e646c244e | ||
|   | 26f31a5899 | ||
|   | 5c79e374dd | ||
|   | 7c1473ea95 | ||
|   | 1fe4cc3258 | ||
|   | 042ad4cea1 | ||
|   | e4c998dbce | ||
|   | 83c8cacdac | ||
|   | f75d5d906e | ||
|   | 85b3856564 | ||
|   | 75cb2569b5 | ||
|   | 0a4ac1cece | ||
|   | a873fd14bd | ||
|   | 85b4cd4998 | ||
|   | e9bc9b1aa8 | ||
|   | e3bf599bf6 | ||
|   | 01ae96840e | ||
|   | 186160ebf4 | ||
|   | 70f5e45c1f | ||
|   | 6dc54ecabc | ||
|   | d21888c047 | ||
|   | 33f7a90042 | ||
|   | a00d3a2c5e | ||
|   | abc64d769c | ||
|   | 88754ac569 | ||
|   | e3ee05d47d | ||
|   | 3b004e7483 | ||
|   | 9aa48c20e4 | ||
|   | 1b5d3beeca | ||
|   | 00115d313e | ||
|   | 190f1a205f | ||
|   | 8ab6f0c3fe | ||
|   | 13eea263c0 | ||
|   | b52b40962e | ||
|   | 7d1fa2e40c | ||
|   | 93b2098829 | ||
|   | a2acdc6b12 | ||
|   | 38b2c1e30f | ||
|   | e07f579f3c | ||
|   | df3297b6ca | ||
|   | fc4eeed764 | ||
|   | 3596d13be1 | ||
|   | 104d49ea1c | ||
|   | 7057317446 | ||
|   | 280575df88 | ||
|   | d2cb434b7b | ||
|   | 2ecb802a2e | ||
|   | 46e706c415 | ||
|   | 3a57349d8a | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | 565db852e0 | ||
|   | 754c3269ec | ||
|   | a079842408 | ||
|   | 7664b58553 | ||
|   | de77488f7e | ||
|   | d808afd21b | ||
|   | b68aff76a1 | ||
|   | 6da7fe158f | ||
|   | 4dbc7fdc7d | ||
|   | ad1e1f7eca | ||
|   | 9c3f7a3823 | ||
|   | 86f4cb7701 | ||
|   | 359a90245d | ||
|   | d8d7d86359 | ||
|   | 7189b629c0 | ||
|   | 55c9b5566c | ||
|   | ab671ccbf7 | ||
|   | 316bda8c3f | ||
|   | 76f77e8a4c | ||
|   | 4a99d5eab7 | ||
|   | 473d287c6d | ||
|   | bddd9896e4 | ||
|   | 95eb115965 | ||
|   | ec87c7f21c | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | 5c684cd499 | ||
|   | bd1ad5fa56 | ||
|   | f2e22e7445 | ||
|   | 0f39007f92 | ||
|   | ab811daba7 | ||
|   | 1428bf8ffa | ||
|   | 53f7f38e23 | ||
|   | ce6ad9e0d3 | ||
|   | 17a0c6123a | ||
|   | 10edc5a8ad | ||
|   | bdf07d6bd5 | ||
|   | 10ff65e71a | ||
|   | 9395097fda | ||
|   | 47eb0e00e3 | ||
|   | 57d5f34ac5 | ||
|   | 06b040412a | ||
|   | cab040c74a | ||
|   | 21706a7d15 | ||
|   | 22e4b8aaeb | ||
|   | bd43a6021a | ||
|   | a90b58b6db | ||
|   | 92a9b096ec | ||
|   | 7a6aa99840 | ||
|   | 5657f0d793 | ||
|   | 798529007e | 
| @@ -36,7 +36,6 @@ services: | |||||||
|   keycloak: |   keycloak: | ||||||
|     image: quay.io/keycloak/keycloak:21.1 |     image: quay.io/keycloak/keycloak:21.1 | ||||||
|     restart: always |     restart: always | ||||||
|     container_name: keycloak |  | ||||||
|     environment: |     environment: | ||||||
|       - KEYCLOAK_ADMIN=admin |       - KEYCLOAK_ADMIN=admin | ||||||
|       - KEYCLOAK_ADMIN_PASSWORD=admin |       - KEYCLOAK_ADMIN_PASSWORD=admin | ||||||
|   | |||||||
| @@ -4,5 +4,9 @@ | |||||||
| **/.devcontainer | **/.devcontainer | ||||||
| **/.github | **/.github | ||||||
| **/.vscode | **/.vscode | ||||||
|  | **/.env | ||||||
|  | **/.env.test | ||||||
|  | **/.env.production | ||||||
|  | **/yarn-error.log | ||||||
| packages/docs | packages/docs | ||||||
| packages/e2e-test | packages/e2e-test | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								.github/workflows/docs-change.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/docs-change.yml
									
									
									
									
										vendored
									
									
								
							| @@ -13,8 +13,6 @@ jobs: | |||||||
|         uses: actions/github-script@v6 |         uses: actions/github-script@v6 | ||||||
|         with: |         with: | ||||||
|           script: | |           script: | | ||||||
|             const github = require('@actions/github'); |  | ||||||
|             const { context } = github; |  | ||||||
|             const { pull_request } = context.payload; |             const { pull_request } = context.payload; | ||||||
|  |  | ||||||
|             const label = 'documentation-change'; |             const label = 'documentation-change'; | ||||||
|   | |||||||
| @@ -1,14 +1,25 @@ | |||||||
| # syntax=docker/dockerfile:1 | # syntax=docker/dockerfile:1 | ||||||
| FROM node:18-alpine | FROM node:18-alpine | ||||||
| WORKDIR /automatisch |  | ||||||
|  | ENV PORT 3000 | ||||||
|  |  | ||||||
|  | RUN \ | ||||||
|  |   apk --no-cache add --virtual build-dependencies python3 build-base git | ||||||
|  |  | ||||||
|  | WORKDIR /automatisch | ||||||
|  |  | ||||||
|  | # copy the app, note .dockerignore | ||||||
|  | COPY . /automatisch | ||||||
|  |  | ||||||
|  | RUN yarn | ||||||
|  |  | ||||||
|  | RUN cd packages/web && yarn build | ||||||
|  |  | ||||||
| RUN \ | RUN \ | ||||||
|   apk --no-cache add --virtual build-dependencies python3 build-base && \ |  | ||||||
|   yarn global add @automatisch/cli@0.10.0 --network-timeout 1000000 && \ |  | ||||||
|   rm -rf /usr/local/share/.cache/ && \ |   rm -rf /usr/local/share/.cache/ && \ | ||||||
|   apk del build-dependencies |   apk del build-dependencies | ||||||
|  |  | ||||||
| COPY ./entrypoint.sh /entrypoint.sh | COPY ./docker/entrypoint.sh /entrypoint.sh | ||||||
|  |  | ||||||
| EXPOSE 3000 | EXPOSE 3000 | ||||||
| ENTRYPOINT ["sh", "/entrypoint.sh"] | ENTRYPOINT ["sh", "/entrypoint.sh"] | ||||||
|   | |||||||
| @@ -1,24 +0,0 @@ | |||||||
| # syntax=docker/dockerfile:1 |  | ||||||
| FROM node:18-alpine |  | ||||||
|  |  | ||||||
| ENV PORT 3000 |  | ||||||
|  |  | ||||||
| RUN \ |  | ||||||
|   apk --no-cache add --virtual build-dependencies python3 build-base git |  | ||||||
|  |  | ||||||
| RUN git clone https://github.com/automatisch/automatisch.git |  | ||||||
|  |  | ||||||
| WORKDIR /automatisch |  | ||||||
|  |  | ||||||
| RUN yarn install |  | ||||||
|  |  | ||||||
| RUN if [ "$WORKER" != "true" ]; then cd packages/web && yarn build; fi |  | ||||||
|  |  | ||||||
| RUN \ |  | ||||||
|   rm -rf /usr/local/share/.cache/ && \ |  | ||||||
|   apk del build-dependencies |  | ||||||
|  |  | ||||||
| COPY ./docker/entrypoint-cloud.sh /entrypoint-cloud.sh |  | ||||||
|  |  | ||||||
| EXPOSE 3000 |  | ||||||
| ENTRYPOINT ["sh", "/entrypoint-cloud.sh"] |  | ||||||
| @@ -1,5 +1,5 @@ | |||||||
| # syntax=docker/dockerfile:1 | # syntax=docker/dockerfile:1 | ||||||
| FROM automatischio/automatisch:0.10.0 | FROM automatischio/automatisch:latest | ||||||
| WORKDIR /automatisch | WORKDIR /automatisch | ||||||
|  |  | ||||||
| RUN apk add --no-cache openssl dos2unix | RUN apk add --no-cache openssl dos2unix | ||||||
|   | |||||||
| @@ -1,13 +0,0 @@ | |||||||
| #!/bin/sh |  | ||||||
|  |  | ||||||
| set -e |  | ||||||
|  |  | ||||||
| cd packages/backend |  | ||||||
|  |  | ||||||
| if [ -n "$WORKER" ]; then |  | ||||||
|   yarn start:worker |  | ||||||
| else |  | ||||||
|   yarn db:migrate |  | ||||||
|   yarn db:seed:user |  | ||||||
|   yarn start |  | ||||||
| fi |  | ||||||
| @@ -2,8 +2,12 @@ | |||||||
|  |  | ||||||
| set -e | set -e | ||||||
|  |  | ||||||
|  | cd packages/backend | ||||||
|  |  | ||||||
| if [ -n "$WORKER" ]; then | if [ -n "$WORKER" ]; then | ||||||
|   automatisch start-worker |   yarn start:worker | ||||||
| else | else | ||||||
|   automatisch start |   yarn db:migrate | ||||||
|  |   yarn db:seed:user | ||||||
|  |   yarn start | ||||||
| fi | fi | ||||||
|   | |||||||
| @@ -2,6 +2,7 @@ import appConfig from '../../src/config/app.js'; | |||||||
| import logger from '../../src/helpers/logger.js'; | import logger from '../../src/helpers/logger.js'; | ||||||
| import client from './client.js'; | import client from './client.js'; | ||||||
| import User from '../../src/models/user.js'; | import User from '../../src/models/user.js'; | ||||||
|  | import Config from '../../src/models/config.js'; | ||||||
| import Role from '../../src/models/role.js'; | import Role from '../../src/models/role.js'; | ||||||
| import '../../src/config/orm.js'; | import '../../src/config/orm.js'; | ||||||
| import process from 'process'; | import process from 'process'; | ||||||
| @@ -21,6 +22,14 @@ export async function createUser( | |||||||
|   email = 'user@automatisch.io', |   email = 'user@automatisch.io', | ||||||
|   password = 'sample' |   password = 'sample' | ||||||
| ) { | ) { | ||||||
|  |   if (appConfig.disableSeedUser) { | ||||||
|  |     logger.info('Seed user is disabled.'); | ||||||
|  |  | ||||||
|  |     process.exit(0); | ||||||
|  |  | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |  | ||||||
|   const UNIQUE_VIOLATION_CODE = '23505'; |   const UNIQUE_VIOLATION_CODE = '23505'; | ||||||
|  |  | ||||||
|   const role = await fetchAdminRole(); |   const role = await fetchAdminRole(); | ||||||
| @@ -37,6 +46,8 @@ export async function createUser( | |||||||
|     if (userCount === 0) { |     if (userCount === 0) { | ||||||
|       const user = await User.query().insertAndFetch(userParams); |       const user = await User.query().insertAndFetch(userParams); | ||||||
|       logger.info(`User has been saved: ${user.email}`); |       logger.info(`User has been saved: ${user.email}`); | ||||||
|  |  | ||||||
|  |       await Config.markInstallationCompleted(); | ||||||
|     } else { |     } else { | ||||||
|       logger.info('No need to seed a user.'); |       logger.info('No need to seed a user.'); | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -31,7 +31,7 @@ | |||||||
|     "accounting": "^0.4.1", |     "accounting": "^0.4.1", | ||||||
|     "ajv-formats": "^2.1.1", |     "ajv-formats": "^2.1.1", | ||||||
|     "axios": "1.6.0", |     "axios": "1.6.0", | ||||||
|     "bcrypt": "^5.0.1", |     "bcrypt": "^5.1.0", | ||||||
|     "bullmq": "^3.0.0", |     "bullmq": "^3.0.0", | ||||||
|     "cors": "^2.8.5", |     "cors": "^2.8.5", | ||||||
|     "crypto-js": "^4.1.1", |     "crypto-js": "^4.1.1", | ||||||
| @@ -67,6 +67,7 @@ | |||||||
|     "pluralize": "^8.0.0", |     "pluralize": "^8.0.0", | ||||||
|     "raw-body": "^2.5.2", |     "raw-body": "^2.5.2", | ||||||
|     "showdown": "^2.1.0", |     "showdown": "^2.1.0", | ||||||
|  |     "uuid": "^9.0.1", | ||||||
|     "winston": "^3.7.1", |     "winston": "^3.7.1", | ||||||
|     "xmlrpc": "^1.3.2" |     "xmlrpc": "^1.3.2" | ||||||
|   }, |   }, | ||||||
| @@ -95,6 +96,7 @@ | |||||||
|     "url": "https://github.com/automatisch/automatisch/issues" |     "url": "https://github.com/automatisch/automatisch/issues" | ||||||
|   }, |   }, | ||||||
|   "devDependencies": { |   "devDependencies": { | ||||||
|  |     "node-gyp": "^10.1.0", | ||||||
|     "nodemon": "^2.0.13", |     "nodemon": "^2.0.13", | ||||||
|     "supertest": "^6.3.3", |     "supertest": "^6.3.3", | ||||||
|     "vitest": "^1.1.3" |     "vitest": "^1.1.3" | ||||||
|   | |||||||
| @@ -11,7 +11,7 @@ export default defineApp({ | |||||||
|     'https://azure.microsoft.com/en-us/products/ai-services/openai-service', |     'https://azure.microsoft.com/en-us/products/ai-services/openai-service', | ||||||
|   apiBaseUrl: '', |   apiBaseUrl: '', | ||||||
|   iconUrl: '{BASE_URL}/apps/azure-openai/assets/favicon.svg', |   iconUrl: '{BASE_URL}/apps/azure-openai/assets/favicon.svg', | ||||||
|   authDocUrl: 'https://automatisch.io/docs/apps/azure-openai/connection', |   authDocUrl: '{DOCS_URL}/apps/azure-openai/connection', | ||||||
|   primaryColor: '000000', |   primaryColor: '000000', | ||||||
|   supportsConnections: true, |   supportsConnections: true, | ||||||
|   beforeRequest: [setBaseUrl, addAuthHeader], |   beforeRequest: [setBaseUrl, addAuthHeader], | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ export default defineApp({ | |||||||
|   name: 'Carbone', |   name: 'Carbone', | ||||||
|   key: 'carbone', |   key: 'carbone', | ||||||
|   iconUrl: '{BASE_URL}/apps/carbone/assets/favicon.svg', |   iconUrl: '{BASE_URL}/apps/carbone/assets/favicon.svg', | ||||||
|   authDocUrl: 'https://automatisch.io/docs/apps/carbone/connection', |   authDocUrl: '{DOCS_URL}/apps/carbone/connection', | ||||||
|   supportsConnections: true, |   supportsConnections: true, | ||||||
|   baseUrl: 'https://carbone.io', |   baseUrl: 'https://carbone.io', | ||||||
|   apiBaseUrl: 'https://api.carbone.io', |   apiBaseUrl: 'https://api.carbone.io', | ||||||
|   | |||||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| After Width: | Height: | Size: 9.9 KiB | 
							
								
								
									
										44
									
								
								packages/backend/src/apps/changedetection/auth/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								packages/backend/src/apps/changedetection/auth/index.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | |||||||
|  | import verifyCredentials from './verify-credentials.js'; | ||||||
|  | import isStillVerified from './is-still-verified.js'; | ||||||
|  |  | ||||||
|  | export default { | ||||||
|  |   fields: [ | ||||||
|  |     { | ||||||
|  |       key: 'screenName', | ||||||
|  |       label: 'Screen Name', | ||||||
|  |       type: 'string', | ||||||
|  |       required: true, | ||||||
|  |       readOnly: false, | ||||||
|  |       value: null, | ||||||
|  |       placeholder: null, | ||||||
|  |       description: | ||||||
|  |         'Screen name of your connection to be used on Automatisch UI.', | ||||||
|  |       clickToCopy: false, | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       key: 'instanceUrl', | ||||||
|  |       label: 'Instance URL', | ||||||
|  |       type: 'string', | ||||||
|  |       required: true, | ||||||
|  |       readOnly: false, | ||||||
|  |       value: null, | ||||||
|  |       placeholder: null, | ||||||
|  |       description: null, | ||||||
|  |       clickToCopy: false, | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       key: 'apiKey', | ||||||
|  |       label: 'API Key', | ||||||
|  |       type: 'string', | ||||||
|  |       required: true, | ||||||
|  |       readOnly: false, | ||||||
|  |       value: null, | ||||||
|  |       placeholder: null, | ||||||
|  |       description: 'Changedetection API key of your account.', | ||||||
|  |       clickToCopy: false, | ||||||
|  |     }, | ||||||
|  |   ], | ||||||
|  |  | ||||||
|  |   verifyCredentials, | ||||||
|  |   isStillVerified, | ||||||
|  | }; | ||||||
| @@ -0,0 +1,8 @@ | |||||||
|  | import verifyCredentials from './verify-credentials.js'; | ||||||
|  |  | ||||||
|  | const isStillVerified = async ($) => { | ||||||
|  |   await verifyCredentials($); | ||||||
|  |   return true; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | export default isStillVerified; | ||||||
| @@ -0,0 +1,10 @@ | |||||||
|  | const verifyCredentials = async ($) => { | ||||||
|  |   await $.http.get('/v1/systeminfo'); | ||||||
|  |  | ||||||
|  |   await $.auth.set({ | ||||||
|  |     screenName: $.auth.data.screenName, | ||||||
|  |     apiKey: $.auth.data.apiKey, | ||||||
|  |   }); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | export default verifyCredentials; | ||||||
| @@ -0,0 +1,9 @@ | |||||||
|  | const addAuthHeader = ($, requestConfig) => { | ||||||
|  |   if ($.auth.data?.apiKey) { | ||||||
|  |     requestConfig.headers['x-api-key'] = $.auth.data.apiKey; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return requestConfig; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | export default addAuthHeader; | ||||||
| @@ -0,0 +1,10 @@ | |||||||
|  | const setBaseUrl = ($, requestConfig) => { | ||||||
|  |   const instanceUrl = $.auth.data.instanceUrl; | ||||||
|  |   if (instanceUrl) { | ||||||
|  |     requestConfig.baseURL = `${instanceUrl}/api`; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return requestConfig; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | export default setBaseUrl; | ||||||
							
								
								
									
										17
									
								
								packages/backend/src/apps/changedetection/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								packages/backend/src/apps/changedetection/index.js
									
									
									
									
									
										Normal file
									
								
							| @@ -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: 'Changedetection', | ||||||
|  |   key: 'changedetection', | ||||||
|  |   iconUrl: '{BASE_URL}/apps/changedetection/assets/favicon.svg', | ||||||
|  |   authDocUrl: '{DOCS_URL}/apps/changedetection/connection', | ||||||
|  |   supportsConnections: true, | ||||||
|  |   baseUrl: 'https://changedetection.io', | ||||||
|  |   apiBaseUrl: '', | ||||||
|  |   primaryColor: '3056d3', | ||||||
|  |   beforeRequest: [setBaseUrl, addAuthHeader], | ||||||
|  |   auth, | ||||||
|  | }); | ||||||
| @@ -5,7 +5,7 @@ export default defineApp({ | |||||||
|   name: 'Datastore', |   name: 'Datastore', | ||||||
|   key: 'datastore', |   key: 'datastore', | ||||||
|   iconUrl: '{BASE_URL}/apps/datastore/assets/favicon.svg', |   iconUrl: '{BASE_URL}/apps/datastore/assets/favicon.svg', | ||||||
|   authDocUrl: 'https://automatisch.io/docs/apps/datastore/connection', |   authDocUrl: '{DOCS_URL}/apps/datastore/connection', | ||||||
|   supportsConnections: false, |   supportsConnections: false, | ||||||
|   baseUrl: '', |   baseUrl: '', | ||||||
|   apiBaseUrl: '', |   apiBaseUrl: '', | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ export default defineApp({ | |||||||
|   name: 'DeepL', |   name: 'DeepL', | ||||||
|   key: 'deepl', |   key: 'deepl', | ||||||
|   iconUrl: '{BASE_URL}/apps/deepl/assets/favicon.svg', |   iconUrl: '{BASE_URL}/apps/deepl/assets/favicon.svg', | ||||||
|   authDocUrl: 'https://automatisch.io/docs/apps/deepl/connection', |   authDocUrl: '{DOCS_URL}/apps/deepl/connection', | ||||||
|   supportsConnections: true, |   supportsConnections: true, | ||||||
|   baseUrl: 'https://deepl.com', |   baseUrl: 'https://deepl.com', | ||||||
|   apiBaseUrl: 'https://api.deepl.com', |   apiBaseUrl: 'https://api.deepl.com', | ||||||
|   | |||||||
| @@ -5,7 +5,7 @@ export default defineApp({ | |||||||
|   name: 'Delay', |   name: 'Delay', | ||||||
|   key: 'delay', |   key: 'delay', | ||||||
|   iconUrl: '{BASE_URL}/apps/delay/assets/favicon.svg', |   iconUrl: '{BASE_URL}/apps/delay/assets/favicon.svg', | ||||||
|   authDocUrl: 'https://automatisch.io/docs/apps/delay/connection', |   authDocUrl: '{DOCS_URL}/apps/delay/connection', | ||||||
|   supportsConnections: false, |   supportsConnections: false, | ||||||
|   baseUrl: '', |   baseUrl: '', | ||||||
|   apiBaseUrl: '', |   apiBaseUrl: '', | ||||||
|   | |||||||
| @@ -10,7 +10,7 @@ export default defineApp({ | |||||||
|   name: 'Discord', |   name: 'Discord', | ||||||
|   key: 'discord', |   key: 'discord', | ||||||
|   iconUrl: '{BASE_URL}/apps/discord/assets/favicon.svg', |   iconUrl: '{BASE_URL}/apps/discord/assets/favicon.svg', | ||||||
|   authDocUrl: 'https://automatisch.io/docs/apps/discord/connection', |   authDocUrl: '{DOCS_URL}/apps/discord/connection', | ||||||
|   supportsConnections: true, |   supportsConnections: true, | ||||||
|   baseUrl: 'https://discord.com', |   baseUrl: 'https://discord.com', | ||||||
|   apiBaseUrl: 'https://discord.com/api', |   apiBaseUrl: 'https://discord.com/api', | ||||||
|   | |||||||
							
								
								
									
										16
									
								
								packages/backend/src/apps/disqus/assets/favicon.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								packages/backend/src/apps/disqus/assets/favicon.svg
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | |||||||
|  | <?xml version="1.0" encoding="utf-8"?> | ||||||
|  | <!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  --> | ||||||
|  | <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> | ||||||
|  | <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" | ||||||
|  | 	 width="200px" height="200px" viewBox="0 0 200 200" enable-background="new 0 0 200 200" xml:space="preserve"> | ||||||
|  | <g id="background"> | ||||||
|  | 	<rect fill="#2E9FFF" width="200" height="200"/> | ||||||
|  | </g> | ||||||
|  | <g id="Layer_2"> | ||||||
|  | </g> | ||||||
|  | <path fill="#FFFFFF" d="M102.535,167.5c-16.518,0-31.621-6.036-43.298-16.021L30.5,155.405l11.102-27.401 | ||||||
|  | 	c-3.868-8.535-6.038-18.01-6.038-28.004c0-37.277,29.984-67.5,66.971-67.5c36.984,0,66.965,30.223,66.965,67.5 | ||||||
|  | 	C169.5,137.284,139.52,167.5,102.535,167.5z M139.102,99.807v-0.188c0-19.479-13.736-33.367-37.42-33.367h-25.58v67.5h25.201 | ||||||
|  | 	C125.171,133.753,139.102,119.284,139.102,99.807L139.102,99.807z M101.964,117.168h-7.482V82.841h7.482 | ||||||
|  | 	c10.989,0,18.283,6.265,18.283,17.07v0.188C120.247,110.995,112.953,117.168,101.964,117.168z"/> | ||||||
|  | </svg> | ||||||
| After Width: | Height: | Size: 1.1 KiB | 
							
								
								
									
										21
									
								
								packages/backend/src/apps/disqus/auth/generate-auth-url.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								packages/backend/src/apps/disqus/auth/generate-auth-url.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | |||||||
|  | import { URLSearchParams } from 'url'; | ||||||
|  | import authScope from '../common/auth-scope.js'; | ||||||
|  |  | ||||||
|  | export default async function generateAuthUrl($) { | ||||||
|  |   const oauthRedirectUrlField = $.app.auth.fields.find( | ||||||
|  |     (field) => field.key == 'oAuthRedirectUrl' | ||||||
|  |   ); | ||||||
|  |   const redirectUri = oauthRedirectUrlField.value; | ||||||
|  |   const searchParams = new URLSearchParams({ | ||||||
|  |     client_id: $.auth.data.apiKey, | ||||||
|  |     scope: authScope.join(','), | ||||||
|  |     response_type: 'code', | ||||||
|  |     redirect_uri: redirectUri, | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   const url = `https://disqus.com/api/oauth/2.0/authorize/?${searchParams.toString()}`; | ||||||
|  |  | ||||||
|  |   await $.auth.set({ | ||||||
|  |     url, | ||||||
|  |   }); | ||||||
|  | } | ||||||
							
								
								
									
										48
									
								
								packages/backend/src/apps/disqus/auth/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								packages/backend/src/apps/disqus/auth/index.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,48 @@ | |||||||
|  | import generateAuthUrl from './generate-auth-url.js'; | ||||||
|  | import verifyCredentials from './verify-credentials.js'; | ||||||
|  | import refreshToken from './refresh-token.js'; | ||||||
|  | import isStillVerified from './is-still-verified.js'; | ||||||
|  |  | ||||||
|  | export default { | ||||||
|  |   fields: [ | ||||||
|  |     { | ||||||
|  |       key: 'oAuthRedirectUrl', | ||||||
|  |       label: 'OAuth Redirect URL', | ||||||
|  |       type: 'string', | ||||||
|  |       required: true, | ||||||
|  |       readOnly: true, | ||||||
|  |       value: '{WEB_APP_URL}/app/disqus/connections/add', | ||||||
|  |       placeholder: null, | ||||||
|  |       description: | ||||||
|  |         'When asked to input a redirect URL in Disqus, enter the URL above.', | ||||||
|  |       clickToCopy: true, | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       key: 'apiKey', | ||||||
|  |       label: 'API Key', | ||||||
|  |       type: 'string', | ||||||
|  |       required: true, | ||||||
|  |       readOnly: false, | ||||||
|  |       value: null, | ||||||
|  |       placeholder: null, | ||||||
|  |       description: null, | ||||||
|  |       clickToCopy: false, | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       key: 'apiSecret', | ||||||
|  |       label: 'API Secret', | ||||||
|  |       type: 'string', | ||||||
|  |       required: true, | ||||||
|  |       readOnly: false, | ||||||
|  |       value: null, | ||||||
|  |       placeholder: null, | ||||||
|  |       description: null, | ||||||
|  |       clickToCopy: false, | ||||||
|  |     }, | ||||||
|  |   ], | ||||||
|  |  | ||||||
|  |   generateAuthUrl, | ||||||
|  |   verifyCredentials, | ||||||
|  |   isStillVerified, | ||||||
|  |   refreshToken, | ||||||
|  | }; | ||||||
| @@ -0,0 +1,8 @@ | |||||||
|  | import getCurrentUser from '../common/get-current-user.js'; | ||||||
|  |  | ||||||
|  | const isStillVerified = async ($) => { | ||||||
|  |   const currentUser = await getCurrentUser($); | ||||||
|  |   return !!currentUser.response.username; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | export default isStillVerified; | ||||||
							
								
								
									
										26
									
								
								packages/backend/src/apps/disqus/auth/refresh-token.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								packages/backend/src/apps/disqus/auth/refresh-token.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | |||||||
|  | import { URLSearchParams } from 'node:url'; | ||||||
|  | import authScope from '../common/auth-scope.js'; | ||||||
|  |  | ||||||
|  | const refreshToken = async ($) => { | ||||||
|  |   const params = new URLSearchParams({ | ||||||
|  |     grant_type: 'refresh_token', | ||||||
|  |     client_id: $.auth.data.apiKey, | ||||||
|  |     client_secret: $.auth.data.apiSecret, | ||||||
|  |     refresh_token: $.auth.data.refreshToken, | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   const { data } = await $.http.post( | ||||||
|  |     `https://disqus.com/api/oauth/2.0/access_token/`, | ||||||
|  |     params.toString() | ||||||
|  |   ); | ||||||
|  |  | ||||||
|  |   await $.auth.set({ | ||||||
|  |     accessToken: data.access_token, | ||||||
|  |     refreshToken: data.refresh_token, | ||||||
|  |     expiresIn: data.expires_in, | ||||||
|  |     scope: authScope.join(','), | ||||||
|  |     tokenType: data.token_type, | ||||||
|  |   }); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | export default refreshToken; | ||||||
							
								
								
									
										34
									
								
								packages/backend/src/apps/disqus/auth/verify-credentials.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								packages/backend/src/apps/disqus/auth/verify-credentials.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | |||||||
|  | import { URLSearchParams } from 'url'; | ||||||
|  |  | ||||||
|  | const verifyCredentials = async ($) => { | ||||||
|  |   const oauthRedirectUrlField = $.app.auth.fields.find( | ||||||
|  |     (field) => field.key == 'oAuthRedirectUrl' | ||||||
|  |   ); | ||||||
|  |   const redirectUri = oauthRedirectUrlField.value; | ||||||
|  |   const params = new URLSearchParams({ | ||||||
|  |     grant_type: 'authorization_code', | ||||||
|  |     client_id: $.auth.data.apiKey, | ||||||
|  |     client_secret: $.auth.data.apiSecret, | ||||||
|  |     redirect_uri: redirectUri, | ||||||
|  |     code: $.auth.data.code, | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   const { data } = await $.http.post( | ||||||
|  |     `https://disqus.com/api/oauth/2.0/access_token/`, | ||||||
|  |     params.toString() | ||||||
|  |   ); | ||||||
|  |  | ||||||
|  |   await $.auth.set({ | ||||||
|  |     accessToken: data.access_token, | ||||||
|  |     tokenType: data.token_type, | ||||||
|  |     apiKey: $.auth.data.apiKey, | ||||||
|  |     apiSecret: $.auth.data.apiSecret, | ||||||
|  |     scope: $.auth.data.scope, | ||||||
|  |     userId: data.user_id, | ||||||
|  |     expiresIn: data.expires_in, | ||||||
|  |     refreshToken: data.refresh_token, | ||||||
|  |     screenName: data.username, | ||||||
|  |   }); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | export default verifyCredentials; | ||||||
							
								
								
									
										15
									
								
								packages/backend/src/apps/disqus/common/add-auth-header.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								packages/backend/src/apps/disqus/common/add-auth-header.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | |||||||
|  | import { URLSearchParams } from 'url'; | ||||||
|  |  | ||||||
|  | const addAuthHeader = ($, requestConfig) => { | ||||||
|  |   const params = new URLSearchParams({ | ||||||
|  |     access_token: $.auth.data.accessToken, | ||||||
|  |     api_key: $.auth.data.apiKey, | ||||||
|  |     api_secret: $.auth.data.apiSecret, | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   requestConfig.params = params; | ||||||
|  |  | ||||||
|  |   return requestConfig; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | export default addAuthHeader; | ||||||
							
								
								
									
										3
									
								
								packages/backend/src/apps/disqus/common/auth-scope.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								packages/backend/src/apps/disqus/common/auth-scope.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | |||||||
|  | const authScope = ['read', 'write', 'admin', 'email']; | ||||||
|  |  | ||||||
|  | export default authScope; | ||||||
							
								
								
									
										10
									
								
								packages/backend/src/apps/disqus/common/get-current-user.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								packages/backend/src/apps/disqus/common/get-current-user.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | |||||||
|  | const getCurrentUser = async ($) => { | ||||||
|  |   try { | ||||||
|  |     const { data: currentUser } = await $.http.get('/3.0/users/details.json'); | ||||||
|  |     return currentUser; | ||||||
|  |   } catch (error) { | ||||||
|  |     throw new Error('You are not authenticated.'); | ||||||
|  |   } | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | export default getCurrentUser; | ||||||
							
								
								
									
										3
									
								
								packages/backend/src/apps/disqus/dynamic-data/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								packages/backend/src/apps/disqus/dynamic-data/index.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | |||||||
|  | import listForums from './list-forums/index.js'; | ||||||
|  |  | ||||||
|  | export default [listForums]; | ||||||
| @@ -0,0 +1,36 @@ | |||||||
|  | export default { | ||||||
|  |   name: 'List forums', | ||||||
|  |   key: 'listForums', | ||||||
|  |  | ||||||
|  |   async run($) { | ||||||
|  |     const forums = { | ||||||
|  |       data: [], | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     const params = { | ||||||
|  |       limit: 100, | ||||||
|  |       order: 'desc', | ||||||
|  |       cursor: undefined, | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     let more; | ||||||
|  |     do { | ||||||
|  |       const { data } = await $.http.get('/3.0/users/listForums.json', { | ||||||
|  |         params, | ||||||
|  |       }); | ||||||
|  |       params.cursor = data.cursor.next; | ||||||
|  |       more = data.cursor.hasNext; | ||||||
|  |  | ||||||
|  |       if (data.response?.length) { | ||||||
|  |         for (const forum of data.response) { | ||||||
|  |           forums.data.push({ | ||||||
|  |             value: forum.id, | ||||||
|  |             name: forum.id, | ||||||
|  |           }); | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } while (more); | ||||||
|  |  | ||||||
|  |     return forums; | ||||||
|  |   }, | ||||||
|  | }; | ||||||
							
								
								
									
										20
									
								
								packages/backend/src/apps/disqus/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								packages/backend/src/apps/disqus/index.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | |||||||
|  | import defineApp from '../../helpers/define-app.js'; | ||||||
|  | import addAuthHeader from './common/add-auth-header.js'; | ||||||
|  | import auth from './auth/index.js'; | ||||||
|  | import dynamicData from './dynamic-data/index.js'; | ||||||
|  | import triggers from './triggers/index.js'; | ||||||
|  |  | ||||||
|  | export default defineApp({ | ||||||
|  |   name: 'Disqus', | ||||||
|  |   key: 'disqus', | ||||||
|  |   baseUrl: 'https://disqus.com', | ||||||
|  |   apiBaseUrl: 'https://disqus.com/api', | ||||||
|  |   iconUrl: '{BASE_URL}/apps/disqus/assets/favicon.svg', | ||||||
|  |   authDocUrl: '{DOCS_URL}/apps/disqus/connection', | ||||||
|  |   primaryColor: '2E9FFF', | ||||||
|  |   supportsConnections: true, | ||||||
|  |   beforeRequest: [addAuthHeader], | ||||||
|  |   auth, | ||||||
|  |   dynamicData, | ||||||
|  |   triggers, | ||||||
|  | }); | ||||||
							
								
								
									
										4
									
								
								packages/backend/src/apps/disqus/triggers/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								packages/backend/src/apps/disqus/triggers/index.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | |||||||
|  | import newComments from './new-comments/index.js'; | ||||||
|  | import newFlaggedComments from './new-flagged-comments/index.js'; | ||||||
|  |  | ||||||
|  | export default [newComments, newFlaggedComments]; | ||||||
| @@ -0,0 +1,92 @@ | |||||||
|  | import defineTrigger from '../../../../helpers/define-trigger.js'; | ||||||
|  | import { URLSearchParams } from 'url'; | ||||||
|  |  | ||||||
|  | export default defineTrigger({ | ||||||
|  |   name: 'New comments', | ||||||
|  |   key: 'newComments', | ||||||
|  |   pollInterval: 15, | ||||||
|  |   description: 'Triggers when a new comment is posted in a forum using Disqus.', | ||||||
|  |   arguments: [ | ||||||
|  |     { | ||||||
|  |       label: 'Post Types', | ||||||
|  |       key: 'postTypes', | ||||||
|  |       type: 'dynamic', | ||||||
|  |       required: false, | ||||||
|  |       description: | ||||||
|  |         'Which posts should be considered for inclusion in the trigger?', | ||||||
|  |       fields: [ | ||||||
|  |         { | ||||||
|  |           label: 'Type', | ||||||
|  |           key: 'type', | ||||||
|  |           type: 'dropdown', | ||||||
|  |           required: false, | ||||||
|  |           description: '', | ||||||
|  |           variables: true, | ||||||
|  |           options: [ | ||||||
|  |             { label: 'Unapproved Posts', value: 'unapproved' }, | ||||||
|  |             { label: 'Approved Posts', value: 'approved' }, | ||||||
|  |             { label: 'Spam Posts', value: 'spam' }, | ||||||
|  |             { label: 'Deleted Posts', value: 'deleted' }, | ||||||
|  |             { label: 'Flagged Posts', value: 'flagged' }, | ||||||
|  |             { label: 'Highlighted Posts', value: 'highlighted' }, | ||||||
|  |           ], | ||||||
|  |         }, | ||||||
|  |       ], | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       label: 'Forum', | ||||||
|  |       key: 'forumId', | ||||||
|  |       type: 'dropdown', | ||||||
|  |       required: true, | ||||||
|  |       description: 'Select the forum where you want comments to be triggered.', | ||||||
|  |       variables: true, | ||||||
|  |       source: { | ||||||
|  |         type: 'query', | ||||||
|  |         name: 'getDynamicData', | ||||||
|  |         arguments: [ | ||||||
|  |           { | ||||||
|  |             name: 'key', | ||||||
|  |             value: 'listForums', | ||||||
|  |           }, | ||||||
|  |         ], | ||||||
|  |       }, | ||||||
|  |     }, | ||||||
|  |   ], | ||||||
|  |  | ||||||
|  |   async run($) { | ||||||
|  |     const forumId = $.step.parameters.forumId; | ||||||
|  |     const postTypes = $.step.parameters.postTypes; | ||||||
|  |     const formattedCommentTypes = postTypes | ||||||
|  |       .filter((type) => type.type !== '') | ||||||
|  |       .map((type) => type.type); | ||||||
|  |  | ||||||
|  |     const params = new URLSearchParams({ | ||||||
|  |       limit: '100', | ||||||
|  |       forum: forumId, | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     if (formattedCommentTypes.length) { | ||||||
|  |       formattedCommentTypes.forEach((type) => params.append('include', type)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     let more; | ||||||
|  |     do { | ||||||
|  |       const { data } = await $.http.get( | ||||||
|  |         `/3.0/posts/list.json?${params.toString()}` | ||||||
|  |       ); | ||||||
|  |       params.set('cursor', data.cursor.next); | ||||||
|  |       more = data.cursor.hasNext; | ||||||
|  |  | ||||||
|  |       if (data.response?.length) { | ||||||
|  |         for (const comment of data.response) { | ||||||
|  |           $.pushTriggerItem({ | ||||||
|  |             raw: comment, | ||||||
|  |             meta: { | ||||||
|  |               internalId: comment.id, | ||||||
|  |             }, | ||||||
|  |           }); | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } while (more); | ||||||
|  |   }, | ||||||
|  | }); | ||||||
| @@ -0,0 +1,60 @@ | |||||||
|  | import defineTrigger from '../../../../helpers/define-trigger.js'; | ||||||
|  | import { URLSearchParams } from 'url'; | ||||||
|  |  | ||||||
|  | export default defineTrigger({ | ||||||
|  |   name: 'New flagged comments', | ||||||
|  |   key: 'newFlaggedComments', | ||||||
|  |   pollInterval: 15, | ||||||
|  |   description: 'Triggers when a Disqus comment is marked with a flag', | ||||||
|  |   arguments: [ | ||||||
|  |     { | ||||||
|  |       label: 'Forum', | ||||||
|  |       key: 'forumId', | ||||||
|  |       type: 'dropdown', | ||||||
|  |       required: true, | ||||||
|  |       description: 'Select the forum where you want comments to be triggered.', | ||||||
|  |       variables: true, | ||||||
|  |       source: { | ||||||
|  |         type: 'query', | ||||||
|  |         name: 'getDynamicData', | ||||||
|  |         arguments: [ | ||||||
|  |           { | ||||||
|  |             name: 'key', | ||||||
|  |             value: 'listForums', | ||||||
|  |           }, | ||||||
|  |         ], | ||||||
|  |       }, | ||||||
|  |     }, | ||||||
|  |   ], | ||||||
|  |  | ||||||
|  |   async run($) { | ||||||
|  |     const forumId = $.step.parameters.forumId; | ||||||
|  |     const isFlaggedFilter = 5; | ||||||
|  |  | ||||||
|  |     const params = new URLSearchParams({ | ||||||
|  |       limit: 100, | ||||||
|  |       forum: forumId, | ||||||
|  |       filters: [isFlaggedFilter], | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     let more; | ||||||
|  |     do { | ||||||
|  |       const { data } = await $.http.get( | ||||||
|  |         `/3.0/posts/list.json?${params.toString()}` | ||||||
|  |       ); | ||||||
|  |       params.set('cursor', data.cursor.next); | ||||||
|  |       more = data.cursor.hasNext; | ||||||
|  |  | ||||||
|  |       if (data.response?.length) { | ||||||
|  |         for (const comment of data.response) { | ||||||
|  |           $.pushTriggerItem({ | ||||||
|  |             raw: comment, | ||||||
|  |             meta: { | ||||||
|  |               internalId: comment.id, | ||||||
|  |             }, | ||||||
|  |           }); | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } while (more); | ||||||
|  |   }, | ||||||
|  | }); | ||||||
| @@ -7,7 +7,7 @@ export default defineApp({ | |||||||
|   name: 'Dropbox', |   name: 'Dropbox', | ||||||
|   key: 'dropbox', |   key: 'dropbox', | ||||||
|   iconUrl: '{BASE_URL}/apps/dropbox/assets/favicon.svg', |   iconUrl: '{BASE_URL}/apps/dropbox/assets/favicon.svg', | ||||||
|   authDocUrl: 'https://automatisch.io/docs/apps/dropbox/connection', |   authDocUrl: '{DOCS_URL}/apps/dropbox/connection', | ||||||
|   supportsConnections: true, |   supportsConnections: true, | ||||||
|   baseUrl: 'https://dropbox.com', |   baseUrl: 'https://dropbox.com', | ||||||
|   apiBaseUrl: 'https://api.dropboxapi.com', |   apiBaseUrl: 'https://api.dropboxapi.com', | ||||||
|   | |||||||
| @@ -5,7 +5,7 @@ export default defineApp({ | |||||||
|   name: 'Filter', |   name: 'Filter', | ||||||
|   key: 'filter', |   key: 'filter', | ||||||
|   iconUrl: '{BASE_URL}/apps/filter/assets/favicon.svg', |   iconUrl: '{BASE_URL}/apps/filter/assets/favicon.svg', | ||||||
|   authDocUrl: 'https://automatisch.io/docs/apps/filter/connection', |   authDocUrl: '{DOCS_URL}/apps/filter/connection', | ||||||
|   supportsConnections: false, |   supportsConnections: false, | ||||||
|   baseUrl: '', |   baseUrl: '', | ||||||
|   apiBaseUrl: '', |   apiBaseUrl: '', | ||||||
|   | |||||||
| @@ -8,7 +8,7 @@ export default defineApp({ | |||||||
|   name: 'Flickr', |   name: 'Flickr', | ||||||
|   key: 'flickr', |   key: 'flickr', | ||||||
|   iconUrl: '{BASE_URL}/apps/flickr/assets/favicon.svg', |   iconUrl: '{BASE_URL}/apps/flickr/assets/favicon.svg', | ||||||
|   authDocUrl: 'https://automatisch.io/docs/apps/flickr/connection', |   authDocUrl: '{DOCS_URL}/apps/flickr/connection', | ||||||
|   docUrl: 'https://automatisch.io/docs/flickr', |   docUrl: 'https://automatisch.io/docs/flickr', | ||||||
|   primaryColor: '000000', |   primaryColor: '000000', | ||||||
|   supportsConnections: true, |   supportsConnections: true, | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ export default defineApp({ | |||||||
|   name: 'Flowers Software', |   name: 'Flowers Software', | ||||||
|   key: 'flowers-software', |   key: 'flowers-software', | ||||||
|   iconUrl: '{BASE_URL}/apps/flowers-software/assets/favicon.svg', |   iconUrl: '{BASE_URL}/apps/flowers-software/assets/favicon.svg', | ||||||
|   authDocUrl: 'https://automatisch.io/docs/apps/flowers-software/connection', |   authDocUrl: '{DOCS_URL}/apps/flowers-software/connection', | ||||||
|   supportsConnections: true, |   supportsConnections: true, | ||||||
|   baseUrl: 'https://flowers-software.com', |   baseUrl: 'https://flowers-software.com', | ||||||
|   apiBaseUrl: 'https://webapp.flowers-software.com/api', |   apiBaseUrl: 'https://webapp.flowers-software.com/api', | ||||||
|   | |||||||
| @@ -2,6 +2,7 @@ import defineAction from '../../../../helpers/define-action.js'; | |||||||
|  |  | ||||||
| import base64ToString from './transformers/base64-to-string.js'; | import base64ToString from './transformers/base64-to-string.js'; | ||||||
| import capitalize from './transformers/capitalize.js'; | import capitalize from './transformers/capitalize.js'; | ||||||
|  | import encodeUriComponent from './transformers/encode-uri-component.js'; | ||||||
| import extractEmailAddress from './transformers/extract-email-address.js'; | import extractEmailAddress from './transformers/extract-email-address.js'; | ||||||
| import extractNumber from './transformers/extract-number.js'; | import extractNumber from './transformers/extract-number.js'; | ||||||
| import htmlToMarkdown from './transformers/html-to-markdown.js'; | import htmlToMarkdown from './transformers/html-to-markdown.js'; | ||||||
| @@ -10,12 +11,14 @@ import markdownToHtml from './transformers/markdown-to-html.js'; | |||||||
| import pluralize from './transformers/pluralize.js'; | import pluralize from './transformers/pluralize.js'; | ||||||
| import replace from './transformers/replace.js'; | import replace from './transformers/replace.js'; | ||||||
| import stringToBase64 from './transformers/string-to-base64.js'; | import stringToBase64 from './transformers/string-to-base64.js'; | ||||||
|  | import encodeUri from './transformers/encode-uri.js'; | ||||||
| import trimWhitespace from './transformers/trim-whitespace.js'; | import trimWhitespace from './transformers/trim-whitespace.js'; | ||||||
| import useDefaultValue from './transformers/use-default-value.js'; | import useDefaultValue from './transformers/use-default-value.js'; | ||||||
|  |  | ||||||
| const transformers = { | const transformers = { | ||||||
|   base64ToString, |   base64ToString, | ||||||
|   capitalize, |   capitalize, | ||||||
|  |   encodeUriComponent, | ||||||
|   extractEmailAddress, |   extractEmailAddress, | ||||||
|   extractNumber, |   extractNumber, | ||||||
|   htmlToMarkdown, |   htmlToMarkdown, | ||||||
| @@ -24,6 +27,7 @@ const transformers = { | |||||||
|   pluralize, |   pluralize, | ||||||
|   replace, |   replace, | ||||||
|   stringToBase64, |   stringToBase64, | ||||||
|  |   encodeUri, | ||||||
|   trimWhitespace, |   trimWhitespace, | ||||||
|   useDefaultValue, |   useDefaultValue, | ||||||
| }; | }; | ||||||
| @@ -43,6 +47,10 @@ export default defineAction({ | |||||||
|       options: [ |       options: [ | ||||||
|         { label: 'Base64 to String', value: 'base64ToString' }, |         { label: 'Base64 to String', value: 'base64ToString' }, | ||||||
|         { label: 'Capitalize', value: 'capitalize' }, |         { label: 'Capitalize', value: 'capitalize' }, | ||||||
|  |         { | ||||||
|  |           label: 'Encode URI Component', | ||||||
|  |           value: 'encodeUriComponent', | ||||||
|  |         }, | ||||||
|         { label: 'Convert HTML to Markdown', value: 'htmlToMarkdown' }, |         { label: 'Convert HTML to Markdown', value: 'htmlToMarkdown' }, | ||||||
|         { label: 'Convert Markdown to HTML', value: 'markdownToHtml' }, |         { label: 'Convert Markdown to HTML', value: 'markdownToHtml' }, | ||||||
|         { label: 'Extract Email Address', value: 'extractEmailAddress' }, |         { label: 'Extract Email Address', value: 'extractEmailAddress' }, | ||||||
| @@ -51,6 +59,7 @@ export default defineAction({ | |||||||
|         { label: 'Pluralize', value: 'pluralize' }, |         { label: 'Pluralize', value: 'pluralize' }, | ||||||
|         { label: 'Replace', value: 'replace' }, |         { label: 'Replace', value: 'replace' }, | ||||||
|         { label: 'String to Base64', value: 'stringToBase64' }, |         { label: 'String to Base64', value: 'stringToBase64' }, | ||||||
|  |         { label: 'Encode URI', value: 'encodeUri' }, | ||||||
|         { label: 'Trim Whitespace', value: 'trimWhitespace' }, |         { label: 'Trim Whitespace', value: 'trimWhitespace' }, | ||||||
|         { label: 'Use Default Value', value: 'useDefaultValue' }, |         { label: 'Use Default Value', value: 'useDefaultValue' }, | ||||||
|       ], |       ], | ||||||
|   | |||||||
| @@ -0,0 +1,8 @@ | |||||||
|  | const encodeUriComponent = ($) => { | ||||||
|  |   const input = $.step.parameters.input; | ||||||
|  |   const encodedString = encodeURIComponent(input); | ||||||
|  |  | ||||||
|  |   return encodedString; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | export default encodeUriComponent; | ||||||
| @@ -0,0 +1,8 @@ | |||||||
|  | const encodeUri = ($) => { | ||||||
|  |   const input = $.step.parameters.input; | ||||||
|  |   const encodedString = encodeURI(input); | ||||||
|  |  | ||||||
|  |   return encodedString; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | export default encodeUri; | ||||||
| @@ -1,5 +1,6 @@ | |||||||
| import base64ToString from './text/base64-to-string.js'; | import base64ToString from './text/base64-to-string.js'; | ||||||
| import capitalize from './text/capitalize.js'; | import capitalize from './text/capitalize.js'; | ||||||
|  | import encodeUriComponent from './text/encode-uri-component.js'; | ||||||
| import extractEmailAddress from './text/extract-email-address.js'; | import extractEmailAddress from './text/extract-email-address.js'; | ||||||
| import extractNumber from './text/extract-number.js'; | import extractNumber from './text/extract-number.js'; | ||||||
| import htmlToMarkdown from './text/html-to-markdown.js'; | import htmlToMarkdown from './text/html-to-markdown.js'; | ||||||
| @@ -8,6 +9,7 @@ import markdownToHtml from './text/markdown-to-html.js'; | |||||||
| import pluralize from './text/pluralize.js'; | import pluralize from './text/pluralize.js'; | ||||||
| import replace from './text/replace.js'; | import replace from './text/replace.js'; | ||||||
| import stringToBase64 from './text/string-to-base64.js'; | import stringToBase64 from './text/string-to-base64.js'; | ||||||
|  | import encodeUri from './text/encode-uri.js'; | ||||||
| import trimWhitespace from './text/trim-whitespace.js'; | import trimWhitespace from './text/trim-whitespace.js'; | ||||||
| import useDefaultValue from './text/use-default-value.js'; | import useDefaultValue from './text/use-default-value.js'; | ||||||
| import performMathOperation from './numbers/perform-math-operation.js'; | import performMathOperation from './numbers/perform-math-operation.js'; | ||||||
| @@ -19,6 +21,7 @@ import formatDateTime from './date-time/format-date-time.js'; | |||||||
| const options = { | const options = { | ||||||
|   base64ToString, |   base64ToString, | ||||||
|   capitalize, |   capitalize, | ||||||
|  |   encodeUriComponent, | ||||||
|   extractEmailAddress, |   extractEmailAddress, | ||||||
|   extractNumber, |   extractNumber, | ||||||
|   htmlToMarkdown, |   htmlToMarkdown, | ||||||
| @@ -27,6 +30,7 @@ const options = { | |||||||
|   pluralize, |   pluralize, | ||||||
|   replace, |   replace, | ||||||
|   stringToBase64, |   stringToBase64, | ||||||
|  |   encodeUri, | ||||||
|   trimWhitespace, |   trimWhitespace, | ||||||
|   useDefaultValue, |   useDefaultValue, | ||||||
|   performMathOperation, |   performMathOperation, | ||||||
|   | |||||||
| @@ -0,0 +1,12 @@ | |||||||
|  | const encodeUriComponent = [ | ||||||
|  |   { | ||||||
|  |     label: 'Input', | ||||||
|  |     key: 'input', | ||||||
|  |     type: 'string', | ||||||
|  |     required: true, | ||||||
|  |     description: 'URI Component to encode', | ||||||
|  |     variables: true, | ||||||
|  |   }, | ||||||
|  | ]; | ||||||
|  |  | ||||||
|  | export default encodeUriComponent; | ||||||
| @@ -0,0 +1,12 @@ | |||||||
|  | const encodeUri = [ | ||||||
|  |   { | ||||||
|  |     label: 'Input', | ||||||
|  |     key: 'input', | ||||||
|  |     type: 'string', | ||||||
|  |     required: true, | ||||||
|  |     description: 'URI to encode', | ||||||
|  |     variables: true, | ||||||
|  |   }, | ||||||
|  | ]; | ||||||
|  |  | ||||||
|  | export default encodeUri; | ||||||
| @@ -6,7 +6,7 @@ export default defineApp({ | |||||||
|   name: 'Formatter', |   name: 'Formatter', | ||||||
|   key: 'formatter', |   key: 'formatter', | ||||||
|   iconUrl: '{BASE_URL}/apps/formatter/assets/favicon.svg', |   iconUrl: '{BASE_URL}/apps/formatter/assets/favicon.svg', | ||||||
|   authDocUrl: 'https://automatisch.io/docs/apps/formatter/connection', |   authDocUrl: '{DOCS_URL}/apps/formatter/connection', | ||||||
|   supportsConnections: false, |   supportsConnections: false, | ||||||
|   baseUrl: '', |   baseUrl: '', | ||||||
|   apiBaseUrl: '', |   apiBaseUrl: '', | ||||||
|   | |||||||
| @@ -10,7 +10,7 @@ export default defineApp({ | |||||||
|   baseUrl: 'https://ghost.org', |   baseUrl: 'https://ghost.org', | ||||||
|   apiBaseUrl: '', |   apiBaseUrl: '', | ||||||
|   iconUrl: '{BASE_URL}/apps/ghost/assets/favicon.svg', |   iconUrl: '{BASE_URL}/apps/ghost/assets/favicon.svg', | ||||||
|   authDocUrl: 'https://automatisch.io/docs/apps/ghost/connection', |   authDocUrl: '{DOCS_URL}/apps/ghost/connection', | ||||||
|   primaryColor: '15171A', |   primaryColor: '15171A', | ||||||
|   supportsConnections: true, |   supportsConnections: true, | ||||||
|   beforeRequest: [setBaseUrl, addAuthHeader], |   beforeRequest: [setBaseUrl, addAuthHeader], | ||||||
|   | |||||||
| @@ -11,7 +11,7 @@ export default defineApp({ | |||||||
|   baseUrl: 'https://github.com', |   baseUrl: 'https://github.com', | ||||||
|   apiBaseUrl: 'https://api.github.com', |   apiBaseUrl: 'https://api.github.com', | ||||||
|   iconUrl: '{BASE_URL}/apps/github/assets/favicon.svg', |   iconUrl: '{BASE_URL}/apps/github/assets/favicon.svg', | ||||||
|   authDocUrl: 'https://automatisch.io/docs/apps/github/connection', |   authDocUrl: '{DOCS_URL}/apps/github/connection', | ||||||
|   primaryColor: '000000', |   primaryColor: '000000', | ||||||
|   supportsConnections: true, |   supportsConnections: true, | ||||||
|   beforeRequest: [addAuthHeader], |   beforeRequest: [addAuthHeader], | ||||||
|   | |||||||
| @@ -11,7 +11,7 @@ export default defineApp({ | |||||||
|   baseUrl: 'https://gitlab.com', |   baseUrl: 'https://gitlab.com', | ||||||
|   apiBaseUrl: 'https://gitlab.com', |   apiBaseUrl: 'https://gitlab.com', | ||||||
|   iconUrl: '{BASE_URL}/apps/gitlab/assets/favicon.svg', |   iconUrl: '{BASE_URL}/apps/gitlab/assets/favicon.svg', | ||||||
|   authDocUrl: 'https://automatisch.io/docs/apps/gitlab/connection', |   authDocUrl: '{DOCS_URL}/apps/gitlab/connection', | ||||||
|   primaryColor: 'FC6D26', |   primaryColor: 'FC6D26', | ||||||
|   supportsConnections: true, |   supportsConnections: true, | ||||||
|   beforeRequest: [setBaseUrl, addAuthHeader], |   beforeRequest: [setBaseUrl, addAuthHeader], | ||||||
|   | |||||||
| @@ -10,7 +10,7 @@ export default defineApp({ | |||||||
|   baseUrl: 'https://calendar.google.com', |   baseUrl: 'https://calendar.google.com', | ||||||
|   apiBaseUrl: 'https://www.googleapis.com/calendar', |   apiBaseUrl: 'https://www.googleapis.com/calendar', | ||||||
|   iconUrl: '{BASE_URL}/apps/google-calendar/assets/favicon.svg', |   iconUrl: '{BASE_URL}/apps/google-calendar/assets/favicon.svg', | ||||||
|   authDocUrl: 'https://automatisch.io/docs/apps/google-calendar/connection', |   authDocUrl: '{DOCS_URL}/apps/google-calendar/connection', | ||||||
|   primaryColor: '448AFF', |   primaryColor: '448AFF', | ||||||
|   supportsConnections: true, |   supportsConnections: true, | ||||||
|   beforeRequest: [addAuthHeader], |   beforeRequest: [addAuthHeader], | ||||||
|   | |||||||
| @@ -10,7 +10,7 @@ export default defineApp({ | |||||||
|   baseUrl: 'https://drive.google.com', |   baseUrl: 'https://drive.google.com', | ||||||
|   apiBaseUrl: 'https://www.googleapis.com/drive', |   apiBaseUrl: 'https://www.googleapis.com/drive', | ||||||
|   iconUrl: '{BASE_URL}/apps/google-drive/assets/favicon.svg', |   iconUrl: '{BASE_URL}/apps/google-drive/assets/favicon.svg', | ||||||
|   authDocUrl: 'https://automatisch.io/docs/apps/google-drive/connection', |   authDocUrl: '{DOCS_URL}/apps/google-drive/connection', | ||||||
|   primaryColor: '1FA463', |   primaryColor: '1FA463', | ||||||
|   supportsConnections: true, |   supportsConnections: true, | ||||||
|   beforeRequest: [addAuthHeader], |   beforeRequest: [addAuthHeader], | ||||||
|   | |||||||
| @@ -10,7 +10,7 @@ export default defineApp({ | |||||||
|   baseUrl: 'https://docs.google.com/forms', |   baseUrl: 'https://docs.google.com/forms', | ||||||
|   apiBaseUrl: 'https://forms.googleapis.com', |   apiBaseUrl: 'https://forms.googleapis.com', | ||||||
|   iconUrl: '{BASE_URL}/apps/google-forms/assets/favicon.svg', |   iconUrl: '{BASE_URL}/apps/google-forms/assets/favicon.svg', | ||||||
|   authDocUrl: 'https://automatisch.io/docs/apps/google-forms/connection', |   authDocUrl: '{DOCS_URL}/apps/google-forms/connection', | ||||||
|   primaryColor: '673AB7', |   primaryColor: '673AB7', | ||||||
|   supportsConnections: true, |   supportsConnections: true, | ||||||
|   beforeRequest: [addAuthHeader], |   beforeRequest: [addAuthHeader], | ||||||
|   | |||||||
| @@ -12,7 +12,7 @@ export default defineApp({ | |||||||
|   baseUrl: 'https://docs.google.com/spreadsheets', |   baseUrl: 'https://docs.google.com/spreadsheets', | ||||||
|   apiBaseUrl: 'https://sheets.googleapis.com', |   apiBaseUrl: 'https://sheets.googleapis.com', | ||||||
|   iconUrl: '{BASE_URL}/apps/google-sheets/assets/favicon.svg', |   iconUrl: '{BASE_URL}/apps/google-sheets/assets/favicon.svg', | ||||||
|   authDocUrl: 'https://automatisch.io/docs/apps/google-sheets/connection', |   authDocUrl: '{DOCS_URL}/apps/google-sheets/connection', | ||||||
|   primaryColor: '0F9D58', |   primaryColor: '0F9D58', | ||||||
|   supportsConnections: true, |   supportsConnections: true, | ||||||
|   beforeRequest: [addAuthHeader], |   beforeRequest: [addAuthHeader], | ||||||
|   | |||||||
| @@ -0,0 +1,31 @@ | |||||||
|  | import defineAction from '../../../../helpers/define-action.js'; | ||||||
|  |  | ||||||
|  | export default defineAction({ | ||||||
|  |   name: 'Create task list', | ||||||
|  |   key: 'createTaskList', | ||||||
|  |   description: 'Creates a new task list.', | ||||||
|  |   arguments: [ | ||||||
|  |     { | ||||||
|  |       label: 'List Title', | ||||||
|  |       key: 'listTitle', | ||||||
|  |       type: 'string', | ||||||
|  |       required: true, | ||||||
|  |       description: '', | ||||||
|  |       variables: true, | ||||||
|  |     }, | ||||||
|  |   ], | ||||||
|  |  | ||||||
|  |   async run($) { | ||||||
|  |     const listTitle = $.step.parameters.listTitle; | ||||||
|  |  | ||||||
|  |     const body = { | ||||||
|  |       title: listTitle, | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     const { data } = await $.http.post('/tasks/v1/users/@me/lists', body); | ||||||
|  |  | ||||||
|  |     $.setActionItem({ | ||||||
|  |       raw: data, | ||||||
|  |     }); | ||||||
|  |   }, | ||||||
|  | }); | ||||||
| @@ -0,0 +1,70 @@ | |||||||
|  | import defineAction from '../../../../helpers/define-action.js'; | ||||||
|  |  | ||||||
|  | export default defineAction({ | ||||||
|  |   name: 'Create task', | ||||||
|  |   key: 'createTask', | ||||||
|  |   description: 'Creates a new task.', | ||||||
|  |   arguments: [ | ||||||
|  |     { | ||||||
|  |       label: 'Task List', | ||||||
|  |       key: 'taskListId', | ||||||
|  |       type: 'dropdown', | ||||||
|  |       required: true, | ||||||
|  |       description: '', | ||||||
|  |       variables: true, | ||||||
|  |       source: { | ||||||
|  |         type: 'query', | ||||||
|  |         name: 'getDynamicData', | ||||||
|  |         arguments: [ | ||||||
|  |           { | ||||||
|  |             name: 'key', | ||||||
|  |             value: 'listTaskLists', | ||||||
|  |           }, | ||||||
|  |         ], | ||||||
|  |       }, | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       label: 'Title', | ||||||
|  |       key: 'title', | ||||||
|  |       type: 'string', | ||||||
|  |       required: true, | ||||||
|  |       description: '', | ||||||
|  |       variables: true, | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       label: 'Notes', | ||||||
|  |       key: 'notes', | ||||||
|  |       type: 'string', | ||||||
|  |       required: false, | ||||||
|  |       description: '', | ||||||
|  |       variables: true, | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       label: 'Due Date', | ||||||
|  |       key: 'due', | ||||||
|  |       type: 'string', | ||||||
|  |       required: false, | ||||||
|  |       description: 'RFC 3339 timestamp.', | ||||||
|  |       variables: true, | ||||||
|  |     }, | ||||||
|  |   ], | ||||||
|  |  | ||||||
|  |   async run($) { | ||||||
|  |     const { taskListId, title, notes, due } = $.step.parameters; | ||||||
|  |  | ||||||
|  |     const body = { | ||||||
|  |       title, | ||||||
|  |       notes, | ||||||
|  |       due, | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     const { data } = await $.http.post( | ||||||
|  |       `/tasks/v1/lists/${taskListId}/tasks`, | ||||||
|  |       body | ||||||
|  |     ); | ||||||
|  |  | ||||||
|  |     $.setActionItem({ | ||||||
|  |       raw: data, | ||||||
|  |     }); | ||||||
|  |   }, | ||||||
|  | }); | ||||||
| @@ -0,0 +1,57 @@ | |||||||
|  | import defineAction from '../../../../helpers/define-action.js'; | ||||||
|  |  | ||||||
|  | export default defineAction({ | ||||||
|  |   name: 'Find task', | ||||||
|  |   key: 'findTask', | ||||||
|  |   description: 'Looking for a specific task.', | ||||||
|  |   arguments: [ | ||||||
|  |     { | ||||||
|  |       label: 'Task List', | ||||||
|  |       key: 'taskListId', | ||||||
|  |       type: 'dropdown', | ||||||
|  |       required: true, | ||||||
|  |       description: 'The list to be searched.', | ||||||
|  |       variables: true, | ||||||
|  |       source: { | ||||||
|  |         type: 'query', | ||||||
|  |         name: 'getDynamicData', | ||||||
|  |         arguments: [ | ||||||
|  |           { | ||||||
|  |             name: 'key', | ||||||
|  |             value: 'listTaskLists', | ||||||
|  |           }, | ||||||
|  |         ], | ||||||
|  |       }, | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       label: 'Title', | ||||||
|  |       key: 'title', | ||||||
|  |       type: 'string', | ||||||
|  |       required: true, | ||||||
|  |       description: '', | ||||||
|  |       variables: true, | ||||||
|  |     }, | ||||||
|  |   ], | ||||||
|  |  | ||||||
|  |   async run($) { | ||||||
|  |     const taskListId = $.step.parameters.taskListId; | ||||||
|  |     const title = $.step.parameters.title; | ||||||
|  |  | ||||||
|  |     const params = { | ||||||
|  |       showCompleted: true, | ||||||
|  |       showHidden: true, | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     const { data } = await $.http.get(`/tasks/v1/lists/${taskListId}/tasks`, { | ||||||
|  |       params, | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     const filteredTask = data.items?.filter((task) => | ||||||
|  |       task.title.includes(title) | ||||||
|  |     ); | ||||||
|  |  | ||||||
|  |     $.setActionItem({ | ||||||
|  |       raw: filteredTask[0], | ||||||
|  |     }); | ||||||
|  |   }, | ||||||
|  | }); | ||||||
							
								
								
									
										6
									
								
								packages/backend/src/apps/google-tasks/actions/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								packages/backend/src/apps/google-tasks/actions/index.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | |||||||
|  | import createTask from './create-task/index.js'; | ||||||
|  | import createTaskList from './create-task-list/index.js'; | ||||||
|  | import findTask from './find-task/index.js'; | ||||||
|  | import updateTask from './update-task/index.js'; | ||||||
|  |  | ||||||
|  | export default [createTask, createTaskList, findTask, updateTask]; | ||||||
| @@ -0,0 +1,108 @@ | |||||||
|  | import defineAction from '../../../../helpers/define-action.js'; | ||||||
|  |  | ||||||
|  | export default defineAction({ | ||||||
|  |   name: 'Update task', | ||||||
|  |   key: 'updateTask', | ||||||
|  |   description: 'Updates an existing task.', | ||||||
|  |   arguments: [ | ||||||
|  |     { | ||||||
|  |       label: 'Task List', | ||||||
|  |       key: 'taskListId', | ||||||
|  |       type: 'dropdown', | ||||||
|  |       required: true, | ||||||
|  |       description: '', | ||||||
|  |       variables: true, | ||||||
|  |       source: { | ||||||
|  |         type: 'query', | ||||||
|  |         name: 'getDynamicData', | ||||||
|  |         arguments: [ | ||||||
|  |           { | ||||||
|  |             name: 'key', | ||||||
|  |             value: 'listTaskLists', | ||||||
|  |           }, | ||||||
|  |         ], | ||||||
|  |       }, | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       label: 'Task', | ||||||
|  |       key: 'taskId', | ||||||
|  |       type: 'dropdown', | ||||||
|  |       required: true, | ||||||
|  |       description: 'Ensure that you choose a list before proceeding.', | ||||||
|  |       variables: true, | ||||||
|  |       dependsOn: ['parameters.taskListId'], | ||||||
|  |       source: { | ||||||
|  |         type: 'query', | ||||||
|  |         name: 'getDynamicData', | ||||||
|  |         arguments: [ | ||||||
|  |           { | ||||||
|  |             name: 'key', | ||||||
|  |             value: 'listTasks', | ||||||
|  |           }, | ||||||
|  |           { | ||||||
|  |             name: 'parameters.taskListId', | ||||||
|  |             value: '{parameters.taskListId}', | ||||||
|  |           }, | ||||||
|  |         ], | ||||||
|  |       }, | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       label: 'Title', | ||||||
|  |       key: 'title', | ||||||
|  |       type: 'string', | ||||||
|  |       required: false, | ||||||
|  |       description: 'Provide a new title for the revised task.', | ||||||
|  |       variables: true, | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       label: 'Status', | ||||||
|  |       key: 'status', | ||||||
|  |       type: 'dropdown', | ||||||
|  |       required: false, | ||||||
|  |       description: | ||||||
|  |         'Specify the status of the updated task. If you opt for a custom value, enter either "needsAttention" or "completed."', | ||||||
|  |       variables: true, | ||||||
|  |       options: [ | ||||||
|  |         { label: 'Incomplete', value: 'needsAction' }, | ||||||
|  |         { label: 'Complete', value: 'completed' }, | ||||||
|  |       ], | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       label: 'Notes', | ||||||
|  |       key: 'notes', | ||||||
|  |       type: 'string', | ||||||
|  |       required: false, | ||||||
|  |       description: 'Provide a note for the revised task.', | ||||||
|  |       variables: true, | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       label: 'Due Date', | ||||||
|  |       key: 'due', | ||||||
|  |       type: 'string', | ||||||
|  |       required: false, | ||||||
|  |       description: | ||||||
|  |         'Specify the deadline for the task (as a RFC 3339 timestamp).', | ||||||
|  |       variables: true, | ||||||
|  |     }, | ||||||
|  |   ], | ||||||
|  |  | ||||||
|  |   async run($) { | ||||||
|  |     const { taskListId, taskId, title, status, notes, due } = $.step.parameters; | ||||||
|  |  | ||||||
|  |     const body = { | ||||||
|  |       title, | ||||||
|  |       status, | ||||||
|  |       notes, | ||||||
|  |       due, | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     const { data } = await $.http.patch( | ||||||
|  |       `/tasks/v1/lists/${taskListId}/tasks/${taskId}`, | ||||||
|  |       body | ||||||
|  |     ); | ||||||
|  |  | ||||||
|  |     $.setActionItem({ | ||||||
|  |       raw: data, | ||||||
|  |     }); | ||||||
|  |   }, | ||||||
|  | }); | ||||||
							
								
								
									
										16
									
								
								packages/backend/src/apps/google-tasks/assets/favicon.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								packages/backend/src/apps/google-tasks/assets/favicon.svg
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | |||||||
|  | <?xml version="1.0" encoding="utf-8"?> | ||||||
|  | <svg version="1.1" | ||||||
|  | 	 id="svg8849" inkscape:version="1.1 (c68e22c387, 2021-05-23)" sodipodi:docname="google tasks.svg" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:svg="http://www.w3.org/2000/svg" | ||||||
|  | 	 xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="527.1px" height="500px" | ||||||
|  | 	 viewBox="0 0 527.1 500" enable-background="new 0 0 527.1 500" xml:space="preserve"> | ||||||
|  | <sodipodi:namedview  bordercolor="#eeeeee" borderopacity="1" id="namedview8851" inkscape:bbox-nodes="true" inkscape:bbox-paths="true" inkscape:current-layer="layer1" inkscape:cx="280.62992" inkscape:cy="277.14384" inkscape:document-units="mm" inkscape:object-paths="true" inkscape:pagecheckerboard="0" inkscape:pageopacity="0" inkscape:pageshadow="0" inkscape:snap-bbox="true" inkscape:snap-bbox-edge-midpoints="true" inkscape:snap-bbox-midpoints="true" inkscape:snap-center="true" inkscape:snap-global="true" inkscape:snap-intersection-paths="true" inkscape:snap-midpoints="true" inkscape:snap-object-midpoints="true" inkscape:snap-page="true" inkscape:snap-smooth-nodes="true" inkscape:snap-text-baseline="true" inkscape:window-height="1009" inkscape:window-maximized="1" inkscape:window-width="1920" inkscape:window-x="1912" inkscape:window-y="760" inkscape:zoom="1.4342733" pagecolor="#505050" showgrid="false" units="px"> | ||||||
|  | 	</sodipodi:namedview> | ||||||
|  | <g> | ||||||
|  | 	<polygon fill="#0066DA" points="410.4,58.3 368.8,81.2 348.2,120.6 368.8,168.8 407.8,211 450,187.5 475.9,142.8 450,87.5 	"/> | ||||||
|  | 	<path fill="#2684FC" d="M249.3,219.4l98.9-98.9c29.1,22.1,50.5,53.8,59.6,90.4L272.1,346.7c-12.2,12.2-32,12.2-44.2,0l-91.5-91.5 | ||||||
|  | 		c-9.8-9.8-9.8-25.6,0-35.3l39-39c9.8-9.8,25.6-9.8,35.3,0L249.3,219.4z M519.8,63.6l-39.7-39.7c-9.7-9.7-25.6-9.7-35.3,0 | ||||||
|  | 		l-34.4,34.4c27.5,23,49.9,51.8,65.5,84.5l43.9-43.9C529.6,89.2,529.6,73.3,519.8,63.6z M412.5,250c0,89.8-72.8,162.5-162.5,162.5 | ||||||
|  | 		S87.5,339.8,87.5,250S160.2,87.5,250,87.5c36.9,0,70.9,12.3,98.2,33.1l62.2-62.2C367,21.9,311.1,0,250,0C111.9,0,0,111.9,0,250 | ||||||
|  | 		s111.9,250,250,250s250-111.9,250-250c0-38.3-8.7-74.7-24.1-107.2L407.8,211C410.8,223.5,412.5,236.6,412.5,250z"/> | ||||||
|  | </g> | ||||||
|  | </svg> | ||||||
| After Width: | Height: | Size: 2.2 KiB | 
| @@ -0,0 +1,23 @@ | |||||||
|  | import { URLSearchParams } from 'url'; | ||||||
|  | import authScope from '../common/auth-scope.js'; | ||||||
|  |  | ||||||
|  | export default async function generateAuthUrl($) { | ||||||
|  |   const oauthRedirectUrlField = $.app.auth.fields.find( | ||||||
|  |     (field) => field.key == 'oAuthRedirectUrl' | ||||||
|  |   ); | ||||||
|  |   const redirectUri = oauthRedirectUrlField.value; | ||||||
|  |   const searchParams = new URLSearchParams({ | ||||||
|  |     client_id: $.auth.data.clientId, | ||||||
|  |     redirect_uri: redirectUri, | ||||||
|  |     prompt: 'select_account', | ||||||
|  |     scope: authScope.join(' '), | ||||||
|  |     response_type: 'code', | ||||||
|  |     access_type: 'offline', | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   const url = `https://accounts.google.com/o/oauth2/v2/auth?${searchParams.toString()}`; | ||||||
|  |  | ||||||
|  |   await $.auth.set({ | ||||||
|  |     url, | ||||||
|  |   }); | ||||||
|  | } | ||||||
							
								
								
									
										48
									
								
								packages/backend/src/apps/google-tasks/auth/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								packages/backend/src/apps/google-tasks/auth/index.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,48 @@ | |||||||
|  | import generateAuthUrl from './generate-auth-url.js'; | ||||||
|  | import verifyCredentials from './verify-credentials.js'; | ||||||
|  | import refreshToken from './refresh-token.js'; | ||||||
|  | import isStillVerified from './is-still-verified.js'; | ||||||
|  |  | ||||||
|  | export default { | ||||||
|  |   fields: [ | ||||||
|  |     { | ||||||
|  |       key: 'oAuthRedirectUrl', | ||||||
|  |       label: 'OAuth Redirect URL', | ||||||
|  |       type: 'string', | ||||||
|  |       required: true, | ||||||
|  |       readOnly: true, | ||||||
|  |       value: '{WEB_APP_URL}/app/google-tasks/connections/add', | ||||||
|  |       placeholder: null, | ||||||
|  |       description: | ||||||
|  |         'When asked to input a redirect URL in Google Cloud, enter the URL above.', | ||||||
|  |       clickToCopy: true, | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       key: 'clientId', | ||||||
|  |       label: 'Client ID', | ||||||
|  |       type: 'string', | ||||||
|  |       required: true, | ||||||
|  |       readOnly: false, | ||||||
|  |       value: null, | ||||||
|  |       placeholder: null, | ||||||
|  |       description: null, | ||||||
|  |       clickToCopy: false, | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       key: 'clientSecret', | ||||||
|  |       label: 'Client Secret', | ||||||
|  |       type: 'string', | ||||||
|  |       required: true, | ||||||
|  |       readOnly: false, | ||||||
|  |       value: null, | ||||||
|  |       placeholder: null, | ||||||
|  |       description: null, | ||||||
|  |       clickToCopy: false, | ||||||
|  |     }, | ||||||
|  |   ], | ||||||
|  |  | ||||||
|  |   generateAuthUrl, | ||||||
|  |   verifyCredentials, | ||||||
|  |   isStillVerified, | ||||||
|  |   refreshToken, | ||||||
|  | }; | ||||||
| @@ -0,0 +1,8 @@ | |||||||
|  | import getCurrentUser from '../common/get-current-user.js'; | ||||||
|  |  | ||||||
|  | const isStillVerified = async ($) => { | ||||||
|  |   const currentUser = await getCurrentUser($); | ||||||
|  |   return !!currentUser.resourceName; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | export default isStillVerified; | ||||||
							
								
								
									
										25
									
								
								packages/backend/src/apps/google-tasks/auth/refresh-token.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								packages/backend/src/apps/google-tasks/auth/refresh-token.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | |||||||
|  | import { URLSearchParams } from 'node:url'; | ||||||
|  | import authScope from '../common/auth-scope.js'; | ||||||
|  |  | ||||||
|  | const refreshToken = async ($) => { | ||||||
|  |   const params = new URLSearchParams({ | ||||||
|  |     client_id: $.auth.data.clientId, | ||||||
|  |     client_secret: $.auth.data.clientSecret, | ||||||
|  |     grant_type: 'refresh_token', | ||||||
|  |     refresh_token: $.auth.data.refreshToken, | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   const { data } = await $.http.post( | ||||||
|  |     'https://oauth2.googleapis.com/token', | ||||||
|  |     params.toString() | ||||||
|  |   ); | ||||||
|  |  | ||||||
|  |   await $.auth.set({ | ||||||
|  |     accessToken: data.access_token, | ||||||
|  |     expiresIn: data.expires_in, | ||||||
|  |     scope: authScope.join(' '), | ||||||
|  |     tokenType: data.token_type, | ||||||
|  |   }); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | export default refreshToken; | ||||||
| @@ -0,0 +1,42 @@ | |||||||
|  | import getCurrentUser from '../common/get-current-user.js'; | ||||||
|  |  | ||||||
|  | const verifyCredentials = async ($) => { | ||||||
|  |   const oauthRedirectUrlField = $.app.auth.fields.find( | ||||||
|  |     (field) => field.key == 'oAuthRedirectUrl' | ||||||
|  |   ); | ||||||
|  |   const redirectUri = oauthRedirectUrlField.value; | ||||||
|  |   const { data } = await $.http.post(`https://oauth2.googleapis.com/token`, { | ||||||
|  |     client_id: $.auth.data.clientId, | ||||||
|  |     client_secret: $.auth.data.clientSecret, | ||||||
|  |     code: $.auth.data.code, | ||||||
|  |     grant_type: 'authorization_code', | ||||||
|  |     redirect_uri: redirectUri, | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   await $.auth.set({ | ||||||
|  |     accessToken: data.access_token, | ||||||
|  |     tokenType: data.token_type, | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   const currentUser = await getCurrentUser($); | ||||||
|  |  | ||||||
|  |   const { displayName } = currentUser.names.find( | ||||||
|  |     (name) => name.metadata.primary | ||||||
|  |   ); | ||||||
|  |   const { value: email } = currentUser.emailAddresses.find( | ||||||
|  |     (emailAddress) => emailAddress.metadata.primary | ||||||
|  |   ); | ||||||
|  |  | ||||||
|  |   await $.auth.set({ | ||||||
|  |     clientId: $.auth.data.clientId, | ||||||
|  |     clientSecret: $.auth.data.clientSecret, | ||||||
|  |     scope: $.auth.data.scope, | ||||||
|  |     idToken: data.id_token, | ||||||
|  |     expiresIn: data.expires_in, | ||||||
|  |     refreshToken: data.refresh_token, | ||||||
|  |     resourceName: currentUser.resourceName, | ||||||
|  |     screenName: `${displayName} - ${email}`, | ||||||
|  |   }); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | export default verifyCredentials; | ||||||
| @@ -0,0 +1,9 @@ | |||||||
|  | const addAuthHeader = ($, requestConfig) => { | ||||||
|  |   if ($.auth.data?.accessToken) { | ||||||
|  |     requestConfig.headers.Authorization = `${$.auth.data.tokenType} ${$.auth.data.accessToken}`; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return requestConfig; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | export default addAuthHeader; | ||||||
| @@ -0,0 +1,7 @@ | |||||||
|  | const authScope = [ | ||||||
|  |   'https://www.googleapis.com/auth/tasks', | ||||||
|  |   'https://www.googleapis.com/auth/userinfo.email', | ||||||
|  |   'https://www.googleapis.com/auth/userinfo.profile', | ||||||
|  | ]; | ||||||
|  |  | ||||||
|  | export default authScope; | ||||||
| @@ -0,0 +1,8 @@ | |||||||
|  | const getCurrentUser = async ($) => { | ||||||
|  |   const { data: currentUser } = await $.http.get( | ||||||
|  |     'https://people.googleapis.com/v1/people/me?personFields=names,emailAddresses' | ||||||
|  |   ); | ||||||
|  |   return currentUser; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | export default getCurrentUser; | ||||||
| @@ -0,0 +1,4 @@ | |||||||
|  | import listTaskLists from './list-task-lists/index.js'; | ||||||
|  | import listTasks from './list-tasks/index.js'; | ||||||
|  |  | ||||||
|  | export default [listTaskLists, listTasks]; | ||||||
| @@ -0,0 +1,33 @@ | |||||||
|  | export default { | ||||||
|  |   name: 'List task lists', | ||||||
|  |   key: 'listTaskLists', | ||||||
|  |  | ||||||
|  |   async run($) { | ||||||
|  |     const taskLists = { | ||||||
|  |       data: [], | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     const params = { | ||||||
|  |       maxResults: 100, | ||||||
|  |       pageToken: undefined, | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     do { | ||||||
|  |       const { data } = await $.http.get('/tasks/v1/users/@me/lists', { | ||||||
|  |         params, | ||||||
|  |       }); | ||||||
|  |       params.pageToken = data.nextPageToken; | ||||||
|  |  | ||||||
|  |       if (data.items) { | ||||||
|  |         for (const taskList of data.items) { | ||||||
|  |           taskLists.data.push({ | ||||||
|  |             value: taskList.id, | ||||||
|  |             name: taskList.title, | ||||||
|  |           }); | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } while (params.pageToken); | ||||||
|  |  | ||||||
|  |     return taskLists; | ||||||
|  |   }, | ||||||
|  | }; | ||||||
| @@ -0,0 +1,40 @@ | |||||||
|  | export default { | ||||||
|  |   name: 'List tasks', | ||||||
|  |   key: 'listTasks', | ||||||
|  |  | ||||||
|  |   async run($) { | ||||||
|  |     const tasks = { | ||||||
|  |       data: [], | ||||||
|  |     }; | ||||||
|  |     const taskListId = $.step.parameters.taskListId; | ||||||
|  |  | ||||||
|  |     const params = { | ||||||
|  |       maxResults: 100, | ||||||
|  |       pageToken: undefined, | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     if (!taskListId) { | ||||||
|  |       return tasks; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     do { | ||||||
|  |       const { data } = await $.http.get(`/tasks/v1/lists/${taskListId}/tasks`, { | ||||||
|  |         params, | ||||||
|  |       }); | ||||||
|  |       params.pageToken = data.nextPageToken; | ||||||
|  |  | ||||||
|  |       if (data.items) { | ||||||
|  |         for (const task of data.items) { | ||||||
|  |           if (task.title !== '') { | ||||||
|  |             tasks.data.push({ | ||||||
|  |               value: task.id, | ||||||
|  |               name: task.title, | ||||||
|  |             }); | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } while (params.pageToken); | ||||||
|  |  | ||||||
|  |     return tasks; | ||||||
|  |   }, | ||||||
|  | }; | ||||||
							
								
								
									
										22
									
								
								packages/backend/src/apps/google-tasks/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								packages/backend/src/apps/google-tasks/index.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | |||||||
|  | import defineApp from '../../helpers/define-app.js'; | ||||||
|  | import addAuthHeader from './common/add-auth-header.js'; | ||||||
|  | import auth from './auth/index.js'; | ||||||
|  | import actions from './actions/index.js'; | ||||||
|  | import triggers from './triggers/index.js'; | ||||||
|  | import dynamicData from './dynamic-data/index.js'; | ||||||
|  |  | ||||||
|  | export default defineApp({ | ||||||
|  |   name: 'Google Tasks', | ||||||
|  |   key: 'google-tasks', | ||||||
|  |   baseUrl: 'https://calendar.google.com/calendar/u/0/r/tasks', | ||||||
|  |   apiBaseUrl: 'https://tasks.googleapis.com', | ||||||
|  |   iconUrl: '{BASE_URL}/apps/google-tasks/assets/favicon.svg', | ||||||
|  |   authDocUrl: '{DOCS_URL}/apps/google-tasks/connection', | ||||||
|  |   primaryColor: '0066DA', | ||||||
|  |   supportsConnections: true, | ||||||
|  |   beforeRequest: [addAuthHeader], | ||||||
|  |   auth, | ||||||
|  |   actions, | ||||||
|  |   dynamicData, | ||||||
|  |   triggers, | ||||||
|  | }); | ||||||
							
								
								
									
										5
									
								
								packages/backend/src/apps/google-tasks/triggers/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								packages/backend/src/apps/google-tasks/triggers/index.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | |||||||
|  | import newCompletedTasks from './new-completed-tasks/index.js'; | ||||||
|  | import newTaskLists from './new-task-lists/index.js'; | ||||||
|  | import newTasks from './new-tasks/index.js'; | ||||||
|  |  | ||||||
|  | export default [newCompletedTasks, newTaskLists, newTasks]; | ||||||
| @@ -0,0 +1,59 @@ | |||||||
|  | import defineTrigger from '../../../../helpers/define-trigger.js'; | ||||||
|  |  | ||||||
|  | export default defineTrigger({ | ||||||
|  |   name: 'New completed tasks', | ||||||
|  |   key: 'newCompletedTasks', | ||||||
|  |   pollInterval: 15, | ||||||
|  |   description: 'Triggers when a task is finished within a specified task list.', | ||||||
|  |   arguments: [ | ||||||
|  |     { | ||||||
|  |       label: 'Task List', | ||||||
|  |       key: 'taskListId', | ||||||
|  |       type: 'dropdown', | ||||||
|  |       required: true, | ||||||
|  |       description: '', | ||||||
|  |       variables: true, | ||||||
|  |       source: { | ||||||
|  |         type: 'query', | ||||||
|  |         name: 'getDynamicData', | ||||||
|  |         arguments: [ | ||||||
|  |           { | ||||||
|  |             name: 'key', | ||||||
|  |             value: 'listTaskLists', | ||||||
|  |           }, | ||||||
|  |         ], | ||||||
|  |       }, | ||||||
|  |     }, | ||||||
|  |   ], | ||||||
|  |  | ||||||
|  |   async run($) { | ||||||
|  |     const taskListId = $.step.parameters.taskListId; | ||||||
|  |  | ||||||
|  |     const params = { | ||||||
|  |       maxResults: 100, | ||||||
|  |       showCompleted: true, | ||||||
|  |       showHidden: true, | ||||||
|  |       pageToken: undefined, | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     do { | ||||||
|  |       const { data } = await $.http.get(`/tasks/v1/lists/${taskListId}/tasks`, { | ||||||
|  |         params, | ||||||
|  |       }); | ||||||
|  |       params.pageToken = data.nextPageToken; | ||||||
|  |  | ||||||
|  |       if (data.items?.length) { | ||||||
|  |         for (const task of data.items) { | ||||||
|  |           if (task.status === 'completed') { | ||||||
|  |             $.pushTriggerItem({ | ||||||
|  |               raw: task, | ||||||
|  |               meta: { | ||||||
|  |                 internalId: task.id, | ||||||
|  |               }, | ||||||
|  |             }); | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } while (params.pageToken); | ||||||
|  |   }, | ||||||
|  | }); | ||||||
| @@ -0,0 +1,31 @@ | |||||||
|  | import defineTrigger from '../../../../helpers/define-trigger.js'; | ||||||
|  |  | ||||||
|  | export default defineTrigger({ | ||||||
|  |   name: 'New task lists', | ||||||
|  |   key: 'newTaskLists', | ||||||
|  |   pollInterval: 15, | ||||||
|  |   description: 'Triggers when a new task list is created.', | ||||||
|  |  | ||||||
|  |   async run($) { | ||||||
|  |     const params = { | ||||||
|  |       maxResults: 100, | ||||||
|  |       pageToken: undefined, | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     do { | ||||||
|  |       const { data } = await $.http.get('/tasks/v1/users/@me/lists'); | ||||||
|  |       params.pageToken = data.nextPageToken; | ||||||
|  |  | ||||||
|  |       if (data.items?.length) { | ||||||
|  |         for (const taskList of data.items.reverse()) { | ||||||
|  |           $.pushTriggerItem({ | ||||||
|  |             raw: taskList, | ||||||
|  |             meta: { | ||||||
|  |               internalId: taskList.id, | ||||||
|  |             }, | ||||||
|  |           }); | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } while (params.pageToken); | ||||||
|  |   }, | ||||||
|  | }); | ||||||
| @@ -0,0 +1,53 @@ | |||||||
|  | import defineTrigger from '../../../../helpers/define-trigger.js'; | ||||||
|  |  | ||||||
|  | export default defineTrigger({ | ||||||
|  |   name: 'New tasks', | ||||||
|  |   key: 'newTasks', | ||||||
|  |   pollInterval: 15, | ||||||
|  |   description: 'Triggers when a new task is created.', | ||||||
|  |   arguments: [ | ||||||
|  |     { | ||||||
|  |       label: 'Task List', | ||||||
|  |       key: 'taskListId', | ||||||
|  |       type: 'dropdown', | ||||||
|  |       required: true, | ||||||
|  |       description: '', | ||||||
|  |       variables: true, | ||||||
|  |       source: { | ||||||
|  |         type: 'query', | ||||||
|  |         name: 'getDynamicData', | ||||||
|  |         arguments: [ | ||||||
|  |           { | ||||||
|  |             name: 'key', | ||||||
|  |             value: 'listTaskLists', | ||||||
|  |           }, | ||||||
|  |         ], | ||||||
|  |       }, | ||||||
|  |     }, | ||||||
|  |   ], | ||||||
|  |  | ||||||
|  |   async run($) { | ||||||
|  |     const taskListId = $.step.parameters.taskListId; | ||||||
|  |  | ||||||
|  |     const params = { | ||||||
|  |       maxResults: 100, | ||||||
|  |       pageToken: undefined, | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     do { | ||||||
|  |       const { data } = await $.http.get(`/tasks/v1/lists/${taskListId}/tasks`); | ||||||
|  |       params.pageToken = data.nextPageToken; | ||||||
|  |  | ||||||
|  |       if (data.items?.length) { | ||||||
|  |         for (const task of data.items) { | ||||||
|  |           $.pushTriggerItem({ | ||||||
|  |             raw: task, | ||||||
|  |             meta: { | ||||||
|  |               internalId: task.id, | ||||||
|  |             }, | ||||||
|  |           }); | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } while (params.pageToken); | ||||||
|  |   }, | ||||||
|  | }); | ||||||
| @@ -10,7 +10,7 @@ export default defineApp({ | |||||||
|   baseUrl: 'https://tryhelix.ai', |   baseUrl: 'https://tryhelix.ai', | ||||||
|   apiBaseUrl: 'https://app.tryhelix.ai', |   apiBaseUrl: 'https://app.tryhelix.ai', | ||||||
|   iconUrl: '{BASE_URL}/apps/helix/assets/favicon.svg', |   iconUrl: '{BASE_URL}/apps/helix/assets/favicon.svg', | ||||||
|   authDocUrl: 'https://automatisch.io/docs/apps/helix/connection', |   authDocUrl: '{DOCS_URL}/apps/helix/connection', | ||||||
|   primaryColor: '000000', |   primaryColor: '000000', | ||||||
|   supportsConnections: true, |   supportsConnections: true, | ||||||
|   beforeRequest: [setBaseUrl, addAuthHeader], |   beforeRequest: [setBaseUrl, addAuthHeader], | ||||||
|   | |||||||
| @@ -90,7 +90,7 @@ export default defineAction({ | |||||||
|  |  | ||||||
|   async run($) { |   async run($) { | ||||||
|     const method = $.step.parameters.method; |     const method = $.step.parameters.method; | ||||||
|     const data = $.step.parameters.data; |     const data = $.step.parameters.data || null; | ||||||
|     const url = $.step.parameters.url; |     const url = $.step.parameters.url; | ||||||
|     const headers = $.step.parameters.headers; |     const headers = $.step.parameters.headers; | ||||||
|  |  | ||||||
| @@ -108,14 +108,17 @@ export default defineAction({ | |||||||
|       return result; |       return result; | ||||||
|     }, {}); |     }, {}); | ||||||
|  |  | ||||||
|     let contentType = headersObject['content-type']; |     let expectedResponseContentType = headersObject.accept; | ||||||
|  |  | ||||||
|     // in case HEAD request is not supported by the URL |     // in case HEAD request is not supported by the URL | ||||||
|     try { |     try { | ||||||
|       const metadataResponse = await $.http.head(url, { |       const metadataResponse = await $.http.head(url, { | ||||||
|         headers: headersObject, |         headers: headersObject, | ||||||
|       }); |       }); | ||||||
|       contentType = metadataResponse.headers['content-type']; |  | ||||||
|  |       if (!expectedResponseContentType) { | ||||||
|  |         expectedResponseContentType = metadataResponse.headers['content-type']; | ||||||
|  |       } | ||||||
|  |  | ||||||
|       throwIfFileSizeExceedsLimit(metadataResponse.headers['content-length']); |       throwIfFileSizeExceedsLimit(metadataResponse.headers['content-length']); | ||||||
|       // eslint-disable-next-line no-empty |       // eslint-disable-next-line no-empty | ||||||
| @@ -128,7 +131,7 @@ export default defineAction({ | |||||||
|       headers: headersObject, |       headers: headersObject, | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     if (!isPossiblyTextBased(contentType)) { |     if (!isPossiblyTextBased(expectedResponseContentType)) { | ||||||
|       requestData.responseType = 'arraybuffer'; |       requestData.responseType = 'arraybuffer'; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -138,7 +141,7 @@ export default defineAction({ | |||||||
|  |  | ||||||
|     let responseData = response.data; |     let responseData = response.data; | ||||||
|  |  | ||||||
|     if (!isPossiblyTextBased(contentType)) { |     if (!isPossiblyTextBased(expectedResponseContentType)) { | ||||||
|       responseData = Buffer.from(responseData).toString('base64'); |       responseData = Buffer.from(responseData).toString('base64'); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -5,7 +5,7 @@ export default defineApp({ | |||||||
|   name: 'HTTP Request', |   name: 'HTTP Request', | ||||||
|   key: 'http-request', |   key: 'http-request', | ||||||
|   iconUrl: '{BASE_URL}/apps/http-request/assets/favicon.svg', |   iconUrl: '{BASE_URL}/apps/http-request/assets/favicon.svg', | ||||||
|   authDocUrl: 'https://automatisch.io/docs/apps/http-request/connection', |   authDocUrl: '{DOCS_URL}/apps/http-request/connection', | ||||||
|   supportsConnections: false, |   supportsConnections: false, | ||||||
|   baseUrl: '', |   baseUrl: '', | ||||||
|   apiBaseUrl: '', |   apiBaseUrl: '', | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ export default defineApp({ | |||||||
|   name: 'HubSpot', |   name: 'HubSpot', | ||||||
|   key: 'hubspot', |   key: 'hubspot', | ||||||
|   iconUrl: '{BASE_URL}/apps/hubspot/assets/favicon.svg', |   iconUrl: '{BASE_URL}/apps/hubspot/assets/favicon.svg', | ||||||
|   authDocUrl: 'https://automatisch.io/docs/apps/hubspot/connection', |   authDocUrl: '{DOCS_URL}/apps/hubspot/connection', | ||||||
|   supportsConnections: true, |   supportsConnections: true, | ||||||
|   baseUrl: 'https://www.hubspot.com', |   baseUrl: 'https://www.hubspot.com', | ||||||
|   apiBaseUrl: 'https://api.hubapi.com', |   apiBaseUrl: 'https://api.hubapi.com', | ||||||
|   | |||||||
| @@ -12,7 +12,7 @@ export default defineApp({ | |||||||
|   baseUrl: 'https://invoiceninja.com', |   baseUrl: 'https://invoiceninja.com', | ||||||
|   apiBaseUrl: 'https://invoicing.co/api', |   apiBaseUrl: 'https://invoicing.co/api', | ||||||
|   iconUrl: '{BASE_URL}/apps/invoice-ninja/assets/favicon.svg', |   iconUrl: '{BASE_URL}/apps/invoice-ninja/assets/favicon.svg', | ||||||
|   authDocUrl: 'https://automatisch.io/docs/apps/invoice-ninja/connection', |   authDocUrl: '{DOCS_URL}/apps/invoice-ninja/connection', | ||||||
|   primaryColor: '000000', |   primaryColor: '000000', | ||||||
|   supportsConnections: true, |   supportsConnections: true, | ||||||
|   beforeRequest: [setBaseUrl, addAuthHeader], |   beforeRequest: [setBaseUrl, addAuthHeader], | ||||||
|   | |||||||
| @@ -10,7 +10,7 @@ export default defineApp({ | |||||||
|   name: 'Mattermost', |   name: 'Mattermost', | ||||||
|   key: 'mattermost', |   key: 'mattermost', | ||||||
|   iconUrl: '{BASE_URL}/apps/mattermost/assets/favicon.svg', |   iconUrl: '{BASE_URL}/apps/mattermost/assets/favicon.svg', | ||||||
|   authDocUrl: 'https://automatisch.io/docs/apps/mattermost/connection', |   authDocUrl: '{DOCS_URL}/apps/mattermost/connection', | ||||||
|   baseUrl: 'https://mattermost.com', |   baseUrl: 'https://mattermost.com', | ||||||
|   apiBaseUrl: '', // there is no cloud version of this app, user always need to provide address of own instance when creating connection |   apiBaseUrl: '', // there is no cloud version of this app, user always need to provide address of own instance when creating connection | ||||||
|   primaryColor: '4a154b', |   primaryColor: '4a154b', | ||||||
|   | |||||||
| @@ -10,7 +10,7 @@ export default defineApp({ | |||||||
|   baseUrl: 'https://miro.com', |   baseUrl: 'https://miro.com', | ||||||
|   apiBaseUrl: 'https://api.miro.com', |   apiBaseUrl: 'https://api.miro.com', | ||||||
|   iconUrl: '{BASE_URL}/apps/miro/assets/favicon.svg', |   iconUrl: '{BASE_URL}/apps/miro/assets/favicon.svg', | ||||||
|   authDocUrl: 'https://automatisch.io/docs/apps/miro/connection', |   authDocUrl: '{DOCS_URL}/apps/miro/connection', | ||||||
|   primaryColor: 'F2CA02', |   primaryColor: 'F2CA02', | ||||||
|   supportsConnections: true, |   supportsConnections: true, | ||||||
|   beforeRequest: [addAuthHeader], |   beforeRequest: [addAuthHeader], | ||||||
|   | |||||||
| @@ -12,7 +12,7 @@ export default defineApp({ | |||||||
|   baseUrl: 'https://notion.com', |   baseUrl: 'https://notion.com', | ||||||
|   apiBaseUrl: 'https://api.notion.com', |   apiBaseUrl: 'https://api.notion.com', | ||||||
|   iconUrl: '{BASE_URL}/apps/notion/assets/favicon.svg', |   iconUrl: '{BASE_URL}/apps/notion/assets/favicon.svg', | ||||||
|   authDocUrl: 'https://automatisch.io/docs/apps/notion/connection', |   authDocUrl: '{DOCS_URL}/apps/notion/connection', | ||||||
|   primaryColor: '000000', |   primaryColor: '000000', | ||||||
|   supportsConnections: true, |   supportsConnections: true, | ||||||
|   beforeRequest: [addAuthHeader, addNotionVersionHeader], |   beforeRequest: [addAuthHeader, addNotionVersionHeader], | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ export default defineApp({ | |||||||
|   name: 'Ntfy', |   name: 'Ntfy', | ||||||
|   key: 'ntfy', |   key: 'ntfy', | ||||||
|   iconUrl: '{BASE_URL}/apps/ntfy/assets/favicon.svg', |   iconUrl: '{BASE_URL}/apps/ntfy/assets/favicon.svg', | ||||||
|   authDocUrl: 'https://automatisch.io/docs/apps/ntfy/connection', |   authDocUrl: '{DOCS_URL}/apps/ntfy/connection', | ||||||
|   supportsConnections: true, |   supportsConnections: true, | ||||||
|   baseUrl: 'https://ntfy.sh', |   baseUrl: 'https://ntfy.sh', | ||||||
|   apiBaseUrl: 'https://ntfy.sh', |   apiBaseUrl: 'https://ntfy.sh', | ||||||
|   | |||||||
| @@ -6,7 +6,7 @@ export default defineApp({ | |||||||
|   name: 'Odoo', |   name: 'Odoo', | ||||||
|   key: 'odoo', |   key: 'odoo', | ||||||
|   iconUrl: '{BASE_URL}/apps/odoo/assets/favicon.svg', |   iconUrl: '{BASE_URL}/apps/odoo/assets/favicon.svg', | ||||||
|   authDocUrl: 'https://automatisch.io/docs/apps/odoo/connection', |   authDocUrl: '{DOCS_URL}/apps/odoo/connection', | ||||||
|   supportsConnections: true, |   supportsConnections: true, | ||||||
|   baseUrl: 'https://odoo.com', |   baseUrl: 'https://odoo.com', | ||||||
|   apiBaseUrl: '', |   apiBaseUrl: '', | ||||||
|   | |||||||
| @@ -10,7 +10,7 @@ export default defineApp({ | |||||||
|   baseUrl: 'https://openai.com', |   baseUrl: 'https://openai.com', | ||||||
|   apiBaseUrl: 'https://api.openai.com', |   apiBaseUrl: 'https://api.openai.com', | ||||||
|   iconUrl: '{BASE_URL}/apps/openai/assets/favicon.svg', |   iconUrl: '{BASE_URL}/apps/openai/assets/favicon.svg', | ||||||
|   authDocUrl: 'https://automatisch.io/docs/apps/openai/connection', |   authDocUrl: '{DOCS_URL}/apps/openai/connection', | ||||||
|   primaryColor: '000000', |   primaryColor: '000000', | ||||||
|   supportsConnections: true, |   supportsConnections: true, | ||||||
|   beforeRequest: [addAuthHeader], |   beforeRequest: [addAuthHeader], | ||||||
|   | |||||||
| @@ -64,32 +64,17 @@ export default defineAction({ | |||||||
|       value: '1', |       value: '1', | ||||||
|       description: |       description: | ||||||
|         'The ID of the stage this deal will be added to. If omitted, the deal will be placed in the first stage of the default pipeline.', |         'The ID of the stage this deal will be added to. If omitted, the deal will be placed in the first stage of the default pipeline.', | ||||||
|       options: [ |       variables: true, | ||||||
|         { |       source: { | ||||||
|           label: 'Qualified (Pipeline)', |         type: 'query', | ||||||
|           value: 1, |         name: 'getDynamicData', | ||||||
|         }, |         arguments: [ | ||||||
|         { |           { | ||||||
|           label: 'Contact Made (Pipeline)', |             name: 'key', | ||||||
|           value: 2, |             value: 'listStages', | ||||||
|         }, |           }, | ||||||
|         { |         ], | ||||||
|           label: 'Prospect Qualified (Pipeline)', |       }, | ||||||
|           value: 3, |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|           label: 'Needs Defined (Pipeline)', |  | ||||||
|           value: 4, |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|           label: 'Proposal Made (Pipeline)', |  | ||||||
|           value: 5, |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|           label: 'Negotiations Started (Pipeline)', |  | ||||||
|           value: 6, |  | ||||||
|         }, |  | ||||||
|       ], |  | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       label: 'Owner', |       label: 'Owner', | ||||||
|   | |||||||
| @@ -1,23 +1,25 @@ | |||||||
| import listActivityTypes from './list-activity-types/index.js'; | import listActivityTypes from './list-activity-types/index.js'; | ||||||
| import listCurrencies from './list-currencies/index.js'; | import listCurrencies from './list-currencies/index.js'; | ||||||
| import listDeals from './list-deals/index.js'; | import listDeals from './list-deals/index.js'; | ||||||
| import listLeads from './list-leads/index.js'; |  | ||||||
| import listLeadLabels from './list-lead-labels/index.js'; | import listLeadLabels from './list-lead-labels/index.js'; | ||||||
| import listOrganizations from './list-organizations/index.js'; | import listLeads from './list-leads/index.js'; | ||||||
| import listOrganizationLabelField from './list-organization-label-field/index.js'; | import listOrganizationLabelField from './list-organization-label-field/index.js'; | ||||||
|  | import listOrganizations from './list-organizations/index.js'; | ||||||
| import listPersonLabelField from './list-person-label-field/index.js'; | import listPersonLabelField from './list-person-label-field/index.js'; | ||||||
| import listPersons from './list-persons/index.js'; | import listPersons from './list-persons/index.js'; | ||||||
|  | import listStages from './list-stages/index.js'; | ||||||
| import listUsers from './list-users/index.js'; | import listUsers from './list-users/index.js'; | ||||||
|  |  | ||||||
| export default [ | export default [ | ||||||
|   listActivityTypes, |   listActivityTypes, | ||||||
|   listCurrencies, |   listCurrencies, | ||||||
|   listDeals, |   listDeals, | ||||||
|   listLeads, |  | ||||||
|   listLeadLabels, |   listLeadLabels, | ||||||
|   listOrganizations, |   listLeads, | ||||||
|   listOrganizationLabelField, |   listOrganizationLabelField, | ||||||
|  |   listOrganizations, | ||||||
|   listPersonLabelField, |   listPersonLabelField, | ||||||
|   listPersons, |   listPersons, | ||||||
|  |   listStages, | ||||||
|   listUsers, |   listUsers, | ||||||
| ]; | ]; | ||||||
|   | |||||||
| @@ -0,0 +1,23 @@ | |||||||
|  | export default { | ||||||
|  |   name: 'List stages', | ||||||
|  |   key: 'listStages', | ||||||
|  |  | ||||||
|  |   async run($) { | ||||||
|  |     const stages = { | ||||||
|  |       data: [], | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     const { data } = await $.http.get('/api/v1/stages'); | ||||||
|  |  | ||||||
|  |     if (data.data?.length) { | ||||||
|  |       for (const stage of data.data) { | ||||||
|  |         stages.data.push({ | ||||||
|  |           value: stage.id, | ||||||
|  |           name: stage.name, | ||||||
|  |         }); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     return stages; | ||||||
|  |   }, | ||||||
|  | }; | ||||||
| @@ -12,7 +12,7 @@ export default defineApp({ | |||||||
|   baseUrl: '', |   baseUrl: '', | ||||||
|   apiBaseUrl: '', |   apiBaseUrl: '', | ||||||
|   iconUrl: '{BASE_URL}/apps/pipedrive/assets/favicon.svg', |   iconUrl: '{BASE_URL}/apps/pipedrive/assets/favicon.svg', | ||||||
|   authDocUrl: 'https://automatisch.io/docs/apps/pipedrive/connection', |   authDocUrl: '{DOCS_URL}/apps/pipedrive/connection', | ||||||
|   primaryColor: 'FFFFFF', |   primaryColor: 'FFFFFF', | ||||||
|   supportsConnections: true, |   supportsConnections: true, | ||||||
|   beforeRequest: [setBaseUrl, addAuthHeader], |   beforeRequest: [setBaseUrl, addAuthHeader], | ||||||
|   | |||||||
| @@ -8,7 +8,7 @@ export default defineApp({ | |||||||
|   name: 'Placetel', |   name: 'Placetel', | ||||||
|   key: 'placetel', |   key: 'placetel', | ||||||
|   iconUrl: '{BASE_URL}/apps/placetel/assets/favicon.svg', |   iconUrl: '{BASE_URL}/apps/placetel/assets/favicon.svg', | ||||||
|   authDocUrl: 'https://automatisch.io/docs/apps/placetel/connection', |   authDocUrl: '{DOCS_URL}/apps/placetel/connection', | ||||||
|   supportsConnections: true, |   supportsConnections: true, | ||||||
|   baseUrl: 'https://placetel.de', |   baseUrl: 'https://placetel.de', | ||||||
|   apiBaseUrl: 'https://api.placetel.de', |   apiBaseUrl: 'https://api.placetel.de', | ||||||
|   | |||||||
| @@ -6,7 +6,7 @@ export default defineApp({ | |||||||
|   name: 'PostgreSQL', |   name: 'PostgreSQL', | ||||||
|   key: 'postgresql', |   key: 'postgresql', | ||||||
|   iconUrl: '{BASE_URL}/apps/postgresql/assets/favicon.svg', |   iconUrl: '{BASE_URL}/apps/postgresql/assets/favicon.svg', | ||||||
|   authDocUrl: 'https://automatisch.io/docs/apps/postgresql/connection', |   authDocUrl: '{DOCS_URL}/apps/postgresql/connection', | ||||||
|   supportsConnections: true, |   supportsConnections: true, | ||||||
|   baseUrl: '', |   baseUrl: '', | ||||||
|   apiBaseUrl: '', |   apiBaseUrl: '', | ||||||
|   | |||||||
| @@ -9,7 +9,7 @@ export default defineApp({ | |||||||
|   baseUrl: 'https://pushover.net', |   baseUrl: 'https://pushover.net', | ||||||
|   apiBaseUrl: 'https://api.pushover.net', |   apiBaseUrl: 'https://api.pushover.net', | ||||||
|   iconUrl: '{BASE_URL}/apps/pushover/assets/favicon.svg', |   iconUrl: '{BASE_URL}/apps/pushover/assets/favicon.svg', | ||||||
|   authDocUrl: 'https://automatisch.io/docs/apps/pushover/connection', |   authDocUrl: '{DOCS_URL}/apps/pushover/connection', | ||||||
|   primaryColor: '249DF1', |   primaryColor: '249DF1', | ||||||
|   supportsConnections: true, |   supportsConnections: true, | ||||||
|   auth, |   auth, | ||||||
|   | |||||||
| @@ -10,7 +10,7 @@ export default defineApp({ | |||||||
|   baseUrl: 'https://www.reddit.com', |   baseUrl: 'https://www.reddit.com', | ||||||
|   apiBaseUrl: 'https://oauth.reddit.com', |   apiBaseUrl: 'https://oauth.reddit.com', | ||||||
|   iconUrl: '{BASE_URL}/apps/reddit/assets/favicon.svg', |   iconUrl: '{BASE_URL}/apps/reddit/assets/favicon.svg', | ||||||
|   authDocUrl: 'https://automatisch.io/docs/apps/reddit/connection', |   authDocUrl: '{DOCS_URL}/apps/reddit/connection', | ||||||
|   primaryColor: 'FF4500', |   primaryColor: 'FF4500', | ||||||
|   supportsConnections: true, |   supportsConnections: true, | ||||||
|   beforeRequest: [addAuthHeader], |   beforeRequest: [addAuthHeader], | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ export default defineApp({ | |||||||
|   name: 'Remove.bg', |   name: 'Remove.bg', | ||||||
|   key: 'removebg', |   key: 'removebg', | ||||||
|   iconUrl: '{BASE_URL}/apps/removebg/assets/favicon.svg', |   iconUrl: '{BASE_URL}/apps/removebg/assets/favicon.svg', | ||||||
|   authDocUrl: 'https://automatisch.io/docs/apps/removebg/connection', |   authDocUrl: '{DOCS_URL}/apps/removebg/connection', | ||||||
|   supportsConnections: true, |   supportsConnections: true, | ||||||
|   baseUrl: 'https://www.remove.bg', |   baseUrl: 'https://www.remove.bg', | ||||||
|   apiBaseUrl: 'https://api.remove.bg/v1.0', |   apiBaseUrl: 'https://api.remove.bg/v1.0', | ||||||
|   | |||||||
| @@ -5,7 +5,7 @@ export default defineApp({ | |||||||
|   name: 'RSS', |   name: 'RSS', | ||||||
|   key: 'rss', |   key: 'rss', | ||||||
|   iconUrl: '{BASE_URL}/apps/rss/assets/favicon.svg', |   iconUrl: '{BASE_URL}/apps/rss/assets/favicon.svg', | ||||||
|   authDocUrl: 'https://automatisch.io/docs/apps/rss/connection', |   authDocUrl: '{DOCS_URL}/apps/rss/connection', | ||||||
|   supportsConnections: false, |   supportsConnections: false, | ||||||
|   baseUrl: '', |   baseUrl: '', | ||||||
|   apiBaseUrl: '', |   apiBaseUrl: '', | ||||||
|   | |||||||
| @@ -9,7 +9,7 @@ export default defineApp({ | |||||||
|   name: 'Salesforce', |   name: 'Salesforce', | ||||||
|   key: 'salesforce', |   key: 'salesforce', | ||||||
|   iconUrl: '{BASE_URL}/apps/salesforce/assets/favicon.svg', |   iconUrl: '{BASE_URL}/apps/salesforce/assets/favicon.svg', | ||||||
|   authDocUrl: 'https://automatisch.io/docs/connections/salesforce', |   authDocUrl: '{DOCS_URL}/connections/salesforce', | ||||||
|   supportsConnections: true, |   supportsConnections: true, | ||||||
|   baseUrl: 'https://salesforce.com', |   baseUrl: 'https://salesforce.com', | ||||||
|   apiBaseUrl: '', |   apiBaseUrl: '', | ||||||
|   | |||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user