Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion integrations/airtable/integration.definition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export default new IntegrationDefinition({
title: 'Airtable',
description:
'Access and manage Airtable data to allow your chatbot to retrieve details, update records, and organize information.',
version: '3.0.0',
version: '3.0.2',
readme: 'hub.md',
icon: 'icon.svg',
configuration: {
Expand Down
3 changes: 1 addition & 2 deletions integrations/airtable/src/oauth-wizard/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { generateRedirection } from '@botpress/common/src/html-dialogs'
import { isOAuthWizardUrl, getInterstitialUrl } from '@botpress/common/src/oauth-wizard'
import { isOAuthWizardUrl, getInterstitialUrl, generateRedirection } from '@botpress/common/src/oauth-wizard'
import * as wizard from './wizard'
import * as bp from '.botpress'

Expand Down
2 changes: 1 addition & 1 deletion integrations/bamboohr/integration.definition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { IntegrationDefinition, z } from '@botpress/sdk'
import { actions, events, subdomain } from './definitions'

export const INTEGRATION_NAME = 'bamboohr'
export const INTEGRATION_VERSION = '2.1.2'
export const INTEGRATION_VERSION = '2.1.3'

export default new IntegrationDefinition({
name: INTEGRATION_NAME,
Expand Down
3 changes: 1 addition & 2 deletions integrations/bamboohr/src/handlers/oauth.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { generateRedirection } from '@botpress/common/src/html-dialogs'
import { isOAuthWizardUrl, getInterstitialUrl } from '@botpress/common/src/oauth-wizard'
import { isOAuthWizardUrl, getInterstitialUrl, generateRedirection } from '@botpress/common/src/oauth-wizard'
import * as wizard from '../wizard'
import * as bp from '.botpress'

Expand Down
2 changes: 1 addition & 1 deletion integrations/calendly/integration.definition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { inviteeEventOutputSchema } from 'definitions/events'
export default new IntegrationDefinition({
name: 'calendly',
title: 'Calendly',
version: '0.0.5',
version: '0.0.6',
readme: 'hub.md',
icon: 'icon.svg',
description: 'Schedule meetings and manage events using the Calendly scheduling platform.',
Expand Down
1 change: 1 addition & 0 deletions integrations/calendly/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"private": true,
"dependencies": {
"@botpress/client": "workspace:*",
"@botpress/common": "workspace:*",
"@botpress/sdk": "workspace:*",
"axios": "^1.11.0"
},
Expand Down
3 changes: 3 additions & 0 deletions integrations/calendly/src/calendly-api/auth.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { handleErrorsDecorator as handleErrors } from '@botpress/common'
import { RuntimeError } from '@botpress/sdk'
import axios, { type AxiosInstance } from 'axios'
import type { CommonHandlerProps, Result } from '../types'
Expand Down Expand Up @@ -47,6 +48,7 @@ export class CalendlyAuthClient {
return { success: true, data: result.data }
}

@handleErrors('Failed to obtain Calendly OAuth access token from authorization code')
public async getAccessTokenWithCode(code: string): Promise<Result<GetOAuthAccessTokenResp>> {
return this._getAccessToken({
grant_type: 'authorization_code',
Expand All @@ -55,6 +57,7 @@ export class CalendlyAuthClient {
})
}

@handleErrors('Failed to refresh Calendly OAuth access token')
public async getAccessTokenWithRefreshToken(refreshToken: string): Promise<Result<GetOAuthAccessTokenResp>> {
return this._getAccessToken({
grant_type: 'refresh_token',
Expand Down
29 changes: 23 additions & 6 deletions integrations/calendly/src/handler.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { generateRedirection, getInterstitialUrl } from '@botpress/common/src/oauth-wizard/interstitial'
import { exchangeAuthCodeForRefreshToken } from './calendly-api/auth'
import { dispatchIntegrationEvent } from './webhooks/event-dispatcher'
import { parseWebhookEvent, verifyWebhookSignature } from './webhooks/webhook-utils'
Expand All @@ -7,24 +8,40 @@ const _isOauthRequest = ({ req }: bp.HandlerProps) => req.path === '/oauth'

export const handler = async (props: bp.HandlerProps) => {
if (_isOauthRequest(props)) {
const oAuthCode = new URLSearchParams(props.req.query).get('code')
if (oAuthCode === null) throw new Error('Missing authentication code')
try {
const searchParams = new URLSearchParams(props.req.query)
const error = searchParams.get('error')
if (error) {
throw new Error(`${error} - ${searchParams.get('error_description') ?? ''}`)
}

await exchangeAuthCodeForRefreshToken(props, oAuthCode)
return
const oAuthCode = searchParams.get('code')
if (!oAuthCode) {
throw new Error('Authorization code not present in OAuth callback')
}

await exchangeAuthCodeForRefreshToken(props, oAuthCode)
return generateRedirection(getInterstitialUrl(true))
} catch (err) {
const msg = err instanceof Error ? err.message : String(err)
const errorMessage = 'OAuth error: ' + msg
props.logger.forBot().error(errorMessage)
return generateRedirection(getInterstitialUrl(false, errorMessage))
}
}

const signatureResult = await verifyWebhookSignature(props)
if (!signatureResult.success) {
props.logger.forBot().error(signatureResult.error.message, signatureResult.error)
return
return {}
}

const result = parseWebhookEvent(props)
if (!result.success) {
props.logger.forBot().error(result.error.message, result.error)
return
return {}
}

await dispatchIntegrationEvent(props, result.data)
return {}
}
4 changes: 3 additions & 1 deletion integrations/calendly/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
"extends": "../../tsconfig.json",
"compilerOptions": {
"paths": { "*": ["./*"] },
"outDir": "dist"
"outDir": "dist",
"experimentalDecorators": true,
"emitDecoratorMetadata": true
},
"include": [".botpress/**/*", "definitions/**/*", "src/**/*", "*.ts"]
}
2 changes: 1 addition & 1 deletion integrations/docusign/integration.definition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { envelopeEventSchema } from 'definitions/events'
export default new IntegrationDefinition({
name: 'docusign',
title: 'Docusign',
version: '2.1.2',
version: '2.1.3',
readme: 'hub.md',
icon: 'icon.svg',
description:
Expand Down
1 change: 1 addition & 0 deletions integrations/docusign/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"private": true,
"dependencies": {
"@botpress/client": "workspace:*",
"@botpress/common": "workspace:*",
"@botpress/sdk": "workspace:*",
"axios": "^1.12.2",
"docusign-esign": "^8.4.0"
Expand Down
4 changes: 4 additions & 0 deletions integrations/docusign/src/docusign-api/auth.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { handleErrorsDecorator as handleErrors } from '@botpress/common'
import { RuntimeError } from '@botpress/sdk'
import axios, { type AxiosInstance } from 'axios'
import type { CommonHandlerProps, Result } from '../types'
Expand Down Expand Up @@ -74,20 +75,23 @@ export class DocusignAuthClient {
}
}

@handleErrors('Failed to obtain Docusign OAuth access token from authorization code')
public async getAccessTokenWithCode(code: string): Promise<Result<GetAccessTokenResp>> {
return this._getAccessToken({
grant_type: 'authorization_code',
code,
})
}

@handleErrors('Failed to refresh Docusign OAuth access token')
public async getAccessTokenWithRefreshToken(refreshToken: string): Promise<Result<GetAccessTokenResp>> {
return this._getAccessToken({
grant_type: 'refresh_token',
refresh_token: refreshToken,
})
}

@handleErrors('Failed to retrieve Docusign user info')
public async getUserInfo(accessToken: string, tokenType: string): Promise<Result<GetUserInfoResp>> {
const resp = await this._axiosClient.get('/oauth/userinfo', {
headers: {
Expand Down
29 changes: 23 additions & 6 deletions integrations/docusign/src/handler.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { generateRedirection, getInterstitialUrl } from '@botpress/common/src/oauth-wizard/interstitial'
import { exchangeAuthCodeForRefreshToken } from './docusign-api/auth-utils'
import { dispatchIntegrationEvent } from './webhooks/event-dispatcher'
import { parseWebhookEvent, verifyWebhookSignature } from './webhooks/utils'
Expand All @@ -7,24 +8,40 @@ const _isOauthRequest = ({ req }: bp.HandlerProps) => req.path === '/oauth'

export const handler = async (props: bp.HandlerProps) => {
if (_isOauthRequest(props)) {
const oAuthCode = new URLSearchParams(props.req.query).get('code')
if (oAuthCode === null) throw new Error('Missing authentication code')
try {
const searchParams = new URLSearchParams(props.req.query)
const error = searchParams.get('error')
if (error) {
throw new Error(`${error} - ${searchParams.get('error_description') ?? ''}`)
}

await exchangeAuthCodeForRefreshToken(props, oAuthCode)
return
const oAuthCode = searchParams.get('code')
if (!oAuthCode) {
throw new Error('Authorization code not present in OAuth callback')
}

await exchangeAuthCodeForRefreshToken(props, oAuthCode)
return generateRedirection(getInterstitialUrl(true))
} catch (err) {
const msg = err instanceof Error ? err.message : String(err)
const errorMessage = 'OAuth error: ' + msg
props.logger.forBot().error(errorMessage)
return generateRedirection(getInterstitialUrl(false, errorMessage))
}
}

const signatureResult = verifyWebhookSignature(props)
if (!signatureResult.success) {
props.logger.forBot().error(signatureResult.error.message, signatureResult.error)
return
return {}
}

const result = parseWebhookEvent(props)
if (!result.success) {
props.logger.forBot().error(result.error.message, result.error)
return
return {}
}

await dispatchIntegrationEvent(props, result.data)
return {}
}
4 changes: 3 additions & 1 deletion integrations/docusign/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
"extends": "../../tsconfig.json",
"compilerOptions": {
"paths": { "*": ["./*"] },
"outDir": "dist"
"outDir": "dist",
"experimentalDecorators": true,
"emitDecoratorMetadata": true
},
"include": [".botpress/**/*", "definitions/**/*", "src/**/*", "*.ts"]
}
2 changes: 1 addition & 1 deletion integrations/dropbox/integration.definition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { actions, configuration, configurations, entities, secrets, states } fro
export default new sdk.IntegrationDefinition({
name: 'dropbox',
title: 'Dropbox',
version: '2.0.2',
version: '2.0.3',
description: 'Manage your files and folders effortlessly.',
readme: 'hub.md',
icon: 'icon.svg',
Expand Down
3 changes: 1 addition & 2 deletions integrations/dropbox/src/webhook-events/oauth/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { generateRedirection } from '@botpress/common/src/html-dialogs'
import { isOAuthWizardUrl, getInterstitialUrl } from '@botpress/common/src/oauth-wizard'
import { isOAuthWizardUrl, getInterstitialUrl, generateRedirection } from '@botpress/common/src/oauth-wizard'
import * as wizard from './wizard'
import * as bp from '.botpress'

Expand Down
2 changes: 1 addition & 1 deletion integrations/github/integration.definition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { actions, events, configuration, configurations, channels, user, secrets
export default new sdk.IntegrationDefinition({
name: INTEGRATION_NAME,
title: 'GitHub',
version: '1.2.1',
version: '1.2.2',
icon: 'icon.svg',
readme: 'hub.md',
description: 'Manage GitHub issues, pull requests, and repositories.',
Expand Down
14 changes: 10 additions & 4 deletions integrations/github/src/handler.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { generateRedirection, getInterstitialUrl } from '@botpress/common/src/oauth-wizard/interstitial'
import * as sdk from '@botpress/sdk'
import { verify as verifyWebhook } from '@octokit/webhooks-methods'
import type { WebhookEvent } from '@octokit/webhooks-types'
Expand Down Expand Up @@ -69,10 +70,15 @@ const _isOauthRequest = ({ req }: bp.HandlerProps) => req.path === '/oauth'

const _handleOauthRequest = async ({ req, client, ctx, logger }: bp.HandlerProps) => {
logger.forBot().info('Handling incoming OAuth callback')
return _handleOauth(req, client, ctx).catch((err) => {
logger.forBot().error('Error while processing OAuth callback', err.response?.data || err.message)
throw err
})
try {
await _handleOauth(req, client, ctx)
return generateRedirection(getInterstitialUrl(true))
} catch (err) {
const msg = err instanceof Error ? err.message : String(err)
const errorMessage = 'OAuth error: ' + msg
logger.forBot().error(errorMessage)
return generateRedirection(getInterstitialUrl(false, errorMessage))
}
}

const _handleOauth = async (req: sdk.Request, client: bp.Client, ctx: bp.Context) => {
Expand Down
8 changes: 1 addition & 7 deletions integrations/github/src/misc/error-handling.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1 @@
import { createAsyncFnWrapperWithErrorRedaction } from '@botpress/common'
import * as sdk from '@botpress/sdk'

export const wrapAsyncFnWithTryCatch = createAsyncFnWrapperWithErrorRedaction((originalError, customErrorMessage) => {
console.info(customErrorMessage, originalError)
return new sdk.RuntimeError(customErrorMessage)
})
export { wrapAsyncFnWithTryCatch, handleErrorsDecorator } from '@botpress/common'
2 changes: 1 addition & 1 deletion integrations/gmail/integration.definition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
} from './definitions'

export const INTEGRATION_NAME = 'gmail'
export const INTEGRATION_VERSION = '1.0.7'
export const INTEGRATION_VERSION = '1.0.8'

export default new sdk.IntegrationDefinition({
name: INTEGRATION_NAME,
Expand Down
2 changes: 2 additions & 0 deletions integrations/gmail/src/google-api/google-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as sdk from '@botpress/sdk'
import { gmail_v1, google } from 'googleapis'
import { IntegrationConfig } from 'src/config/integration-config'
import { composeRawEmail } from 'src/utils/mail-composing'
import { handleErrorsDecorator as handleErrors } from './error-handling'
import { GmailClient, GoogleOAuth2Client } from './types'
import * as bp from '.botpress'

Expand Down Expand Up @@ -53,6 +54,7 @@ export class GoogleClient {
return new GoogleClient(gmailClient, topicName)
}

@handleErrors('Failed to obtain Gmail OAuth refresh token from authorization code')
public static async createFromAuthorizationCode({
client,
ctx,
Expand Down
1 change: 1 addition & 0 deletions integrations/gmail/src/webhook-events/handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export const handler = async (props: bp.HandlerProps) => {
}

await handleIncomingEmail(props)
return {}
}

/*
Expand Down
Loading
Loading