Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
aa771ff
feat(integrations): helper integration for creating the faq counter t…
mpetruu May 2, 2025
fa86f10
feat(plugins): init template for faq hook
mpetruu May 2, 2025
42fe2b6
fix(plugins): table capabilities
mpetruu May 2, 2025
b5f25d3
fix(plugins): table is created if not existing on first user message
mpetruu May 2, 2025
0f3b0e4
chore: removing the unneeded helper integration
mpetruu May 2, 2025
3c4b57e
fix(plugin/faq): replacing the vanilla client with the props client
mpetruu May 5, 2025
e17bfd8
fix(plugin): refactor of error, vanilla-client, and table handling
mpetruu May 5, 2025
6d5dd74
chore(plugin): fix typing for props logger
mpetruu May 5, 2025
4b69b04
feat(plugin/faq): table configuration schema
mpetruu May 6, 2025
2e1db72
fix(plugin/faq): table name safety
mpetruu May 6, 2025
7dc2219
chore: description update
mpetruu May 6, 2025
50f3d75
chore: naming convention for configurations
mpetruu May 6, 2025
0b77e59
feat(plugin/faq): zai packaging added + legacy peer deps
mpetruu May 6, 2025
1ad9c3b
chore(plugin/faq): version bump
mpetruu May 6, 2025
25391eb
fix(plugin/faq): "deadlock" fixed when manually adding rows
mpetruu May 6, 2025
eb25835
chore(plugin/faq): refactor
mpetruu May 6, 2025
e199f10
feat(plugin/faq): processing feature added
mpetruu May 6, 2025
80397b0
fix(plugin/faq): duplicate processing check
mpetruu May 6, 2025
ea6aafc
fix(plugin/faq): added defensive handling to states
mpetruu May 6, 2025
e9205ee
chore(plugin/faq): spacing refactor
mpetruu May 6, 2025
b0a65d2
[WIP] feat(plugin/faq): after hook refactors
mpetruu May 7, 2025
da86108
chore: complete stack trace for faq error logging
mpetruu May 8, 2025
c2f08c9
chore: prettier + type expectances
mpetruu May 8, 2025
834f1f3
fix(plugin/faq): replacement of zod with internal zod fork
mpetruu May 8, 2025
78b0b34
fix(plugin/faq): (intermediate value).split is not a function prevention
mpetruu May 8, 2025
a0d07b8
chore: increased logging (yes i brought back split im trying to test)
mpetruu May 8, 2025
9076403
[WIP] fix(plugin/faq): extraction updates
mpetruu May 8, 2025
2d68ca6
fix(plugin/faq): works! (now I can focus on optimization on costs + c…
mpetruu May 8, 2025
c19bf01
fix(plugin/faq): prompt engineering
mpetruu May 8, 2025
d727425
chore(plugin/faq): version bump
mpetruu May 8, 2025
1ea3bb1
fix(plugin/faq): hard-coding an entity check
mpetruu May 8, 2025
06521ec
chore(plugin/faq): slight refactor
mpetruu May 9, 2025
90c1e21
chore(plugin/faq): global schema
mpetruu May 9, 2025
a275498
chore: small refactor
mpetruu May 9, 2025
5741073
chore: defensive handling for non-standard errors
mpetruu May 9, 2025
05a3050
chore: more refactors
mpetruu May 9, 2025
74cd9e2
chore: safe creation and safe state refactor
mpetruu May 9, 2025
a64894a
chore: prettier
mpetruu May 9, 2025
3378103
fix(plugin/faq): forcing the JSON schema from zai
mpetruu May 12, 2025
524bf05
fix: state checker
mpetruu May 12, 2025
6c2ca98
chore: json
mpetruu May 12, 2025
d1601ab
fix: massive refactors + optimization
mpetruu May 12, 2025
59493b8
fix: MASSIVE semantic fixes + refactors!
mpetruu May 12, 2025
136059c
chore: version bump
mpetruu May 12, 2025
123ad14
fix(plugin/faq): access denied error
mpetruu May 12, 2025
fa478da
chore: version bump from studio
mpetruu May 12, 2025
22a65f6
fix: icon
mpetruu May 13, 2025
798e0f8
fix
mpetruu May 13, 2025
0c3bb8d
chore: version bump
mpetruu May 13, 2025
71db5b6
minor refactor
mpetruu May 15, 2025
17cb713
minor refactor
mpetruu May 15, 2025
1f8fb46
fix: some any types
mpetruu May 15, 2025
59b5e1e
woops reverting client (my mistake)
mpetruu May 15, 2025
63bbc4b
merging from master (#78)
mpetruu May 20, 2025
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
27 changes: 27 additions & 0 deletions .github/actions/setup/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: Setup
description: install dependencies and build

inputs:
extra_filters:
description: 'Turbo additional filters to select packages to build'
required: false

runs:
using: 'composite'
steps:
- uses: pnpm/action-setup@v4
with:
version: 8.6.2

- uses: actions/setup-node@v3
with:
node-version: '18.x'
check-latest: true

- name: Install dependencies
shell: ${{ runner.os == 'Windows' && 'pwsh' || 'bash' }}
run: pnpm i --frozen-lockfile

- name: Build
shell: ${{ runner.os == 'Windows' && 'pwsh' || 'bash' }}
run: pnpm build ${{ inputs.extra_filters }}
30 changes: 30 additions & 0 deletions .github/scripts/check-integration-version-without-build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#!/bin/bash

if [ -z "$1" ]; then
echo "Error: integration name is not provided" >&2
exit 1
fi

integration=$1
integration_path="integrations/$integration"

definition_file="$integration_path/integration.definition.ts"
if [ ! -f "$definition_file" ]; then
echo "Error: integration definition file not found at $definition_file" >&2
exit 1
fi

version=$(grep -o "version: ['\"].*['\"]" "$definition_file" | head -1 | sed "s/version: ['\"]//g" | sed "s/['\"]//g")
name=$(grep -o "name: ['\"].*['\"]" "$definition_file" | head -1 | sed "s/name: ['\"]//g" | sed "s/['\"]//g" | sed "s/.*\\///g")

if [[ "$name" == *integrationName* ]] || [ -z "$name" ]; then
name=$(grep -o "\"integrationName\": ['\"].*['\"]" "$integration_path/package.json" | head -1 | sed "s/\"integrationName\": ['\"]//g" | sed "s/['\"]//g")
fi

if [ -n "$version" ] && [ -n "$name" ]; then
exists=$(pnpm bp integrations ls --name "$name" --version-number "$version" --json | jq '[ .[] | select(.public) ] | length')
echo $exists
else
echo "Error: Could not extract version or name from integration" >&2
exit 2
fi
14 changes: 14 additions & 0 deletions .github/scripts/integration-exists.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
if [ -z "$1" ]; then
echo "Error: integration name is not provided" >&2
exit 1
fi
integration=$1

integration_path="integrations/$integration"
integration_def=$(pnpm bp read --work-dir $integration_path --json)

name=$(echo $integration_def | jq -r ".name")
version=$(echo $integration_def | jq -r ".version")

exists=$(pnpm bp integrations ls --name $name --version-number $version --json | jq '[ .[] | select(.public) ] | length') # 0 if not exists
echo $exists
15 changes: 15 additions & 0 deletions .github/scripts/interface-exists.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
if [ -z "$1" ]; then
echo "Error: interface name is not provided" >&2
exit 1
fi
interface=$1

interface_path="interfaces/$interface"
interface_def=$(pnpm bp read --work-dir $interface_path --json)

name=$(echo $interface_def | jq -r ".name")
version=$(echo $interface_def | jq -r ".version")

command="pnpm bp interfaces get \"$name@$version\" --json >/dev/null 2>&1"
exists=$(eval $command && echo 1 || echo 0)
echo $exists
11 changes: 11 additions & 0 deletions .github/scripts/ls-sentry-integrations.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
sentry_integrations=( $(ls integrations/*/.sentryclirc) )

filter=""

for sentry_integration in "${sentry_integrations[@]}";
do
actual_integration=$(echo $sentry_integration | sed 's/\.sentryclirc//g')
filter="-F ./$actual_integration $filter"
done

echo $filter
15 changes: 15 additions & 0 deletions .github/scripts/plugin-exists.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
if [ -z "$1" ]; then
echo "Error: plugin name is not provided" >&2
exit 1
fi
plugin=$1

plugin_path="plugins/$plugin"
plugin_def=$(pnpm bp read --work-dir $plugin_path --json)

name=$(echo $plugin_def | jq -r ".name")
version=$(echo $plugin_def | jq -r ".version")

command="pnpm bp plugins get \"$name@$version\" --json >/dev/null 2>&1"
exists=$(eval $command && echo 1 || echo 0)
echo $exists
19 changes: 19 additions & 0 deletions .github/workflows/check-all-workflows.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: Check All
on:
pull_request:
branches:
- master

jobs:
check-all:
runs-on: ubuntu-latest
permissions:
checks: read
statuses: read
steps:
- name: Check All
uses: upsidr/merge-gatekeeper@v1
with:
timeout: 900 # 15 minutes
token: ${{ secrets.GITHUB_TOKEN }}
self: check-all
110 changes: 110 additions & 0 deletions .github/workflows/check-integration-naming.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
name: Check Integration Plus Prefix

on: pull_request

jobs:
check-integration-plus-prefix:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v2

- name: Create integration validation script
run: |
cat > ./validate-integration-plus-prefix.js << 'EOF'
const fs = require('fs');
const path = require('path');

function validateIntegration(integrationPath) {
const errors = [];

// CHECKING IF PACKAGE.JSON EXISTS

const packageJsonPath = path.join(integrationPath, 'package.json');
let packageJson = null;
if (fs.existsSync(packageJsonPath)) {
try {
packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));

// CHECKING IF INTEGRATION NAME EXISTS AND STARTS WITH PLUS/

if (!packageJson.integrationName) {
errors.push(`Missing 'integrationName' in package.json`);
} else if (!packageJson.integrationName.startsWith('plus/')) {
errors.push(`'integrationName' in package.json must start with 'plus/' prefix, found: ${packageJson.integrationName}`);
}
} catch (err) {
errors.push(`Error parsing package.json: ${err.message}`);
}
} else {
errors.push('package.json file not found');
}

// CHECKING IF INTEGRATION.DEFINITION.TS EXISTS

const definitionPath = path.join(integrationPath, 'integration.definition.ts');
if (fs.existsSync(definitionPath)) {
try {
const definition = fs.readFileSync(definitionPath, 'utf8');

// CHECKING IF NAME PROPERTY WITH PLUS/ PREFIX EXISTS

const nameMatch = definition.match(/name:\s*['"]([^'"]+)['"]/);
const nameVarMatch = definition.match(/name:\s*integrationName/);

if (!nameMatch && !nameVarMatch) {
errors.push('Could not find "name" property in integration.definition.ts');
} else if (nameMatch && !nameMatch[1].startsWith('plus/')) {
errors.push(`"name" in integration.definition.ts must start with 'plus/' prefix, found: ${nameMatch[1]}`);
} else if (nameVarMatch && packageJson) {
if (!packageJson.integrationName) {
errors.push('Using integrationName in definition but missing in package.json');
} else if (!packageJson.integrationName.startsWith('plus/')) {
errors.push(`'integrationName' in package.json must start with 'plus/' prefix, found: ${packageJson.integrationName}`);
}
}

// CHECKING IF TITLE PROPERTY EXISTS

const titleMatch = definition.match(/title:\s*['"]([^'"]+)['"]/);
if (!titleMatch) {
errors.push('Could not find "title" property in integration.definition.ts');
}
} catch (err) {
errors.push(`Error reading integration.definition.ts: ${err.message}`);
}
} else {
errors.push('integration.definition.ts file not found');
}

return errors;
}

const integrationsDir = './integrations';
const integrationDirs = fs.readdirSync(integrationsDir)
.filter(file => fs.statSync(path.join(integrationsDir, file)).isDirectory());

let validationFailed = false;

integrationDirs.forEach(integration => {
const integrationPath = path.join(integrationsDir, integration);
const errors = validateIntegration(integrationPath);

if (errors.length > 0) {
console.error(`❌ Validation failed for ${integration}:`);
errors.forEach(error => console.error(` - ${error}`));
validationFailed = true;
} else {
console.log(`✅ Integration ${integration} passed validation`);
}
});

if (validationFailed) {
process.exit(1);
}
EOF

chmod +x ./validate-integration-plus-prefix.js

- name: Check all integrations
run: node ./validate-integration-plus-prefix.js
88 changes: 88 additions & 0 deletions .github/workflows/check-integration-versions.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
name: Check Integration Versions

on: pull_request

permissions:
id-token: write
contents: read

jobs:
check-integration-versions:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v2
- name: Setup
uses: ./.github/actions/setup
- name: Login to Botpress
run: pnpm bp login -y --token ${{ secrets.ERMEK_PROD_PAT }} --workspace-id ${{ secrets.BP_WORKSPACEID_PROD }}
- name: Get changed files
id: changed-files
uses: tj-actions/changed-files@v46
with:
files: 'integrations/**/*.{ts,md,svg,json}'
separator: '\n'
- name: Create version check script
run: |
cat > ./.github/scripts/check-integration-version-without-build.sh << 'EOF'
#!/bin/bash

if [ -z "$1" ]; then
echo "Error: integration name is not provided" >&2
exit 1
fi

integration=$1
integration_path="integrations/$integration"

# Extract the version directly from integration.definition.ts using grep and sed
definition_file="$integration_path/integration.definition.ts"
if [ ! -f "$definition_file" ]; then
echo "Error: integration definition file not found at $definition_file" >&2
exit 1
fi

# Get the version from the definition file
version=$(grep -o "version: ['\"].*['\"]" "$definition_file" | head -1 | sed "s/version: ['\"]//g" | sed "s/['\"]//g")
name=$(grep -o "name: ['\"].*['\"]" "$definition_file" | head -1 | sed "s/name: ['\"]//g" | sed "s/['\"]//g" | sed "s/.*\\///g")

# If no name found or using package.json reference, try to get from package.json
if [[ "$name" == *integrationName* ]] || [ -z "$name" ]; then
name=$(grep -o "\"integrationName\": ['\"].*['\"]" "$integration_path/package.json" | head -1 | sed "s/\"integrationName\": ['\"]//g" | sed "s/['\"]//g")
fi

# Check if this version already exists in production
if [ -n "$version" ] && [ -n "$name" ]; then
exists=$(pnpm bp integrations ls --name "$name" --version-number "$version" --json | jq '[ .[] | select(.public) ] | length')
echo $exists
else
echo "Error: Could not extract version or name from integration" >&2
exit 2
fi
EOF

chmod +x ./.github/scripts/check-integration-version-without-build.sh
- name: Check integration versions
run: |
modified_integrations=$(echo -e "${{ steps.changed-files.outputs.all_changed_files }}" | awk -F'/' '{print $2}' | sort -u)

should_fail=0

for integration in $modified_integrations; do
echo "Checking $integration"
if [ -d "integrations/$integration" ]; then
exists=$(./.github/scripts/check-integration-version-without-build.sh $integration)

if [ "$exists" -ne 0 ]; then
echo "Integration $integration is already deployed publicly with the same version. Please update the version of your integration."
should_fail=1
fi
else
echo "Integration directory not found: integrations/$integration"
fi
done

if [ $should_fail -ne 0 ]; then
echo "Please update the version of your integration before pushing your changes."
exit 1
fi
22 changes: 22 additions & 0 deletions CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Global
* @botpress/growth

# Kitchen Sink
/advanced-starter-bot-template @matthewbotpress @botpress/growth

# Integration Runner
/bp-integration-runner @aj-botpress @botpress/growth

# Integrations
/integrations/gohighlevel @matthewbotpress @botpress/growth
/integrations/google-chat-spaces @matthewbotpress @botpress/growth
/integrations/hitl-api @ptrckbp @botpress/growth
/integrations/hitl-salesforce @davidvitora @botpress/growth
/integrations/hubspot-hitl @ermek-botpress @botpress/growth
/integrations/huggingface @ermek-botpress @botpress/growth
/integrations/salesforce @ermek-botpress @botpress/growth
/integrations/sharepoint @aj-botpress @botpress/growth
/integrations/twiliovoice @ermek-botpress @botpress/growth
/integrations/zoho-sales-iq-hitl @matthewbotpress @botpress/growth

# Plugins (coming soon)
Loading
Loading