1 Commits

Author SHA1 Message Date
poduck
3aa7199503 Add Activepieces integration for workflow automation
- Add Activepieces fork with SmoothSchedule custom piece
- Create integrations app with Activepieces service layer
- Add embed token endpoint for iframe integration
- Create Automations page with embedded workflow builder
- Add sidebar visibility fix for embed mode
- Add list inactive customers endpoint to Public API
- Include SmoothSchedule triggers: event created/updated/cancelled
- Include SmoothSchedule actions: create/update/cancel events, list resources/services/customers

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-18 22:59:37 -05:00
16292 changed files with 1284892 additions and 4708 deletions

4
activepieces-fork/.npmrc Normal file
View File

@@ -0,0 +1,4 @@
@activepieces:registry=https://registry.npmjs.org/
//registry.npmjs.org/:_authToken=${NPM_TOKEN}
legacy-peer-deps=true
save-exact=true

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,30 @@
{
"name": "nx-cloud-client-bundle",
"version": "0.0.1",
"type": "commonjs",
"main": "index.js",
"author": "Victor Savkin",
"license": "proprietary",
"dependencies": {
"@opentelemetry/api": "^1.9.0",
"@opentelemetry/context-async-hooks": "^1.30.1",
"@opentelemetry/core": "^1.30.1",
"@opentelemetry/resources": "^1.30.1",
"@opentelemetry/sdk-trace-base": "^1.30.1",
"@opentelemetry/semantic-conventions": "^1.29.0",
"axios": "1.1.3",
"enquirer": "2.4.1",
"dotenv": "~10.0.0",
"node-machine-id": "^1.1.12",
"tar": "6.1.11",
"strip-json-comments": "^5.0.1",
"chalk": "4.1.2",
"yargs-parser": "21.1.1",
"fs-extra": "^11.1.0",
"open": "~8.4.0",
"html-entities": "^2.6.0",
"ini": "4.1.3",
"yaml": "2.6.1",
"semver": "7.5.4"
}
}

View File

@@ -0,0 +1,414 @@
<html>
<head>
<title>Nx Cloud login</title>
<style>
*,
:before,
:after {
-webkit-text-size-adjust: 100%;
tab-size: 4;
font-family:
ui-sans-serif,
system-ui,
sans-serif,
'Apple Color Emoji',
'Segoe UI Emoji',
Segoe UI Symbol,
'Noto Color Emoji';
font-feature-settings: normal;
font-variation-settings: normal;
-webkit-tap-highlight-color: transparent;
line-height: inherit;
--tw-text-opacity: 1;
color: rgb(51 65 85 / var(--tw-text-opacity));
box-sizing: border-box;
border-width: 0;
border-style: solid;
--tw-border-spacing-x: 0;
--tw-border-spacing-y: 0;
--tw-translate-x: 0;
--tw-translate-y: 0;
--tw-rotate: 0;
--tw-skew-x: 0;
--tw-skew-y: 0;
--tw-scale-x: 1;
--tw-scale-y: 1;
--tw-pan-x: ;
--tw-pan-y: ;
--tw-pinch-zoom: ;
--tw-scroll-snap-strictness: proximity;
--tw-gradient-from-position: ;
--tw-gradient-via-position: ;
--tw-gradient-to-position: ;
--tw-ordinal: ;
--tw-slashed-zero: ;
--tw-numeric-figure: ;
--tw-numeric-spacing: ;
--tw-numeric-fraction: ;
--tw-ring-inset: ;
--tw-ring-offset-width: 0px;
--tw-ring-offset-color: #fff;
--tw-ring-color: rgb(59 130 246 / 0.5);
--tw-ring-offset-shadow: 0 0 #0000;
--tw-ring-shadow: 0 0 #0000;
--tw-shadow: 0 0 #0000;
--tw-shadow-colored: 0 0 #0000;
--tw-blur: ;
--tw-brightness: ;
--tw-contrast: ;
--tw-grayscale: ;
--tw-hue-rotate: ;
--tw-invert: ;
--tw-saturate: ;
--tw-sepia: ;
--tw-drop-shadow: ;
--tw-backdrop-blur: ;
--tw-backdrop-brightness: ;
--tw-backdrop-contrast: ;
--tw-backdrop-grayscale: ;
--tw-backdrop-hue-rotate: ;
--tw-backdrop-invert: ;
--tw-backdrop-opacity: ;
--tw-backdrop-saturate: ;
--tw-backdrop-sepia: ;
--tw-contain-size: ;
--tw-contain-layout: ;
--tw-contain-paint: ;
--tw-contain-style: ;
/*border-bottom-width: 1px;*/
--tw-border-opacity: 1;
border-color: rgb(226 232 240 / var(--tw-border-opacity));
--tw-bg-opacity: 1;
background-color: rgb(255 255 255 / var(--tw-bg-opacity));
}
.mx-auto {
margin-left: auto;
margin-right: auto;
}
.mb-2 {
margin-bottom: 0.5rem;
}
.mt-20 {
margin-top: 5rem;
}
.flex {
display: flex;
}
.hidden {
display: none;
}
.h-14 {
height: 3.5rem;
}
.h-5 {
height: 1.25rem;
}
.h-6 {
height: 1.5rem;
}
.min-h-full {
min-height: 100%;
}
.w-5 {
width: 1.25rem;
}
.w-6 {
width: 1.5rem;
}
.w-auto {
width: auto;
}
.max-w-7xl {
max-width: 80rem;
}
.flex-shrink-0 {
flex-shrink: 0;
}
.flex-col {
flex-direction: column;
}
.items-start {
align-items: flex-start;
}
.items-center {
align-items: center;
}
.justify-center {
justify-content: center;
}
.justify-between {
justify-content: space-between;
}
.gap-4 {
gap: 1rem;
}
.gap-8 {
gap: 2rem;
}
.border-b {
border-bottom-width: 1px;
}
.border-t {
border-top-width: 1px;
}
.border-slate-100 {
--tw-border-opacity: 1;
border-color: rgb(241 245 249 / var(--tw-border-opacity));
}
.border-slate-200 {
--tw-border-opacity: 1;
border-color: rgb(226 232 240 / var(--tw-border-opacity));
}
.bg-white {
--tw-bg-opacity: 1;
background-color: rgb(255 255 255 / var(--tw-bg-opacity));
}
.p-8 {
padding: 2rem;
}
.px-4 {
padding-left: 1rem;
padding-right: 1rem;
}
.px-40 {
padding-left: 10rem;
padding-right: 10rem;
}
.py-10 {
padding-top: 2.5rem;
padding-bottom: 2.5rem;
}
.text-2xl {
font-size: 1.5rem;
line-height: 2rem;
}
.text-xs {
font-size: 0.75rem;
line-height: 1rem;
}
.text-wrap {
max-width: 100%;
word-wrap: break-word;
}
.font-bold {
font-weight: 700;
}
.font-semibold {
font-weight: 600;
}
.italic {
font-style: italic;
}
.leading-7 {
line-height: 1.75rem;
}
.text-slate-400 {
--tw-text-opacity: 1;
color: rgb(148 163 184 / var(--tw-text-opacity));
}
.text-slate-700 {
--tw-text-opacity: 1;
color: rgb(51 65 85 / var(--tw-text-opacity));
}
.text-slate-900 {
--tw-text-opacity: 1;
color: rgb(15 23 42 / var(--tw-text-opacity));
}
.underline {
text-decoration-line: underline;
}
.opacity-50 {
opacity: 0.5;
}
.opacity-25 {
opacity: 0.3;
}
.transition {
transition-property: color, background-color, border-color,
text-decoration-color, fill, stroke, opacity, box-shadow, transform,
filter, backdrop-filter;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
transition-duration: 0.15s;
}
body {
min-height: 100%;
height: 100%;
}
a {
color: inherit;
text-decoration: inherit;
}
.hover\:opacity-100:hover {
opacity: 1;
}
@media (min-width: 640px) {
.sm\:-my-px {
margin-top: -1px;
margin-bottom: -1px;
}
.sm\:ml-6 {
margin-left: 1.5rem;
}
.sm\:flex {
display: flex;
}
.sm\:truncate {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.sm\:px-6 {
padding-left: 1.5rem;
padding-right: 1.5rem;
}
.sm\:text-3xl {
font-size: 1.875rem;
line-height: 2.25rem;
}
.sm\:tracking-tight {
letter-spacing: -0.025em;
}
}
@media (min-width: 768px) {
.md\:grid {
display: grid;
}
.md\:grid-cols-4 {
grid-template-columns: repeat(4, minmax(0, 1fr));
}
.md\:gap-4 {
gap: 1rem;
}
.md\:p-2 {
padding: 0.5rem;
}
}
@media (min-width: 1024px) {
.lg\:flex {
display: flex;
}
.lg\:px-8 {
padding-left: 2rem;
padding-right: 2rem;
}
}
</style>
</head>
<body>
<div class="min-h-full">
<nav class="border-b border-slate-200 bg-white">
<div class="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
<div class="flex h-14 justify-between">
<div class="flex">
<div class="flex flex-shrink-0 items-center">
<a href="{{ nxCloudUrl }}">
<svg
id="nx-cloud-header-logo"
role="img"
xmlns="http://www.w3.org/2000/svg"
stroke="currentColor"
fill="transparent"
viewBox="0 0 24 24"
class="h-6 w-6"
>
<path
stroke-width="2"
d="M23 3.75V6.5c-3.036 0-5.5 2.464-5.5 5.5s-2.464 5.5-5.5 5.5-5.5 2.464-5.5 5.5H3.75C2.232 23 1 21.768 1 20.25V3.75C1 2.232 2.232 1 3.75 1h16.5C21.768 1 23 2.232 23 3.75Z"
id="nx-cloud-header-logo-stroke-1"
></path>
<path
stroke-width="2"
d="M23 6v14.1667C23 21.7307 21.7307 23 20.1667 23H6c0-3.128 2.53867-5.6667 5.6667-5.6667 3.128 0 5.6666-2.5386 5.6666-5.6666C17.3333 8.53867 19.872 6 23 6Z"
id="nx-cloud-header-logo-stroke-2"
></path>
</svg>
</a>
</div>
<div class="hidden sm:-my-px sm:ml-6 sm:flex sm:space-x-8"></div>
</div>
</div>
</div>
</nav>
<div class="py-10">
<div
class="mx-auto flex max-w-7xl flex-col items-start justify-center gap-2 px-40"
>
<h1
class="text-2xl leading-7 font-bold text-slate-900 sm:truncate sm:text-3xl sm:tracking-tight"
>
Your workspace is connected to Nx Cloud
</h1>
<div>
<p class="mb-2">You may now close this window.</p>
</div>
</div>
</div>
<footer
class="mt-20 flex border-t border-slate-100 dark:border-slate-800"
>
<nav
role="menu"
aria-labelledby="bottom-navigation"
class="mx-auto flex w-auto max-w-7xl items-center px-4 text-slate-400 dark:text-slate-600"
>
<div class="flex items-center gap-4 p-8 opacity-50">
<a title="Nx Cloud" href="{{ nxCloudUrl }}">
<svg
id="nx-cloud-header-logo"
role="img"
xmlns="http://www.w3.org/2000/svg"
stroke="currentColor"
fill="transparent"
viewBox="0 0 24 24"
class="h-5 w-5"
>
<path
stroke-width="2"
d="M23 3.75V6.5c-3.036 0-5.5 2.464-5.5 5.5s-2.464 5.5-5.5 5.5-5.5 2.464-5.5 5.5H3.75C2.232 23 1 21.768 1 20.25V3.75C1 2.232 2.232 1 3.75 1h16.5C21.768 1 23 2.232 23 3.75Z"
id="nx-cloud-header-logo-stroke-1"
></path>
<path
stroke-width="2"
d="M23 6v14.1667C23 21.7307 21.7307 23 20.1667 23H6c0-3.128 2.53867-5.6667 5.6667-5.6667 3.128 0 5.6666-2.5386 5.6666-5.6666C17.3333 8.53867 19.872 6 23 6Z"
id="nx-cloud-header-logo-stroke-2"
></path>
</svg>
</a>
<p class="text-xs transition">&copy; 2024 - Nx Cloud</p>
</div>
<section
class="hidden gap-8 p-8 text-xs opacity-25 transition hover:opacity-100 md:grid md:grid-cols-4 md:gap-4 md:p-2 lg:flex"
>
<a href="https://nx.app/terms" title="Terms of Service"
>Terms of Service</a
><a href="https://nx.app/privacy" title="Privacy Policy"
>Privacy Policy</a
><a
href="https://status.nx.app"
title="Status"
target="_blank"
rel="noopener"
>Status</a
><a
href="https://nx.dev/ci/intro/ci-with-nx?utm_source=nx.app"
title="Docs"
>Docs</a
><a href="mailto:cloud-support@nrwl.io" title="Contact Nx Cloud"
>Contact Nx Cloud</a
><a href="https://nx.dev/pricing?utm_source=nx.app" title="Pricing"
>Pricing</a
><a href="https://nx.dev/company?utm_source=nx.app" title="Company"
>Company</a
><a
href="https://twitter.com/nxdevtools"
title="@NxDevTools"
target="_blank"
rel="noopener"
>@NxDevTools</a
>
</section>
</nav>
</footer>
</div>
</body>
</html>

View File

@@ -0,0 +1,432 @@
<html>
<head>
<title>Nx Cloud login</title>
<style>
*,
:before,
:after {
-webkit-text-size-adjust: 100%;
tab-size: 4;
font-family:
ui-sans-serif,
system-ui,
sans-serif,
'Apple Color Emoji',
'Segoe UI Emoji',
Segoe UI Symbol,
'Noto Color Emoji';
font-feature-settings: normal;
font-variation-settings: normal;
-webkit-tap-highlight-color: transparent;
line-height: inherit;
--tw-text-opacity: 1;
color: rgb(51 65 85 / var(--tw-text-opacity));
box-sizing: border-box;
border-width: 0;
border-style: solid;
--tw-border-spacing-x: 0;
--tw-border-spacing-y: 0;
--tw-translate-x: 0;
--tw-translate-y: 0;
--tw-rotate: 0;
--tw-skew-x: 0;
--tw-skew-y: 0;
--tw-scale-x: 1;
--tw-scale-y: 1;
--tw-pan-x: ;
--tw-pan-y: ;
--tw-pinch-zoom: ;
--tw-scroll-snap-strictness: proximity;
--tw-gradient-from-position: ;
--tw-gradient-via-position: ;
--tw-gradient-to-position: ;
--tw-ordinal: ;
--tw-slashed-zero: ;
--tw-numeric-figure: ;
--tw-numeric-spacing: ;
--tw-numeric-fraction: ;
--tw-ring-inset: ;
--tw-ring-offset-width: 0px;
--tw-ring-offset-color: #fff;
--tw-ring-color: rgb(59 130 246 / 0.5);
--tw-ring-offset-shadow: 0 0 #0000;
--tw-ring-shadow: 0 0 #0000;
--tw-shadow: 0 0 #0000;
--tw-shadow-colored: 0 0 #0000;
--tw-blur: ;
--tw-brightness: ;
--tw-contrast: ;
--tw-grayscale: ;
--tw-hue-rotate: ;
--tw-invert: ;
--tw-saturate: ;
--tw-sepia: ;
--tw-drop-shadow: ;
--tw-backdrop-blur: ;
--tw-backdrop-brightness: ;
--tw-backdrop-contrast: ;
--tw-backdrop-grayscale: ;
--tw-backdrop-hue-rotate: ;
--tw-backdrop-invert: ;
--tw-backdrop-opacity: ;
--tw-backdrop-saturate: ;
--tw-backdrop-sepia: ;
--tw-contain-size: ;
--tw-contain-layout: ;
--tw-contain-paint: ;
--tw-contain-style: ;
/*border-bottom-width: 1px;*/
--tw-border-opacity: 1;
border-color: rgb(226 232 240 / var(--tw-border-opacity));
--tw-bg-opacity: 1;
background-color: rgb(255 255 255 / var(--tw-bg-opacity));
}
.mx-auto {
margin-left: auto;
margin-right: auto;
}
.mb-2 {
margin-bottom: 0.5rem;
}
.mt-20 {
margin-top: 5rem;
}
.flex {
display: flex;
}
.hidden {
display: none;
}
.h-14 {
height: 3.5rem;
}
.h-5 {
height: 1.25rem;
}
.h-6 {
height: 1.5rem;
}
.min-h-full {
min-height: 100%;
}
.w-5 {
width: 1.25rem;
}
.w-6 {
width: 1.5rem;
}
.w-auto {
width: auto;
}
.max-w-7xl {
max-width: 80rem;
}
.flex-shrink-0 {
flex-shrink: 0;
}
.flex-col {
flex-direction: column;
}
.items-start {
align-items: flex-start;
}
.items-center {
align-items: center;
}
.justify-center {
justify-content: center;
}
.justify-between {
justify-content: space-between;
}
.gap-4 {
gap: 1rem;
}
.gap-8 {
gap: 2rem;
}
.border-b {
border-bottom-width: 1px;
}
.border-t {
border-top-width: 1px;
}
.border-slate-100 {
--tw-border-opacity: 1;
border-color: rgb(241 245 249 / var(--tw-border-opacity));
}
.border-slate-200 {
--tw-border-opacity: 1;
border-color: rgb(226 232 240 / var(--tw-border-opacity));
}
.bg-white {
--tw-bg-opacity: 1;
background-color: rgb(255 255 255 / var(--tw-bg-opacity));
}
.p-8 {
padding: 2rem;
}
.px-4 {
padding-left: 1rem;
padding-right: 1rem;
}
.px-40 {
padding-left: 10rem;
padding-right: 10rem;
}
.py-10 {
padding-top: 2.5rem;
padding-bottom: 2.5rem;
}
.text-2xl {
font-size: 1.5rem;
line-height: 2rem;
}
.text-xs {
font-size: 0.75rem;
line-height: 1rem;
}
.font-bold {
font-weight: 700;
}
.font-semibold {
font-weight: 600;
}
.italic {
font-style: italic;
}
.leading-7 {
line-height: 1.75rem;
}
.text-slate-400 {
--tw-text-opacity: 1;
color: rgb(148 163 184 / var(--tw-text-opacity));
}
.text-slate-700 {
--tw-text-opacity: 1;
color: rgb(51 65 85 / var(--tw-text-opacity));
}
.text-slate-900 {
--tw-text-opacity: 1;
color: rgb(15 23 42 / var(--tw-text-opacity));
}
.underline {
text-decoration-line: underline;
}
.opacity-50 {
opacity: 0.5;
}
.opacity-25 {
opacity: 0.3;
}
.transition {
transition-property: color, background-color, border-color,
text-decoration-color, fill, stroke, opacity, box-shadow, transform,
filter, backdrop-filter;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
transition-duration: 0.15s;
}
body {
min-height: 100%;
height: 100%;
}
a {
color: inherit;
text-decoration: inherit;
}
.hover\:opacity-100:hover {
opacity: 1;
}
@media (min-width: 640px) {
.sm\:-my-px {
margin-top: -1px;
margin-bottom: -1px;
}
.sm\:ml-6 {
margin-left: 1.5rem;
}
.sm\:flex {
display: flex;
}
.sm\:truncate {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.sm\:px-6 {
padding-left: 1.5rem;
padding-right: 1.5rem;
}
.sm\:text-3xl {
font-size: 1.875rem;
line-height: 2.25rem;
}
.sm\:tracking-tight {
letter-spacing: -0.025em;
}
}
@media (min-width: 768px) {
.md\:grid {
display: grid;
}
.md\:grid-cols-4 {
grid-template-columns: repeat(4, minmax(0, 1fr));
}
.md\:gap-4 {
gap: 1rem;
}
.md\:p-2 {
padding: 0.5rem;
}
}
@media (min-width: 1024px) {
.lg\:flex {
display: flex;
}
.lg\:px-8 {
padding-left: 2rem;
padding-right: 2rem;
}
}
</style>
<script>
function startCountdown() {
let countdownElement = document.getElementById('countdown');
let countdown = 5;
let interval = setInterval(function () {
countdownElement.innerHTML = countdown;
countdown--;
if (countdown < 0) {
clearInterval(interval);
window.location.href = '{{ redirectUrl }}'; // Replace with your redirect URL
}
}, 1000);
}
</script>
</head>
<body onload="startCountdown()">
<div class="min-h-full">
<nav class="border-b border-slate-200 bg-white">
<div class="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
<div class="flex h-14 justify-between">
<div class="flex">
<div class="flex flex-shrink-0 items-center">
<a href="{{ nxCloudUrl }}">
<svg
id="nx-cloud-header-logo"
role="img"
xmlns="http://www.w3.org/2000/svg"
stroke="currentColor"
fill="transparent"
viewBox="0 0 24 24"
class="h-6 w-6"
>
<path
stroke-width="2"
d="M23 3.75V6.5c-3.036 0-5.5 2.464-5.5 5.5s-2.464 5.5-5.5 5.5-5.5 2.464-5.5 5.5H3.75C2.232 23 1 21.768 1 20.25V3.75C1 2.232 2.232 1 3.75 1h16.5C21.768 1 23 2.232 23 3.75Z"
id="nx-cloud-header-logo-stroke-1"
></path>
<path
stroke-width="2"
d="M23 6v14.1667C23 21.7307 21.7307 23 20.1667 23H6c0-3.128 2.53867-5.6667 5.6667-5.6667 3.128 0 5.6666-2.5386 5.6666-5.6666C17.3333 8.53867 19.872 6 23 6Z"
id="nx-cloud-header-logo-stroke-2"
></path>
</svg>
</a>
</div>
<div class="hidden sm:-my-px sm:ml-6 sm:flex sm:space-x-8"></div>
</div>
</div>
</div>
</nav>
<div class="py-10">
<div
class="mx-auto flex max-w-7xl flex-col items-start justify-center gap-2 px-40"
>
<h1
class="text-2xl leading-7 font-bold text-slate-900 sm:truncate sm:text-3xl sm:tracking-tight"
>
Nx Cloud Login
</h1>
<div>
<p class="mb-2">
You will be redirected to
<a class="font-semibold underline" href="{{ redirectUrl }}"
>Nx Cloud</a
>
in <span id="countdown">5</span> seconds.
</p>
</div>
</div>
</div>
<footer
class="mt-20 flex border-t border-slate-100 dark:border-slate-800"
>
<nav
role="menu"
aria-labelledby="bottom-navigation"
class="mx-auto flex w-auto max-w-7xl items-center px-4 text-slate-400 dark:text-slate-600"
>
<div class="flex items-center gap-4 p-8 opacity-50">
<a title="Nx Cloud" href="{{ nxCloudUrl }}">
<svg
id="nx-cloud-header-logo"
role="img"
xmlns="http://www.w3.org/2000/svg"
stroke="currentColor"
fill="transparent"
viewBox="0 0 24 24"
class="h-5 w-5"
>
<path
stroke-width="2"
d="M23 3.75V6.5c-3.036 0-5.5 2.464-5.5 5.5s-2.464 5.5-5.5 5.5-5.5 2.464-5.5 5.5H3.75C2.232 23 1 21.768 1 20.25V3.75C1 2.232 2.232 1 3.75 1h16.5C21.768 1 23 2.232 23 3.75Z"
id="nx-cloud-header-logo-stroke-1"
></path>
<path
stroke-width="2"
d="M23 6v14.1667C23 21.7307 21.7307 23 20.1667 23H6c0-3.128 2.53867-5.6667 5.6667-5.6667 3.128 0 5.6666-2.5386 5.6666-5.6666C17.3333 8.53867 19.872 6 23 6Z"
id="nx-cloud-header-logo-stroke-2"
></path>
</svg>
</a>
<p class="text-xs transition">&copy; 2024 - Nx Cloud</p>
</div>
<section
class="hidden gap-8 p-8 text-xs opacity-25 transition hover:opacity-100 md:grid md:grid-cols-4 md:gap-4 md:p-2 lg:flex"
>
<a href="https://nx.app/terms" title="Terms of Service"
>Terms of Service</a
><a href="https://nx.app/privacy" title="Privacy Policy"
>Privacy Policy</a
><a
href="https://status.nx.app"
title="Status"
target="_blank"
rel="noopener"
>Status</a
><a
href="https://nx.dev/ci/intro/ci-with-nx?utm_source=nx.app"
title="Docs"
>Docs</a
><a href="mailto:cloud-support@nrwl.io" title="Contact Nx Cloud"
>Contact Nx Cloud</a
><a href="https://nx.dev/pricing?utm_source=nx.app" title="Pricing"
>Pricing</a
><a href="https://nx.dev/company?utm_source=nx.app" title="Company"
>Company</a
><a
href="https://twitter.com/nxdevtools"
title="@NxDevTools"
target="_blank"
rel="noopener"
>@NxDevTools</a
>
</section>
</nav>
</footer>
</div>
</body>
</html>

View File

@@ -0,0 +1 @@
1766103708902

View File

@@ -0,0 +1,13 @@
<!-- omit in toc -->
# Contributing to Activepieces
First off, thanks for taking the time to contribute! ❤️
All types of contributions are encouraged and valued. See the [Contributing Guide](https://www.activepieces.com/docs/developers/building-pieces/start-building) for different ways to help and details about how this project handles them. Please make sure to read the relevant section before making your contribution. It will make it a lot easier for us maintainers and smooth out the experience for all involved. The community looks forward to your contributions. 🎉
> And if you like the project, but just don't have time to contribute, that's fine. There are other easy ways to support the project and show your appreciation, which we would also be very happy about:
> - Star the project
> - Tweet about it
> - Refer this project in your project's readme
> - Mention the project at local meetups and tell your friends/colleagues

View File

@@ -0,0 +1,123 @@
FROM node:20.19-bullseye-slim AS base
# Set environment variables early for better layer caching
ENV LANG=en_US.UTF-8 \
LANGUAGE=en_US:en \
LC_ALL=en_US.UTF-8 \
NX_DAEMON=false \
NX_NO_CLOUD=true
# Install all system dependencies in a single layer with cache mounts
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
--mount=type=cache,target=/var/lib/apt,sharing=locked \
apt-get update && \
apt-get install -y --no-install-recommends \
openssh-client \
python3 \
g++ \
build-essential \
git \
poppler-utils \
poppler-data \
procps \
locales \
locales-all \
unzip \
curl \
ca-certificates \
libcap-dev && \
yarn config set python /usr/bin/python3
RUN export ARCH=$(uname -m) && \
if [ "$ARCH" = "x86_64" ]; then \
curl -fSL https://github.com/oven-sh/bun/releases/download/bun-v1.3.1/bun-linux-x64-baseline.zip -o bun.zip; \
elif [ "$ARCH" = "aarch64" ]; then \
curl -fSL https://github.com/oven-sh/bun/releases/download/bun-v1.3.1/bun-linux-aarch64.zip -o bun.zip; \
fi
RUN unzip bun.zip \
&& mv bun-*/bun /usr/local/bin/bun \
&& chmod +x /usr/local/bin/bun \
&& rm -rf bun.zip bun-*
RUN bun --version
# Install global npm packages in a single layer
RUN --mount=type=cache,target=/root/.npm \
npm install -g --no-fund --no-audit \
node-gyp \
npm@9.9.3 \
pm2@6.0.10 \
typescript@4.9.4
# Install isolated-vm globally (needed for sandboxes)
RUN --mount=type=cache,target=/root/.bun/install/cache \
cd /usr/src && bun install isolated-vm@5.0.1
### STAGE 1: Build ###
FROM base AS build
WORKDIR /usr/src/app
# Copy only dependency files first for better layer caching
COPY .npmrc package.json bun.lock ./
# Install all dependencies with frozen lockfile
RUN --mount=type=cache,target=/root/.bun/install/cache \
bun install --frozen-lockfile
# Copy source code after dependency installation
COPY . .
# Build all projects including the SmoothSchedule piece
RUN npx nx run-many --target=build --projects=react-ui,server-api,pieces-smoothschedule --configuration production --parallel=2 --skip-nx-cache
# Install production dependencies only for the backend API
RUN --mount=type=cache,target=/root/.bun/install/cache \
cd dist/packages/server/api && \
bun install --production --frozen-lockfile
# Install dependencies for the SmoothSchedule piece
RUN --mount=type=cache,target=/root/.bun/install/cache \
cd dist/packages/pieces/community/smoothschedule && \
bun install --production
### STAGE 2: Run ###
FROM base AS run
WORKDIR /usr/src/app
# Install Nginx and gettext in a single layer with cache mount
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
--mount=type=cache,target=/var/lib/apt,sharing=locked \
apt-get update && \
apt-get install -y --no-install-recommends nginx gettext
# Copy static configuration files first (better layer caching)
COPY nginx.react.conf /etc/nginx/nginx.conf
COPY --from=build /usr/src/app/packages/server/api/src/assets/default.cf /usr/local/etc/isolate
COPY docker-entrypoint.sh .
# Create all necessary directories in one layer
RUN mkdir -p \
/usr/src/app/dist/packages/server \
/usr/src/app/dist/packages/engine \
/usr/src/app/dist/packages/shared \
/usr/src/app/dist/packages/pieces && \
chmod +x docker-entrypoint.sh
# Copy built artifacts from build stage
COPY --from=build /usr/src/app/LICENSE .
COPY --from=build /usr/src/app/dist/packages/engine/ ./dist/packages/engine/
COPY --from=build /usr/src/app/dist/packages/server/ ./dist/packages/server/
COPY --from=build /usr/src/app/dist/packages/shared/ ./dist/packages/shared/
COPY --from=build /usr/src/app/dist/packages/pieces/ ./dist/packages/pieces/
COPY --from=build /usr/src/app/packages ./packages
# Copy frontend files to Nginx document root
COPY --from=build /usr/src/app/dist/packages/react-ui /usr/share/nginx/html/
LABEL service=activepieces
ENTRYPOINT ["./docker-entrypoint.sh"]
EXPOSE 80

25
activepieces-fork/LICENSE Executable file
View File

@@ -0,0 +1,25 @@
Copyright (c) 2020-2024 Activepieces Inc.
Portions of this software are licensed as follows:
* All content that resides under the "packages/ee/" and "packages/server/api/src/app/ee" directory of this repository, if that directory exists, is licensed under the license defined in packages/ee/LICENSE
* All third party components incorporated into the Activepieces Inc Software are licensed under the original license provided by the owner of the applicable component.
* Content outside of the above mentioned directories or restrictions above is available under the "MIT Expat" license as defined below.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

464
activepieces-fork/README.md Normal file
View File

@@ -0,0 +1,464 @@
<h1 align="center">
<a
target="_blank"
href="https://activepieces.com"
>
<img
align="center"
alt="Activepieces"
src="https://github.com/activepieces/activepieces/assets/1812998/76c97441-c285-4480-bc75-30a0c73ed340"
style="width:100%;"
/>
</a>
</h1>
<p align="center">
<a href="/LICENSE" target="_blank"><img src='https://img.shields.io/badge/license-MIT-green?style=for-the-badge' /></a>&nbsp;<img src='https://img.shields.io/github/commit-activity/w/activepieces/activepieces/main?style=for-the-badge' />&nbsp;<a href='https://discord.gg/2jUXBKDdP8'><img src='https://img.shields.io/discord/966798490984382485?style=for-the-badge' /></a>
</p>
<p align="center">
An open source replacement for Zapier
</p>
<p align="center">
<a
href="https://www.activepieces.com/docs"
target="_blank"
><b>Documentation</b></a>&nbsp;&nbsp;&nbsp;🌪️&nbsp;&nbsp;&nbsp;
<a
href="https://www.activepieces.com/docs/developers/building-pieces/overview"
target="_blank"
><b>Create a Piece</b></a>&nbsp;&nbsp;&nbsp;🖉&nbsp;&nbsp;&nbsp;
<a
href="https://www.activepieces.com/docs/install/overview"
target="_blank"
><b>Deploy</b></a>&nbsp;&nbsp;&nbsp;🔥&nbsp;&nbsp;&nbsp;
<a
href="https://discord.gg/yvxF5k5AUb"
target="_blank"
>
<b>Join Discord</b>
</a>
</p>
<br>
<br>
# 🤯 Welcome to Activepieces
All-in-one AI automation designed to be **extensible** through a **type-safe** pieces framework written in **TypeScript**.
When you contribute pieces to Activepieces they become automatically available as MCP servers that you can use with LLMs through Claude Desktop, Cursor or Windsurf!
<br>
<br>
## 🔥 Why Activepieces is Different:
- **💖 Loved by Everyone**: Intuitive interface and great experience for both technical and non-technical users with a quick learning curve.
<img src="/docs/resources/templates.gif">
- **🌐 Open Ecosystem:** All pieces are open source and available on npmjs.com, **60% of the pieces are contributed by the community**.
- **🛠️ Largest open source MCP toolkit**: All our pieces (280+) are available as MCP that you can use with LLMs on Claude Desktop, Cursor or Windsurf.
- **🛠️ Pieces are written in Typescript**: Pieces are npm packages in TypeScript, offering full customization with the best developer experience, including **hot reloading** for **local** piece development on your machine. 😎
<img src="/docs/resources/create-action.png" alt="">
- **🤖 AI-First**: Native AI pieces let you experiment with various providers, or create your own agents using our AI SDK to help you build flows inside the builder.
- **🏢 Enterprise-Ready**: Developers set up the tools, and anyone in the organization can use the no-code builder. Full customization from branding to control.
- **🔒 Secure by Design**: Self-hosted and network-gapped for maximum security and control over your data.
- **🧠 Human in the Loop**: Delay execution for a period of time or require approval. These are just pieces built on top of the piece framework, and you can build many pieces like that. 🎨
- **💻 Human Input Interfaces**: Built-in support for human input triggers like "Chat Interface" 💬 and "Form Interface" 📝
## 🛠️ Builder Features:
- [x] Loops
- [x] Branches
- [x] Auto Retries
- [x] HTTP
- [x] Code with **NPM**
- [x] ASK AI in Code Piece (Non technical user can clean data without knowing to code)
- [x] Flows are fully versioned.
- [x] Languages Translations
- [x] Customizable Templates
- [X] 200+ Pieces, check https://www.activepieces.com/pieces
**We release updates frequently. Check the product changelog for the latest features.**
## 🔌 Create Your Own Piece
Activepieces supports integrations with Google Sheets, OpenAI, Discord, RSS, and over 200 other services. [Check out the full list of supported integrations](https://www.activepieces.com/pieces), which is constantly expanding thanks to our community's contributions.
As an **open ecosystem**, all integration source code is accessible in our repository. These integrations are versioned and [published](https://www.npmjs.com/search?q=%40activepieces) directly to npmjs.com upon contribution.
You can easily create your own integration using our TypeScript framework. For detailed instructions, please refer to our [Contributor's Guide](https://www.activepieces.com/docs/developers/building-pieces/overview).
<br>
<br>
<br>
<br>
# License
Activepieces' Community Edition is released as open source under the [MIT license](https://github.com/activepieces/activepieces/blob/main/LICENSE) and enterprise features are released under [Commercial License](https://github.com/activepieces/activepieces/blob/main/packages/ee/LICENSE)
Read more about the feature comparison here https://www.activepieces.com/docs/about/editions
<br>
<br>
# 💭 Join Our Community
<a href="https://discord.gg/2jUXBKDdP8" target="_blank">
<img src="https://discordapp.com/api/guilds/966798490984382485/widget.png?style=banner3" alt="">
</a>
<br>
<br>
# 🌐 Contributions
We welcome contributions big or small and in different directions. The best way to do this is to check this [document](https://www.activepieces.com/docs/developers/building-pieces/create-action) and we are always up to talk on [our Discord Server](https://discord.gg/2jUXBKDdP8).
## 📚 Translations
Not into coding but still interested in contributing? Come join our [Discord](https://discord.gg/2jUXBKDdP8) and visit https://www.activepieces.com/docs/about/i18n for more information.
![fr translation](https://img.shields.io/badge/dynamic/json?color=blue&label=fr&style=for-the-badge&logo=crowdin&query=%24.progress[?(@.data.languageId==%27fr%27)].data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-16093902-626364-update.json)
![it translation](https://img.shields.io/badge/dynamic/json?color=blue&label=it&style=for-the-badge&logo=crowdin&query=%24.progress[?(@.data.languageId==%27it%27)].data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-16093902-626364-update.json)
![de translation](https://img.shields.io/badge/dynamic/json?color=blue&label=de&style=for-the-badge&logo=crowdin&query=%24.progress[?(@.data.languageId==%27de%27)].data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-16093902-626364-update.json)
![ja translation](https://img.shields.io/badge/dynamic/json?color=blue&label=ja&style=for-the-badge&logo=crowdin&query=%24.progress[?(@.data.languageId==%27ja%27)].data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-16093902-626364-update.json)
![pt-BR translation](https://img.shields.io/badge/dynamic/json?color=blue&label=pt-BR&style=for-the-badge&logo=crowdin&query=%24.progress[?(@.data.languageId==%27pt-BR%27)].data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-16093902-626364-update.json)
## 🦫 Contributors
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
<!-- prettier-ignore-start -->
<!-- markdownlint-disable -->
<table>
<tbody>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ShahedAlMashni"><img src="https://avatars.githubusercontent.com/u/41443850?v=4?s=100" width="100px;" alt="ShahedAlMashni"/><br /><sub><b>ShahedAlMashni</b></sub></a><br /><a href="#plugin-ShahedAlMashni" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/AbdulTheActivePiecer"><img src="https://avatars.githubusercontent.com/u/106555838?v=4?s=100" width="100px;" alt="AbdulTheActivePiecer"/><br /><sub><b>AbdulTheActivePiecer</b></sub></a><br /><a href="#maintenance-AbdulTheActivePiecer" title="Maintenance">🚧</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/khaledmashaly"><img src="https://avatars.githubusercontent.com/u/61781545?v=4?s=100" width="100px;" alt="Khaled Mashaly"/><br /><sub><b>Khaled Mashaly</b></sub></a><br /><a href="#maintenance-khaledmashaly" title="Maintenance">🚧</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/abuaboud"><img src="https://avatars.githubusercontent.com/u/1812998?v=4?s=100" width="100px;" alt="Mohammed Abu Aboud"/><br /><sub><b>Mohammed Abu Aboud</b></sub></a><br /><a href="#maintenance-abuaboud" title="Maintenance">🚧</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://aboudzein.github.io"><img src="https://avatars.githubusercontent.com/u/12976630?v=4?s=100" width="100px;" alt="Abdulrahman Zeineddin"/><br /><sub><b>Abdulrahman Zeineddin</b></sub></a><br /><a href="#plugin-aboudzein" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/creed983"><img src="https://avatars.githubusercontent.com/u/62152944?v=4?s=100" width="100px;" alt="ahmad jaber"/><br /><sub><b>ahmad jaber</b></sub></a><br /><a href="#plugin-creed983" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ashrafsamhouri"><img src="https://avatars.githubusercontent.com/u/97393596?v=4?s=100" width="100px;" alt="ashrafsamhouri"/><br /><sub><b>ashrafsamhouri</b></sub></a><br /><a href="#plugin-ashrafsamhouri" title="Plugin/utility libraries">🔌</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://steercampaign.com"><img src="https://avatars.githubusercontent.com/u/12627658?v=4?s=100" width="100px;" alt="Mohammad Abu Musa"/><br /><sub><b>Mohammad Abu Musa</b></sub></a><br /><a href="#projectManagement-mabumusa1" title="Project Management">📆</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/kanarelo"><img src="https://avatars.githubusercontent.com/u/393261?v=4?s=100" width="100px;" alt="Mukewa Wekalao"/><br /><sub><b>Mukewa Wekalao</b></sub></a><br /><a href="#plugin-kanarelo" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://osamahaikal.me/"><img src="https://avatars.githubusercontent.com/u/72370395?v=4?s=100" width="100px;" alt="Osama Abdallah Essa Haikal"/><br /><sub><b>Osama Abdallah Essa Haikal</b></sub></a><br /><a href="#plugin-OsamaHaikal" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/M-Arman"><img src="https://avatars.githubusercontent.com/u/54455592?v=4?s=100" width="100px;" alt="Arman"/><br /><sub><b>Arman</b></sub></a><br /><a href="#security-M-Arman" title="Security">🛡️</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/oskarkraemer"><img src="https://avatars.githubusercontent.com/u/42745862?v=4?s=100" width="100px;" alt="Oskar Krämer"/><br /><sub><b>Oskar Krämer</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/commits?author=oskarkraemer" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://thibpat.com"><img src="https://avatars.githubusercontent.com/u/494686?v=4?s=100" width="100px;" alt="Thibaut Patel"/><br /><sub><b>Thibaut Patel</b></sub></a><br /><a href="#ideas-tpatel" title="Ideas, Planning, & Feedback">🤔</a> <a href="#plugin-tpatel" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Applesaucesomer"><img src="https://avatars.githubusercontent.com/u/18318905?v=4?s=100" width="100px;" alt="Applesaucesomer"/><br /><sub><b>Applesaucesomer</b></sub></a><br /><a href="#ideas-Applesaucesomer" title="Ideas, Planning, & Feedback">🤔</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/crazyTweek"><img src="https://avatars.githubusercontent.com/u/6828237?v=4?s=100" width="100px;" alt="crazyTweek"/><br /><sub><b>crazyTweek</b></sub></a><br /><a href="#ideas-crazyTweek" title="Ideas, Planning, & Feedback">🤔</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://linkedin.com/in/muhammad-tabaza"><img src="https://avatars.githubusercontent.com/u/23503983?v=4?s=100" width="100px;" alt="Muhammad Tabaza"/><br /><sub><b>Muhammad Tabaza</b></sub></a><br /><a href="#plugin-m-tabaza" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://shaypunter.co.uk"><img src="https://avatars.githubusercontent.com/u/18310437?v=4?s=100" width="100px;" alt="Shay Punter"/><br /><sub><b>Shay Punter</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/commits?author=ShayPunter" title="Documentation">📖</a> <a href="#plugin-ShayPunter" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/abaza738"><img src="https://avatars.githubusercontent.com/u/50132270?v=4?s=100" width="100px;" alt="abaza738"/><br /><sub><b>abaza738</b></sub></a><br /><a href="#plugin-abaza738" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/jonaboe"><img src="https://avatars.githubusercontent.com/u/51358680?v=4?s=100" width="100px;" alt="Jona Boeddinghaus"/><br /><sub><b>Jona Boeddinghaus</b></sub></a><br /><a href="#plugin-jonaboe" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/fomojola"><img src="https://avatars.githubusercontent.com/u/264253?v=4?s=100" width="100px;" alt="fomojola"/><br /><sub><b>fomojola</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/commits?author=fomojola" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/astorozhevsky"><img src="https://avatars.githubusercontent.com/u/11055414?v=4?s=100" width="100px;" alt="Alexander Storozhevsky"/><br /><sub><b>Alexander Storozhevsky</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/commits?author=astorozhevsky" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/J0LGER"><img src="https://avatars.githubusercontent.com/u/54769522?v=4?s=100" width="100px;" alt="J0LGER"/><br /><sub><b>J0LGER</b></sub></a><br /><a href="#security-J0LGER" title="Security">🛡️</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://about.me/veverkap"><img src="https://avatars.githubusercontent.com/u/22348?v=4?s=100" width="100px;" alt="Patrick Veverka"/><br /><sub><b>Patrick Veverka</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/issues?q=author%3Aveverkap" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://berksmbl.com"><img src="https://avatars.githubusercontent.com/u/10000339?v=4?s=100" width="100px;" alt="Berk Sümbül"/><br /><sub><b>Berk Sümbül</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/commits?author=berksmbl" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Willianwg"><img src="https://avatars.githubusercontent.com/u/51550522?v=4?s=100" width="100px;" alt="Willian Guedes"/><br /><sub><b>Willian Guedes</b></sub></a><br /><a href="#plugin-Willianwg" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/abdullahranginwala"><img src="https://avatars.githubusercontent.com/u/19731056?v=4?s=100" width="100px;" alt="Abdullah Ranginwala"/><br /><sub><b>Abdullah Ranginwala</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/commits?author=abdullahranginwala" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/dentych"><img src="https://avatars.githubusercontent.com/u/2256372?v=4?s=100" width="100px;" alt="Dennis Tychsen"/><br /><sub><b>Dennis Tychsen</b></sub></a><br /><a href="#plugin-dentych" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/MyWay"><img src="https://avatars.githubusercontent.com/u/1765284?v=4?s=100" width="100px;" alt="MyWay"/><br /><sub><b>MyWay</b></sub></a><br /><a href="#plugin-MyWay" title="Plugin/utility libraries">🔌</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/bibhuty-did-this"><img src="https://avatars.githubusercontent.com/u/28416188?v=4?s=100" width="100px;" alt="Bibhuti Bhusan Panda"/><br /><sub><b>Bibhuti Bhusan Panda</b></sub></a><br /><a href="#plugin-bibhuty-did-this" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/tarunsamanta2k20"><img src="https://avatars.githubusercontent.com/u/55488549?v=4?s=100" width="100px;" alt="Tarun Samanta"/><br /><sub><b>Tarun Samanta</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/issues?q=author%3Atarunsamanta2k20" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://www.linkedin.com/in/herman-kudria-10868b207/"><img src="https://avatars.githubusercontent.com/u/9007211?v=4?s=100" width="100px;" alt="Herman Kudria"/><br /><sub><b>Herman Kudria</b></sub></a><br /><a href="#plugin-HKudria" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://nulldev.imagefoo.com/"><img src="https://avatars.githubusercontent.com/u/66683380?v=4?s=100" width="100px;" alt="[NULL] Dev"/><br /><sub><b>[NULL] Dev</b></sub></a><br /><a href="#plugin-Abdallah-Alwarawreh" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/JanHolger"><img src="https://avatars.githubusercontent.com/u/25184957?v=4?s=100" width="100px;" alt="Jan Bebendorf"/><br /><sub><b>Jan Bebendorf</b></sub></a><br /><a href="#plugin-JanHolger" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://blog.nileshtrivedi.com"><img src="https://avatars.githubusercontent.com/u/19304?v=4?s=100" width="100px;" alt="Nilesh"/><br /><sub><b>Nilesh</b></sub></a><br /><a href="#plugin-nileshtrivedi" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://certopus.com"><img src="https://avatars.githubusercontent.com/u/40790016?v=4?s=100" width="100px;" alt="Vraj Gohil"/><br /><sub><b>Vraj Gohil</b></sub></a><br /><a href="#plugin-VrajGohil" title="Plugin/utility libraries">🔌</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/BastienMe"><img src="https://avatars.githubusercontent.com/u/71411115?v=4?s=100" width="100px;" alt="BastienMe"/><br /><sub><b>BastienMe</b></sub></a><br /><a href="#plugin-BastienMe" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://blog.fosketts.net"><img src="https://avatars.githubusercontent.com/u/8627862?v=4?s=100" width="100px;" alt="Stephen Foskett"/><br /><sub><b>Stephen Foskett</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/commits?author=SFoskett" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://ganapati.fr"><img src="https://avatars.githubusercontent.com/u/15729117?v=4?s=100" width="100px;" alt="Nathan"/><br /><sub><b>Nathan</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/commits?author=asuri0n" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://www.n-soft.pl"><img src="https://avatars.githubusercontent.com/u/4056319?v=4?s=100" width="100px;" alt="Marcin Natanek"/><br /><sub><b>Marcin Natanek</b></sub></a><br /><a href="#plugin-mnatanek" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://all-tech-plus.com"><img src="https://avatars.githubusercontent.com/u/23551912?v=4?s=100" width="100px;" alt="Mark van Bellen"/><br /><sub><b>Mark van Bellen</b></sub></a><br /><a href="#plugin-buttonsbond" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://guzguz.fr"><img src="https://avatars.githubusercontent.com/u/13715916?v=4?s=100" width="100px;" alt="Olivier Guzzi"/><br /><sub><b>Olivier Guzzi</b></sub></a><br /><a href="#plugin-olivierguzzi" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Ozak93"><img src="https://avatars.githubusercontent.com/u/31257994?v=4?s=100" width="100px;" alt="Osama Zakarneh"/><br /><sub><b>Osama Zakarneh</b></sub></a><br /><a href="#plugin-Ozak93" title="Plugin/utility libraries">🔌</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/phestvik"><img src="https://avatars.githubusercontent.com/u/88210985?v=4?s=100" width="100px;" alt="phestvik"/><br /><sub><b>phestvik</b></sub></a><br /><a href="#ideas-phestvik" title="Ideas, Planning, & Feedback">🤔</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://website-portfolio-bucket.s3-website-ap-northeast-1.amazonaws.com/"><img src="https://avatars.githubusercontent.com/u/113296626?v=4?s=100" width="100px;" alt="Rajdeep Pal"/><br /><sub><b>Rajdeep Pal</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/commits?author=Rajdeep1311" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://www.tepote.com"><img src="https://avatars.githubusercontent.com/u/40870?v=4?s=100" width="100px;" alt="Camilo Usuga"/><br /><sub><b>Camilo Usuga</b></sub></a><br /><a href="#plugin-camilou" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/kishanprmr"><img src="https://avatars.githubusercontent.com/u/135701940?v=4?s=100" width="100px;" alt="Kishan Parmar"/><br /><sub><b>Kishan Parmar</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/commits?author=kishanprmr" title="Documentation">📖</a> <a href="#plugin-kishanprmr" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/BBND"><img src="https://avatars.githubusercontent.com/u/42919338?v=4?s=100" width="100px;" alt="BBND"/><br /><sub><b>BBND</b></sub></a><br /><a href="#plugin-BBND" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/haseebrehmanpc"><img src="https://avatars.githubusercontent.com/u/37938986?v=4?s=100" width="100px;" alt="Haseeb Rehman"/><br /><sub><b>Haseeb Rehman</b></sub></a><br /><a href="#plugin-haseebrehmanpc" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://www.linkedin.com/in/ritagorokhod/"><img src="https://avatars.githubusercontent.com/u/60586879?v=4?s=100" width="100px;" alt="Rita Gorokhod"/><br /><sub><b>Rita Gorokhod</b></sub></a><br /><a href="#plugin-rita-gorokhod" title="Plugin/utility libraries">🔌</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/facferreira"><img src="https://avatars.githubusercontent.com/u/487349?v=4?s=100" width="100px;" alt="Fábio Ferreira"/><br /><sub><b>Fábio Ferreira</b></sub></a><br /><a href="#plugin-facferreira" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://buffetitservices.ch"><img src="https://avatars.githubusercontent.com/u/73933252?v=4?s=100" width="100px;" alt="Florin Buffet"/><br /><sub><b>Florin Buffet</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/commits?author=FlorinBuffet" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Owlcept"><img src="https://avatars.githubusercontent.com/u/67299472?v=4?s=100" width="100px;" alt="Drew Lewis"/><br /><sub><b>Drew Lewis</b></sub></a><br /><a href="#plugin-Owlcept" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://bendersej.com"><img src="https://avatars.githubusercontent.com/u/10613140?v=4?s=100" width="100px;" alt="Benjamin André-Micolon"/><br /><sub><b>Benjamin André-Micolon</b></sub></a><br /><a href="#plugin-bendersej" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/DGurskij"><img src="https://avatars.githubusercontent.com/u/26856659?v=4?s=100" width="100px;" alt="Denis Gurskij"/><br /><sub><b>Denis Gurskij</b></sub></a><br /><a href="#plugin-DGurskij" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://neferlopez.com"><img src="https://avatars.githubusercontent.com/u/11466949?v=4?s=100" width="100px;" alt="Nefer Lopez"/><br /><sub><b>Nefer Lopez</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/commits?author=thatguynef" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/fardeenpanjwani-codeglo"><img src="https://avatars.githubusercontent.com/u/141914308?v=4?s=100" width="100px;" alt="fardeenpanjwani-codeglo"/><br /><sub><b>fardeenpanjwani-codeglo</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/commits?author=fardeenpanjwani-codeglo" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/landonmoir"><img src="https://avatars.githubusercontent.com/u/29764668?v=4?s=100" width="100px;" alt="Landon Moir"/><br /><sub><b>Landon Moir</b></sub></a><br /><a href="#plugin-landonmoir" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://lightspeed-it.nl/"><img src="https://avatars.githubusercontent.com/u/22002313?v=4?s=100" width="100px;" alt="Diego Nijboer"/><br /><sub><b>Diego Nijboer</b></sub></a><br /><a href="#plugin-lldiegon" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://ductan.me/"><img src="https://avatars.githubusercontent.com/u/24206229?v=4?s=100" width="100px;" alt="Tân Một Nắng"/><br /><sub><b>Tân Một Nắng</b></sub></a><br /><a href="#plugin-tanoggy" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://geteduca.com"><img src="https://avatars.githubusercontent.com/u/838788?v=4?s=100" width="100px;" alt="Gavin Foley"/><br /><sub><b>Gavin Foley</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/commits?author=GFoley83" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://dtrautwein.eu"><img src="https://avatars.githubusercontent.com/u/11836793?v=4?s=100" width="100px;" alt="Dennis Trautwein"/><br /><sub><b>Dennis Trautwein</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/issues?q=author%3Adennis-tra" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/inspiredclick"><img src="https://avatars.githubusercontent.com/u/1548613?v=4?s=100" width="100px;" alt="Andrew Rosenblatt"/><br /><sub><b>Andrew Rosenblatt</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/issues?q=author%3Ainspiredclick" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/w95"><img src="https://avatars.githubusercontent.com/u/6433752?v=4?s=100" width="100px;" alt="rika"/><br /><sub><b>rika</b></sub></a><br /><a href="#plugin-w95" title="Plugin/utility libraries">🔌</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/cyrilselasi"><img src="https://avatars.githubusercontent.com/u/7190330?v=4?s=100" width="100px;" alt="Cyril Selasi"/><br /><sub><b>Cyril Selasi</b></sub></a><br /><a href="#plugin-cyrilselasi" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://nijfranck.github.io"><img src="https://avatars.githubusercontent.com/u/9940307?v=4?s=100" width="100px;" alt="Franck Nijimbere"/><br /><sub><b>Franck Nijimbere</b></sub></a><br /><a href="#plugin-nijfranck" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/alerdenisov"><img src="https://avatars.githubusercontent.com/u/3899837?v=4?s=100" width="100px;" alt="Aleksandr Denisov"/><br /><sub><b>Aleksandr Denisov</b></sub></a><br /><a href="#plugin-alerdenisov" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/rbnswartz"><img src="https://avatars.githubusercontent.com/u/724704?v=4?s=100" width="100px;" alt="Reuben Swartz"/><br /><sub><b>Reuben Swartz</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/commits?author=rbnswartz" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://lupianezjose.com"><img src="https://avatars.githubusercontent.com/u/4380557?v=4?s=100" width="100px;" alt="joselupianez"/><br /><sub><b>joselupianez</b></sub></a><br /><a href="#plugin-joselupianez" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://www.zidoary.com"><img src="https://avatars.githubusercontent.com/u/24081860?v=4?s=100" width="100px;" alt="Awais Manzoor"/><br /><sub><b>Awais Manzoor</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/issues?q=author%3Aawais000" title="Bug reports">🐛</a> <a href="https://github.com/activepieces/activepieces/commits?author=awais000" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/andchir"><img src="https://avatars.githubusercontent.com/u/6392311?v=4?s=100" width="100px;" alt="Andrei"/><br /><sub><b>Andrei</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/issues?q=author%3Aandchir" title="Bug reports">🐛</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/derbbre"><img src="https://avatars.githubusercontent.com/u/281843?v=4?s=100" width="100px;" alt="derbbre"/><br /><sub><b>derbbre</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/commits?author=derbbre" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/maor-rozenfeld"><img src="https://avatars.githubusercontent.com/u/49363375?v=4?s=100" width="100px;" alt="Maor Rozenfeld"/><br /><sub><b>Maor Rozenfeld</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/commits?author=maor-rozenfeld" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/miqh"><img src="https://avatars.githubusercontent.com/u/43751307?v=4?s=100" width="100px;" alt="Michael Huynh"/><br /><sub><b>Michael Huynh</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/commits?author=miqh" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/fdundjer"><img src="https://avatars.githubusercontent.com/u/17405319?v=4?s=100" width="100px;" alt="Filip Dunđer"/><br /><sub><b>Filip Dunđer</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/commits?author=fdundjer" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://donthorp.net"><img src="https://avatars.githubusercontent.com/u/8629?v=4?s=100" width="100px;" alt="Don Thorp"/><br /><sub><b>Don Thorp</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/commits?author=donthorp" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://joeworkman.net"><img src="https://avatars.githubusercontent.com/u/225628?v=4?s=100" width="100px;" alt="Joe Workman"/><br /><sub><b>Joe Workman</b></sub></a><br /><a href="#plugin-joeworkman" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Autumnlight02"><img src="https://avatars.githubusercontent.com/u/68244453?v=4?s=100" width="100px;" alt="Aykut Akgün"/><br /><sub><b>Aykut Akgün</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/commits?author=Autumnlight02" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/yann120"><img src="https://avatars.githubusercontent.com/u/10012140?v=4?s=100" width="100px;" alt="Yann Petitjean"/><br /><sub><b>Yann Petitjean</b></sub></a><br /><a href="#plugin-yann120" title="Plugin/utility libraries">🔌</a> <a href="https://github.com/activepieces/activepieces/issues?q=author%3Ayann120" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/pfernandez98"><img src="https://avatars.githubusercontent.com/u/54374282?v=4?s=100" width="100px;" alt="pfernandez98"/><br /><sub><b>pfernandez98</b></sub></a><br /><a href="#plugin-pfernandez98" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://denieler.com"><img src="https://avatars.githubusercontent.com/u/2836281?v=4?s=100" width="100px;" alt="Daniel O."/><br /><sub><b>Daniel O.</b></sub></a><br /><a href="#plugin-denieler" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://myh.tw"><img src="https://avatars.githubusercontent.com/u/12458706?v=4?s=100" width="100px;" alt="Meng-Yuan Huang"/><br /><sub><b>Meng-Yuan Huang</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/commits?author=MrMYHuang" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/bigfluffycookie"><img src="https://avatars.githubusercontent.com/u/54935347?v=4?s=100" width="100px;" alt="Leyla"/><br /><sub><b>Leyla</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/issues?q=author%3Abigfluffycookie" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://i-nithin.netlify.app/"><img src="https://avatars.githubusercontent.com/u/97078688?v=4?s=100" width="100px;" alt="i-nithin"/><br /><sub><b>i-nithin</b></sub></a><br /><a href="#plugin-i-nithin" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://lawrenceli.me"><img src="https://avatars.githubusercontent.com/u/24540598?v=4?s=100" width="100px;" alt="la3rence"/><br /><sub><b>la3rence</b></sub></a><br /><a href="#plugin-la3rence" title="Plugin/utility libraries">🔌</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="http://dennisrongo.com"><img src="https://avatars.githubusercontent.com/u/51771021?v=4?s=100" width="100px;" alt="Dennis Rongo"/><br /><sub><b>Dennis Rongo</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/issues?q=author%3Adennisrongo" title="Bug reports">🐛</a> <a href="#plugin-dennisrongo" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/kartikmehta8"><img src="https://avatars.githubusercontent.com/u/77505989?v=4?s=100" width="100px;" alt="Kartik Mehta"/><br /><sub><b>Kartik Mehta</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/commits?author=kartikmehta8" title="Documentation">📖</a> <a href="https://github.com/activepieces/activepieces/commits?author=kartikmehta8" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://zakher.me"><img src="https://avatars.githubusercontent.com/u/46135573?v=4?s=100" width="100px;" alt="Zakher Masri"/><br /><sub><b>Zakher Masri</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/commits?author=zaaakher" title="Documentation">📖</a> <a href="https://github.com/activepieces/activepieces/commits?author=zaaakher" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/AbdullahBitar"><img src="https://avatars.githubusercontent.com/u/122645579?v=4?s=100" width="100px;" alt="AbdullahBitar"/><br /><sub><b>AbdullahBitar</b></sub></a><br /><a href="#plugin-AbdullahBitar" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mariomeyer"><img src="https://avatars.githubusercontent.com/u/867650?v=4?s=100" width="100px;" alt="Mario Meyer"/><br /><sub><b>Mario Meyer</b></sub></a><br /><a href="#plugin-mariomeyer" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/karimkhaleel"><img src="https://avatars.githubusercontent.com/u/94621779?v=4?s=100" width="100px;" alt="Karim Khaleel"/><br /><sub><b>Karim Khaleel</b></sub></a><br /><a href="#plugin-karimkhaleel" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/CPonchet"><img src="https://avatars.githubusercontent.com/u/40756925?v=4?s=100" width="100px;" alt="CPonchet"/><br /><sub><b>CPonchet</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/issues?q=author%3ACPonchet" title="Bug reports">🐛</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/AdamSelene"><img src="https://avatars.githubusercontent.com/u/79495?v=4?s=100" width="100px;" alt="Olivier Sambourg"/><br /><sub><b>Olivier Sambourg</b></sub></a><br /><a href="#plugin-AdamSelene" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Verlich"><img src="https://avatars.githubusercontent.com/u/30838131?v=4?s=100" width="100px;" alt="Ahmad(Ed)"/><br /><sub><b>Ahmad(Ed)</b></sub></a><br /><a href="#plugin-Verlich" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/leenmashni"><img src="https://avatars.githubusercontent.com/u/102361544?v=4?s=100" width="100px;" alt="leenmashni"/><br /><sub><b>leenmashni</b></sub></a><br /><a href="#plugin-leenmashni" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/AliasKingsWorth"><img src="https://avatars.githubusercontent.com/u/47811610?v=4?s=100" width="100px;" alt="M Abdul Rauf"/><br /><sub><b>M Abdul Rauf</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/commits?author=AliasKingsWorth" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/vbarrier"><img src="https://avatars.githubusercontent.com/u/446808?v=4?s=100" width="100px;" alt="Vincent Barrier"/><br /><sub><b>Vincent Barrier</b></sub></a><br /><a href="#plugin-vbarrier" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://johnmark.dev"><img src="https://avatars.githubusercontent.com/u/65794951?v=4?s=100" width="100px;" alt="John"/><br /><sub><b>John</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/commits?author=jmgb27" title="Code">💻</a> <a href="#plugin-jmgb27" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://joost.blog/"><img src="https://avatars.githubusercontent.com/u/487629?v=4?s=100" width="100px;" alt="Joost de Valk"/><br /><sub><b>Joost de Valk</b></sub></a><br /><a href="#plugin-jdevalk" title="Plugin/utility libraries">🔌</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://www.linkedin.com/in/nyamkamunhjin/"><img src="https://avatars.githubusercontent.com/u/44439626?v=4?s=100" width="100px;" alt="MJ"/><br /><sub><b>MJ</b></sub></a><br /><a href="#plugin-nyamkamunhjin" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/shravankshenoy"><img src="https://avatars.githubusercontent.com/u/29670290?v=4?s=100" width="100px;" alt="ShravanShenoy"/><br /><sub><b>ShravanShenoy</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/commits?author=shravankshenoy" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://jonkristian.no"><img src="https://avatars.githubusercontent.com/u/13219?v=4?s=100" width="100px;" alt="Jon Kristian"/><br /><sub><b>Jon Kristian</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/commits?author=jonkristian" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/cr0fters"><img src="https://avatars.githubusercontent.com/u/1754858?v=4?s=100" width="100px;" alt="cr0fters"/><br /><sub><b>cr0fters</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/issues?q=author%3Acr0fters" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://bibek-timsina.com.np/"><img src="https://avatars.githubusercontent.com/u/29589003?v=4?s=100" width="100px;" alt="Bibek Timsina"/><br /><sub><b>Bibek Timsina</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/issues?q=author%3Abimsina" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/szepeviktor/debian-server-tools/blob/master/CV.md"><img src="https://avatars.githubusercontent.com/u/952007?v=4?s=100" width="100px;" alt="Viktor Szépe"/><br /><sub><b>Viktor Szépe</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/commits?author=szepeviktor" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/rendyt1"><img src="https://avatars.githubusercontent.com/u/38492810?v=4?s=100" width="100px;" alt="Rendy Tan"/><br /><sub><b>Rendy Tan</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/commits?author=rendyt1" title="Documentation">📖</a> <a href="#plugin-rendyt1" title="Plugin/utility libraries">🔌</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="http://islamaf.github.io"><img src="https://avatars.githubusercontent.com/u/44944648?v=4?s=100" width="100px;" alt="Islam Abdelfattah"/><br /><sub><b>Islam Abdelfattah</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/issues?q=author%3Aislamaf" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/uniqueeest"><img src="https://avatars.githubusercontent.com/u/123538138?v=4?s=100" width="100px;" alt="Yoonjae Choi"/><br /><sub><b>Yoonjae Choi</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/commits?author=uniqueeest" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://javix64.com"><img src="https://avatars.githubusercontent.com/u/58471170?v=4?s=100" width="100px;" alt="Javier HM"/><br /><sub><b>Javier HM</b></sub></a><br /><a href="#plugin-javix64" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://farag.tech"><img src="https://avatars.githubusercontent.com/u/50884619?v=4?s=100" width="100px;" alt="Mohamed Hassan"/><br /><sub><b>Mohamed Hassan</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/issues?q=author%3AMohamedHassan499" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://www.coasy.com/"><img src="https://avatars.githubusercontent.com/u/17610709?v=4?s=100" width="100px;" alt="Christian Schab"/><br /><sub><b>Christian Schab</b></sub></a><br /><a href="#plugin-christian-schab" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://www.gamespecifications.com/"><img src="https://avatars.githubusercontent.com/u/37847256?v=4?s=100" width="100px;" alt="Pratik Kinage"/><br /><sub><b>Pratik Kinage</b></sub></a><br /><a href="#plugin-thirstycode" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/LevwTech"><img src="https://avatars.githubusercontent.com/u/69399787?v=4?s=100" width="100px;" alt="Abdelrahman Mostafa "/><br /><sub><b>Abdelrahman Mostafa </b></sub></a><br /><a href="#plugin-LevwTech" title="Plugin/utility libraries">🔌</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/HamzaZagha"><img src="https://avatars.githubusercontent.com/u/45468866?v=4?s=100" width="100px;" alt="Hamza Zagha"/><br /><sub><b>Hamza Zagha</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/issues?q=author%3AHamzaZagha" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://founderblocks.io/"><img src="https://avatars.githubusercontent.com/u/88160672?v=4?s=100" width="100px;" alt="Lasse Schuirmann"/><br /><sub><b>Lasse Schuirmann</b></sub></a><br /><a href="#plugin-founderblocks-sils" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://about.me/cyril_duchon_doris"><img src="https://avatars.githubusercontent.com/u/7388889?v=4?s=100" width="100px;" alt="Cyril Duchon-Doris"/><br /><sub><b>Cyril Duchon-Doris</b></sub></a><br /><a href="#plugin-Startouf" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Javiink"><img src="https://avatars.githubusercontent.com/u/43996484?v=4?s=100" width="100px;" alt="Javiink"/><br /><sub><b>Javiink</b></sub></a><br /><a href="#plugin-Javiink" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/hharchani"><img src="https://avatars.githubusercontent.com/u/6430611?v=4?s=100" width="100px;" alt="Harshit Harchani"/><br /><sub><b>Harshit Harchani</b></sub></a><br /><a href="#plugin-hharchani" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/MrAkber"><img src="https://avatars.githubusercontent.com/u/170118042?v=4?s=100" width="100px;" alt="MrAkber"/><br /><sub><b>MrAkber</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/commits?author=MrAkber" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/marek-slavicek"><img src="https://avatars.githubusercontent.com/u/136325104?v=4?s=100" width="100px;" alt="marek-slavicek"/><br /><sub><b>marek-slavicek</b></sub></a><br /><a href="#plugin-marek-slavicek" title="Plugin/utility libraries">🔌</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/hugh-codes"><img src="https://avatars.githubusercontent.com/u/166336705?v=4?s=100" width="100px;" alt="hugh-codes"/><br /><sub><b>hugh-codes</b></sub></a><br /><a href="#plugin-hugh-codes" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/alewis001"><img src="https://avatars.githubusercontent.com/u/3482446?v=4?s=100" width="100px;" alt="Alex Lewis"/><br /><sub><b>Alex Lewis</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/issues?q=author%3Aalewis001" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://yual.in"><img src="https://avatars.githubusercontent.com/u/21105863?v=4?s=100" width="100px;" alt="Yuanlin Lin"/><br /><sub><b>Yuanlin Lin</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/commits?author=yuaanlin" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://klo.dev"><img src="https://avatars.githubusercontent.com/u/96867907?v=4?s=100" width="100px;" alt="Ala Shiban"/><br /><sub><b>Ala Shiban</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/commits?author=AlaShibanAtKlo" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://hamedsh.medium.com"><img src="https://avatars.githubusercontent.com/u/6043214?v=4?s=100" width="100px;" alt="hamsh"/><br /><sub><b>hamsh</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/commits?author=hamedsh" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://www.anne-mariel.com/"><img src="https://avatars.githubusercontent.com/u/77142075?v=4?s=100" width="100px;" alt="Anne Mariel Catapang"/><br /><sub><b>Anne Mariel Catapang</b></sub></a><br /><a href="#plugin-AnneMariel95" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://hi.carlogino.com"><img src="https://avatars.githubusercontent.com/u/19299524?v=4?s=100" width="100px;" alt="Carlo Gino Catapang"/><br /><sub><b>Carlo Gino Catapang</b></sub></a><br /><a href="#plugin-codegino" title="Plugin/utility libraries">🔌</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/drona2938"><img src="https://avatars.githubusercontent.com/u/34496554?v=4?s=100" width="100px;" alt="Aditya Rathore"/><br /><sub><b>Aditya Rathore</b></sub></a><br /><a href="#plugin-drona2938" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/coderbob2"><img src="https://avatars.githubusercontent.com/u/47177246?v=4?s=100" width="100px;" alt="coderbob2"/><br /><sub><b>coderbob2</b></sub></a><br /><a href="#plugin-coderbob2" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://raamyy.netlify.app"><img src="https://avatars.githubusercontent.com/u/29176293?v=4?s=100" width="100px;" alt="Ramy Gamal"/><br /><sub><b>Ramy Gamal</b></sub></a><br /><a href="#plugin-Raamyy" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://alexandrudanpop.dev/"><img src="https://avatars.githubusercontent.com/u/15979292?v=4?s=100" width="100px;" alt="Alexandru-Dan Pop"/><br /><sub><b>Alexandru-Dan Pop</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/commits?author=alexandrudanpop" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Trayshmhirk"><img src="https://avatars.githubusercontent.com/u/112286458?v=4?s=100" width="100px;" alt="Frank Micheal "/><br /><sub><b>Frank Micheal </b></sub></a><br /><a href="#plugin-Trayshmhirk" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/emmanuel-ferdman"><img src="https://avatars.githubusercontent.com/u/35470921?v=4?s=100" width="100px;" alt="Emmanuel Ferdman"/><br /><sub><b>Emmanuel Ferdman</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/commits?author=emmanuel-ferdman" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/sany2407"><img src="https://avatars.githubusercontent.com/u/179091674?v=4?s=100" width="100px;" alt="Sany A"/><br /><sub><b>Sany A</b></sub></a><br /><a href="#plugin-sany2407" title="Plugin/utility libraries">🔌</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://swimburger.net"><img src="https://avatars.githubusercontent.com/u/3382717?v=4?s=100" width="100px;" alt="Niels Swimberghe"/><br /><sub><b>Niels Swimberghe</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/issues?q=author%3ASwimburger" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/lostinbug"><img src="https://avatars.githubusercontent.com/u/157452389?v=4?s=100" width="100px;" alt="lostinbug"/><br /><sub><b>lostinbug</b></sub></a><br /><a href="#plugin-lostinbug" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/gushkool"><img src="https://avatars.githubusercontent.com/u/64713308?v=4?s=100" width="100px;" alt="gushkool"/><br /><sub><b>gushkool</b></sub></a><br /><a href="#plugin-gushkool" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://www.linkedin.com/in/omarsayed"><img src="https://avatars.githubusercontent.com/u/3813045?v=4?s=100" width="100px;" alt="Omar Sayed"/><br /><sub><b>Omar Sayed</b></sub></a><br /><a href="#plugin-OmarSayed" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/rSnapkoOpenOps"><img src="https://avatars.githubusercontent.com/u/179845343?v=4?s=100" width="100px;" alt="rSnapkoOpenOps"/><br /><sub><b>rSnapkoOpenOps</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/issues?q=author%3ArSnapkoOpenOps" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ahronshor"><img src="https://avatars.githubusercontent.com/u/25138831?v=4?s=100" width="100px;" alt="ahronshor"/><br /><sub><b>ahronshor</b></sub></a><br /><a href="#plugin-ahronshor" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/cezudas"><img src="https://avatars.githubusercontent.com/u/3786138?v=4?s=100" width="100px;" alt="Cezar"/><br /><sub><b>Cezar</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/issues?q=author%3Acezudas" title="Bug reports">🐛</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/geekyme-fsmk"><img src="https://avatars.githubusercontent.com/u/100678833?v=4?s=100" width="100px;" alt="Shawn Lim"/><br /><sub><b>Shawn Lim</b></sub></a><br /><a href="#plugin-geekyme-fsmk" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://shawn.storyline.io/"><img src="https://avatars.githubusercontent.com/u/977460?v=4?s=100" width="100px;" alt="Shawn Lim"/><br /><sub><b>Shawn Lim</b></sub></a><br /><a href="#plugin-geekyme" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/pavloDeshko"><img src="https://avatars.githubusercontent.com/u/27104046?v=4?s=100" width="100px;" alt="pavloDeshko"/><br /><sub><b>pavloDeshko</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/issues?q=author%3ApavloDeshko" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/liuhuapiaoyuan"><img src="https://avatars.githubusercontent.com/u/8020726?v=4?s=100" width="100px;" alt="abc"/><br /><sub><b>abc</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/commits?author=liuhuapiaoyuan" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/manojkum-d"><img src="https://avatars.githubusercontent.com/u/141437046?v=4?s=100" width="100px;" alt="manoj kumar d"/><br /><sub><b>manoj kumar d</b></sub></a><br /><a href="#plugin-manojkum-d" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/felifluid"><img src="https://avatars.githubusercontent.com/u/59516203?v=4?s=100" width="100px;" alt="Feli"/><br /><sub><b>Feli</b></sub></a><br /><a href="#plugin-felifluid" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mordonez"><img src="https://avatars.githubusercontent.com/u/293837?v=4?s=100" width="100px;" alt="Miguel"/><br /><sub><b>Miguel</b></sub></a><br /><a href="#plugin-mordonez" title="Plugin/utility libraries">🔌</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/dev-instasent"><img src="https://avatars.githubusercontent.com/u/116744368?v=4?s=100" width="100px;" alt="Instasent DEV"/><br /><sub><b>Instasent DEV</b></sub></a><br /><a href="#plugin-dev-instasent" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/matthieu-lombard"><img src="https://avatars.githubusercontent.com/u/33624489?v=4?s=100" width="100px;" alt="Matthieu Lombard"/><br /><sub><b>Matthieu Lombard</b></sub></a><br /><a href="#plugin-matthieu-lombard" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/beyondlevi"><img src="https://avatars.githubusercontent.com/u/57486338?v=4?s=100" width="100px;" alt="beyondlevi"/><br /><sub><b>beyondlevi</b></sub></a><br /><a href="#plugin-beyondlevi" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://rafal.fyi"><img src="https://avatars.githubusercontent.com/u/10667346?v=4?s=100" width="100px;" alt="Rafal Zawadzki"/><br /><sub><b>Rafal Zawadzki</b></sub></a><br /><a href="#plugin-rafalzawadzki" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://www.pdfmonkey.io/"><img src="https://avatars.githubusercontent.com/u/119303?v=4?s=100" width="100px;" alt="Simon Courtois"/><br /><sub><b>Simon Courtois</b></sub></a><br /><a href="#plugin-simonc" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/alegria-solutions"><img src="https://avatars.githubusercontent.com/u/124846022?v=4?s=100" width="100px;" alt="alegria-solutions"/><br /><sub><b>alegria-solutions</b></sub></a><br /><a href="#plugin-alegria-solutions" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/D-Rowe-FS"><img src="https://avatars.githubusercontent.com/u/142934784?v=4?s=100" width="100px;" alt="D-Rowe-FS"/><br /><sub><b>D-Rowe-FS</b></sub></a><br /><a href="#plugin-D-Rowe-FS" title="Plugin/utility libraries">🔌</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ChineseHamberger"><img src="https://avatars.githubusercontent.com/u/101547635?v=4?s=100" width="100px;" alt="张晟杰"/><br /><sub><b>张晟杰</b></sub></a><br /><a href="#plugin-ChineseHamberger" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://codesign.rf.gd"><img src="https://avatars.githubusercontent.com/u/72438085?v=4?s=100" width="100px;" alt="Ashot"/><br /><sub><b>Ashot</b></sub></a><br /><a href="#plugin-AshotZaqoyan" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/amrabuaza"><img src="https://avatars.githubusercontent.com/u/30035105?v=4?s=100" width="100px;" alt="Amr Abu Aza"/><br /><sub><b>Amr Abu Aza</b></sub></a><br /><a href="#plugin-amrabuaza" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://johng.io"><img src="https://avatars.githubusercontent.com/u/9030780?v=4?s=100" width="100px;" alt="John Goodliff"/><br /><sub><b>John Goodliff</b></sub></a><br /><a href="#plugin-jerboa88" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/DiwashDev"><img src="https://avatars.githubusercontent.com/u/182864159?v=4?s=100" width="100px;" alt="Diwash Dev"/><br /><sub><b>Diwash Dev</b></sub></a><br /><a href="#plugin-DiwashDev" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://www.seven.io"><img src="https://avatars.githubusercontent.com/u/12965261?v=4?s=100" width="100px;" alt="André"/><br /><sub><b>André</b></sub></a><br /><a href="#plugin-matthiez" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/loudotdigital"><img src="https://avatars.githubusercontent.com/u/7611772?v=4?s=100" width="100px;" alt="Lou &#124; Digital Marketing"/><br /><sub><b>Lou &#124; Digital Marketing</b></sub></a><br /><a href="#plugin-loudotdigital" title="Plugin/utility libraries">🔌</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/maarteNNNN"><img src="https://avatars.githubusercontent.com/u/14275291?v=4?s=100" width="100px;" alt="Maarten Coppens"/><br /><sub><b>Maarten Coppens</b></sub></a><br /><a href="#plugin-maarteNNNN" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mahmuthamet"><img src="https://avatars.githubusercontent.com/u/90776946?v=4?s=100" width="100px;" alt="Mahmoud Hamed"/><br /><sub><b>Mahmoud Hamed</b></sub></a><br /><a href="#plugin-mahmuthamet" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://dammaretz.com"><img src="https://avatars.githubusercontent.com/u/14098167?v=4?s=100" width="100px;" alt="Theo Dammaretz"/><br /><sub><b>Theo Dammaretz</b></sub></a><br /><a href="#plugin-Blightwidow" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/s31w4n"><img src="https://avatars.githubusercontent.com/u/63353528?v=4?s=100" width="100px;" alt="s31w4n"/><br /><sub><b>s31w4n</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/commits?author=s31w4n" title="Documentation">📖</a> <a href="https://github.com/activepieces/activepieces/commits?author=s31w4n" title="Code">💻</a> <a href="#plugin-s31w4n" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://kallabot.com"><img src="https://avatars.githubusercontent.com/u/94991678?v=4?s=100" width="100px;" alt="Abdul Rahman"/><br /><sub><b>Abdul Rahman</b></sub></a><br /><a href="#plugin-abdulrahmanmajid" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/coat"><img src="https://avatars.githubusercontent.com/u/1661?v=4?s=100" width="100px;" alt="Kent Smith"/><br /><sub><b>Kent Smith</b></sub></a><br /><a href="#plugin-coat" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ArvindEnvoy"><img src="https://avatars.githubusercontent.com/u/25014185?v=4?s=100" width="100px;" alt="Arvind Ramesh"/><br /><sub><b>Arvind Ramesh</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/commits?author=ArvindEnvoy" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/valentin-mourtialon"><img src="https://avatars.githubusercontent.com/u/88686764?v=4?s=100" width="100px;" alt="valentin-mourtialon"/><br /><sub><b>valentin-mourtialon</b></sub></a><br /><a href="#plugin-valentin-mourtialon" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/psgpsg16"><img src="https://avatars.githubusercontent.com/u/188385621?v=4?s=100" width="100px;" alt="psgpsg16"/><br /><sub><b>psgpsg16</b></sub></a><br /><a href="#plugin-psgpsg16" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mariiawidrpay"><img src="https://avatars.githubusercontent.com/u/110456120?v=4?s=100" width="100px;" alt="Mariia Shyn"/><br /><sub><b>Mariia Shyn</b></sub></a><br /><a href="#plugin-mariiawidrpay" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/joshuaheslin"><img src="https://avatars.githubusercontent.com/u/48037470?v=4?s=100" width="100px;" alt="Joshua Heslin"/><br /><sub><b>Joshua Heslin</b></sub></a><br /><a href="#plugin-joshuaheslin" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ahmad-swanblocks"><img src="https://avatars.githubusercontent.com/u/165162455?v=4?s=100" width="100px;" alt="Ahmad"/><br /><sub><b>Ahmad</b></sub></a><br /><a href="#plugin-ahmad-swanblocks" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/danielpoonwj"><img src="https://avatars.githubusercontent.com/u/17039704?v=4?s=100" width="100px;" alt="Daniel Poon"/><br /><sub><b>Daniel Poon</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/commits?author=danielpoonwj" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Kevinyu-alan"><img src="https://avatars.githubusercontent.com/u/198612963?v=4?s=100" width="100px;" alt="Kévin Yu"/><br /><sub><b>Kévin Yu</b></sub></a><br /><a href="#plugin-Kevinyu-alan" title="Plugin/utility libraries">🔌</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/flex-yeongeun"><img src="https://avatars.githubusercontent.com/u/186537288?v=4?s=100" width="100px;" alt="노영은"/><br /><sub><b>노영은</b></sub></a><br /><a href="#plugin-flex-yeongeun" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/reemayoush"><img src="https://avatars.githubusercontent.com/u/168414383?v=4?s=100" width="100px;" alt="reemayoush"/><br /><sub><b>reemayoush</b></sub></a><br /><a href="#plugin-reemayoush" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/briceflaceliere"><img src="https://avatars.githubusercontent.com/u/5811531?v=4?s=100" width="100px;" alt="Brice"/><br /><sub><b>Brice</b></sub></a><br /><a href="#security-briceflaceliere" title="Security">🛡️</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://mg-wunna.github.io/mg-wunna/"><img src="https://avatars.githubusercontent.com/u/63114419?v=4?s=100" width="100px;" alt="Mg Wunna"/><br /><sub><b>Mg Wunna</b></sub></a><br /><a href="#plugin-mg-wunna" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://www.linkedin.com/in/harikrishnanum/"><img src="https://avatars.githubusercontent.com/u/61736905?v=4?s=100" width="100px;" alt="Harikrishnan U M"/><br /><sub><b>Harikrishnan U M</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/issues?q=author%3Ahakrsh" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/perrine-pullicino-alan"><img src="https://avatars.githubusercontent.com/u/143406842?v=4?s=100" width="100px;" alt="perrine-pullicino-alan"/><br /><sub><b>perrine-pullicino-alan</b></sub></a><br /><a href="#plugin-perrine-pullicino-alan" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://kaovilai.pw"><img src="https://avatars.githubusercontent.com/u/11228024?v=4?s=100" width="100px;" alt="Tiger Kaovilai"/><br /><sub><b>Tiger Kaovilai</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/commits?author=kaovilai" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/CarefulGuru"><img src="https://avatars.githubusercontent.com/u/141072854?v=4?s=100" width="100px;" alt="CarefulGuru"/><br /><sub><b>CarefulGuru</b></sub></a><br /><a href="#plugin-CarefulGuru" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/AnkitSharmaOnGithub"><img src="https://avatars.githubusercontent.com/u/53289186?v=4?s=100" width="100px;" alt="Ankit Kumar Sharma"/><br /><sub><b>Ankit Kumar Sharma</b></sub></a><br /><a href="#plugin-AnkitSharmaOnGithub" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/nhnansari"><img src="https://avatars.githubusercontent.com/u/116841234?v=4?s=100" width="100px;" alt="Naeem Hassan"/><br /><sub><b>Naeem Hassan</b></sub></a><br /><a href="#plugin-nhnansari" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://timpetricola.com"><img src="https://avatars.githubusercontent.com/u/674084?v=4?s=100" width="100px;" alt="Tim Petricola"/><br /><sub><b>Tim Petricola</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/commits?author=TimPetricola" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/amaan-ai20"><img src="https://avatars.githubusercontent.com/u/188329978?v=4?s=100" width="100px;" alt="Amaan"/><br /><sub><b>Amaan</b></sub></a><br /><a href="#plugin-amaan-ai20" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://www.marcllopartriera.com"><img src="https://avatars.githubusercontent.com/u/1257083?v=4?s=100" width="100px;" alt="Marc Llopart"/><br /><sub><b>Marc Llopart</b></sub></a><br /><a href="#plugin-mllopart" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/onyedikachi-david"><img src="https://avatars.githubusercontent.com/u/51977119?v=4?s=100" width="100px;" alt="David Anyatonwu"/><br /><sub><b>David Anyatonwu</b></sub></a><br /><a href="#plugin-onyedikachi-david" title="Plugin/utility libraries">🔌</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://huzef.com"><img src="https://avatars.githubusercontent.com/u/62795688?v=4?s=100" width="100px;" alt="neo773"/><br /><sub><b>neo773</b></sub></a><br /><a href="#plugin-neo773" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Daniel-Klippa"><img src="https://avatars.githubusercontent.com/u/207180643?v=4?s=100" width="100px;" alt="Daniel-Klippa"/><br /><sub><b>Daniel-Klippa</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/commits?author=Daniel-Klippa" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/krushnarout"><img src="https://avatars.githubusercontent.com/u/129386740?v=4?s=100" width="100px;" alt="Krushna Kanta Rout"/><br /><sub><b>Krushna Kanta Rout</b></sub></a><br /><a href="#plugin-krushnarout" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://www.snimesh.com"><img src="https://avatars.githubusercontent.com/u/12984120?v=4?s=100" width="100px;" alt="Nimesh Solanki"/><br /><sub><b>Nimesh Solanki</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/commits?author=nish17" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/rimjhimyadav"><img src="https://avatars.githubusercontent.com/u/187646079?v=4?s=100" width="100px;" alt="Rimjhim Yadav"/><br /><sub><b>Rimjhim Yadav</b></sub></a><br /><a href="#plugin-rimjhimyadav" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/gs03-dev"><img src="https://avatars.githubusercontent.com/u/70076620?v=4?s=100" width="100px;" alt="gs03"/><br /><sub><b>gs03</b></sub></a><br /><a href="#plugin-gs03-dev" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Kunal-Darekar"><img src="https://avatars.githubusercontent.com/u/150500530?v=4?s=100" width="100px;" alt="Kunal Darekar"/><br /><sub><b>Kunal Darekar</b></sub></a><br /><a href="#plugin-Kunal-Darekar" title="Plugin/utility libraries">🔌</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Sanket6652"><img src="https://avatars.githubusercontent.com/u/119039046?v=4?s=100" width="100px;" alt="Sanket6652"/><br /><sub><b>Sanket6652</b></sub></a><br /><a href="#plugin-Sanket6652" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Ani-4x"><img src="https://avatars.githubusercontent.com/u/174266491?v=4?s=100" width="100px;" alt="Animesh"/><br /><sub><b>Animesh</b></sub></a><br /><a href="#plugin-Ani-4x" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://tarvent.com"><img src="https://avatars.githubusercontent.com/u/13419128?v=4?s=100" width="100px;" alt="Derek Johnson"/><br /><sub><b>Derek Johnson</b></sub></a><br /><a href="#plugin-DerekJDev" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mamiefurax"><img src="https://avatars.githubusercontent.com/u/3955802?v=4?s=100" width="100px;" alt="MamieFurax"/><br /><sub><b>MamieFurax</b></sub></a><br /><a href="#plugin-mamiefurax" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/jadhavharshh"><img src="https://avatars.githubusercontent.com/u/182950168?v=4?s=100" width="100px;" alt="Harsh Jadhav"/><br /><sub><b>Harsh Jadhav</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/commits?author=jadhavharshh" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://twitter.com/lucaslima_souza"><img src="https://avatars.githubusercontent.com/u/1576846?v=4?s=100" width="100px;" alt="Lucas Lima de Souza"/><br /><sub><b>Lucas Lima de Souza</b></sub></a><br /><a href="#plugin-lucaslimasouza" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/BenjaminAlan"><img src="https://avatars.githubusercontent.com/u/42831606?v=4?s=100" width="100px;" alt="Benjamin Benouarka"/><br /><sub><b>Benjamin Benouarka</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/commits?author=BenjaminAlan" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://www.linkedin.com/in/chris-wu/"><img src="https://avatars.githubusercontent.com/u/4491213?v=4?s=100" width="100px;" alt="Chris Wu"/><br /><sub><b>Chris Wu</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/commits?author=cjwooo" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/prasanna2000-max"><img src="https://avatars.githubusercontent.com/u/61037314?v=4?s=100" width="100px;" alt="Prasanna R"/><br /><sub><b>Prasanna R</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/commits?author=prasanna2000-max" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/AdminCraftHD"><img src="https://avatars.githubusercontent.com/u/33310274?v=4?s=100" width="100px;" alt="AdminCraftHD"/><br /><sub><b>AdminCraftHD</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/commits?author=AdminCraftHD" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://tumrabertworld.vercel.app/resume"><img src="https://avatars.githubusercontent.com/u/38305310?v=4?s=100" width="100px;" alt="Tanakit Phentun"/><br /><sub><b>Tanakit Phentun</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/commits?author=tumrabert" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/marapper"><img src="https://avatars.githubusercontent.com/u/1397054?v=4?s=100" width="100px;" alt="Sergey Bondar"/><br /><sub><b>Sergey Bondar</b></sub></a><br /><a href="#plugin-marapper" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://yusufcirak.net"><img src="https://avatars.githubusercontent.com/u/81169996?v=4?s=100" width="100px;" alt="Yusuf Çırak"/><br /><sub><b>Yusuf Çırak</b></sub></a><br /><a href="#plugin-yusuf-cirak" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://ezhil.dev"><img src="https://avatars.githubusercontent.com/u/103899034?v=4?s=100" width="100px;" alt="Ezhil Shanmugham"/><br /><sub><b>Ezhil Shanmugham</b></sub></a><br /><a href="#plugin-ezhil56x" title="Plugin/utility libraries">🔌</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/sunorains"><img src="https://avatars.githubusercontent.com/u/211304820?v=4?s=100" width="100px;" alt="Anderson"/><br /><sub><b>Anderson</b></sub></a><br /><a href="#plugin-sunorains" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/calladodan"><img src="https://avatars.githubusercontent.com/u/7246416?v=4?s=100" width="100px;" alt="Daniel Callado"/><br /><sub><b>Daniel Callado</b></sub></a><br /><a href="#plugin-calladodan" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/sparkybug"><img src="https://avatars.githubusercontent.com/u/52334088?v=4?s=100" width="100px;" alt="Ukaegbu Osinachi"/><br /><sub><b>Ukaegbu Osinachi</b></sub></a><br /><a href="#plugin-sparkybug" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://mavrick-portfolio.vercel.app/"><img src="https://avatars.githubusercontent.com/u/146999057?v=4?s=100" width="100px;" alt="Rishi Mondal"/><br /><sub><b>Rishi Mondal</b></sub></a><br /><a href="#plugin-MAVRICK-1" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Cloudieunnie"><img src="https://avatars.githubusercontent.com/u/178718590?v=4?s=100" width="100px;" alt="Cloudieunnie"/><br /><sub><b>Cloudieunnie</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/commits?author=Cloudieunnie" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/balwant1707"><img src="https://avatars.githubusercontent.com/u/17769387?v=4?s=100" width="100px;" alt="Balwant Singh"/><br /><sub><b>Balwant Singh</b></sub></a><br /><a href="#plugin-balwant1707" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ravikiranvm"><img src="https://avatars.githubusercontent.com/u/36404296?v=4?s=100" width="100px;" alt="Ravi Kiran Vallamkonda"/><br /><sub><b>Ravi Kiran Vallamkonda</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/commits?author=ravikiranvm" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/owuzo"><img src="https://avatars.githubusercontent.com/u/173556464?v=4?s=100" width="100px;" alt="Owuzo Joy"/><br /><sub><b>Owuzo Joy</b></sub></a><br /><a href="#plugin-owuzo" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/helenedurand-smet"><img src="https://avatars.githubusercontent.com/u/206527847?v=4?s=100" width="100px;" alt="helenedurand-smet"/><br /><sub><b>helenedurand-smet</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/commits?author=helenedurand-smet" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/nuvex-dev"><img src="https://avatars.githubusercontent.com/u/181783827?v=4?s=100" width="100px;" alt="Nuvex"/><br /><sub><b>Nuvex</b></sub></a><br /><a href="#plugin-nuvex-dev" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Zebi15"><img src="https://avatars.githubusercontent.com/u/80625145?v=4?s=100" width="100px;" alt="Apostol Eusebiu"/><br /><sub><b>Apostol Eusebiu</b></sub></a><br /><a href="#plugin-Zebi15" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/fortunamide"><img src="https://avatars.githubusercontent.com/u/122938302?v=4?s=100" width="100px;" alt="Fortunate"/><br /><sub><b>Fortunate</b></sub></a><br /><a href="#plugin-fortunamide" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://jaachiwrites.com"><img src="https://avatars.githubusercontent.com/u/173014495?v=4?s=100" width="100px;" alt="Jaachịmmá Anyatọnwụ"/><br /><sub><b>Jaachịmmá Anyatọnwụ</b></sub></a><br /><a href="#plugin-thejaachi" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://luizmainart.com"><img src="https://avatars.githubusercontent.com/u/55499897?v=4?s=100" width="100px;" alt="Luiz D. M. Mainart"/><br /><sub><b>Luiz D. M. Mainart</b></sub></a><br /><a href="#plugin-LuizDMM" title="Plugin/utility libraries">🔌</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/uvenkatateja"><img src="https://avatars.githubusercontent.com/u/118493739?v=4?s=100" width="100px;" alt="uvenkatateja"/><br /><sub><b>uvenkatateja</b></sub></a><br /><a href="#plugin-uvenkatateja" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://akramcodez.tech"><img src="https://avatars.githubusercontent.com/u/179671552?v=4?s=100" width="100px;" alt="SK Akram"/><br /><sub><b>SK Akram</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/commits?author=akramcodez" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/im-soohyun"><img src="https://avatars.githubusercontent.com/u/127273427?v=4?s=100" width="100px;" alt="Kim SooHyun"/><br /><sub><b>Kim SooHyun</b></sub></a><br /><a href="#security-im-soohyun" title="Security">🛡️</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/srimalleswari205"><img src="https://avatars.githubusercontent.com/u/235991945?v=4?s=100" width="100px;" alt="Sri malleswari"/><br /><sub><b>Sri malleswari</b></sub></a><br /><a href="#plugin-srimalleswari205" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/SinghaAnirban005"><img src="https://avatars.githubusercontent.com/u/143536290?v=4?s=100" width="100px;" alt="Anirban Singha"/><br /><sub><b>Anirban Singha</b></sub></a><br /><a href="#plugin-SinghaAnirban005" title="Plugin/utility libraries">🔌</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://dania.es"><img src="https://avatars.githubusercontent.com/u/11240307?v=4?s=100" width="100px;" alt="Dania Es"/><br /><sub><b>Dania Es</b></sub></a><br /><a href="https://github.com/activepieces/activepieces/commits?author=Dania02525" title="Code">💻</a></td>
</tr>
</tbody>
</table>
<!-- markdownlint-restore -->
<!-- prettier-ignore-end -->
<!-- ALL-CONTRIBUTORS-LIST:END -->
This project follows the [all-contributors](https://allcontributors.org) specification.
Contributions of any kind are welcome!

View File

@@ -0,0 +1,39 @@
# Security
Contact: security@activepieces.com
Based on [https://supabase.com/.well-known/security.txt](https://supabase.com/.well-known/security.txt)
At Activepieces.com, we consider the security of our systems a top priority. But no matter how much effort we put into system security, there can still be vulnerabilities present.
If you discover a vulnerability, we would like to know about it so we can take steps to address it as quickly as possible. We would like to ask you to help us better protect our clients and our systems.
## Out of scope vulnerabilities:
- Clickjacking on pages with no sensitive actions.
- Unauthenticated/logout/login CSRF.
- Attacks requiring MITM or physical access to a user's device.
- Any activity that could lead to the disruption of our service (DoS).
- Content spoofing and text injection issues without showing an attack vector/without being able to modify HTML/CSS.
- Email spoofing
- Missing DNSSEC, CAA, CSP headers
- Lack of Secure or HTTP only flag on non-sensitive cookies
- Deadlinks
## Please do the following:
- E-mail your findings to [security@activepieces.com](mailto:security@activepieces.com).
- Do not run automated scanners on our infrastructure or dashboard. If you wish to do this, contact us and we will set up a sandbox for you.
- Do not take advantage of the vulnerability or problem you have discovered, for example by downloading more data than necessary to demonstrate the vulnerability or deleting or modifying other people's data,
- Do not reveal the problem to others until it has been resolved,
- Do not use attacks on physical security, social engineering, distributed denial of service, spam or applications of third parties,
- Do provide sufficient information to reproduce the problem, so we will be able to resolve it as quickly as possible. Usually, the IP address or the URL of the affected system and a description of the vulnerability will be sufficient, but complex vulnerabilities may require further explanation.
## What we promise:
- We will respond to your report within 3 business days with our evaluation of the report and an expected resolution date,
- If you have followed the instructions above, we will not take any legal action against you in regard to the report,
- We will handle your report with strict confidentiality, and not pass on your personal details to third parties without your permission,
- We will keep you informed of the progress towards resolving the problem,
- In the public information concerning the problem reported, we will give your name as the discoverer of the problem (unless you desire otherwise), and
- We strive to resolve all problems as quickly as possible, and we would like to play an active role in the ultimate publication on the problem after it is resolved.

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

11167
activepieces-fork/bun.lock Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1 @@
module.exports = { extends: ['@commitlint/config-conventional'] };

View File

@@ -0,0 +1,12 @@
project_id_env: CROWDIN_PROJECT_ID
api_token_env: CROWDIN_PERSONAL_TOKEN
base_path: .
base_url: 'https://api.crowdin.com'
preserve_hierarchy: 1
files:
- type: i18next_json
source: packages/react-ui/public/locales/en/translation.json
translation: /packages/react-ui/public/locales/%two_letters_code%/translation.json
- type: json
source: packages/pieces/**/**/src/i18n/translation.json
translation: /packages/pieces/**/**/src/i18n/%two_letters_code%.json

View File

@@ -0,0 +1,5 @@
# Ignore downloaded Helm chart dependencies
charts/*.tgz
# Ignore Chart.lock file variations
Chart.lock

View File

@@ -0,0 +1,23 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*.orig
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/

View File

@@ -0,0 +1,39 @@
apiVersion: v2
name: activepieces
description: A Helm chart for Activepieces
icon: https://cdn.activepieces.com/brand/logo.svg
# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 0.3.0
# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
# It is recommended to use it with quotes.
appVersion: "0.71.2"
dependencies:
- name: kubernetes-secret-generator
version: "3.4.1"
repository: "https://helm.mittwald.de"
condition: kubernetes-secret-generator.enabled
- name: postgresql
version: "11.7.2"
repository: "https://charts.bitnami.com/bitnami"
condition: postgresql.enabled
- name: redis
version: "17.4.2"
repository: "https://charts.bitnami.com/bitnami"
condition: redis.enabled

View File

@@ -0,0 +1 @@
Activepieces has been deployed successfully!

View File

@@ -0,0 +1,62 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "activepieces.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "activepieces.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "activepieces.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Common labels
*/}}
{{- define "activepieces.labels" -}}
helm.sh/chart: {{ include "activepieces.chart" . }}
{{ include "activepieces.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{/*
Selector labels
*/}}
{{- define "activepieces.selectorLabels" -}}
app.kubernetes.io/name: {{ include "activepieces.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
{{/*
Create the name of the service account to use
*/}}
{{- define "activepieces.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "activepieces.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,469 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "activepieces.fullname" . }}
labels:
{{- include "activepieces.labels" . | nindent 4 }}
spec:
{{- if not .Values.autoscaling.enabled }}
replicas: {{ .Values.replicaCount }}
{{- end }}
selector:
matchLabels:
{{- include "activepieces.selectorLabels" . | nindent 6 }}
template:
metadata:
{{- with .Values.podAnnotations }}
annotations:
{{- toYaml . | nindent 8 }}
{{- end }}
labels:
{{- include "activepieces.labels" . | nindent 8 }}
{{- with .Values.podLabels }}
{{- toYaml . | nindent 8 }}
{{- end }}
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
serviceAccountName: {{ include "activepieces.serviceAccountName" . }}
{{- with .Values.podSecurityContext }}
securityContext:
{{- toYaml . | nindent 8 }}
{{- end }}
containers:
- name: {{ .Chart.Name }}
{{- with .Values.securityContext }}
securityContext:
{{- toYaml . | nindent 12 }}
{{- end }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- name: http
containerPort: {{ .Values.container.port }}
protocol: TCP
env:
# Core Activepieces configuration
{{- if .Values.activepieces.frontendUrl }}
- name: AP_FRONTEND_URL
value: {{ .Values.activepieces.frontendUrl | quote }}
{{- end }}
{{- if .Values.activepieces.apiKey }}
- name: AP_API_KEY
value: {{ .Values.activepieces.apiKey | quote }}
{{- end }}
{{- if .Values.activepieces.clientRealIpHeader }}
- name: AP_CLIENT_REAL_IP_HEADER
value: {{ .Values.activepieces.clientRealIpHeader | quote }}
{{- end }}
{{- if .Values.activepieces.configPath }}
- name: AP_CONFIG_PATH
value: {{ .Values.activepieces.configPath | quote }}
{{- end }}
{{- if .Values.activepieces.devPieces }}
- name: AP_DEV_PIECES
value: {{ .Values.activepieces.devPieces | quote }}
{{- end }}
{{- if .Values.activepieces.internalUrl }}
- name: AP_INTERNAL_URL
value: {{ .Values.activepieces.internalUrl | quote }}
{{- end }}
{{- if .Values.activepieces.maxConcurrentJobsPerProject }}
- name: AP_MAX_CONCURRENT_JOBS_PER_PROJECT
value: {{ .Values.activepieces.maxConcurrentJobsPerProject | quote }}
{{- end }}
{{- if .Values.activepieces.perplexityBaseUrl }}
- name: AP_PERPLEXITY_BASE_URL
value: {{ .Values.activepieces.perplexityBaseUrl | quote }}
{{- end }}
{{- if .Values.activepieces.piecesSyncMode }}
- name: AP_PIECES_SYNC_MODE
value: {{ .Values.activepieces.piecesSyncMode | quote }}
{{- end }}
{{- if .Values.activepieces.featurebaseApiKey }}
- name: AP_FEATUREBASE_API_KEY
value: {{ .Values.activepieces.featurebaseApiKey | quote }}
{{- end }}
{{- if .Values.activepieces.enableFlowOnPublish }}
- name: AP_ENABLE_FLOW_ON_PUBLISH
value: {{ .Values.activepieces.enableFlowOnPublish | quote }}
{{- end }}
{{- if .Values.activepieces.issueArchiveDays }}
- name: AP_ISSUE_ARCHIVE_DAYS
value: {{ .Values.activepieces.issueArchiveDays | quote }}
{{- end }}
{{- if .Values.activepieces.pausedFlowTimeoutDays }}
- name: AP_PAUSED_FLOW_TIMEOUT_DAYS
value: {{ .Values.activepieces.pausedFlowTimeoutDays | quote }}
{{- end }}
{{- if .Values.activepieces.logLevel }}
- name: AP_LOG_LEVEL
value: {{ .Values.activepieces.logLevel | quote }}
{{- end }}
{{- if .Values.activepieces.logPretty }}
- name: AP_LOG_PRETTY
value: {{ .Values.activepieces.logPretty | quote }}
{{- end }}
{{- if .Values.activepieces.appWebhookSecrets }}
- name: AP_APP_WEBHOOK_SECRETS
value: {{ .Values.activepieces.appWebhookSecrets | quote }}
{{- end }}
{{- if .Values.activepieces.maxFileSizeMb }}
- name: AP_MAX_FILE_SIZE_MB
value: {{ .Values.activepieces.maxFileSizeMb | quote }}
{{- end }}
{{- if .Values.activepieces.sandboxMemoryLimit }}
- name: AP_SANDBOX_MEMORY_LIMIT
value: {{ .Values.activepieces.sandboxMemoryLimit | quote }}
{{- end }}
{{- if .Values.activepieces.sandboxPropagatedEnvVars }}
- name: AP_SANDBOX_PROPAGATED_ENV_VARS
value: {{ .Values.activepieces.sandboxPropagatedEnvVars | quote }}
{{- end }}
{{- if .Values.activepieces.piecesSource }}
- name: AP_PIECES_SOURCE
value: {{ .Values.activepieces.piecesSource | quote }}
{{- end }}
{{- if .Values.activepieces.apiRateLimiting.authn.enabled }}
- name: AP_API_RATE_LIMIT_AUTHN_ENABLED
value: {{ .Values.activepieces.apiRateLimiting.authn.enabled | quote }}
{{- end }}
{{- if .Values.activepieces.apiRateLimiting.authn.max }}
- name: AP_API_RATE_LIMIT_AUTHN_MAX
value: {{ .Values.activepieces.apiRateLimiting.authn.max | quote }}
{{- end }}
{{- if .Values.activepieces.apiRateLimiting.authn.window }}
- name: AP_API_RATE_LIMIT_AUTHN_WINDOW
value: {{ .Values.activepieces.apiRateLimiting.authn.window | quote }}
{{- end }}
{{- if .Values.activepieces.projectRateLimiter.enabled }}
- name: AP_PROJECT_RATE_LIMITER_ENABLED
value: {{ .Values.activepieces.projectRateLimiter.enabled | quote }}
{{- end }}
- name: AP_ENCRYPTION_KEY
valueFrom:
secretKeyRef:
name: {{ include "activepieces.fullname" . }}-secrets
key: encryption-key
- name: AP_JWT_SECRET
valueFrom:
secretKeyRef:
name: {{ include "activepieces.fullname" . }}-jwt-secret
key: jwt-secret
{{- if .Values.activepieces.environment }}
- name: AP_ENVIRONMENT
value: {{ .Values.activepieces.environment | quote }}
{{- end }}
{{- if .Values.activepieces.edition }}
- name: AP_EDITION
value: {{ .Values.activepieces.edition | quote }}
{{- end }}
{{- if .Values.activepieces.executionMode }}
- name: AP_EXECUTION_MODE
value: {{ .Values.activepieces.executionMode | quote }}
{{- end }}
{{- if .Values.activepieces.telemetryEnabled }}
- name: AP_TELEMETRY_ENABLED
value: {{ .Values.activepieces.telemetryEnabled | quote }}
{{- end }}
{{- if .Values.activepieces.templatesSourceUrl }}
- name: AP_TEMPLATES_SOURCE_URL
value: {{ .Values.activepieces.templatesSourceUrl | quote }}
{{- end }}
{{- if .Values.activepieces.flowWorkerConcurrency }}
- name: AP_FLOW_WORKER_CONCURRENCY
value: {{ .Values.activepieces.flowWorkerConcurrency | quote }}
{{- end }}
{{- if .Values.activepieces.scheduledWorkerConcurrency }}
- name: AP_SCHEDULED_WORKER_CONCURRENCY
value: {{ .Values.activepieces.scheduledWorkerConcurrency | quote }}
{{- end }}
{{- if .Values.activepieces.triggerDefaultPollInterval }}
- name: AP_TRIGGER_DEFAULT_POLL_INTERVAL
value: {{ .Values.activepieces.triggerDefaultPollInterval | quote }}
{{- end }}
{{- if .Values.activepieces.triggerTimeoutSeconds }}
- name: AP_TRIGGER_TIMEOUT_SECONDS
value: {{ .Values.activepieces.triggerTimeoutSeconds | quote }}
{{- end }}
{{- if .Values.activepieces.flowTimeoutSeconds }}
- name: AP_FLOW_TIMEOUT_SECONDS
value: {{ .Values.activepieces.flowTimeoutSeconds | quote }}
{{- end }}
{{- if .Values.activepieces.webhookTimeoutSeconds }}
- name: AP_WEBHOOK_TIMEOUT_SECONDS
value: {{ .Values.activepieces.webhookTimeoutSeconds | quote }}
{{- end }}
{{- if .Values.activepieces.executionDataRetentionDays }}
- name: AP_EXECUTION_DATA_RETENTION_DAYS
value: {{ .Values.activepieces.executionDataRetentionDays | quote }}
{{- end }}
{{- if or .Values.postgresql.enabled (or .Values.postgresql.host .Values.postgresql.url) }}
# PostgreSQL configuration (subchart or external)
- name: AP_DB_TYPE
value: "POSTGRES"
{{- if .Values.postgresql.auth.database }}
- name: AP_POSTGRES_DATABASE
value: {{ .Values.postgresql.auth.database | quote }}
{{- end }}
{{- if .Values.postgresql.host }}
- name: AP_POSTGRES_HOST
value: {{ .Values.postgresql.host | quote }}
{{- else if .Values.postgresql.enabled }}
- name: AP_POSTGRES_HOST
value: {{ printf "%s-postgresql" (include "activepieces.fullname" .) | quote }}
{{- end }}
{{- if .Values.postgresql.port }}
- name: AP_POSTGRES_PORT
value: {{ .Values.postgresql.port | quote }}
{{- end }}
{{- if .Values.postgresql.auth.username }}
- name: AP_POSTGRES_USERNAME
value: {{ .Values.postgresql.auth.username | quote }}
{{- end }}
{{- if .Values.postgresql.auth.externalSecret }}
- name: AP_POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: {{ .Values.postgresql.auth.externalSecret.name | quote }}
key: {{ .Values.postgresql.auth.externalSecret.key | quote }}
{{- else if .Values.postgresql.auth.password }}
- name: AP_POSTGRES_PASSWORD
value: {{ .Values.postgresql.auth.password | quote }}
{{- else if .Values.postgresql.enabled }}
- name: AP_POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: {{ include "activepieces.fullname" . }}-postgresql
key: postgres-password
{{- end }}
{{- if .Values.postgresql.useSSL }}
- name: AP_POSTGRES_USE_SSL
value: {{ .Values.postgresql.useSSL | quote }}
{{- end }}
{{- if .Values.postgresql.sslCa }}
- name: AP_POSTGRES_SSL_CA
value: {{ .Values.postgresql.sslCa | quote }}
{{- end }}
{{- if .Values.postgresql.url }}
- name: AP_POSTGRES_URL
value: {{ .Values.postgresql.url | quote }}
{{- end }}
{{- else }}
# SQLite configuration (fallback)
- name: AP_DB_TYPE
value: "SQLITE3"
{{- end }}
{{- if or .Values.redis.enabled (or .Values.redis.host .Values.redis.url) }}
# Redis configuration (subchart or external)
{{- if .Values.redis.host }}
- name: AP_REDIS_HOST
value: {{ .Values.redis.host | quote }}
{{- else if .Values.redis.enabled }}
- name: AP_REDIS_HOST
value: {{ printf "%s-redis-master" (include "activepieces.fullname" .) | quote }}
{{- end }}
{{- if .Values.redis.port }}
- name: AP_REDIS_PORT
value: {{ .Values.redis.port | quote }}
{{- end }}
{{- if .Values.redis.useSSL }}
- name: AP_REDIS_USE_SSL
value: {{ .Values.redis.useSSL | quote }}
{{- end }}
{{- if .Values.redis.sslCaFile }}
- name: AP_REDIS_SSL_CA_FILE
value: {{ .Values.redis.sslCaFile | quote }}
{{- end }}
{{- if .Values.redis.db }}
- name: AP_REDIS_DB
value: {{ .Values.redis.db | quote }}
{{- end }}
{{- if .Values.redis.user }}
- name: AP_REDIS_USER
value: {{ .Values.redis.user | quote }}
{{- end }}
{{- if .Values.redis.url }}
- name: AP_REDIS_URL
value: {{ .Values.redis.url | quote }}
{{- end }}
{{- if eq .Values.redis.type "sentinel" }}
- name: AP_REDIS_TYPE
value: "SENTINEL"
{{- else }}
# Default to DEFAULT for standalone Redis
- name: AP_REDIS_TYPE
value: "DEFAULT"
{{- end }}
{{- if .Values.redis.sentinel.role }}
- name: AP_REDIS_SENTINEL_ROLE
value: {{ .Values.redis.sentinel.role | quote }}
{{- end }}
{{- if .Values.redis.sentinel.hosts }}
- name: AP_REDIS_SENTINEL_HOSTS
value: {{ .Values.redis.sentinel.hosts | quote }}
{{- end }}
{{- if .Values.redis.sentinel.name }}
- name: AP_REDIS_SENTINEL_NAME
value: {{ .Values.redis.sentinel.name | quote }}
{{- end }}
{{- if .Values.redis.failedJob.retentionDays }}
- name: AP_REDIS_FAILED_JOB_RETENTION_DAYS
value: {{ .Values.redis.failedJob.retentionDays | quote }}
{{- end }}
{{- if .Values.redis.failedJob.retentionMaxCount }}
- name: AP_REDIS_FAILED_JOB_RETENTION_MAX_COUNT
value: {{ .Values.redis.failedJob.retentionMaxCount | quote }}
{{- end }}
{{- if .Values.redis.auth.externalSecret }}
- name: AP_REDIS_PASSWORD
valueFrom:
secretKeyRef:
name: {{ .Values.redis.auth.externalSecret.name | quote }}
key: {{ .Values.redis.auth.externalSecret.key | quote }}
{{- else if .Values.redis.auth.password }}
- name: AP_REDIS_PASSWORD
value: {{ .Values.redis.auth.password | quote }}
{{- else if and .Values.redis.enabled .Values.redis.auth.enabled }}
- name: AP_REDIS_PASSWORD
valueFrom:
secretKeyRef:
name: {{ .Release.Name }}-redis
key: redis-password
{{- end }}
{{- else }}
# Memory queue (fallback)
- name: AP_REDIS_TYPE
value: "MEMORY"
{{- end }}
{{- if .Values.smtp.enabled }}
# SMTP configuration
{{- if .Values.smtp.host }}
- name: AP_SMTP_HOST
value: {{ .Values.smtp.host | quote }}
{{- end }}
{{- if .Values.smtp.port }}
- name: AP_SMTP_PORT
value: {{ .Values.smtp.port | quote }}
{{- end }}
{{- if .Values.smtp.username }}
- name: AP_SMTP_USERNAME
value: {{ .Values.smtp.username | quote }}
{{- end }}
{{- if .Values.smtp.password }}
- name: AP_SMTP_PASSWORD
value: {{ .Values.smtp.password | quote }}
{{- end }}
{{- if .Values.smtp.senderEmail }}
- name: AP_SMTP_SENDER_EMAIL
value: {{ .Values.smtp.senderEmail | quote }}
{{- end }}
{{- if .Values.smtp.senderName }}
- name: AP_SMTP_SENDER_NAME
value: {{ .Values.smtp.senderName | quote }}
{{- end }}
{{- end }}
{{- if .Values.s3.enabled }}
# S3 configuration
{{- if .Values.s3.accessKeyId }}
- name: AP_S3_ACCESS_KEY_ID
value: {{ .Values.s3.accessKeyId | quote }}
{{- end }}
{{- if .Values.s3.secretAccessKey }}
- name: AP_S3_SECRET_ACCESS_KEY
value: {{ .Values.s3.secretAccessKey | quote }}
{{- end }}
{{- if .Values.s3.bucket }}
- name: AP_S3_BUCKET
value: {{ .Values.s3.bucket | quote }}
{{- end }}
{{- if .Values.s3.endpoint }}
- name: AP_S3_ENDPOINT
value: {{ .Values.s3.endpoint | quote }}
{{- end }}
{{- if .Values.s3.region }}
- name: AP_S3_REGION
value: {{ .Values.s3.region | quote }}
{{- end }}
{{- if .Values.s3.useSignedUrls }}
- name: AP_S3_USE_SIGNED_URLS
value: {{ .Values.s3.useSignedUrls | quote }}
{{- end }}
{{- if .Values.s3.useIrsa }}
- name: AP_S3_USE_IRSA
value: {{ .Values.s3.useIrsa | quote }}
{{- end }}
{{- end }}
{{- if .Values.queueUi.enabled }}
# Queue UI configuration
- name: AP_QUEUE_UI_ENABLED
value: {{ .Values.queueUi.enabled | quote }}
{{- if .Values.queueUi.username }}
- name: AP_QUEUE_UI_USERNAME
value: {{ .Values.queueUi.username | quote }}
{{- end }}
{{- if .Values.queueUi.password }}
- name: AP_QUEUE_UI_PASSWORD
value: {{ .Values.queueUi.password | quote }}
{{- end }}
{{- end }}
{{- if .Values.activepieces.engineExecutablePath }}
- name: AP_ENGINE_EXECUTABLE_PATH
value: {{ .Values.activepieces.engineExecutablePath | quote }}
{{- end }}
# OpenTelemetry configuration
{{- if .Values.activepieces.otel.enabled }}
- name: AP_OTEL_ENABLED
value: {{ .Values.activepieces.otel.enabled | quote }}
{{- end }}
{{- if .Values.activepieces.otel.exporterOtlpEndpoint }}
- name: OTEL_EXPORTER_OTLP_ENDPOINT
value: {{ .Values.activepieces.otel.exporterOtlpEndpoint | quote }}
{{- end }}
{{- if .Values.activepieces.otel.exporterOtlpHeaders }}
- name: OTEL_EXPORTER_OTLP_HEADERS
value: {{ .Values.activepieces.otel.exporterOtlpHeaders | quote }}
{{- end }}
{{- with .Values.livenessProbe }}
livenessProbe:
{{- toYaml . | nindent 12 }}
{{- end }}
{{- with .Values.readinessProbe }}
readinessProbe:
{{- toYaml . | nindent 12 }}
{{- end }}
{{- with .Values.resources }}
resources:
{{- toYaml . | nindent 12 }}
{{- end }}
volumeMounts:
{{- if .Values.persistence.enabled }}
- name: cache
mountPath: {{ .Values.persistence.mountPath | quote }}
{{- end }}
{{- with .Values.volumeMounts }}
{{- toYaml . | nindent 12 }}
{{- end }}
volumes:
{{- if .Values.persistence.enabled }}
- name: cache
persistentVolumeClaim:
claimName: {{ include "activepieces.fullname" . }}-cache
{{- end }}
{{- with .Values.volumes }}
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}

View File

@@ -0,0 +1,32 @@
{{- if .Values.autoscaling.enabled }}
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: {{ include "activepieces.fullname" . }}
labels:
{{- include "activepieces.labels" . | nindent 4 }}
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: {{ include "activepieces.fullname" . }}
minReplicas: {{ .Values.autoscaling.minReplicas }}
maxReplicas: {{ .Values.autoscaling.maxReplicas }}
metrics:
{{- if .Values.autoscaling.targetCPUUtilizationPercentage }}
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }}
{{- end }}
{{- if .Values.autoscaling.targetMemoryUtilizationPercentage }}
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,43 @@
{{- if .Values.ingress.enabled -}}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ include "activepieces.fullname" . }}
labels:
{{- include "activepieces.labels" . | nindent 4 }}
{{- with .Values.ingress.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- with .Values.ingress.className }}
ingressClassName: {{ . }}
{{- end }}
{{- if .Values.ingress.tls }}
tls:
{{- range .Values.ingress.tls }}
- hosts:
{{- range .hosts }}
- {{ . | quote }}
{{- end }}
secretName: {{ .secretName }}
{{- end }}
{{- end }}
rules:
{{- range .Values.ingress.hosts }}
- host: {{ .host | quote }}
http:
paths:
{{- range .paths }}
- path: {{ .path }}
{{- with .pathType }}
pathType: {{ . }}
{{- end }}
backend:
service:
name: {{ include "activepieces.fullname" $ }}
port:
number: {{ $.Values.service.port }}
{{- end }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,14 @@
{{- if .Values.persistence.enabled }}
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: {{ include "activepieces.fullname" . }}-cache
labels:
{{- include "activepieces.labels" . | nindent 4 }}
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: {{ .Values.persistence.size | quote }}
{{- end }}

View File

@@ -0,0 +1,24 @@
apiVersion: v1
kind: Secret
metadata:
name: {{ include "activepieces.fullname" . }}-secrets
labels:
{{- include "activepieces.labels" . | nindent 4 }}
annotations:
secret-generator.v1.mittwald.de/autogenerate: encryption-key
secret-generator.v1.mittwald.de/encoding: hex
secret-generator.v1.mittwald.de/length: "32"
type: Opaque
data: {}
---
apiVersion: v1
kind: Secret
metadata:
name: {{ include "activepieces.fullname" . }}-jwt-secret
labels:
{{- include "activepieces.labels" . | nindent 4 }}
annotations:
secret-generator.v1.mittwald.de/autogenerate: jwt-secret
secret-generator.v1.mittwald.de/length: "64"
type: Opaque
data: {}

View File

@@ -0,0 +1,15 @@
apiVersion: v1
kind: Service
metadata:
name: {{ include "activepieces.fullname" . }}
labels:
{{- include "activepieces.labels" . | nindent 4 }}
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.port }}
targetPort: http
protocol: TCP
name: http
selector:
{{- include "activepieces.selectorLabels" . | nindent 4 }}

View File

@@ -0,0 +1,13 @@
{{- if .Values.serviceAccount.create -}}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ include "activepieces.serviceAccountName" . }}
labels:
{{- include "activepieces.labels" . | nindent 4 }}
{{- with .Values.serviceAccount.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
automountServiceAccountToken: {{ .Values.serviceAccount.automount }}
{{- end }}

View File

@@ -0,0 +1,15 @@
apiVersion: v1
kind: Pod
metadata:
name: "{{ include "activepieces.fullname" . }}-test-connection"
labels:
{{- include "activepieces.labels" . | nindent 4 }}
annotations:
"helm.sh/hook": test
spec:
containers:
- name: wget
image: busybox
command: ['wget']
args: ['{{ include "activepieces.fullname" . }}:{{ .Values.service.port }}']
restartPolicy: Never

View File

@@ -0,0 +1,324 @@
# Default values for activepieces.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
# This will set the replicaset count more information can be found here: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/
replicaCount: 1
# This sets the container image more information can be found here: https://kubernetes.io/docs/concepts/containers/images/
image:
repository: ghcr.io/activepieces/activepieces
# This sets the pull policy for images.
pullPolicy: IfNotPresent
# Overrides the image tag whose default is the chart appVersion.
tag: ""
# This is for the secrets for pulling an image from a private repository more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/
imagePullSecrets: []
# This is to override the chart name.
nameOverride: ""
fullnameOverride: ""
# This section builds out the service account more information can be found here: https://kubernetes.io/docs/concepts/security/service-accounts/
serviceAccount:
# Specifies whether a service account should be created
create: true
# Automatically mount a ServiceAccount's API credentials?
automount: true
# Annotations to add to the service account
annotations: {}
# The name of the service account to use.
# If not set and create is true, a name is generated using the fullname template
name: ""
# This is for setting Kubernetes Annotations to a Pod.
# For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/
podAnnotations: {}
# This is for setting Kubernetes Labels to a Pod.
# For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/
podLabels: {}
podSecurityContext: {}
# fsGroup: 2000
securityContext: {}
# capabilities:
# drop:
# - ALL
# readOnlyRootFilesystem: true
# runAsNonRoot: true
# runAsUser: 1000
# Container configuration
container:
port: 80
# This is for setting up a service more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/
service:
# This sets the service type more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types
type: ClusterIP
# This sets the ports more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/#field-spec-ports
port: 80
# This block is for setting up the ingress for more information can be found here: https://kubernetes.io/docs/concepts/services-networking/ingress/
ingress:
enabled: false
className: ""
annotations: {}
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: "true"
hosts:
- host: chart-example.local
paths:
- path: /
pathType: ImplementationSpecific
tls: []
# - secretName: chart-example-tls
# hosts:
# - chart-example.local
resources: {}
# We usually recommend not to specify default resources and to leave this as a conscious
# choice for the user. This also increases chances charts run on environments with little
# resources, such as Minikube. If you do want to specify resources, uncomment the following
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
# limits:
# cpu: 100m
# memory: 128Mi
# requests:
# cpu: 100m
# memory: 128Mi
# This is to setup the liveness and readiness probes more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/
livenessProbe:
httpGet:
path: /v1/health
port: http
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /v1/health
port: http
initialDelaySeconds: 5
periodSeconds: 5
# This section is for setting up autoscaling more information can be found here: https://kubernetes.io/docs/concepts/workloads/autoscaling/
autoscaling:
enabled: false
minReplicas: 1
maxReplicas: 100
targetCPUUtilizationPercentage: 80
# targetMemoryUtilizationPercentage: 80
persistence:
enabled: true
size: 2Gi
mountPath: "/usr/src/app/cache"
volumes: []
volumeMounts: []
nodeSelector: {}
tolerations: []
affinity: {}
activepieces:
# ============================================================================
# REQUIRED: Core configuration that must be set for production deployment
# ============================================================================
# The URL where Activepieces will be accessible (e.g., https://activepieces.yourdomain.com)
frontendUrl: "http://localhost:4200"
# Edition: ce (Community) or ee (Enterprise)
# Community Edition (ce) is the default open-source version
edition: "ce"
# Execution mode for flows - see: https://www.activepieces.com/docs/install/architecture/workers
# Options: SANDBOX_CODE_ONLY, UNSANDBOXED
executionMode: "SANDBOX_CODE_ONLY"
# Environment: prod or dev
environment: "prod"
# ============================================================================
# OPTIONAL: Additional configuration (defaults are usually sufficient)
# ============================================================================
telemetryEnabled: true
templatesSourceUrl: "https://cloud.activepieces.com/api/v1/templates"
flowWorkerConcurrency: ""
scheduledWorkerConcurrency: ""
triggerDefaultPollInterval: ""
triggerTimeoutSeconds: ""
flowTimeoutSeconds: ""
webhookTimeoutSeconds: ""
executionDataRetentionDays: ""
issueArchiveDays: ""
pausedFlowTimeoutDays: ""
logLevel: "info"
logPretty: false
apiRateLimiting:
authn:
enabled: false
max: 100
window: 60
projectRateLimiter:
enabled: false
piecesSource: ""
devPieces: false
piecesSyncMode: ""
# ============================================================================
# OPTIONAL: Advanced configuration (only set if needed)
# ============================================================================
# Networking & API
clientRealIpHeader: "" # Header to extract real client IP (e.g., X-Forwarded-For)
apiKey: "" # API key for platform authentication
internalUrl: "" # Internal URL for service communication
# Performance & Limits
maxConcurrentJobsPerProject: "" # Limit concurrent jobs per project
maxFileSizeMb: "" # Maximum file upload size in MB
sandboxMemoryLimit: "" # Memory limit for sandbox execution
sandboxPropagatedEnvVars: "" # Environment variables to pass to sandbox
# Integrations
perplexityBaseUrl: "" # Custom Perplexity AI base URL
featurebaseApiKey: "" # Featurebase API key for feedback
appWebhookSecrets: "" # Secrets for app webhooks
# UI & Behavior
showChangelog: true # Show changelog to users
enableFlowOnPublish: true # Auto-enable flows when published
# System Paths
configPath: "" # Custom config file path
engineExecutablePath: "dist/packages/engine/main.js" # Engine executable path
# OpenTelemetry Configuration (for observability)
otel:
enabled: false
exporterOtlpEndpoint: ""
exporterOtlpHeaders: ""
# ============================================================================
# Database Configuration
# PostgreSQL is deployed by default using the Bitnami subchart
# ============================================================================
postgresql:
# Set to true to deploy PostgreSQL subchart (Bitnami)
# Set to false and provide host/url to use external PostgreSQL
enabled: true
# External PostgreSQL host (required if enabled=false and using external PostgreSQL)
host: ""
# PostgreSQL port
port: 5432
# Enable SSL for PostgreSQL connection
useSSL: false
# PostgreSQL connection URL (alternative to host/port/auth)
# If provided, host/port/auth will be ignored
url: ""
# SSL CA certificate for PostgreSQL (if useSSL is true)
sslCa: ""
auth:
database: "activepieces"
username: "postgres"
# Password for PostgreSQL
# - If using subchart (enabled=true), password is automatically generated if not provided
# - If using external PostgreSQL, provide password here or use externalSecret
password: ""
# External secret reference for password (alternative to password field)
# Use this when password is stored in a Kubernetes secret (e.g., External Secrets Operator)
# externalSecret:
# name: "postgresql-credentials"
# key: "password"
primary:
persistence:
enabled: true
# ============================================================================
# Queue Configuration
# Redis is deployed by default using the Bitnami subchart
# ============================================================================
redis:
# Set to true to deploy Redis subchart (Bitnami)
# Set to false and provide host/url to use external Redis
enabled: true
# External Redis host (required if enabled=false and using external Redis)
host: ""
# Redis port
port: 6379
# Enable SSL for Redis connection
useSSL: false
# SSL CA certificate file path for Redis (if useSSL is true)
sslCaFile: ""
# Redis database number
db: 0
# Redis connection URL (alternative to host/port/auth)
# If provided, host/port/auth will be ignored
url: ""
# Redis type: "standalone" or "sentinel"
type: "standalone"
# Redis username (for Redis 6+ ACL)
user: ""
sentinel:
name: ""
hosts: ""
role: ""
failedJob:
retentionDays: 7
retentionMaxCount: 100
auth:
# Set to true if Redis requires authentication
# - If using subchart (enabled=true), password is automatically generated if not provided
# - If using external Redis, provide password or use externalSecret
enabled: true
# Password for Redis
password: ""
# External secret reference for password (alternative to password field)
# Use this when password is stored in a Kubernetes secret (e.g., External Secrets Operator)
# externalSecret:
# name: "redis-credentials"
# key: "password"
master:
persistence:
enabled: true
# ============================================================================
# OPTIONAL: Email Configuration
# Enable SMTP to send email notifications
# ============================================================================
smtp:
enabled: false # Set to true and configure below to enable emails
host: ""
port: 587
username: ""
password: ""
senderEmail: ""
senderName: ""
# ============================================================================
# OPTIONAL: S3 Storage Configuration
# Enable S3 for file storage (alternative to local storage)
# ============================================================================
s3:
enabled: false # Set to true and configure below to use S3
accessKeyId: ""
secretAccessKey: ""
bucket: ""
endpoint: "" # For S3-compatible services like MinIO
region: ""
useSignedUrls: false
useIrsa: false # Use IAM Roles for Service Accounts (EKS)
# ============================================================================
# OPTIONAL: Queue UI Configuration
# Enable BullMQ Board for monitoring job queues
# ============================================================================
queueUi:
enabled: false # Set to true and configure credentials below
username: ""
password: ""

View File

@@ -0,0 +1,33 @@
/.pulumi/
/.vscode/
/.vs/
bin/
build/
node_modules/
*.pyc
.Python
venv/
include/
lib/
yarn.lock
package-lock.json
# https://www.pulumi.com/blog/iac-recommended-practices-developer-stacks-git-branches/#using-developer-stacks
# Pulumi.*.yaml
# Pulumi.*dev*.yaml
.idea/
.ionide/
*.iml
key.rsa*
obj/
vendor
Gopkg.lock
**/.DS_Store
**/ci-scripts
# Java app
.gradle/
.settings/
.project
.classpath
target/

View File

@@ -0,0 +1,22 @@
encryptionsalt: v1:wHCVNl3bj/g=:v1:mxogi9ZeBjIcxNZC:q+bjpLv9rnJnu8qq7xwKGLd/GAZOqA==
config:
activepieces:environment: "dev"
activepieces:apEncryptionKey:
activepieces:apJwtSecret:
activepieces:deployLocalBuild: "false"
activepieces:repoName:
activepieces:containerCpu: "256"
activepieces:containerMemory: "512"
activepieces:containerInstances: "1"
activepieces:usePostgres: "false"
activepieces:dbInstanceClass: "db.t3.small"
activepieces:dbUsername: "postgres"
activepieces:dbIsPublic: "false"
activepieces:dbPassword:
secure: v1:MXNSOcqZCp10X2PX:mU2iTrcETjdisk8FkD5yHLJYUxRei/9l
activepieces:addIpToPostgresSecurityGroup:
activepieces:useRedis: "false"
activepieces:redisNodeType: "cache.t3.small"
activepieces:domain:
activepieces:subDomain:
aws:region: "us-east-1"

View File

@@ -0,0 +1,19 @@
encryptionsalt: v1:icXg2cmIvSc=:v1:y8+4YhdMCPPDY26J:5cNYmimH353n8sjUDDc6srvcPgb+8Q==
config:
activepieces:environment: "prod"
activepieces:apEncryptionKey:
activepieces:apJwtSecret:
activepieces:deployLocalBuild: "true"
activepieces:repoName: "activepieces-prod-repo"
activepieces:containerCpu: "512"
activepieces:containerMemory: "1024"
activepieces:containerInstances: "1"
activepieces:usePostgres: "true"
activepieces:dbInstanceClass: "db.t3.small"
activepieces:dbIsPublic: "false"
activepieces:dbPassword:
secure: v1:MXNSOcqZCp10X2PX:mU2iTrcETjdisk8FkD5yHLJYUxRei/9l
activepieces:dbUsername: "postgres"
activepieces:useRedis: "true"
activepieces:redisNodeType: "cache.t3.small"
aws:region: "us-east-1"

View File

@@ -0,0 +1,56 @@
runtime: nodejs
name: activepieces
description: A Pulumi template to deploy Activepieces in a development or production configuration.
stack: activepieces-dev
template:
description: Deploy Activepieces into into an ECS Fargate instance & optionally add Postgres, Redis and a DNS registration with SSL.
config:
aws:region:
description: The AWS region to deploy into
default: us-west-2
environment:
description: Environment
default: prod
containerCpu:
description: The amount of CPU to allocate for the container
default: 256
containerMemory:
description: The amount of memory to allocate for the container
default: 512
containerInstances:
description: Number of running containers behind load balancer
default: 1
usePostgres:
description: Add Postgres for storage or use SQLite3 locally
default: true
dbIsPublic:
description: Should Db be publicly reachable. Ignored if usePostgres is false.
default: false
dbUsername:
description: Default username for the Postgres. Ignored if usePostgres is false
default: postgres
dbPassword:
description: Defaults to "postgres". Ignored if usePostgres is false
default: postgres
secret: true
dbInstanceClass:
description: The size of the RDS instance
default: db.t3.micro
useRedis:
description: Use a single node Redis cluster or in-memory
default: true
redisNodeType:
description: Node type for the Redis 7 cluster
default: cache.t3.micro
domain:
description: Optional - E.g. "yourdomain.com". Hosted zone must already exist in Route 53. Creates SSL cert
subDomain:
description: Optional - E.g. "activepieces". "domain" must be set
addIpToPostgresSecurityGroup:
description: Optional - An IP address to add to the allowed inbound traffic for the Postgres
apEncryptionKey:
description: Optional - Run 'openssl rand -hex 16' locally to generate or leave blank to auto-generate
secret: true
apJwtSecret:
description: Optional - Run 'openssl rand -hex 32' locally to generate or leave blank to auto-generate
secret: true

View File

@@ -0,0 +1,3 @@
# Getting Started
See instruction on https://www.activepieces.com/docs/install/options/aws

View File

@@ -0,0 +1,16 @@
import * as pulumi from "@pulumi/pulumi";
import { isTaggable } from "./taggable";
/**
* registerAutoTags registers a global stack transformation that merges a set
* of tags with whatever was also explicitly added to the resource definition.
*/
export function registerAutoTags(autoTags: Record<string, string>): void {
pulumi.runtime.registerStackTransformation((args) => {
if (isTaggable(args.type)) {
args.props["tags"] = { ...args.props["tags"], ...autoTags };
return { props: args.props, opts: args.opts };
}
return undefined;
});
}

View File

@@ -0,0 +1,466 @@
import * as aws from "@pulumi/aws";
import * as docker from "@pulumi/docker";
import * as pulumi from "@pulumi/pulumi";
import * as awsx from "@pulumi/awsx";
import { ApplicationLoadBalancer } from "@pulumi/awsx/lb/applicationLoadBalancer";
import { registerAutoTags } from './autotag';
import * as child_process from "child_process";
const stack = pulumi.getStack();
const config = new pulumi.Config();
const apEncryptionKey = config.getSecret("apEncryptionKey")?.apply(secretValue => {
return secretValue || child_process.execSync("openssl rand -hex 16").toString().trim();
});
const apJwtSecret = config.getSecret("apJwtSecret")?.apply(secretValue => {
return secretValue || child_process.execSync("openssl rand -hex 32").toString().trim();
});
const containerCpu = config.requireNumber("containerCpu");
const containerMemory = config.requireNumber("containerMemory");
const containerInstances = config.requireNumber("containerInstances");
const addIpToPostgresSecurityGroup = config.get("addIpToPostgresSecurityGroup");
const domain = config.get("domain");
const subDomain = config.get("subDomain");
const usePostgres = config.requireBoolean("usePostgres");
const useRedis = config.requireBoolean("useRedis");
const redisNodeType = config.require("redisNodeType");
const dbIsPublic = config.getBoolean("dbIsPublic");
const dbUsername = config.get("dbUsername");
const dbPassword = config.getSecret("dbPassword");
const dbInstanceClass = config.require("dbInstanceClass");
// Add tags for every resource that allows them, with the following properties.
// Useful to know who or what created the resource/service
registerAutoTags({
"pulumi:Project": pulumi.getProject(),
"pulumi:Stack": pulumi.getStack(),
"Created by": config.get("author") || child_process.execSync("pulumi whoami").toString().trim().replace('\\', '/')
});
let imageName;
// Check if we're deploying a local build or direct from Docker Hub
if (config.getBoolean("deployLocalBuild")) {
const repoName = config.require("repoName");
const repo = new aws.ecr.Repository(repoName, {
name: repoName // https://www.pulumi.com/docs/intro/concepts/resources/names/#autonaming
}); // Create a private ECR repository
const repoUrl = pulumi.interpolate`${repo.repositoryUrl}`; // Get registry info (creds and endpoint)
const name = pulumi.interpolate`${repoUrl}:latest`;
// Get the repository credentials we use to push the image to the repository
const repoCreds = repo.registryId.apply(async (registryId) => {
const credentials = await aws.ecr.getCredentials({
registryId: registryId,
});
const decodedCredentials = Buffer.from(credentials.authorizationToken, "base64").toString();
const [username, password] = decodedCredentials.split(":");
return {
server: credentials.proxyEndpoint,
username,
password
};
});
// Build and publish the container image.
const image = new docker.Image(stack, {
build: {
context: `../../`,
dockerfile: `../../Dockerfile`,
builderVersion: "BuilderBuildKit",
args: {
"BUILDKIT_INLINE_CACHE": "1"
},
},
skipPush: pulumi.runtime.isDryRun(),
imageName: name,
registry: repoCreds
});
imageName = image.imageName;
pulumi.log.info(`Finished pushing image to ECR`, image);
} else {
imageName = process.env.IMAGE_NAME || config.get("imageName") || "activepieces/activepieces:latest";
}
const containerEnvironmentVars: awsx.types.input.ecs.TaskDefinitionKeyValuePairArgs[] = [];
// Allocate a new VPC with the default settings:
const vpc = new awsx.ec2.Vpc(`${stack}-vpc`, {
numberOfAvailabilityZones: 2,
natGateways: {
strategy: "Single"
},
tags: {
// For some reason, this is how you name a VPC with AWS:
// https://github.com/pulumi/pulumi-terraform/issues/38#issue-262186406
Name: `${stack}-vpc`
},
enableDnsHostnames: true,
enableDnsSupport: true
});
const albSecGroup = new aws.ec2.SecurityGroup(`${stack}-alb-sg`, {
name: `${stack}-alb-sg`,
vpcId: vpc.vpcId,
ingress: [{ // Allow only http & https traffic
protocol: "tcp",
fromPort: 443,
toPort: 443,
cidrBlocks: ["0.0.0.0/0"]
},
{
protocol: "tcp",
fromPort: 80,
toPort: 80,
cidrBlocks: ["0.0.0.0/0"]
}],
egress: [{
protocol: "-1",
fromPort: 0,
toPort: 0,
cidrBlocks: ["0.0.0.0/0"]
}]
})
const fargateSecGroup = new aws.ec2.SecurityGroup(`${stack}-fargate-sg`, {
name: `${stack}-fargate-sg`,
vpcId: vpc.vpcId,
ingress: [
{
protocol: "tcp",
fromPort: 80,
toPort: 80,
securityGroups: [albSecGroup.id]
}
],
egress: [ // allow all outbound traffic
{
protocol: "-1",
fromPort: 0,
toPort: 0,
cidrBlocks: ["0.0.0.0/0"]
}
]
});
if (usePostgres) {
const rdsSecurityGroupArgs: aws.ec2.SecurityGroupArgs = {
name: `${stack}-db-sg`,
vpcId: vpc.vpcId,
ingress: [{
protocol: "tcp",
fromPort: 5432,
toPort: 5432,
securityGroups: [fargateSecGroup.id] // The id of the Fargate security group
}],
egress: [ // allow all outbound traffic
{
protocol: "-1",
fromPort: 0,
toPort: 0,
cidrBlocks: ["0.0.0.0/0"]
}
]
};
// Optionally add the current outgoing public IP address to the CIDR block
// so that they can connect directly to the Db during development
if (addIpToPostgresSecurityGroup) {
// @ts-ignore
rdsSecurityGroupArgs.ingress.push({
protocol: "tcp",
fromPort: 5432,
toPort: 5432,
cidrBlocks: [`${addIpToPostgresSecurityGroup}/32`],
description: `Public IP for local connection`
});
}
const rdsSecurityGroup = new aws.ec2.SecurityGroup(`${stack}-db-sg`, rdsSecurityGroupArgs);
const rdsSubnets = new aws.rds.SubnetGroup(`${stack}-db-subnet-group`, {
name: `${stack}-db-subnet-group`,
subnetIds: dbIsPublic ? vpc.publicSubnetIds : vpc.privateSubnetIds
});
const db = new aws.rds.Instance(stack, {
allocatedStorage: 10,
engine: "postgres",
engineVersion: "14.9",
identifier: stack, // In RDS
dbName: "postgres", // When connected to the DB host
instanceClass: dbInstanceClass,
port: 5432,
publiclyAccessible: dbIsPublic,
skipFinalSnapshot: true,
storageType: "gp2",
username: dbUsername,
password: dbPassword,
dbSubnetGroupName: rdsSubnets.id,
vpcSecurityGroupIds: [rdsSecurityGroup.id],
backupRetentionPeriod: 0,
applyImmediately: true,
allowMajorVersionUpgrade: true,
autoMinorVersionUpgrade: true
}, {
protect: dbIsPublic === false,
deleteBeforeReplace: true
});
containerEnvironmentVars.push(
{
name: "AP_POSTGRES_DATABASE",
value: db.dbName
},
{
name: "AP_POSTGRES_HOST",
value: db.address
},
{
name: "AP_POSTGRES_PORT",
value: pulumi.interpolate`${db.port}`
},
{
name: "AP_POSTGRES_USERNAME",
value: db.username
},
{
name: "AP_POSTGRES_PASSWORD",
value: config.requireSecret("dbPassword")
},
{
name: "AP_POSTGRES_USE_SSL",
value: "false"
});
} else {
containerEnvironmentVars.push(
{
name: "AP_DB_TYPE",
value: "SQLITE3"
});
}
if (useRedis) {
const redisCluster = new aws.elasticache.Cluster(`${stack}-redis-cluster`, {
clusterId: `${stack}-redis-cluster`,
engine: "redis",
engineVersion: '7.0',
nodeType: redisNodeType,
numCacheNodes: 1,
parameterGroupName: "default.redis7",
port: 6379,
subnetGroupName: new aws.elasticache.SubnetGroup(`${stack}-redis-subnet-group`, {
name: `${stack}-redis-subnet-group`,
subnetIds: vpc.privateSubnetIds
}).id,
securityGroupIds: [
new aws.ec2.SecurityGroup(`${stack}-redis-sg`, {
name: `${stack}-redis-sg`,
vpcId: vpc.vpcId,
ingress: [{
protocol: "tcp",
fromPort: 6379, // The standard port for Redis
toPort: 6379,
securityGroups: [fargateSecGroup.id]
}],
egress: [{
protocol: "-1",
fromPort: 0,
toPort: 0,
cidrBlocks: ["0.0.0.0/0"]
}]
}).id
]
});
const redisUrl = pulumi.interpolate`${redisCluster.cacheNodes[0].address}:${redisCluster.cacheNodes[0].port}`;
containerEnvironmentVars.push(
{
name: "AP_REDIS_URL",
value: redisUrl
});
} else {
containerEnvironmentVars.push(
{
name: "AP_QUEUE_MODE",
value: "MEMORY"
});
}
let alb: ApplicationLoadBalancer;
// Export the URL so we can easily access it.
let frontendUrl;
if (subDomain && domain) {
const fullDomain = `${subDomain}.${domain}`;
const exampleCertificate = new aws.acm.Certificate(`${stack}-cert`, {
domainName: fullDomain,
validationMethod: "DNS",
});
const hostedZoneId = aws.route53.getZone({ name: domain }, { async: true }).then(zone => zone.zoneId);
// DNS records to verify SSL Certificate
const certificateValidationDomain = new aws.route53.Record(`${fullDomain}-validation`, {
name: exampleCertificate.domainValidationOptions[0].resourceRecordName,
zoneId: hostedZoneId,
type: exampleCertificate.domainValidationOptions[0].resourceRecordType,
records: [exampleCertificate.domainValidationOptions[0].resourceRecordValue],
ttl: 600,
});
const certificateValidation = new aws.acm.CertificateValidation(`${fullDomain}-cert-validation`, {
certificateArn: exampleCertificate.arn,
validationRecordFqdns: [certificateValidationDomain.fqdn],
});
// Creates an ALB associated with our custom VPC.
alb = new awsx.lb.ApplicationLoadBalancer(`${stack}-alb`, {
securityGroups: [albSecGroup.id],
name: `${stack}-alb`,
subnetIds: vpc.publicSubnetIds,
listeners: [{
port: 80, // port on the docker container
protocol: "HTTP",
defaultActions: [{
type: "redirect",
redirect: {
protocol: "HTTPS",
port: "443",
statusCode: "HTTP_301",
},
}]
},
{
protocol: "HTTPS",
port: 443,
certificateArn: certificateValidation.certificateArn
}],
defaultTargetGroup: {
name: `${stack}-alb-tg`,
port: 80 // port on the docker container ,
}
});
// Create a DNS record for the load balancer
const albDomain = new aws.route53.Record(fullDomain, {
name: fullDomain,
zoneId: hostedZoneId,
type: "CNAME",
records: [alb.loadBalancer.dnsName],
ttl: 600,
});
frontendUrl = pulumi.interpolate`https://${subDomain}.${domain}`;
} else {
// Creates an ALB associated with our custom VPC.
alb = new awsx.lb.ApplicationLoadBalancer(`${stack}-alb`, {
securityGroups: [albSecGroup.id],
name: `${stack}-alb`,
subnetIds: vpc.publicSubnetIds,
listeners: [{
port: 80, // exposed port from the docker file
protocol: "HTTP"
}],
defaultTargetGroup: {
name: `${stack}-alb-tg`,
port: 80, // port on the docker container
protocol: "HTTP"
}
});
frontendUrl = pulumi.interpolate`http://${alb.loadBalancer.dnsName}`;
}
const environmentVariables = [
...containerEnvironmentVars,
{
name: "AP_ENGINE_EXECUTABLE_PATH",
value: "dist/packages/engine/main.js"
},
{
name: "AP_ENCRYPTION_KEY",
value: apEncryptionKey
},
{
name: "AP_JWT_SECRET",
value: apJwtSecret
},
{
name: "AP_ENVIRONMENT",
value: "prod"
},
{
name: "AP_FRONTEND_URL",
value: frontendUrl
},
{
name: "AP_TRIGGER_DEFAULT_POLL_INTERVAL",
value: "5"
},
{
name: "AP_EXECUTION_MODE",
value: "UNSANDBOXED"
},
{
name: "AP_REDIS_USE_SSL",
value: "false"
},
{
name: "AP_SANDBOX_RUN_TIME_SECONDS",
value: "600"
},
{
name: "AP_TELEMETRY_ENABLED",
value: "true"
},
{
name: "AP_TEMPLATES_SOURCE_URL",
value: "https://cloud.activepieces.com/api/v1/templates"
}
];
const fargateService = new awsx.ecs.FargateService(`${stack}-fg`, {
name: `${stack}-fg`,
cluster: (new aws.ecs.Cluster(`${stack}-cluster`, {
name: `${stack}-cluster`
})).arn,
networkConfiguration: {
subnets: vpc.publicSubnetIds,
securityGroups: [fargateSecGroup.id],
assignPublicIp: true
},
desiredCount: containerInstances,
taskDefinitionArgs: {
family: `${stack}-fg-task-definition`,
container: {
name: "activepieces",
image: imageName,
cpu: containerCpu,
memory: containerMemory,
portMappings: [{
targetGroup: alb.defaultTargetGroup,
}],
environment: environmentVariables
}
}
});
pulumi.log.info("Finished running Pulumi");
export const _ = {
activePiecesUrl: frontendUrl,
activepiecesEnv: environmentVariables
};

View File

@@ -0,0 +1,13 @@
{
"name": "pulumi",
"main": "index.ts",
"devDependencies": {
"@types/node": "^18"
},
"dependencies": {
"@pulumi/pulumi": "^3.0.0",
"@pulumi/aws": "^6.0.0",
"@pulumi/awsx": "^2.20.0",
"@pulumi/docker": "^4.4.0"
}
}

View File

@@ -0,0 +1,237 @@
/**
* isTaggable returns true if the given resource type is an AWS resource that supports tags.
*/
export function isTaggable(t: string): boolean {
return (taggableResourceTypes.indexOf(t) !== -1);
}
// taggableResourceTypes is a list of known AWS type tokens that are taggable.
const taggableResourceTypes = [
"aws:accessanalyzer/analyzer:Analyzer",
"aws:acm/certificate:Certificate",
"aws:acmpca/certificateAuthority:CertificateAuthority",
"aws:alb/loadBalancer:LoadBalancer",
"aws:alb/targetGroup:TargetGroup",
"aws:apigateway/apiKey:ApiKey",
"aws:apigateway/clientCertificate:ClientCertificate",
"aws:apigateway/domainName:DomainName",
"aws:apigateway/restApi:RestApi",
"aws:apigateway/stage:Stage",
"aws:apigateway/usagePlan:UsagePlan",
"aws:apigateway/vpcLink:VpcLink",
"aws:applicationloadbalancing/loadBalancer:LoadBalancer",
"aws:applicationloadbalancing/targetGroup:TargetGroup",
"aws:appmesh/mesh:Mesh",
"aws:appmesh/route:Route",
"aws:appmesh/virtualNode:VirtualNode",
"aws:appmesh/virtualRouter:VirtualRouter",
"aws:appmesh/virtualService:VirtualService",
"aws:appsync/graphQLApi:GraphQLApi",
"aws:athena/workgroup:Workgroup",
"aws:autoscaling/group:Group",
"aws:backup/plan:Plan",
"aws:backup/vault:Vault",
"aws:cfg/aggregateAuthorization:AggregateAuthorization",
"aws:cfg/configurationAggregator:ConfigurationAggregator",
"aws:cfg/rule:Rule",
"aws:cloudformation/stack:Stack",
"aws:cloudformation/stackSet:StackSet",
"aws:cloudfront/distribution:Distribution",
"aws:cloudhsmv2/cluster:Cluster",
"aws:cloudtrail/trail:Trail",
"aws:cloudwatch/eventRule:EventRule",
"aws:cloudwatch/logGroup:LogGroup",
"aws:cloudwatch/metricAlarm:MetricAlarm",
"aws:codebuild/project:Project",
"aws:codecommit/repository:Repository",
"aws:codepipeline/pipeline:Pipeline",
"aws:codepipeline/webhook:Webhook",
"aws:codestarnotifications/notificationRule:NotificationRule",
"aws:cognito/identityPool:IdentityPool",
"aws:cognito/userPool:UserPool",
"aws:datapipeline/pipeline:Pipeline",
"aws:datasync/agent:Agent",
"aws:datasync/efsLocation:EfsLocation",
"aws:datasync/locationSmb:LocationSmb",
"aws:datasync/nfsLocation:NfsLocation",
"aws:datasync/s3Location:S3Location",
"aws:datasync/task:Task",
"aws:dax/cluster:Cluster",
"aws:directconnect/connection:Connection",
"aws:directconnect/hostedPrivateVirtualInterfaceAccepter:HostedPrivateVirtualInterfaceAccepter",
"aws:directconnect/hostedPublicVirtualInterfaceAccepter:HostedPublicVirtualInterfaceAccepter",
"aws:directconnect/hostedTransitVirtualInterfaceAcceptor:HostedTransitVirtualInterfaceAcceptor",
"aws:directconnect/linkAggregationGroup:LinkAggregationGroup",
"aws:directconnect/privateVirtualInterface:PrivateVirtualInterface",
"aws:directconnect/publicVirtualInterface:PublicVirtualInterface",
"aws:directconnect/transitVirtualInterface:TransitVirtualInterface",
"aws:directoryservice/directory:Directory",
"aws:dlm/lifecyclePolicy:LifecyclePolicy",
"aws:dms/endpoint:Endpoint",
"aws:dms/replicationInstance:ReplicationInstance",
"aws:dms/replicationSubnetGroup:ReplicationSubnetGroup",
"aws:dms/replicationTask:ReplicationTask",
"aws:docdb/cluster:Cluster",
"aws:docdb/clusterInstance:ClusterInstance",
"aws:docdb/clusterParameterGroup:ClusterParameterGroup",
"aws:docdb/subnetGroup:SubnetGroup",
"aws:dynamodb/table:Table",
"aws:ebs/snapshot:Snapshot",
"aws:ebs/snapshotCopy:SnapshotCopy",
"aws:ebs/volume:Volume",
"aws:ec2/ami:Ami",
"aws:ec2/amiCopy:AmiCopy",
"aws:ec2/amiFromInstance:AmiFromInstance",
"aws:ec2/capacityReservation:CapacityReservation",
"aws:ec2/customerGateway:CustomerGateway",
"aws:ec2/defaultNetworkAcl:DefaultNetworkAcl",
"aws:ec2/defaultRouteTable:DefaultRouteTable",
"aws:ec2/defaultSecurityGroup:DefaultSecurityGroup",
"aws:ec2/defaultSubnet:DefaultSubnet",
"aws:ec2/defaultVpc:DefaultVpc",
"aws:ec2/defaultVpcDhcpOptions:DefaultVpcDhcpOptions",
"aws:ec2/eip:Eip",
"aws:ec2/fleet:Fleet",
"aws:ec2/instance:Instance",
"aws:ec2/internetGateway:InternetGateway",
"aws:ec2/keyPair:KeyPair",
"aws:ec2/launchTemplate:LaunchTemplate",
"aws:ec2/natGateway:NatGateway",
"aws:ec2/networkAcl:NetworkAcl",
"aws:ec2/networkInterface:NetworkInterface",
"aws:ec2/placementGroup:PlacementGroup",
"aws:ec2/routeTable:RouteTable",
"aws:ec2/securityGroup:SecurityGroup",
"aws:ec2/spotInstanceRequest:SpotInstanceRequest",
"aws:ec2/subnet:Subnet",
"aws:ec2/vpc:Vpc",
"aws:ec2/vpcDhcpOptions:VpcDhcpOptions",
"aws:ec2/vpcEndpoint:VpcEndpoint",
"aws:ec2/vpcEndpointService:VpcEndpointService",
"aws:ec2/vpcPeeringConnection:VpcPeeringConnection",
"aws:ec2/vpcPeeringConnectionAccepter:VpcPeeringConnectionAccepter",
"aws:ec2/vpnConnection:VpnConnection",
"aws:ec2/vpnGateway:VpnGateway",
"aws:ec2clientvpn/endpoint:Endpoint",
"aws:ec2transitgateway/routeTable:RouteTable",
"aws:ec2transitgateway/transitGateway:TransitGateway",
"aws:ec2transitgateway/vpcAttachment:VpcAttachment",
"aws:ec2transitgateway/vpcAttachmentAccepter:VpcAttachmentAccepter",
"aws:ecr/repository:Repository",
"aws:ecs/capacityProvider:CapacityProvider",
"aws:ecs/cluster:Cluster",
"aws:ecs/service:Service",
"aws:ecs/taskDefinition:TaskDefinition",
"aws:efs/fileSystem:FileSystem",
"aws:eks/cluster:Cluster",
"aws:eks/fargateProfile:FargateProfile",
"aws:eks/nodeGroup:NodeGroup",
"aws:elasticache/cluster:Cluster",
"aws:elasticache/replicationGroup:ReplicationGroup",
"aws:elasticbeanstalk/application:Application",
"aws:elasticbeanstalk/applicationVersion:ApplicationVersion",
"aws:elasticbeanstalk/environment:Environment",
"aws:elasticloadbalancing/loadBalancer:LoadBalancer",
"aws:elasticloadbalancingv2/loadBalancer:LoadBalancer",
"aws:elasticloadbalancingv2/targetGroup:TargetGroup",
"aws:elasticsearch/domain:Domain",
"aws:elb/loadBalancer:LoadBalancer",
"aws:emr/cluster:Cluster",
"aws:fsx/lustreFileSystem:LustreFileSystem",
"aws:fsx/windowsFileSystem:WindowsFileSystem",
"aws:gamelift/alias:Alias",
"aws:gamelift/build:Build",
"aws:gamelift/fleet:Fleet",
"aws:gamelift/gameSessionQueue:GameSessionQueue",
"aws:glacier/vault:Vault",
"aws:glue/crawler:Crawler",
"aws:glue/job:Job",
"aws:glue/trigger:Trigger",
"aws:iam/role:Role",
"aws:iam/user:User",
"aws:inspector/resourceGroup:ResourceGroup",
"aws:kinesis/analyticsApplication:AnalyticsApplication",
"aws:kinesis/firehoseDeliveryStream:FirehoseDeliveryStream",
"aws:kinesis/stream:Stream",
"aws:kms/externalKey:ExternalKey",
"aws:kms/key:Key",
"aws:lambda/function:Function",
"aws:lb/loadBalancer:LoadBalancer",
"aws:lb/targetGroup:TargetGroup",
"aws:licensemanager/licenseConfiguration:LicenseConfiguration",
"aws:lightsail/instance:Instance",
"aws:mediaconvert/queue:Queue",
"aws:mediapackage/channel:Channel",
"aws:mediastore/container:Container",
"aws:mq/broker:Broker",
"aws:mq/configuration:Configuration",
"aws:msk/cluster:Cluster",
"aws:neptune/cluster:Cluster",
"aws:neptune/clusterInstance:ClusterInstance",
"aws:neptune/clusterParameterGroup:ClusterParameterGroup",
"aws:neptune/eventSubscription:EventSubscription",
"aws:neptune/parameterGroup:ParameterGroup",
"aws:neptune/subnetGroup:SubnetGroup",
"aws:opsworks/stack:Stack",
"aws:organizations/account:Account",
"aws:pinpoint/app:App",
"aws:qldb/ledger:Ledger",
"aws:ram/resourceShare:ResourceShare",
"aws:rds/cluster:Cluster",
"aws:rds/clusterEndpoint:ClusterEndpoint",
"aws:rds/clusterInstance:ClusterInstance",
"aws:rds/clusterParameterGroup:ClusterParameterGroup",
"aws:rds/clusterSnapshot:ClusterSnapshot",
"aws:rds/eventSubscription:EventSubscription",
"aws:rds/instance:Instance",
"aws:rds/optionGroup:OptionGroup",
"aws:rds/parameterGroup:ParameterGroup",
"aws:rds/securityGroup:SecurityGroup",
"aws:rds/snapshot:Snapshot",
"aws:rds/subnetGroup:SubnetGroup",
"aws:redshift/cluster:Cluster",
"aws:redshift/eventSubscription:EventSubscription",
"aws:redshift/parameterGroup:ParameterGroup",
"aws:redshift/snapshotCopyGrant:SnapshotCopyGrant",
"aws:redshift/snapshotSchedule:SnapshotSchedule",
"aws:redshift/subnetGroup:SubnetGroup",
"aws:resourcegroups/group:Group",
"aws:route53/healthCheck:HealthCheck",
"aws:route53/resolverEndpoint:ResolverEndpoint",
"aws:route53/resolverRule:ResolverRule",
"aws:route53/zone:Zone",
"aws:s3/bucket:Bucket",
"aws:s3/bucketObject:BucketObject",
"aws:sagemaker/endpoint:Endpoint",
"aws:sagemaker/endpointConfiguration:EndpointConfiguration",
"aws:sagemaker/model:Model",
"aws:sagemaker/notebookInstance:NotebookInstance",
"aws:secretsmanager/secret:Secret",
"aws:servicecatalog/portfolio:Portfolio",
"aws:sfn/activity:Activity",
"aws:sfn/stateMachine:StateMachine",
"aws:sns/topic:Topic",
"aws:sqs/queue:Queue",
"aws:ssm/activation:Activation",
"aws:ssm/document:Document",
"aws:ssm/maintenanceWindow:MaintenanceWindow",
"aws:ssm/parameter:Parameter",
"aws:ssm/patchBaseline:PatchBaseline",
"aws:storagegateway/cachesIscsiVolume:CachesIscsiVolume",
"aws:storagegateway/gateway:Gateway",
"aws:storagegateway/nfsFileShare:NfsFileShare",
"aws:storagegateway/smbFileShare:SmbFileShare",
"aws:swf/domain:Domain",
"aws:transfer/server:Server",
"aws:transfer/user:User",
"aws:waf/rateBasedRule:RateBasedRule",
"aws:waf/rule:Rule",
"aws:waf/ruleGroup:RuleGroup",
"aws:waf/webAcl:WebAcl",
"aws:wafregional/rateBasedRule:RateBasedRule",
"aws:wafregional/rule:Rule",
"aws:wafregional/ruleGroup:RuleGroup",
"aws:wafregional/webAcl:WebAcl",
"aws:workspaces/directory:Directory",
"aws:workspaces/ipGroup:IpGroup",
];

View File

@@ -0,0 +1,20 @@
{
"compilerOptions": {
"strict": true,
"outDir": "bin",
"target": "es2016",
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": true,
"experimentalDecorators": true,
"pretty": true,
"noFallthroughCasesInSwitch": true,
"noImplicitReturns": true,
"forceConsistentCasingInFileNames": true,
"noImplicitAny": false,
"types": ["node"]
},
"files": [
"index.ts"
]
}

View File

@@ -0,0 +1 @@
{"id":"du7O4b0e8P"}

View File

@@ -0,0 +1,23 @@
services:
db:
image: postgres:14.4
environment:
POSTGRES_DB: activepieces
POSTGRES_USER: postgres
POSTGRES_PASSWORD: A79Vm5D4p2VQHOp2gd5
volumes:
- postgres_data:/var/lib/postgresql/data
ports:
- "5432:5432"
redis:
image: redis:7.0.7
volumes:
- redis_data:/data
ports:
- "6379:6379"
volumes:
postgres_data:
redis_data:

View File

@@ -0,0 +1,28 @@
services:
app:
extends:
file: docker-compose.dev.yml
service: app
user: "${UID}:${GID}"
command: /bin/sh -c "npm_config_cache=/usr/src/app/.npm-cache npx nx run-tests backend"
postgres:
extends:
file: docker-compose.dev.yml
service: postgres
ports:
- "5432:5432"
redis:
extends:
file: docker-compose.dev.yml
service: redis
ports:
- "6379:6379"
volumes:
postgres_data_dev:
redis_data_dev:
networks:
activepieces_dev:

View File

@@ -0,0 +1,43 @@
services:
activepieces:
image: ghcr.io/activepieces/activepieces:0.74.3
container_name: activepieces
restart: unless-stopped
## Enable the following line if you already use AP_EXECUTION_MODE with SANDBOX_PROCESS or old activepieces, checking the breaking change documentation for more info.
## privileged: true
ports:
- '8080:80'
depends_on:
- postgres
- redis
env_file: .env
volumes:
- ./cache:/usr/src/app/cache
networks:
- activepieces
postgres:
image: 'postgres:14.4'
container_name: postgres
restart: unless-stopped
env_file: .env
environment:
- 'POSTGRES_DB=${AP_POSTGRES_DATABASE}'
- 'POSTGRES_PASSWORD=${AP_POSTGRES_PASSWORD}'
- 'POSTGRES_USER=${AP_POSTGRES_USERNAME}'
volumes:
- postgres_data:/var/lib/postgresql/data
networks:
- activepieces
redis:
image: 'redis:7.0.7'
container_name: redis
restart: unless-stopped
volumes:
- 'redis_data:/data'
networks:
- activepieces
volumes:
postgres_data:
redis_data:
networks:
activepieces:

View File

@@ -0,0 +1,26 @@
#!/bin/sh
# Set default values if not provided
export AP_APP_TITLE="${AP_APP_TITLE:-Activepieces}"
export AP_FAVICON_URL="${AP_FAVICON_URL:-https://cdn.activepieces.com/brand/favicon.ico}"
# Debug: Print environment variables
echo "AP_APP_TITLE: $AP_APP_TITLE"
echo "AP_FAVICON_URL: $AP_FAVICON_URL"
# Process environment variables in index.html BEFORE starting services
envsubst '${AP_APP_TITLE} ${AP_FAVICON_URL}' < /usr/share/nginx/html/index.html > /usr/share/nginx/html/index.html.tmp && \
mv /usr/share/nginx/html/index.html.tmp /usr/share/nginx/html/index.html
# Start Nginx server
nginx -g "daemon off;" &
# Start backend server
if [ "$AP_CONTAINER_TYPE" = "APP" ] && [ "$AP_PM2_ENABLED" = "true" ]; then
echo "Starting backend server with PM2 (APP mode)"
pm2-runtime start dist/packages/server/api/main.cjs --name "activepieces-app" --node-args="--enable-source-maps" -i 0
else
echo "Starting backend server with Node.js (WORKER mode or default)"
node --enable-source-maps dist/packages/server/api/main.cjs
fi

View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2023 Mintlify
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,43 @@
# Mintlify Starter Kit
Use the starter kit to get your docs deployed and ready to customize.
Click the green **Use this template** button at the top of this repo to copy the Mintlify starter kit. The starter kit contains examples with
- Guide pages
- Navigation
- Customizations
- API reference pages
- Use of popular components
**[Follow the full quickstart guide](https://starter.mintlify.com/quickstart)**
## Development
Install the [Mintlify CLI](https://www.npmjs.com/package/mint) to preview your documentation changes locally. To install, use the following command:
```
npm i -g mint
```
Run the following command at the root of your documentation, where your `docs.json` is located:
```
mint dev
```
View your local preview at `http://localhost:3000`.
## Publishing changes
Install our GitHub app from your [dashboard](https://dashboard.mintlify.com/settings/organization/github-app) to propagate changes from your repo to your deployment. Changes are deployed to production automatically after pushing to the default branch.
## Need help?
### Troubleshooting
- If your dev environment isn't running: Run `mint update` to ensure you have the most recent version of the CLI.
- If a page loads as a 404: Make sure you are running in a folder with a valid `docs.json`.
### Resources
- [Mintlify documentation](https://mintlify.com/docs)

View File

@@ -0,0 +1,3 @@
<Tip>
This feature is available in our paid editions. Contact us [here](https://www.activepieces.com/sales), and we'll be delighted to assist you!
</Tip>

View File

@@ -0,0 +1,6 @@
| Name | Supports NPM in Code Piece | Requires Docker to be Privileged | Performance | Secure for Multi Tenant | Reusable Workers | Environment Variable |
|-------------------------------|----------------------------|----------------------------------|-----------------------|-------------------------|------------------|-------------------------------------------|
| V8/Code Sandboxing | ❌ | No | Fast & Lightweight | ✅ | ✅ | Set `AP_EXECUTION_MODE` to `SANDBOX_CODE_ONLY` |
| No Sandboxing | ✅ | No | Fast & Lightweight | ❌ | ✅ | Set `AP_EXECUTION_MODE` to `UNSANDBOXED` |
| Kernel Namespaces Sandboxing | ✅ | Yes | Slow & CPU Intensive | ✅ | ❌ | Set `AP_EXECUTION_MODE` to `SANDBOX_PROCESS` |
| Combined Sandboxing | ❌ | Yes | Medium & CPU Intensive | ✅ | ✅ | Set `AP_EXECUTION_MODE` to `SANDBOX_CODE_AND_PROCESS` |

View File

@@ -0,0 +1,3 @@
<Tip>
If you would like your users to use your own OAuth2 apps, we recommend you check [this](/admin-guide/guides/manage-oauth2).
</Tip>

View File

@@ -0,0 +1,6 @@
---
title: "Changelog"
description: "A log of all notable changes to Activepieces"
icon: "code-commit"
url: "https://github.com/activepieces/activepieces/releases"
---

View File

@@ -0,0 +1,29 @@
---
title: "i18n Translations"
description: ""
icon: "language"
---
This guide helps you understand how to change or add new translations.
Activepieces uses Crowdin because it helps translators who don't know how to code. It also makes the approval process easier. Activepieces automatically sync new text from the code and translations back into the code.
## Contribute to existing translations
1. Create Crowdin account
2. Join the project https://crowdin.com/project/activepieces
![Join Project](/resources/crowdin.png)
3. Click on the language you want to translate
4. Click on "Translate All"
![Translate All](/resources/crowdin-translate-all.png)
5. Select Strings you want to translate and click on "Save" button
## Adding a new language
- Please contact us (support@activepieces.com) if you want to add a new language. We will add it to the project and you can start translating.

View File

@@ -0,0 +1,22 @@
---
title: "License"
description: ""
icon: 'file-contract'
---
Activepieces' **core** is released as open source under the [MIT license](https://github.com/activepieces/activepieces/blob/main/LICENSE) and enterprise / cloud editions features are released under [Commercial License](https://github.com/activepieces/activepieces/blob/main/packages/ee/LICENSE)
The MIT license is a permissive license that grants users the freedom to use, modify, or distribute the software without any significant restrictions. The only requirement is that you include the license notice along with the software when distributing it.
Using the enterprise features (under the packages/ee and packages/server/api/src/app/ee folder) with a self-hosted instance requires an Activepieces license. If you are looking for these features, contact us at [sales@activepieces.com](mailto:sales@activepieces.com).
**Benefits of Dual Licensing Repo**
- **Transparency** - Everyone can see what we are doing and contribute to the project.
- **Clarity** - Everyone can see what the difference is between the open source and commercial versions of our software.
- **Audit** - Everyone can audit our code and see what we are doing.
- **Faster Development** - We can develop faster and more efficiently.
<Tip>
If you are still confused or have feedback, please open an issue on GitHub or send a message in the #contribution channel on Discord.
</Tip>

View File

@@ -0,0 +1,26 @@
---
title: "Override OAuth2 Apps"
description: "Use your own OAuth2 credentials instead of the default Activepieces apps"
icon: "lock"
---
<Snippet file="enterprise-feature.mdx" />
## Default Behavior
When users connect to services like Google Sheets or Slack, they see "Activepieces" as the app requesting access. This works out of the box with no setup required.
## Why Replace OAuth2 Apps?
- **Branding**: Show your company name instead of "Activepieces" in authorization screens
- **Higher Limits**: Some services have stricter rate limits for shared OAuth apps
- **Compliance**: Your organization may require using company-owned credentials
## How to Configure
1. Go to **Platform Admin → Setup → Pieces**
2. Find the piece you want to configure (e.g., Google Sheets)
3. Click the lock icon to open the OAuth2 settings
4. Enter your own Client ID and Client Secret
![Manage Oauth2 apps](/resources/screenshots/manage-oauth2.png)

View File

@@ -0,0 +1,88 @@
---
title: "How to Manage Pieces"
description: "Control which integrations are available to your users"
icon: "puzzle-piece"
---
<Snippet file="enterprise-feature.mdx" />
## Overview
**Pieces** are the building blocks of Activepieces — they are integrations and connectors (like Google Sheets, Slack, OpenAI, etc.) that users can use in their automation flows.
As a platform administrator, you have full control over which pieces are available to your users. This allows you to:
- **Enforce security policies** by restricting access to certain integrations
- **Simplify the user experience** by showing only relevant pieces for your use case
- **Deploy custom/private pieces** that are specific to your organization
There are **two levels** of piece management:
| Level | Who Can Manage | Scope |
|-------|----------------|-------|
| **Platform Level** | Platform Admin | Install and remove across the entire platform |
| **Project Level** | Project Admin | Show/hide specific pieces for specfic project |
---
## Platform-Level Management
Platform administrators can manage pieces for the entire Activepieces instance from **Platform Admin → Setup → Pieces**.
## Project-Level Management
Project administrators can further restrict which pieces are available within their specific project. This is useful when different teams or projects need access to different integrations.
### Show/Hide Pieces in a Project
<Steps>
<Step title="Open Project Settings">
Navigate to your project and go to **Settings → Pieces**.
</Step>
<Step title="Configure Visibility">
You'll see a list of all pieces installed on the platform. Toggle the visibility for each piece:
- **Enabled**: Users in this project can use the piece
- **Disabled**: The piece is hidden from users in this project
</Step>
<Step title="Save Changes">
Changes take effect immediately — users will only see the enabled pieces when building their flows.
</Step>
</Steps>
![Manage Pieces](/resources/screenshots/manage-pieces.png)
![Manage Pieces](/resources/screenshots/manage-pieces-2.png)
<Note>
Project-level settings can only **hide** pieces that are installed at the platform level. You cannot add pieces at the project level that aren't already installed on the platform.
</Note>
### Install Private Pieces
<Tip>
For detailed instructions on building custom pieces, check the [Building Pieces](/build-pieces/building-pieces/overview) documentation.
</Tip>
If you've built a custom piece for your organization, you can upload it directly as a tarball (`.tgz`) file.
<Steps>
<Step title="Build Your Piece">
Build your piece using the Activepieces CLI:
```bash
npm run pieces -- build --name=your-piece-name
```
This generates a tarball in `dist/packages/pieces/your-piece-name`.
</Step>
<Step title="Navigate to Pieces Settings">
Go to **Platform Admin → Setup → Pieces** and click **Install Piece**.
</Step>
<Step title="Select File Upload">
Choose **Upload File** as the installation source.
</Step>
<Step title="Upload the Tarball">
Select the `.tgz` file from your build output and upload it.
</Step>
</Steps>
![Install Piece](/resources/screenshots/install-piece.png)

View File

@@ -0,0 +1,53 @@
---
title: "Manage User Roles"
description: "Documentation on project permissions in Activepieces"
icon: 'user'
---
<Snippet file="enterprise-feature.mdx" />
Activepieces utilizes Role-Based Access Control (RBAC) for managing permissions within projects. Each project consists of multiple flows and users, with each user assigned specific roles that define their actions within the project.
## Default Roles
Activepieces comes with four standard roles out of the box. The table below shows the permissions for each role:
| Permission | Admin | Editor | Operator | Viewer |
|------------|:-----:|:------:|:--------:|:------:|
| **Flows** |||||
| View Flows | ✓ | ✓ | ✓ | ✓ |
| Edit Flows | ✓ | ✓ | | |
| Publish / Toggle Flows | ✓ | ✓ | ✓ | |
| **Runs** |||||
| View Runs | ✓ | ✓ | ✓ | ✓ |
| Retry Runs | ✓ | ✓ | ✓ | |
| **Connections** |||||
| View Connections | ✓ | ✓ | ✓ | ✓ |
| Edit Connections | ✓ | ✓ | ✓ | |
| **Team** |||||
| View Project Members | ✓ | ✓ | ✓ | ✓ |
| Add/Remove Project Members | ✓ | | | |
| **Git Sync** | | | | |
| Configure Git Repo | ✓ | | | |
| Pull Flows from Git | ✓ | | | |
| Push Flows to Git | ✓ | | | |
## Custom Roles
If the default roles don't fit your needs, you can create custom roles with specific permissions.
<Steps>
<Step title="Navigate to Project Roles">
Go to **Platform Admin** → **Security** → **Project Roles**
</Step>
<Step title="Create a New Role">
Click **Create Role** and give it a name
</Step>
<Step title="Configure Permissions">
Select the specific permissions you want to grant to this role
</Step>
</Steps>
<Tip>
Custom roles are useful when you need fine-grained control, such as allowing users to view and retry runs without being able to edit flows.
</Tip>

View File

@@ -0,0 +1,31 @@
---
title: "Setup AI Providers"
description: ""
icon: "sparkles"
---
AI providers are configured by the platform admin to centrally manage credentials and access, making [AI pieces](https://www.activepieces.com/pieces/ai) and their features available to everyone in all projects.
## Supported Providers
- **OpenAI**
- **Anthropic**
- **Gemini**
- **Vercel AI Gateway**
- **Cloudflare AI Gateway**
## How to Setup
Go to **Admin Console** → **AI** page. Add your provider's base URL and API key. These settings apply to all projects.
![Manage AI Providers](/resources/screenshots/configure-ai-provider.png)
## Cost Control & Logging
Use an AI gateway like **Vercel AI Gateway** or **Cloudflare AI Gateway** to:
- Set rate limits and budgets
- Log and monitor all AI requests
- Track usage across projects
Just set the gateway URL as your provider's base URL in the Admin Console.

View File

@@ -0,0 +1,223 @@
---
title: "How to Setup SSO"
description: "Configure Single Sign-On (SSO) to enable secure, centralized authentication for your Activepieces platform"
icon: 'key'
---
<Snippet file="enterprise-feature.mdx" />
## Overview
Single Sign-On (SSO) allows your team to authenticate using your organization's existing identity provider, eliminating the need for separate Activepieces credentials. This improves security, simplifies user management, and provides a seamless login experience.
## Prerequisites
Before configuring SSO, ensure you have:
- **Admin access** to your Activepieces platform
- **Admin access** to your identity provider (Google, GitHub, Okta, or JumpCloud)
- The **redirect URL** from your Activepieces SSO configuration screen
## Accessing SSO Configuration
Navigate to **Platform Settings** → **SSO** in your Activepieces admin dashboard to access the SSO configuration screen.
![SSO Configuration](/resources/screenshots/sso.png)
## Enforcing SSO
You can enforce SSO by specifying your organization's email domain. When SSO enforcement is enabled:
- Users with matching email domains must authenticate through the SSO provider
- Email/password login can be disabled for enhanced security
- All authentication is routed through your designated identity provider
<Tip>
We recommend testing SSO with a small group of users before enforcing it organization-wide.
</Tip>
## Supported SSO Providers
Activepieces supports multiple SSO providers to integrate with your existing identity management system.
### Google
<Steps>
<Step title="Access Google Cloud Console">
Go to the [Google Cloud Console](https://console.cloud.google.com/) and select your project (or create a new one).
</Step>
<Step title="Create OAuth2 Credentials">
Navigate to **APIs & Services** → **Credentials** → **Create Credentials** → **OAuth client ID**.
Select **Web application** as the application type.
</Step>
<Step title="Configure Redirect URI">
Copy the **Redirect URL** from the Activepieces SSO configuration screen and add it to the **Authorized redirect URIs** in Google Cloud Console.
</Step>
<Step title="Copy Credentials to Activepieces">
Copy the **Client ID** and **Client Secret** from Google and paste them into the corresponding fields in Activepieces.
</Step>
<Step title="Save Configuration">
Click **Finish** to complete the setup.
</Step>
</Steps>
### GitHub
<Steps>
<Step title="Access GitHub Developer Settings">
Go to [GitHub Developer Settings](https://github.com/settings/developers) → **OAuth Apps** → **New OAuth App**.
</Step>
<Step title="Register New Application">
Fill in the application details:
- **Application name**: Choose a recognizable name (e.g., "Activepieces SSO")
- **Homepage URL**: Enter your Activepieces instance URL
</Step>
<Step title="Configure Authorization Callback">
Copy the **Redirect URL** from the Activepieces SSO configuration screen and paste it into the **Authorization callback URL** field.
</Step>
<Step title="Complete Registration">
Click **Register application** to create the OAuth App.
</Step>
<Step title="Generate Client Secret">
After registration, click **Generate a new client secret** and copy it immediately (it won't be shown again).
</Step>
<Step title="Copy Credentials to Activepieces">
Copy the **Client ID** and **Client Secret** and paste them into the corresponding fields in Activepieces.
</Step>
<Step title="Save Configuration">
Click **Finish** to complete the setup.
</Step>
</Steps>
### SAML with Okta
<Steps>
<Step title="Create New Application in Okta">
Go to the [Okta Admin Portal](https://login.okta.com/) → **Applications** → **Create App Integration**.
</Step>
<Step title="Select SAML 2.0">
Choose **SAML 2.0** as the sign-on method and click **Next**.
</Step>
<Step title="Configure General Settings">
Enter an **App name** (e.g., "Activepieces") and optionally upload a logo. Click **Next**.
</Step>
<Step title="Configure SAML Settings">
- **Single sign-on URL**: Copy the SSO URL from the Activepieces configuration screen
- **Audience URI (SP Entity ID)**: Enter `Activepieces`
- **Name ID format**: Select `EmailAddress`
</Step>
<Step title="Add Attribute Statements">
Add the following attribute mappings:
| Name | Value |
|------|-------|
| `firstName` | `user.firstName` |
| `lastName` | `user.lastName` |
| `email` | `user.email` |
</Step>
<Step title="Complete Setup in Okta">
Click **Next**, select the appropriate feedback option, and click **Finish**.
</Step>
<Step title="Export IdP Metadata">
Go to the **Sign On** tab → **View SAML setup instructions** or **View IdP metadata**. Copy the Identity Provider metadata XML.
</Step>
<Step title="Configure Activepieces">
- Paste the **IdP Metadata** XML into the corresponding field
- Copy the **X.509 Certificate** from Okta and paste it into the **Signing Key** field
</Step>
<Step title="Save Configuration">
Click **Save** to complete the setup.
</Step>
</Steps>
### SAML with JumpCloud
<Steps>
<Step title="Create New Application in JumpCloud">
Go to the [JumpCloud Admin Portal](https://console.jumpcloud.com/) → **SSO Applications** → **Add New Application** → **Custom SAML App**.
</Step>
<Step title="Configure ACS URL">
Copy the **ACS URL** from the Activepieces configuration screen and paste it into the **ACS URLs** field in JumpCloud.
![JumpCloud ACS URL](/resources/screenshots/jumpcloud/acl-url.png)
</Step>
<Step title="Configure SP Entity ID">
Set the **SP Entity ID** (Audience URI) to `Activepieces`.
</Step>
<Step title="Add User Attributes">
Configure the following attribute mappings:
| Service Provider Attribute | JumpCloud Attribute |
|---------------------------|---------------------|
| `firstName` | `firstname` |
| `lastName` | `lastname` |
| `email` | `email` |
![JumpCloud User Attributes](/resources/screenshots/jumpcloud/user-attribute.png)
</Step>
<Step title="Enable HTTP-Redirect Binding">
JumpCloud does not include the `HTTP-Redirect` binding by default. You **must** enable this option.
![JumpCloud Redirect Binding](/resources/screenshots/jumpcloud/declare-login.png)
<Warning>
Without HTTP-Redirect binding, the SSO integration will not work correctly.
</Warning>
</Step>
<Step title="Export Metadata">
Click **Save**, then refresh the page and click **Export Metadata**.
![JumpCloud Export Metadata](/resources/screenshots/jumpcloud/export-metadata.png)
<Tip>
Verify that the exported XML contains `Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"` to ensure the binding was properly enabled.
</Tip>
</Step>
<Step title="Configure IdP Metadata in Activepieces">
Paste the exported metadata XML into the **IdP Metadata** field in Activepieces.
</Step>
<Step title="Configure Signing Certificate">
Locate the `<ds:X509Certificate>` element in the IdP metadata and extract its value. Format it as a PEM certificate:
```
-----BEGIN CERTIFICATE-----
[PASTE THE CERTIFICATE VALUE HERE]
-----END CERTIFICATE-----
```
Paste this into the **Signing Key** field.
</Step>
<Step title="Assign Users to Application">
In JumpCloud, assign the application to the appropriate users or user groups.
![JumpCloud Assign App](/resources/screenshots/jumpcloud/user-groups.png)
</Step>
<Step title="Save Configuration">
Click **Finish** to complete the setup.
</Step>
</Steps>
## Troubleshooting
<AccordionGroup>
<Accordion title="Users cannot log in after SSO configuration">
- Verify the redirect URL is correctly configured in your identity provider
- Ensure users are assigned to the application in your identity provider
- Check that email domains match the SSO enforcement settings
</Accordion>
<Accordion title="SAML authentication fails">
- Confirm the IdP metadata is complete and correctly formatted
- Verify the signing certificate is properly formatted with BEGIN/END markers
- Ensure all required attributes (firstName, lastName, email) are mapped
</Accordion>
<Accordion title="HTTP-Redirect binding error (JumpCloud)">
- Enable the HTTP-Redirect binding option in JumpCloud
- Re-export the metadata after enabling the binding
- Verify the binding appears in the exported XML
</Accordion>
</AccordionGroup>
## Need Help?
If you encounter issues during SSO setup, please contact our enterprise support or [sales team](https://www.activepieces.com/sales).

View File

@@ -0,0 +1,15 @@
---
title: "How to Structure Projects"
description: ""
icon: "building"
---
<Snippet file="enterprise-feature.mdx" />
Projects in Activepieces are the main units for organizing your automations and resources within your organization. Every project contains its own flows, connections, and tables. Access to these resources is shared among everyone who has access to that project.
There are two types of projects:
- **Personal Projects**: Each user invited to your organization automatically receives a personal project. This is a private space where only that user can create and manage flows, connections, and tables.
- **Team Projects**: Team projects are shared spaces that can be created and managed from this page. Multiple users can be invited to a team project, allowing them to collaborate, share access to flows, connections, and tables, and work together.
When organizing your work, create team projects for group collaboration and utilize personal projects for individual or private tasks.

View File

@@ -0,0 +1,23 @@
---
title: "Overview"
icon: "hand-wave"
description: "Manage and customize your Activepieces instance"
---
The **Platform Admin** is the centralized admin panel for managing your Activepieces instance. It's designed for teams and organizations that want full control over users, integrations, security, and internal automation.
## What Can You Do?
With Platform Admin, you can:
- **Custom Branding:** Tailor the appearance of Activepieces to match your organization's identity, including colors, logos, and fonts.
- **Project Management:** Create, edit, and organize projects for internal teams and users.
- **Piece Management:** Control which integration pieces are available, including managing custom or internal pieces for your team's workflows.
- **User Management:** Add and remove users, send invitations, and assign roles and permissions.
- **AI Provider Management:** Configure and manage AI providers (like OpenAI, Anthropic, etc.) available for use in your flows.
- **SSO & Security:** Configure Single Sign-On (SSO) providers and manage security settings to ensure your instance is secure.

View File

@@ -0,0 +1,5 @@
---
title: 'Connection Deleted'
openapi-schema: connection.deleted
icon: link
---

View File

@@ -0,0 +1,5 @@
---
title: 'Connection Upserted'
openapi-schema: connection.upserted
icon: link
---

View File

@@ -0,0 +1,5 @@
---
title: 'Flow Created'
openapi-schema: flow.created
icon: bolt
---

View File

@@ -0,0 +1,5 @@
---
title: 'Flow Deleted'
openapi-schema: flow.deleted
icon: bolt
---

View File

@@ -0,0 +1,5 @@
---
title: 'Flow Run Finished'
openapi-schema: flow.run.finished
icon: play
---

View File

@@ -0,0 +1,5 @@
---
title: 'Flow Run Started'
openapi-schema: flow.run.started
icon: play
---

View File

@@ -0,0 +1,5 @@
---
title: 'Flow Updated'
openapi-schema: flow.updated
icon: bolt
---

View File

@@ -0,0 +1,5 @@
---
title: 'Folder Created'
openapi-schema: folder.created
icon: folder
---

View File

@@ -0,0 +1,5 @@
---
title: 'Folder Deleted'
openapi-schema: folder.deleted
icon: folder
---

View File

@@ -0,0 +1,5 @@
---
title: 'Folder Updated'
openapi-schema: folder.updated
icon: folder
---

View File

@@ -0,0 +1,10 @@
---
title: "Overview"
description: ""
---
<Snippet file="enterprise-feature.mdx" />
This table in admin console contains all application events. We are constantly adding new events, so there is no better place to see the events defined in the code than [here](https://github.com/activepieces/activepieces/blob/main/packages/ee/shared/src/lib/audit-events/index.ts).
![Audit Logs](/resources/screenshots/audit-logs.png)

View File

@@ -0,0 +1,5 @@
---
title: 'Signing Key Created'
openapi-schema: signing.key.created
icon: key
---

View File

@@ -0,0 +1,5 @@
---
title: 'User Email Verified'
openapi-schema: user.email.verified
icon: lock
---

View File

@@ -0,0 +1,5 @@
---
title: 'User Password Reset'
openapi-schema: user.password.reset
icon: lock
---

View File

@@ -0,0 +1,5 @@
---
title: 'User Signed In'
openapi-schema: user.signed.in
icon: lock
---

View File

@@ -0,0 +1,5 @@
---
title: 'User Signed Up'
openapi-schema: user.signed.up
icon: lock
---

View File

@@ -0,0 +1,56 @@
---
title: "Security & Data Practices"
description: "We prioritize security and follow these practices to keep information safe."
icon: 'lock'
---
## External Systems Credentials
**Storing Credentials**
All credentials are stored with 256-bit encryption keys, and there is no API to retrieve them for the user. They are sent only during processing, after which access is revoked from the engine.
**Data Masking**
We implement a robust data masking mechanism where third-party credentials or any sensitive information are systematically censored within the logs, guaranteeing that sensitive information is never stored or documented.
**OAuth2**
Integrations with third parties are always done using OAuth2, with a limited number of scopes when third-party support allows.
## Vulnerability Disclosure
Activepieces is an open-source project that welcomes contributors to test and report security issues.
For detailed information about our security policy, please refer to our GitHub Security Policy at: [https://github.com/activepieces/activepieces/security/policy](https://github.com/activepieces/activepieces/security/policy)
## Access and Authentication
**Role-Based Access Control (RBAC)**
To manage user access, we utilize Role-Based Access Control (RBAC). Team admins assign roles to users, granting them specific permissions to access and interact with projects, folders, and resources. RBAC allows for fine-grained control, enabling administrators to define and enforce access policies based on user roles.
**Single Sign-On (SSO)**
Implementing Single Sign-On (SSO) serves as a pivotal component of our security strategy. SSO streamlines user authentication by allowing them to access Activepieces with a single set of credentials. This not only enhances user convenience but also strengthens security by reducing the potential attack surface associated with managing multiple login credentials.
**Audit Logs**
We maintain comprehensive audit logs to track and monitor all access activities within Activepieces. This includes user interactions, system changes, and other relevant events. Our meticulous logging helps identify security threats and ensures transparency and accountability in our security measures.
**Password Policy Enforcement**
Users log in to Activepieces using a password known only to them. Activepieces enforces password length and complexity standards. Passwords are not stored; instead, only a secure hash of the password is stored in the database. For more information.
## Privacy & Data
**Supported Cloud Regions**
Presently, our cloud services are available in Germany as the supported data region.
We have plans to expand to additional regions in the near future.
If you opt for **self-hosting**, the available regions will depend on where you choose to host.
**Policy**
To better understand how we handle your data and prioritize your privacy, please take a moment to review our [Privacy Policy](https://www.activepieces.com/privacy). This document outlines in detail the measures we take to safeguard your information and the principles guiding our approach to privacy and data protection.

View File

@@ -0,0 +1,109 @@
---
title: 'Create Action'
icon: 'circle-5'
description: ''
---
## Action Definition
Now let's create first action which fetch random ice-cream flavor.
```bash
npm run cli actions create
```
You will be asked three questions to define your new piece:
1. `Piece Folder Name`: This is the name associated with the folder where the action resides. It helps organize and categorize actions within the piece.
2. `Action Display Name`: The name users see in the interface, conveying the action's purpose clearly.
3. `Action Description`: A brief, informative text in the UI, guiding users about the action's function and purpose.
Next, Let's create the action file:
**Example:**
```bash
npm run cli actions create
? Enter the piece folder name : gelato
? Enter the action display name : get icecream flavor
? Enter the action description : fetches random icecream flavor.
```
This will create a new TypeScript file named `get-icecream-flavor.ts` in the `packages/pieces/community/gelato/src/lib/actions` directory.
Inside this file, paste the following code:
```typescript
import {
createAction,
Property,
PieceAuth,
} from '@activepieces/pieces-framework';
import { httpClient, HttpMethod } from '@activepieces/pieces-common';
import { gelatoAuth } from '../..';
export const getIcecreamFlavor = createAction({
name: 'get_icecream_flavor', // Must be a unique across the piece, this shouldn't be changed.
auth: gelatoAuth,
displayName: 'Get Icecream Flavor',
description: 'Fetches random icecream flavor',
props: {},
async run(context) {
const res = await httpClient.sendRequest<string[]>({
method: HttpMethod.GET,
url: 'https://cloud.activepieces.com/api/v1/webhooks/RGjv57ex3RAHOgs0YK6Ja/sync',
headers: {
Authorization: context.auth, // Pass API key in headers
},
});
return res.body;
},
});
```
The createAction function takes an object with several properties, including the `name`, `displayName`, `description`, `props`, and `run` function of the action.
The `name` property is a unique identifier for the action. The `displayName` and `description` properties are used to provide a human-readable name and description for the action.
The `props` property is an object that defines the properties that the action requires from the user. In this case, the action doesn't require any properties.
The `run` function is the function that is called when the action is executed. It takes a single argument, context, which contains the values of the action's properties.
The `run` function utilizes the httpClient.sendRequest function to make a GET request, fetching a random ice cream flavor. It incorporates API key authentication in the request headers. Finally, it returns the response body.
## Expose The Definition
To make the action readable by Activepieces, add it to the array of actions in the piece definition.
```typescript
import { createPiece } from '@activepieces/pieces-framework';
// Don't forget to add the following import.
import { getIcecreamFlavor } from './lib/actions/get-icecream-flavor';
export const gelato = createPiece({
displayName: 'Gelato',
logoUrl: 'https://cdn.activepieces.com/pieces/gelato.png',
authors: [],
auth: gelatoAuth,
// Add the action here.
actions: [getIcecreamFlavor], // <--------
triggers: [],
});
```
# Testing
By default, the development setup only builds specific components. Open the file `packages/server/api/.env` and include "gelato" in the `AP_DEV_PIECES`.
For more details, check out the [Piece Development](./development-setup) section.
Once you edit the environment variable, restart the backend. The piece will be rebuilt. After this process, you'll need to **refresh** the frontend to see the changes.
<Tip>
If the build fails, try debugging by running `npx nx run-many -t build --projects=gelato`.
It will display any errors in your code.
</Tip>
To test the action, use the flow builder in Activepieces. It should function as shown in the screenshot.
![Gelato Action](/resources/screenshots/gelato-action.png)

View File

@@ -0,0 +1,137 @@
---
title: 'Create Trigger'
icon: 'circle-6'
description: ''
---
This tutorial will guide you through the process of creating trigger for a Gelato piece that fetches new icecream flavor.
## Trigger Definition
To create trigger run the following command,
```bash
npm run cli triggers create
```
1. `Piece Folder Name`: This is the name associated with the folder where the trigger resides. It helps organize and categorize triggers within the piece.
2. `Trigger Display Name`: The name users see in the interface, conveying the trigger's purpose clearly.
3. `Trigger Description`: A brief, informative text in the UI, guiding users about the trigger's function and purpose.
4. `Trigger Technique`: Specifies the trigger type - either [polling](../piece-reference/triggers/polling-trigger) or [webhook](../piece-reference/triggers/webhook-trigger).
**Example:**
```bash
npm run cli triggers create
? Enter the piece folder name : gelato
? Enter the trigger display name : new flavor created
? Enter the trigger description : triggers when a new icecream flavor is created.
? Select the trigger technique: polling
```
This will create a new TypeScript file at `packages/pieces/community/gelato/src/lib/triggers` named `new-flavor-created.ts`.
Inside this file, paste the following code:
```ts
import { gelatoAuth } from '../../';
import {
DedupeStrategy,
HttpMethod,
HttpRequest,
Polling,
httpClient,
pollingHelper,
} from '@activepieces/pieces-common';
import {
PiecePropValueSchema,
TriggerStrategy,
createTrigger,
} from '@activepieces/pieces-framework';
import dayjs from 'dayjs';
const polling: Polling<
PiecePropValueSchema<typeof gelatoAuth>,
Record<string, never>
> = {
strategy: DedupeStrategy.TIMEBASED,
items: async ({ auth, propsValue, lastFetchEpochMS }) => {
const request: HttpRequest = {
method: HttpMethod.GET,
url: 'https://cloud.activepieces.com/api/v1/webhooks/aHlEaNLc6vcF1nY2XJ2ed/sync',
headers: {
authorization: auth,
},
};
const res = await httpClient.sendRequest(request);
return res.body['flavors'].map((flavor: string) => ({
epochMilliSeconds: dayjs().valueOf(),
data: flavor,
}));
},
};
export const newFlavorCreated = createTrigger({
auth: gelatoAuth,
name: 'newFlavorCreated',
displayName: 'new flavor created',
description: 'triggers when a new icecream flavor is created.',
props: {},
sampleData: {},
type: TriggerStrategy.POLLING,
async test(context) {
return await pollingHelper.test(polling, context);
},
async onEnable(context) {
const { store, auth, propsValue } = context;
await pollingHelper.onEnable(polling, { store, auth, propsValue });
},
async onDisable(context) {
const { store, auth, propsValue } = context;
await pollingHelper.onDisable(polling, { store, auth, propsValue });
},
async run(context) {
return await pollingHelper.poll(polling, context);
},
});
```
The way polling triggers usually work is as follows:
`Run`:The run method executes every 5 minutes, fetching data from the endpoint within a specified timestamp range or continuing until it identifies the last item ID. It then returns the new items as an array. In this example, the httpClient.sendRequest method is utilized to retrieve new flavors, which are subsequently stored in the store along with a timestamp.
## Expose The Definition
To make the trigger readable by Activepieces, add it to the array of triggers in the piece definition.
```typescript
import { createPiece } from '@activepieces/pieces-framework';
import { getIcecreamFlavor } from './lib/actions/get-icecream-flavor';
// Don't forget to add the following import.
import { newFlavorCreated } from './lib/triggers/new-flavor-created';
export const gelato = createPiece({
displayName: 'Gelato Tutorial',
logoUrl: 'https://cdn.activepieces.com/pieces/gelato.png',
authors: [],
auth: gelatoAuth,
actions: [getIcecreamFlavor],
// Add the trigger here.
triggers: [newFlavorCreated], // <--------
});
```
# Testing
By default, the development setup only builds specific components. Open the file `packages/server/api/.env` and include "gelato" in the `AP_DEV_PIECES`.
For more details, check out the [Piece Development](./development-setup) section.
Once you edit the environment variable, restart the backend. The piece will be rebuilt. After this process, you'll need to **refresh** the frontend to see the changes.
To test the trigger, use the load sample data from flow builder in Activepieces. It should function as shown in the screenshot.
![Gelato Action](/resources/screenshots/gelato-trigger.png)

View File

@@ -0,0 +1,50 @@
---
title: 'Development setup'
icon: 'circle-2'
---
## Prerequisites
- Node.js v18+
- npm v9+
## Instructions
1. Setup the environment
```bash
node tools/setup-dev.js
```
2. Start the environment
This command will start activepieces with sqlite3 and in memory queue.
```bash
npm start
```
<Note>
By default, the development setup only builds specific pieces.Open the file
`packages/server/api/.env` and add comma-separated list of pieces to make
available.
For more details, check out the [Piece Development](/build-pieces/building-pieces/development-setup#pieces-development) section.
</Note>
3. Go to **_localhost:4200_** on your web browser and sign in with these details:
Email: `dev@ap.com`
Password: `12345678`
## Pieces Development
When [`AP_SYNC_MODE`](https://github.com/activepieces/activepieces/blob/main/packages/server/api/.env#L17) is set to `OFFICIAL_AUTO`, all pieces are automatically loaded from the cloud API and synced to the database on first launch. This process may take a few seconds to several minutes depending on your internet connection.
For local development, pieces are loaded from your local `dist` folder instead of the database. To enable this, set the [`AP_DEV_PIECES`](https://github.com/activepieces/activepieces/blob/main/packages/server/api/.env#L4) environment variable with a comma-separated list of pieces. For example, to develop with `google-sheets` and `cal-com`:
```sh
AP_DEV_PIECES=google-sheets,cal-com npm start
```

View File

@@ -0,0 +1,31 @@
---
title: 'Overview'
description: 'This section helps developers build and contribute pieces.'
icon: 'hand-wave'
---
Building pieces is fun and important; it allows you to customize Activepieces for your own needs.
<Tip>
We love contributions! In fact, most of the pieces are contributed by the community. Feel free to open a pull request.
</Tip>
<Tip>
**Friendly Tip:**
For the fastest support, we recommend joining our Discord community. We are dedicated to addressing every question and concern raised there.
</Tip>
<CardGroup cols={2}>
<Card title="Code with TypeScript" icon="code">
Build pieces using TypeScript for a more powerful and flexible development process.
</Card>
<Card title="Hot Reloading" icon="cloud-bolt">
See your changes in the browser within 7 seconds.
</Card>
<Card title="Open Source" icon="earth-americas">
Work within the open-source environment, explore, and contribute to other pieces.
</Card>
<Card title="Community Support" icon="people">
Join our large community, where you can ask questions, share ideas, and develop alongside others.
</Card>
</CardGroup>

View File

@@ -0,0 +1,38 @@
---
title: 'Add Piece Authentication'
icon: 'circle-4'
description: ''
---
### Piece Authentication
Activepieces supports multiple forms of authentication, you can check those forms [here](../piece-reference/authentication)
Now, let's establish authentication for this piece, which necessitates the inclusion of an API Key in the headers.
Modify `src/index.ts` file to add authentication,
```ts
import { PieceAuth, createPiece } from '@activepieces/pieces-framework';
export const gelatoAuth = PieceAuth.SecretText({
displayName: 'API Key',
required: true,
description: 'Please use **test-key** as value for API Key',
});
export const gelato = createPiece({
displayName: 'Gelato',
logoUrl: 'https://cdn.activepieces.com/pieces/gelato.png',
auth: gelatoAuth,
authors: [],
actions: [],
triggers: [],
});
```
<Note>
Use the value **test-key** as the API key when testing actions or triggers for
Gelato.
</Note>

View File

@@ -0,0 +1,51 @@
---
title: 'Create Piece Definition'
icon: 'circle-3'
description: ''
---
This tutorial will guide you through the process of creating a Gelato piece with an action that fetches random icecream flavor and trigger that fetches new icecream flavor created. It assumes that you are familiar with the following:
- [Activepieces Local development](./development-setup) Or [GitHub Codespaces](../misc/codespaces).
- TypeScript syntax.
## Piece Definition
To get started, let's generate a new piece for Gelato
```bash
npm run cli pieces create
```
You will be asked three questions to define your new piece:
1. `Piece Name`: Specify a name for your piece. This name uniquely identifies your piece within the ActivePieces ecosystem.
2. `Package Name`: Optionally, you can enter a name for the npm package associated with your piece. If left blank, the default name will be used.
3. `Piece Type`: Choose the piece type based on your intention. It can be either "custom" if it's a tailored solution for your needs, or "community" if it's designed to be shared and used by the broader community.
**Example:**
```bash
npm run cli pieces create
? Enter the piece name: gelato
? Enter the package name: @activepieces/piece-gelato
? Select the piece type: community
```
The piece will be generated at `packages/pieces/community/gelato/`,
the `src/index.ts` file should contain the following code
```ts
import { PieceAuth, createPiece } from '@activepieces/pieces-framework';
export const gelato = createPiece({
displayName: 'Gelato',
logoUrl: 'https://cdn.activepieces.com/pieces/gelato.png',
auth: PieceAuth.None(),
authors: [],
actions: [],
triggers: [],
});
```

View File

@@ -0,0 +1,18 @@
---
title: 'Fork Repository'
icon: "circle-1"
---
To start building pieces, we need to fork the repository that contains the framework library and the development environment. Later, we will publish these pieces as `npm` artifacts.
Follow these steps to fork the repository:
1. Go to the repository page at https://github.com/activepieces/activepieces.
2. Click the `Fork` button located in the top right corner of the page.
![Fork Repository](/resources/screenshots/fork-repository.jpg)
<Tip>
If you are an enterprise customer and want to use the private pieces feature, you can refer to the tutorial on how to set up a [private fork](../misc/private-fork).
</Tip>

View File

@@ -0,0 +1,41 @@
---
title: 'Start Building'
icon: 'hammer'
description: ''
---
This section guides you in creating a Gelato piece, from setting up your development environment to contributing the piece. By the end of this tutorial, you will have a piece with an action that fetches a random ice cream flavor and a trigger that fetches newly created ice cream flavors.
<Info>
These are the next sections. In each step, we will do one small thing. This tutorial should take around 30 minutes.
</Info>
## Steps Overview
<Steps>
<Step title="Fork Repository" icon="code-branch">
Fork the repository to create your own copy of the codebase.
</Step>
<Step title="Setup Development Environment" icon="code">
Set up your development environment with the necessary tools and dependencies.
</Step>
<Step title="Create Piece Definition" icon="gear">
Define the structure and behavior of your Gelato piece.
</Step>
<Step title="Add Piece Authentication" icon="lock">
Implement authentication mechanisms for your Gelato piece.
</Step>
<Step title="Create Action" icon="ice-cream">
Create an action that fetches a random ice cream flavor.
</Step>
<Step title="Create Trigger" icon="ice-cream">
Create a trigger that fetches newly created ice cream flavors.
</Step>
<Step title="Sharing Pieces" icon="share">
Share your Gelato piece with others.
</Step>
</Steps>
<Card title="Contribution" icon="gift" iconType="duotone" color="#6e41e2">
Contribute a piece to our repo and receive +1,400 tasks/month on [Activepieces Cloud](https://cloud.activepieces.com).
</Card>

View File

@@ -0,0 +1,38 @@
---
title: 'Build Custom Pieces'
icon: 'box'
---
You can use the CLI to build custom pieces for the platform. This process compiles the pieces and exports them as a `.tgz` packed archive.
### How It Works
The CLI scans the `packages/pieces/` directory for the specified piece. It checks the **name** in the `package.json` file. If the piece is found, it builds and packages it into a `.tgz` archive.
### Usage
To build a piece, follow these steps:
1. Ensure you have the CLI installed by cloning the repository.
2. Run the following command:
```bash
npm run build-piece
```
You will be prompted to enter the name of the piece you want to build. For example:
```bash
? Enter the piece folder name : google-drive
```
The CLI will build the piece and you will be given the path to the archive. For example:
```bash
Piece 'google-drive' built and packed successfully at dist/packages/pieces/community/google-drive
```
You may also build the piece non-interactively by passing the piece name as an argument. For example:
```bash
npm run build-piece google-drive
```

View File

@@ -0,0 +1,31 @@
---
title: 'GitHub Codespaces'
icon: 'github'
description: ''
---
GitHub Codespaces is a cloud development platform that enables developers to write, run, and debug code directly in their browsers, seamlessly integrated with GitHub.
### Steps to setup Codespaces
1. Go to [Activepieces repo](https://github.com/activepieces/activepieces).
2. Click Code `<>`, then under codespaces click create codespace on main.
![Create Codespace](/resources/screenshots/development-setup_codespaces.png)
<Note>
By default, the development setup only builds specific pieces.Open the file
`packages/server/api/.env` and add comma-separated list of pieces to make
available.
For more details, check out the [Piece Development](/build-pieces/building-pieces/development-setup#pieces-development) section.
</Note>
3. Open the terminal and run `npm start`
4. Access the frontend URL by opening port 4200 and signing in with these details:
Email: `dev@ap.com`
Password: `12345678`

View File

@@ -0,0 +1,101 @@
---
title: 'Create New AI Provider'
icon: 'sparkles'
---
ActivePieces currently supports the following AI providers:
- OpenAI
- Anthropic
To create a new AI provider, you need to follow these steps:
## Implement the AI Interface
Create a new factory that returns an instance of the `AI` interface in the `packages/pieces/community/common/src/lib/ai/providers/your-ai-provider.ts` file.
```typescript
export const yourAiProvider = ({
serverUrl,
engineToken,
}: { serverUrl: string, engineToken: string }): AI<YourAiProviderSDK> => {
const impl = new YourAiProviderSDK(serverUrl, engineToken);
return {
provider: "YOUR_AI_PROVIDER" as const,
chat: {
text: async (params) => {
try {
const response = await impl.chat.text(params);
return response;
} catch (e: any) {
if (e?.error?.error) {
throw e.error.error;
}
throw e;
}
}
},
};
};
```
## Register the AI Provider
Add the new AI provider to the `AiProviders` enum in `packages/pieces/community/common/src/lib/ai/providers/index.ts` file.
```diff
export const AiProviders = [
+ {
+ logoUrl: 'https://cdn.activepieces.com/pieces/openai.png',
+ defaultBaseUrl: 'https://api.your-ai-provider.com',
+ label: 'Your AI Provider' as const,
+ value: 'your-ai-provider' as const,
+ models: [
+ { label: 'model-1', value: 'model-1' },
+ { label: 'model-2', value: 'model-2' },
+ { label: 'model-3', value: 'model-3' },
+ ],
+ factory: yourAiProvider,
+ },
...
]
```
## Define Authentication Header
Now we need to tell ActivePieces how to authenticate to your AI provider. You can do this by adding an `auth` property to the `AiProvider` object.
The `auth` property is an object that defines the authentication mechanism for your AI provider. It consists of two properties: `name` and `mapper`. The `name` property specifies the name of the header that will be used to authenticate with your AI provider, and the `mapper` property defines a function that maps the value of the header to the format that your AI provider expects.
Here's an example of how to define the authentication header for a bearer token:
```diff
export const AiProviders = [
{
logoUrl: 'https://cdn.activepieces.com/pieces/openai.png',
defaultBaseUrl: 'https://api.your-ai-provider.com',
label: 'Your AI Provider' as const,
value: 'your-ai-provider' as const,
models: [
{ label: 'model-1', value: 'model-1' },
{ label: 'model-2', value: 'model-2' },
{ label: 'model-3', value: 'model-3' },
],
+ auth: authHeader({ bearer: true }), // or authHeader({ name: 'x-api-key', bearer: false })
factory: yourAiProvider,
},
...
]
```
## Test the AI Provider
To test the AI provider, you can use a **universal AI** piece in a flow. Follow these steps:
- Add the required headers from the admin console for the newly created AI provider. These headers will be used to authenticate the requests to the AI provider.
![Configure AI Provider](/resources/screenshots/configure-ai-provider.png)
- Create a flow that uses our **universal AI** pieces. And select **"Your AI Provider"** as the AI provider in the **Ask AI** action settings.
![Configure AI Provider](/resources/screenshots/use-ai-provider.png)

View File

@@ -0,0 +1,58 @@
---
title: 'Dev Containers'
icon: 'docker'
description: ''
---
## Using Dev Containers in Visual Studio Code
The project includes a dev container configuration that allows you to use Visual Studio Code's [Remote Development](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.vscode-remote-extensionpack) extension to develop the project in a consistent environment. This can be especially helpful if you are new to the project or if you have a different environment setup on your local machine.
## Prerequisites
Before you can use the dev container, you will need to install the following:
- [Visual Studio Code](https://code.visualstudio.com/).
- The [Remote Development](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.vscode-remote-extensionpack) extension for Visual Studio Code.
- [Docker](https://www.docker.com/).
## Using the Dev Container
To use the dev container for the Activepieces project, follow these steps:
1. Clone the Activepieces repository to your local machine.
2. Open the project in Visual Studio Code.
3. Press `Ctrl+Shift+P` and type `> Dev Containers: Reopen in Container`.
4. Run `npm start`.
5. The backend will run at `localhost:3000` and the frontend will run at `localhost:4200`.
<Note>
By default, the development setup only builds specific pieces.Open the file
`packages/server/api/.env` and add comma-separated list of pieces to make
available.
For more details, check out the [Piece Development](/build-pieces/building-pieces/development-setup#pieces-development) section.
</Note>
The login credentials are:
Email: `dev@ap.com`
Password: `12345678`
## Exiting the Dev Container
To exit the dev container and return to your local environment, follow these steps:
1. In the bottom left corner of Visual Studio Code, click the `Remote-Containers: Reopen folder locally` button.
2. Visual Studio Code will close the connection to the dev container and reopen the project in your local environment.
## Troubleshoot
One of the best trouble shoot after an error occur is to reset the dev container.
1. Exit the dev container
2. Run the following
```sh
sh tools/reset-dev.sh
```
3. Rebuild the dev container from above steps

View File

@@ -0,0 +1,82 @@
---
title: 'Custom Pieces CI/CD'
icon: 'hammer'
---
You can use the CLI to sync custom pieces. There is no need to rebuild the Docker image as they are loaded directly from npm.
### How It Works
Use the CLI to sync items from `packages/pieces/custom/` to instances. In production, Activepieces acts as an npm registry, storing all piece versions.
The CLI scans the directory for `package.json` files, checking the **name** and **version** of each piece. If a piece isn't uploaded, it packages and uploads it via the API.
### Usage
To use the CLI, follow these steps:
1. Generate an API Key from the Admin Interface. Go to Settings and generate the API Key.
2. Install the CLI by cloning the repository.
3. Run the following command, replacing `API_KEY` with your generated API Key and `INSTANCE_URL` with your instance URL:
```bash
AP_API_KEY=your_api_key_here bun run sync-pieces -- --apiUrl https://INSTANCE_URL/api
```
### Developer Workflow
1. Developers create and modify the pieces offline.
2. Increment the piece version in their corresponding `package.json`. For more information, refer to the [piece versioning](../piece-reference/piece-versioning) documentation.
3. Open a pull request towards the main branch.
4. Once the pull request is merged to the main branch, manually run the CLI or use a GitHub/GitLab Action to trigger the synchronization process.
### GitHub Action
```yaml
name: Sync Custom Pieces
on:
push:
branches:
- main
workflow_dispatch:
jobs:
sync-pieces:
runs-on: ubuntu-latest
steps:
# Step 1: Check out the repository code with full history
- name: Check out repository code
uses: actions/checkout@v3
with:
fetch-depth: 0
# Step 2: Set up Bun
- name: Set up Bun
uses: oven-sh/setup-bun@v1
with:
bun-version: latest
# Step 3: Cache Bun dependencies
- name: Cache Bun dependencies
uses: actions/cache@v3
with:
path: ~/.bun/install/cache
key: bun-${{ hashFiles('bun.lockb') }}
restore-keys: |
bun-
# Step 4: Install dependencies using Bun
- name: Install dependencies
run: bun install --no-save
# Step 5: Sync Custom Pieces
- name: Sync Custom Pieces
env:
AP_API_KEY: ${{ secrets.AP_API_KEY }}
run: bun run sync-pieces -- --apiUrl ${{ secrets.INSTANCE_URL }}/api
```

View File

@@ -0,0 +1,84 @@
---
title: 'Setup Private Fork'
icon: "code-branch"
---
<Tip>
**Friendly Tip #1:** If you want to experiment, you can fork or clone the public repository.
</Tip>
<Tip>
For private piece installation, you will need the paid edition. However, you can still develop pieces, contribute them back, **OR** publish them to the public npm registry and use them in your own instance or project.
</Tip>
## Create a Private Fork (Private Pieces)
By following these steps, you can create a private fork on GitHub, GitLab or another platform and configure the "activepieces" repository as the upstream source, allowing you to incorporate changes from the "activepieces" repository.
1. **Clone the Repository:**
Begin by creating a bare clone of the repository. Remember that this is a temporary step and will be deleted later.
```bash
git clone --bare git@github.com:activepieces/activepieces.git
```
2. **Create a Private Git Repository**
Generate a new private repository on GitHub or your chosen platform. When initializing the new repository, do not include a README, license, or gitignore files. This precaution is essential to avoid merge conflicts when synchronizing your fork with the original repository.
3. **Mirror-Push to the Private Repository:**
Mirror-push the bare clone you created earlier to your newly created "activepieces" repository. Make sure to replace `<your_username>` in the URL below with your actual GitHub username.
```bash
cd activepieces.git
git push --mirror git@github.com:<your_username>/activepieces.git
```
4. **Remove the Temporary Local Repository:**
```bash
cd ..
rm -rf activepieces.git
```
5. **Clone Your Private Repository:**
Now, you can clone your "activepieces" repository onto your local machine into your desired directory.
```bash
cd ~/path/to/directory
git clone git@github.com:<your_username>/activepieces.git
```
6. **Add the Original Repository as a Remote:**
If desired, you can add the original repository as a remote to fetch potential future changes. However, remember to disable push operations for this remote, as you are not permitted to push changes to it.
```bash
git remote add upstream git@github.com:activepieces/activepieces.git
git remote set-url --push upstream DISABLE
```
You can view a list of all your remotes using `git remote -v`. It should resemble the following:
```
origin git@github.com:<your_username>/activepieces.git (fetch)
origin git@github.com:<your_username>/activepieces.git (push)
upstream git@github.com:activepieces/activepieces.git (fetch)
upstream DISABLE (push)
```
> When pushing changes, always use `git push origin`.
### Sync Your Fork
To retrieve changes from the "upstream" repository, fetch the remote and rebase your work on top of it.
```bash
git fetch upstream
git merge upstream/main
```
Conflict resolution should not be necessary since you've only added pieces to your repository.

View File

@@ -0,0 +1,57 @@
---
title: 'Publish Custom Pieces'
icon: 'upload'
---
You can use the CLI to publish custom pieces to the platform. This process packages the pieces and uploads them to the specified API endpoint.
### How It Works
The CLI scans the `packages/pieces/` directory for the specified piece. It checks the **name** and **version** in the `package.json` file. If the piece is not already published, it builds, packages, and uploads it to the platform using the API.
### Usage
To publish a piece, follow these steps:
1. Ensure you have an API Key. Generate it from the Admin Interface by navigating to Settings.
2. Install the CLI by cloning the repository.
3. Run the following command:
```bash
npm run publish-piece-to-api
```
4. You will be asked three questions to publish your piece:
- `Piece Folder Name`: This is the name associated with the folder where the action resides. It helps organize and categorize actions within the piece.
- `API URL`: This is the URL of the API endpoint where the piece will be published (ex: https://cloud.activepieces.com/api).
- `API Key Source`: This is the source of the API key. It can be either `Env Variable (AP_API_KEY)` or `Manually`.
In case you choose `Env Variable (AP_API_KEY)`, the CLI will use the API key from the `.env` file in the `packages/server/api` directory.
In case you choose `Manually`, you will be asked to enter the API key.
Examples:
```bash
npm run publish-piece-to-api
? Enter the piece folder name : google-drive
? Enter the API URL : https://cloud.activepieces.com/api
? Enter the API Key Source : Env Variable (AP_API_KEY)
```
```bash
npm run publish-piece-to-api
? Enter the piece folder name : google-drive
? Enter the API URL : https://cloud.activepieces.com/api
? Enter the API Key Source : Manually
? Enter the API Key : ap_1234567890abcdef1234567890abcdef
```

View File

@@ -0,0 +1,133 @@
---
title: "Piece Auth"
description: "Learn about piece authentication"
icon: 'key'
---
Piece authentication is used to gather user credentials and securely store them for future use in different flows.
The authentication must be defined as the `auth` parameter in the `createPiece`, `createTrigger`, and `createAction` functions.
This requirement ensures that the type of authentication can be inferred correctly in triggers and actions.
<Warning>
The auth parameter for `createPiece`, `createTrigger`, and `createAction` functions can take an array, but you cannot have more than one auth property of the same type, i.e two OAUTH2 properties.
</Warning>
### Secret Text
This authentication collects sensitive information, such as passwords or API keys. It is displayed as a masked input field.
**Example:**
```typescript
PieceAuth.SecretText({
displayName: 'API Key',
description: 'Enter your API key',
required: true,
// Optional Validation
validate: async ({auth}) => {
if(auth.startsWith('sk_')){
return {
valid: true,
}
}
return {
valid: false,
error: 'Invalid Api Key'
}
}
})
```
### Username and Password
This authentication collects a username and password as separate fields.
**Example:**
```typescript
PieceAuth.BasicAuth({
displayName: 'Credentials',
description: 'Enter your username and password',
required: true,
username: {
displayName: 'Username',
description: 'Enter your username',
},
password: {
displayName: 'Password',
description: 'Enter your password',
},
// Optional Validation
validate: async ({auth}) => {
if(auth){
return {
valid: true,
}
}
return {
valid: false,
error: 'Invalid Api Key'
}
}
})
```
### Custom
This authentication allows for custom authentication by collecting specific properties, such as a base URL and access token.
**Example:**
```typescript
PieceAuth.CustomAuth({
displayName: 'Custom Authentication',
description: 'Enter custom authentication details',
props: {
base_url: Property.ShortText({
displayName: 'Base URL',
description: 'Enter the base URL',
required: true,
}),
access_token: PieceAuth.SecretText({
displayName: 'Access Token',
description: 'Enter the access token',
required: true
})
},
// Optional Validation
validate: async ({auth}) => {
if(auth){
return {
valid: true,
}
}
return {
valid: false,
error: 'Invalid Api Key'
}
},
required: true
})
```
### OAuth2
This authentication collects OAuth2 authentication details, including the authentication URL, token URL, and scope.
**Example:**
```typescript
PieceAuth.OAuth2({
displayName: 'OAuth2 Authentication',
grantType: OAuth2GrantType.AUTHORIZATION_CODE,
required: true,
authUrl: 'https://example.com/auth',
tokenUrl: 'https://example.com/token',
scope: ['read', 'write']
})
```
<Tip>
Please note `OAuth2GrantType.CLIENT_CREDENTIALS` is also supported for service-based authentication.
</Tip>

View File

@@ -0,0 +1,55 @@
---
title: "Enable Custom API Calls"
description: "Learn how to enable custom API calls for your pieces"
icon: 'webhook'
---
Custom API Calls allow the user to send a request to a specific endpoint if no action has been implemented for it.
This will show in the actions list of the piece as `Custom API Call`, to enable this action for a piece, you need to call the `createCustomApiCallAction` in your actions array.
## Basic Example
The example below implements the action for the OpenAI piece. The OpenAI piece uses a `Bearer token` authorization header to identify the user sending the request.
```typescript
actions: [
...yourActions,
createCustomApiCallAction({
// The auth object defined in the piece
auth: openaiAuth,
// The base URL for the API
baseUrl: () => {
'https://api.openai.com/v1'
},
// Mapping the auth object to the needed authorization headers
authMapping: async (auth) => {
return {
'Authorization': `Bearer ${auth}`
}
}
})
]
```
## Dynamic Base URL and Basic Auth Example
The example below implements the action for the Jira Cloud piece. The Jira Cloud piece uses a dynamic base URL for it's actions, where the base URL changes based on the values the user authenticated with. We will also implement a Basic authentication header.
```typescript
actions: [
...yourActions,
createCustomApiCallAction({
baseUrl: (auth) => {
return `${(auth as JiraAuth).instanceUrl}/rest/api/3`
},
auth: jiraCloudAuth,
authMapping: async (auth) => {
const typedAuth = auth as JiraAuth
return {
'Authorization': `Basic ${typedAuth.email}:${typedAuth.apiToken}`
}
}
})
]
```

View File

@@ -0,0 +1,31 @@
---
title: "Piece Examples"
description: "Explore a collection of example triggers and actions"
icon: 'brackets-curly'
---
To get the full benefit, it is recommended to read the tutorial first.
## Triggers:
**Webhooks:**
- [New Form Submission on Typeform](https://github.com/activepieces/activepieces/blob/main/packages/pieces/community/typeform/src/lib/trigger/new-submission.ts)
**Polling:**
- [New Completed Task On Todoist](https://github.com/activepieces/activepieces/blob/main/packages/pieces/community/todoist/src/lib/triggers/task-completed-trigger.ts)
## Actions:
- [Send a message On Discord](https://github.com/activepieces/activepieces/blob/main/packages/pieces/community/discord/src/lib/actions/send-message-webhook.ts)
- [Send an mail On Gmail](https://github.com/activepieces/activepieces/blob/main/packages/pieces/community/gmail/src/lib/actions/send-email-action.ts)
## Authentication
**OAuth2:**
- [Slack](https://github.com/activepieces/activepieces/blob/main/packages/pieces/community/slack/src/index.ts)
- [Gmail](https://github.com/activepieces/activepieces/blob/main/packages/pieces/community/gmail/src/index.ts)
**API Key:**
- [Sendgrid](https://github.com/activepieces/activepieces/blob/main/packages/pieces/community/sendgrid/src/index.ts)
**Basic Authentication:**
- [Twilio](https://github.com/activepieces/activepieces/blob/main/packages/pieces/community/twilio/src/index.ts)

View File

@@ -0,0 +1,20 @@
---
title: "External Libraries"
icon: 'npm'
description: "Learn how to install and use external libraries."
---
The Activepieces repository is structured as a monorepo, employing Nx as its build tool.
To keep our main `package.json` as light as possible, we keep libraries that are only used for a piece in the piece `package.json` . This means when adding a new library you should navigate to the piece folder and install the library with our package manager `bun`
```bash
cd packages/pieces/<piece-path>
bun install --save <library-name>
```
- Import the library into your piece.
Guidelines:
- Make sure you are using well-maintained libraries.
- Ensure that the library size is not too large to avoid bloating the bundle size; this will make the piece load faster in the sandbox.

View File

@@ -0,0 +1,25 @@
---
title: "Files"
icon: 'file'
description: "Learn how to use files object to create file references."
---
The `ctx.files` object allow you to store files in local storage or in a remote storage depending on the run environment.
## Write
You can use the `write` method to write a file to the storage, It returns a string that can be used in other actions or triggers properties to reference the file.
**Example:**
```ts
const fileReference = await files.write({
fileName: 'file.txt',
data: Buffer.from('text')
});
```
<Tip>
This code will store the file in the database If the run environment is testing mode since it will be required to test other steps, other wise it will store it in the local temporary directory.
</Tip>
For Reading the file If you are using the file property in a trigger or action, It will be automatically parsed and you can use it directly, please refer to `Property.File` in the [properties](./properties#file) section.

View File

@@ -0,0 +1,65 @@
---
title: 'Flow Control'
icon: 'Joystick'
description: 'Learn How to Control Flow from Inside the Piece'
---
Flow Controls provide the ability to control the flow of execution from inside a piece. By using the `ctx` parameter in the `run` method of actions, you can perform various operations to control the flow.
## Stop Flow
You can stop the flow and provide a response to the webhook trigger. This can be useful when you want to terminate the execution of the piece and send a specific response back.
**Example with Response:**
```typescript
context.run.stop({
response: {
status: context.propsValue.status ?? StatusCodes.OK,
body: context.propsValue.body,
headers: (context.propsValue.headers as Record<string, string>) ?? {},
},
});
```
**Example without Response:**
```typescript
context.run.stop();
```
## Pause Flow and Wait for Webhook
You can pause flow and return HTTP response, also provide a callback to URL that you can call with certain payload and continue the flow.
**Example:**
```typescript
ctx.run.pause({
pauseMetadata: {
type: PauseType.WEBHOOK,
response: {
callbackUrl: context.generateResumeUrl({
queryParams: {},
}),
},
},
});
```
## Pause Flow and Delay
You can pause or delay the flow until a specific timestamp. Currently, the only supported type of pause is a delay based on a future timestamp.
**Example:**
```typescript
ctx.run.pause({
pauseMetadata: {
type: PauseType.DELAY,
resumeDateTime: futureTime.toUTCString()
}
});
```
These flow hooks give you control over the execution of the piece by allowing you to stop the flow or pause it until a certain condition is met. You can use these hooks to customize the behavior and flow of your actions.

Some files were not shown because too many files have changed in this diff Show More