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