Compare commits
	
		
			2 Commits
		
	
	
		
			dependabot
			...
			AUT-1023
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 5263e774d2 | ||
|   | 22b4a04567 | 
							
								
								
									
										7
									
								
								packages/backend/src/apps/eventbrite/assets/favicon.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								packages/backend/src/apps/eventbrite/assets/favicon.svg
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <svg width="256px" height="256px" viewBox="0 0 256 256" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid"> | ||||
| 		<g> | ||||
| 				<circle fill="#F05537" cx="128" cy="128" r="128"></circle> | ||||
| 				<path d="M117.475323,82.7290398 C136.772428,78.4407943 156.069532,86.3025777 166.790146,101.311437 L81.5017079,120.608542 C84.3605382,102.26438 98.1782181,87.0172853 117.475323,82.7290398 Z M167.266618,153.48509 C160.596014,163.252761 150.351872,170.161601 138.678314,172.782195 C119.38121,177.070441 99.8458692,169.208657 89.1252554,153.961562 L174.651929,134.664457 L188.469609,131.567391 L215.152026,125.611495 C214.91379,119.893834 214.199082,114.176173 213.007903,108.696749 C202.287289,62.7172275 155.354825,33.8906884 108.42236,44.6113021 C61.4898956,55.3319159 32.1868848,101.073201 43.1457344,147.290958 C54.1045839,193.508715 100.798813,222.097018 147.731277,211.376404 C175.366637,205.182272 196.807864,186.599875 207.766714,163.014525 L167.266618,153.48509 L167.266618,153.48509 Z" fill="#FFFFFF" fill-rule="nonzero"></path> | ||||
| 		</g> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 1.1 KiB | 
| @@ -0,0 +1,19 @@ | ||||
| import { URLSearchParams } from 'url'; | ||||
|  | ||||
| export default async function generateAuthUrl($) { | ||||
|   const oauthRedirectUrlField = $.app.auth.fields.find( | ||||
|     (field) => field.key == 'oAuthRedirectUrl' | ||||
|   ); | ||||
|   const redirectUri = oauthRedirectUrlField.value; | ||||
|   const searchParams = new URLSearchParams({ | ||||
|     response_type: 'code', | ||||
|     client_id: $.auth.data.clientId, | ||||
|     redirect_uri: redirectUri, | ||||
|   }); | ||||
|  | ||||
|   const url = `https://www.eventbrite.com/oauth/authorize?${searchParams.toString()}`; | ||||
|  | ||||
|   await $.auth.set({ | ||||
|     url, | ||||
|   }); | ||||
| } | ||||
							
								
								
									
										46
									
								
								packages/backend/src/apps/eventbrite/auth/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								packages/backend/src/apps/eventbrite/auth/index.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | ||||
| import generateAuthUrl from './generate-auth-url.js'; | ||||
| import verifyCredentials from './verify-credentials.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/eventbrite/connections/add', | ||||
|       placeholder: null, | ||||
|       description: | ||||
|         'When asked to input a redirect URL in Eventbrite, enter the URL above.', | ||||
|       clickToCopy: true, | ||||
|     }, | ||||
|     { | ||||
|       key: 'clientId', | ||||
|       label: 'API Key', | ||||
|       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, | ||||
| }; | ||||
| @@ -0,0 +1,8 @@ | ||||
| import getCurrentUser from '../common/get-current-user.js'; | ||||
|  | ||||
| const isStillVerified = async ($) => { | ||||
|   const currentUser = await getCurrentUser($); | ||||
|   return !!currentUser.id; | ||||
| }; | ||||
|  | ||||
| export default isStillVerified; | ||||
| @@ -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://www.eventbrite.com/oauth/token', | ||||
|     { | ||||
|       grant_type: 'authorization_code', | ||||
|       client_id: $.auth.data.clientId, | ||||
|       client_secret: $.auth.data.clientSecret, | ||||
|       code: $.auth.data.code, | ||||
|       redirect_uri: redirectUri, | ||||
|     }, | ||||
|     { | ||||
|       headers: { | ||||
|         'Content-Type': 'application/x-www-form-urlencoded', | ||||
|       }, | ||||
|     } | ||||
|   ); | ||||
|  | ||||
|   await $.auth.set({ | ||||
|     accessToken: data.access_token, | ||||
|     tokenType: data.token_type, | ||||
|   }); | ||||
|  | ||||
|   const currentUser = await getCurrentUser($); | ||||
|  | ||||
|   const screenName = [currentUser.name, currentUser.emails[0].email] | ||||
|     .filter(Boolean) | ||||
|     .join(' @ '); | ||||
|  | ||||
|   await $.auth.set({ | ||||
|     clientId: $.auth.data.clientId, | ||||
|     clientSecret: $.auth.data.clientSecret, | ||||
|     screenName, | ||||
|   }); | ||||
| }; | ||||
|  | ||||
| export default verifyCredentials; | ||||
| @@ -0,0 +1,9 @@ | ||||
| const addAuthHeader = ($, requestConfig) => { | ||||
|   if ($.auth.data?.accessToken) { | ||||
|     requestConfig.headers.Authorization = `Bearer ${$.auth.data.accessToken}`; | ||||
|   } | ||||
|  | ||||
|   return requestConfig; | ||||
| }; | ||||
|  | ||||
| export default addAuthHeader; | ||||
| @@ -0,0 +1,6 @@ | ||||
| const getCurrentUser = async ($) => { | ||||
|   const { data: currentUser } = await $.http.get('/v3/users/me'); | ||||
|   return currentUser; | ||||
| }; | ||||
|  | ||||
| export default getCurrentUser; | ||||
| @@ -0,0 +1,3 @@ | ||||
| import listOrganizations from './list-organizations/index.js'; | ||||
|  | ||||
| export default [listOrganizations]; | ||||
| @@ -0,0 +1,35 @@ | ||||
| export default { | ||||
|   name: 'List organizations', | ||||
|   key: 'listOrganizations', | ||||
|  | ||||
|   async run($) { | ||||
|     const organizations = { | ||||
|       data: [], | ||||
|     }; | ||||
|  | ||||
|     const params = { | ||||
|       continuation: undefined, | ||||
|     }; | ||||
|  | ||||
|     do { | ||||
|       const { data } = await $.http.get('/v3/users/me/organizations', { | ||||
|         params, | ||||
|       }); | ||||
|  | ||||
|       if (data.pagination.has_more_items) { | ||||
|         params.continuation = data.pagination.continuation; | ||||
|       } | ||||
|  | ||||
|       if (data.organizations) { | ||||
|         for (const organization of data.organizations) { | ||||
|           organizations.data.push({ | ||||
|             value: organization.id, | ||||
|             name: organization.name, | ||||
|           }); | ||||
|         } | ||||
|       } | ||||
|     } while (params.continuation); | ||||
|  | ||||
|     return organizations; | ||||
|   }, | ||||
| }; | ||||
							
								
								
									
										20
									
								
								packages/backend/src/apps/eventbrite/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								packages/backend/src/apps/eventbrite/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: 'Eventbrite', | ||||
|   key: 'eventbrite', | ||||
|   baseUrl: 'https://www.eventbrite.com', | ||||
|   apiBaseUrl: 'https://www.eventbriteapi.com', | ||||
|   iconUrl: '{BASE_URL}/apps/eventbrite/assets/favicon.svg', | ||||
|   authDocUrl: '{DOCS_URL}/apps/eventbrite/connection', | ||||
|   primaryColor: 'F05537', | ||||
|   supportsConnections: true, | ||||
|   beforeRequest: [addAuthHeader], | ||||
|   auth, | ||||
|   dynamicData, | ||||
|   triggers, | ||||
| }); | ||||
							
								
								
									
										3
									
								
								packages/backend/src/apps/eventbrite/triggers/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								packages/backend/src/apps/eventbrite/triggers/index.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| import newEvents from './new-events/index.js'; | ||||
|  | ||||
| export default [newEvents]; | ||||
| @@ -0,0 +1,98 @@ | ||||
| import Crypto from 'crypto'; | ||||
| import defineTrigger from '../../../../helpers/define-trigger.js'; | ||||
|  | ||||
| export default defineTrigger({ | ||||
|   name: 'New events', | ||||
|   key: 'newEvents', | ||||
|   type: 'webhook', | ||||
|   description: | ||||
|     'Triggers when a new event is published and live within an organization.', | ||||
|   arguments: [ | ||||
|     { | ||||
|       label: 'Organization', | ||||
|       key: 'organizationId', | ||||
|       type: 'dropdown', | ||||
|       required: true, | ||||
|       description: '', | ||||
|       variables: true, | ||||
|       source: { | ||||
|         type: 'query', | ||||
|         name: 'getDynamicData', | ||||
|         arguments: [ | ||||
|           { | ||||
|             name: 'key', | ||||
|             value: 'listOrganizations', | ||||
|           }, | ||||
|         ], | ||||
|       }, | ||||
|     }, | ||||
|   ], | ||||
|  | ||||
|   async run($) { | ||||
|     const dataItem = { | ||||
|       raw: $.request.body, | ||||
|       meta: { | ||||
|         internalId: Crypto.randomUUID(), | ||||
|       }, | ||||
|     }; | ||||
|  | ||||
|     $.pushTriggerItem(dataItem); | ||||
|   }, | ||||
|  | ||||
|   async testRun($) { | ||||
|     const organizationId = $.step.parameters.organizationId; | ||||
|  | ||||
|     const params = { | ||||
|       orderBy: 'created_desc', | ||||
|       status: 'all', | ||||
|     }; | ||||
|  | ||||
|     const { | ||||
|       data: { events }, | ||||
|     } = await $.http.get(`/v3/organizations/${organizationId}/events/`, params); | ||||
|  | ||||
|     if (events.length === 0) { | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|     const computedWebhookEvent = { | ||||
|       config: { | ||||
|         action: 'event.published', | ||||
|         user_id: events[0].organization_id, | ||||
|         webhook_id: '11111111', | ||||
|         endpoint_url: $.webhookUrl, | ||||
|       }, | ||||
|       api_url: events[0].resource_uri, | ||||
|     }; | ||||
|  | ||||
|     const dataItem = { | ||||
|       raw: computedWebhookEvent, | ||||
|       meta: { | ||||
|         internalId: computedWebhookEvent.user_id, | ||||
|       }, | ||||
|     }; | ||||
|  | ||||
|     $.pushTriggerItem(dataItem); | ||||
|   }, | ||||
|  | ||||
|   async registerHook($) { | ||||
|     const organizationId = $.step.parameters.organizationId; | ||||
|  | ||||
|     const payload = { | ||||
|       endpoint_url: $.webhookUrl, | ||||
|       actions: 'event.published', | ||||
|       event_id: '', | ||||
|     }; | ||||
|  | ||||
|     const { data } = await $.http.post( | ||||
|       `/v3/organizations/${organizationId}/webhooks/`, | ||||
|       payload | ||||
|     ); | ||||
|  | ||||
|     await $.flow.setRemoteWebhookId(data.id); | ||||
|   }, | ||||
|  | ||||
|   async unregisterHook($) { | ||||
|     await $.http.delete(`/v3/webhooks/${$.flow.remoteWebhookId}/`); | ||||
|   }, | ||||
| }); | ||||
| @@ -113,6 +113,15 @@ export default defineConfig({ | ||||
|             { text: 'Connection', link: '/apps/dropbox/connection' }, | ||||
|           ], | ||||
|         }, | ||||
|         { | ||||
|           text: 'Eventbrite', | ||||
|           collapsible: true, | ||||
|           collapsed: true, | ||||
|           items: [ | ||||
|             { text: 'Triggers', link: '/apps/eventbrite/triggers' }, | ||||
|             { text: 'Connection', link: '/apps/eventbrite/connection' }, | ||||
|           ], | ||||
|         }, | ||||
|         { | ||||
|           text: 'Filter', | ||||
|           collapsible: true, | ||||
|   | ||||
							
								
								
									
										18
									
								
								packages/docs/pages/apps/eventbrite/connection.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								packages/docs/pages/apps/eventbrite/connection.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | ||||
| # Eventbrite | ||||
|  | ||||
| :::info | ||||
| This page explains the steps you need to follow to set up the Eventbrite | ||||
| connection in Automatisch. If any of the steps are outdated, please let us know! | ||||
| ::: | ||||
|  | ||||
| 1. Go to your Eventbrite account settings. | ||||
| 2. Click on the **Developer Links**, and click on the **API Keys** button. | ||||
| 3. Click on the **Create API Key** button. | ||||
| 4. Fill the form. | ||||
| 5. Copy **OAuth Redirect URL** from Automatisch to **OAuth Redirect URI** field in the form. | ||||
| 6. After filling the form, click on the **Create Key** button. | ||||
| 7. Click on the **Show API key, client secret and tokens** in the middle of the page. | ||||
| 8. Copy the **API Key** value to the `API Key` field on Automatisch. | ||||
| 9. Copy the **Client secret** value to the `Client Secret` field on Automatisch. | ||||
| 10. Click **Submit** button on Automatisch. | ||||
| 11. Congrats! Start using your new Eventbrite connection within the flows. | ||||
							
								
								
									
										12
									
								
								packages/docs/pages/apps/eventbrite/triggers.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								packages/docs/pages/apps/eventbrite/triggers.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| --- | ||||
| favicon: /favicons/eventbrite.svg | ||||
| items: | ||||
|   - name: New events | ||||
|     desc: Triggers when a new event is published and live within an organization. | ||||
| --- | ||||
|  | ||||
| <script setup> | ||||
|   import CustomListing from '../../components/CustomListing.vue' | ||||
| </script> | ||||
|  | ||||
| <CustomListing /> | ||||
| @@ -11,6 +11,7 @@ The following integrations are currently supported by Automatisch. | ||||
| - [Discord](/apps/discord/actions) | ||||
| - [Disqus](/apps/disqus/triggers) | ||||
| - [Dropbox](/apps/dropbox/actions) | ||||
| - [Eventbrite](/apps/eventbrite/triggers) | ||||
| - [Filter](/apps/filter/actions) | ||||
| - [Flickr](/apps/flickr/triggers) | ||||
| - [Formatter](/apps/formatter/actions) | ||||
|   | ||||
							
								
								
									
										7
									
								
								packages/docs/pages/public/favicons/eventbrite.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								packages/docs/pages/public/favicons/eventbrite.svg
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <svg width="256px" height="256px" viewBox="0 0 256 256" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid"> | ||||
| 		<g> | ||||
| 				<circle fill="#F05537" cx="128" cy="128" r="128"></circle> | ||||
| 				<path d="M117.475323,82.7290398 C136.772428,78.4407943 156.069532,86.3025777 166.790146,101.311437 L81.5017079,120.608542 C84.3605382,102.26438 98.1782181,87.0172853 117.475323,82.7290398 Z M167.266618,153.48509 C160.596014,163.252761 150.351872,170.161601 138.678314,172.782195 C119.38121,177.070441 99.8458692,169.208657 89.1252554,153.961562 L174.651929,134.664457 L188.469609,131.567391 L215.152026,125.611495 C214.91379,119.893834 214.199082,114.176173 213.007903,108.696749 C202.287289,62.7172275 155.354825,33.8906884 108.42236,44.6113021 C61.4898956,55.3319159 32.1868848,101.073201 43.1457344,147.290958 C54.1045839,193.508715 100.798813,222.097018 147.731277,211.376404 C175.366637,205.182272 196.807864,186.599875 207.766714,163.014525 L167.266618,153.48509 L167.266618,153.48509 Z" fill="#FFFFFF" fill-rule="nonzero"></path> | ||||
| 		</g> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 1.1 KiB | 
		Reference in New Issue
	
	Block a user