-
Notifications
You must be signed in to change notification settings - Fork 312
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1300 from automatisch/miro-integration
feat(miro): add create board action
- Loading branch information
Showing
17 changed files
with
319 additions
and
0 deletions.
There are no files selected for viewing
94 changes: 94 additions & 0 deletions
94
packages/backend/src/apps/miro/actions/create-board/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
import defineAction from '../../../../helpers/define-action'; | ||
|
||
export default defineAction({ | ||
name: 'Create board', | ||
key: 'createBoard', | ||
description: 'Creates a new board.', | ||
arguments: [ | ||
{ | ||
label: 'Title', | ||
key: 'title', | ||
type: 'string' as const, | ||
required: true, | ||
description: 'Title for the board.', | ||
variables: true, | ||
}, | ||
{ | ||
label: 'Description', | ||
key: 'description', | ||
type: 'string' as const, | ||
required: false, | ||
description: 'Description of the board.', | ||
variables: true, | ||
}, | ||
{ | ||
label: 'Team Access', | ||
key: 'teamAccess', | ||
type: 'dropdown' as const, | ||
required: false, | ||
description: | ||
'Team access to the board. Can be private, view, comment or edit. Default: private.', | ||
variables: true, | ||
options: [ | ||
{ | ||
label: 'Private - nobody in the team can find and access the board', | ||
value: 'private', | ||
}, | ||
{ | ||
label: 'View - any team member can find and view the board', | ||
value: 'view', | ||
}, | ||
{ | ||
label: 'Comment - any team member can find and comment the board', | ||
value: 'comment', | ||
}, | ||
{ | ||
label: 'Edit - any team member can find and edit the board', | ||
value: 'edit', | ||
}, | ||
], | ||
}, | ||
{ | ||
label: 'Access Via Link', | ||
key: 'accessViaLink', | ||
type: 'dropdown' as const, | ||
required: false, | ||
description: | ||
'Access to the board by link. Can be private, view, comment. Default: private.', | ||
variables: true, | ||
options: [ | ||
{ | ||
label: 'Private - only you have access to the board', | ||
value: 'private', | ||
}, | ||
{ | ||
label: 'View - can view, no sign-in required', | ||
value: 'view', | ||
}, | ||
{ | ||
label: 'Comment - can comment, no sign-in required', | ||
value: 'comment', | ||
}, | ||
], | ||
}, | ||
], | ||
|
||
async run($) { | ||
const body = { | ||
name: $.step.parameters.title, | ||
description: $.step.parameters.description, | ||
policy: { | ||
sharingPolicy: { | ||
access: $.step.parameters.accessViaLink || 'private', | ||
teamAccess: $.step.parameters.teamAccess || 'private', | ||
}, | ||
}, | ||
}; | ||
|
||
const { data } = await $.http.post('/v2/boards', body); | ||
|
||
$.setActionItem({ | ||
raw: data, | ||
}); | ||
}, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
import createBoard from './create-board'; | ||
|
||
export default [createBoard]; |
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { IField, IGlobalVariable } from '@automatisch/types'; | ||
import { URLSearchParams } from 'url'; | ||
|
||
export default async function generateAuthUrl($: IGlobalVariable) { | ||
const oauthRedirectUrlField = $.app.auth.fields.find( | ||
(field: IField) => field.key == 'oAuthRedirectUrl' | ||
); | ||
const redirectUri = oauthRedirectUrlField.value as string; | ||
const searchParams = new URLSearchParams({ | ||
response_type: 'code', | ||
client_id: $.auth.data.clientId as string, | ||
redirect_uri: redirectUri, | ||
}); | ||
|
||
const url = `https://miro.com/oauth/authorize?${searchParams.toString()}`; | ||
|
||
await $.auth.set({ | ||
url, | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import generateAuthUrl from './generate-auth-url'; | ||
import verifyCredentials from './verify-credentials'; | ||
import refreshToken from './refresh-token'; | ||
import isStillVerified from './is-still-verified'; | ||
|
||
export default { | ||
fields: [ | ||
{ | ||
key: 'oAuthRedirectUrl', | ||
label: 'OAuth Redirect URL', | ||
type: 'string' as const, | ||
required: true, | ||
readOnly: true, | ||
value: '{WEB_APP_URL}/app/miro/connections/add', | ||
placeholder: null, | ||
description: | ||
'When asked to input a redirect URL in Miro, enter the URL above.', | ||
clickToCopy: true, | ||
}, | ||
{ | ||
key: 'clientId', | ||
label: 'Client ID', | ||
type: 'string' as const, | ||
required: true, | ||
readOnly: false, | ||
value: null, | ||
placeholder: null, | ||
description: null, | ||
clickToCopy: false, | ||
}, | ||
{ | ||
key: 'clientSecret', | ||
label: 'Client Secret', | ||
type: 'string' as const, | ||
required: true, | ||
readOnly: false, | ||
value: null, | ||
placeholder: null, | ||
description: null, | ||
clickToCopy: false, | ||
}, | ||
], | ||
|
||
generateAuthUrl, | ||
verifyCredentials, | ||
isStillVerified, | ||
refreshToken, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import { IGlobalVariable } from '@automatisch/types'; | ||
import getCurrentUser from '../common/get-current-user'; | ||
|
||
const isStillVerified = async ($: IGlobalVariable) => { | ||
const currentUser = await getCurrentUser($); | ||
return !!currentUser; | ||
}; | ||
|
||
export default isStillVerified; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { URLSearchParams } from 'node:url'; | ||
import { IGlobalVariable } from '@automatisch/types'; | ||
|
||
const refreshToken = async ($: IGlobalVariable) => { | ||
const params = new URLSearchParams({ | ||
grant_type: 'refresh_token', | ||
client_id: $.auth.data.clientId as string, | ||
client_secret: $.auth.data.clientSecret as string, | ||
refresh_token: $.auth.data.refreshToken as string, | ||
}); | ||
|
||
const { data } = await $.http.post('/v1/oauth/token', params.toString()); | ||
|
||
await $.auth.set({ | ||
accessToken: data.access_token, | ||
expiresIn: data.expires_in, | ||
refreshToken: data.refresh_token, | ||
scope: data.scope, | ||
tokenType: data.token_type, | ||
}); | ||
}; | ||
|
||
export default refreshToken; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import { IField, IGlobalVariable } from '@automatisch/types'; | ||
import getCurrentUser from '../common/get-current-user'; | ||
|
||
const verifyCredentials = async ($: IGlobalVariable) => { | ||
const oauthRedirectUrlField = $.app.auth.fields.find( | ||
(field: IField) => field.key == 'oAuthRedirectUrl' | ||
); | ||
const redirectUri = oauthRedirectUrlField.value as string; | ||
const params = { | ||
grant_type: 'authorization_code', | ||
client_id: $.auth.data.clientId, | ||
client_secret: $.auth.data.clientSecret, | ||
code: $.auth.data.code, | ||
redirect_uri: redirectUri, | ||
}; | ||
|
||
const { data } = await $.http.post(`/v1/oauth/token`, null, { | ||
params, | ||
}); | ||
|
||
await $.auth.set({ | ||
accessToken: data.access_token, | ||
tokenType: data.token_type, | ||
}); | ||
|
||
const currentUser = await getCurrentUser($); | ||
|
||
await $.auth.set({ | ||
userId: data.user_id, | ||
refreshToken: data.refresh_token, | ||
expiresIn: data.expires_in, | ||
teamId: data.team_id, | ||
scope: data.scope, | ||
clientId: $.auth.data.clientId, | ||
clientSecret: $.auth.data.clientSecret, | ||
screenName: currentUser.name, | ||
}); | ||
}; | ||
|
||
export default verifyCredentials; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import { TBeforeRequest } from '@automatisch/types'; | ||
|
||
const addAuthHeader: TBeforeRequest = ($, requestConfig) => { | ||
if ($.auth.data?.accessToken) { | ||
requestConfig.headers.Authorization = `${$.auth.data.tokenType} ${$.auth.data.accessToken}`; | ||
} | ||
|
||
return requestConfig; | ||
}; | ||
|
||
export default addAuthHeader; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import { IGlobalVariable } from '@automatisch/types'; | ||
|
||
const getCurrentUser = async ($: IGlobalVariable) => { | ||
const { data } = await $.http.get( | ||
`https://api.miro.com/v1/oauth-token?access_token=${$.auth.data.accessToken}` | ||
); | ||
return data.user; | ||
}; | ||
|
||
export default getCurrentUser; |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import defineApp from '../../helpers/define-app'; | ||
import addAuthHeader from './common/add-auth-header'; | ||
import auth from './auth'; | ||
import actions from './actions'; | ||
|
||
export default defineApp({ | ||
name: 'Miro', | ||
key: 'miro', | ||
baseUrl: 'https://miro.com', | ||
apiBaseUrl: 'https://api.miro.com', | ||
iconUrl: '{BASE_URL}/apps/miro/assets/favicon.svg', | ||
authDocUrl: 'https://automatisch.io/docs/apps/miro/connection', | ||
primaryColor: 'F2CA02', | ||
supportsConnections: true, | ||
beforeRequest: [addAuthHeader], | ||
auth, | ||
actions, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
--- | ||
favicon: /favicons/miro.svg | ||
items: | ||
- name: Create board | ||
desc: Creates a new board. | ||
--- | ||
|
||
<script setup> | ||
import CustomListing from '../../components/CustomListing.vue' | ||
</script> | ||
|
||
<CustomListing /> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# Miro | ||
|
||
:::info | ||
This page explains the steps you need to follow to set up the Miro | ||
connection in Automatisch. If any of the steps are outdated, please let us know! | ||
::: | ||
|
||
1. Go to [link](https://miro.com/signup/) to create a user account in Miro. | ||
2. After signin in, go to [link](https://miro.com/app/dashboard/?createDevTeam=1) to create a developer team. | ||
3. In the **Create new team** modal, select the checkbox and then click **Create team** button. | ||
4. After that, click **Create new app** in Your app section. | ||
5. Fill the field of **App Name**. | ||
6. Select the **Expire user authorization token** checkbox and click the **Create app**. | ||
7. Copy **OAuth Redirect URL** from Automatisch to the **Redirect URI for OAuth2.0** field. | ||
8. Give permissions for **boards**, **identity**, and **team** scopes in Permissions field. | ||
9. Copy the **Client ID** value to the `Client ID` field on Automatisch. | ||
10. Copy the **Client secret** value to the `Client Secret` field on Automatisch. | ||
11. Click **Submit** button on Automatisch. | ||
12. Congrats! Start using your new Miro connection within the flows. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.