Activepieces (an open-source Zapier alternative you can self-host) gives you the same repeatable flows without a new subscription. You connect Gmail, Slack, Google Sheets, and OpenAI, then schedule runs or react to webhooks. It is simple enough to ship in one sitting, and you own the stack.
You are going to spin up Activepieces (an open-source Zapier alternative you can self-host), connect Gmail and Slack, then build a daily follow up that pulls new leads from a Sheet, summarizes with OpenAI, and sends messages.
First, get Docker running. On macOS, install Docker Desktop with Homebrew, then open Docker once so it finishes setup.
bash
brew install --cask docker
Verify Docker is ready:
bash
docker --version
Now bring up Activepieces with Docker Compose, then visit it in the browser. In the full guide I give you a drop-in compose file with Postgres and Redis. You run one command to start, then sign up on http://localhost and create your first flow. Use the Schedule trigger set to 09:00 in your timezone, add Google Sheets to read new rows, drop in an OpenAI step to summarize the row, then send a Gmail or Slack message. Test one run. If it looks right, publish the flow and it will execute every morning without another paid seat.
You are going to spin up Activepieces (an open-source Zapier alternative you can self-host), connect Gmail and Slack, then build a daily follow up that pulls new leads from a Sheet, summarizes with OpenAI, and sends messages.
First, get Docker running. On macOS, install Docker Desktop with Homebrew, then open Docker once so it finishes setup.
bash
brew install --cask docker
Verify Docker is ready:
bash
docker --version
Now bring up Activepieces with Docker Compose, then visit it in the browser. In the full guide I give you a drop-in compose file with Postgres and Redis. You run one command to start, then sign up on http://localhost and create your first flow. Use the Schedule trigger set to 09:00 in your timezone, add Google Sheets to read new rows, drop in an OpenAI step to summarize the row, then send a Gmail or Slack message. Test one run. If it looks right, publish the flow and it will execute every morning without another paid seat.
Setup
macOS
1) Install Docker Desktop and start it once:
bash
brew install --cask docker
open -a Docker
2) Create a project folder and a Docker Compose file:
bash
mkdir -p ~/activepieces && cd ~/activepieces
cat > docker-compose.yml <<'YAML'
version: '3.8'
services:
postgres:
image: postgres:15-alpine
environment:
POSTGRES_USER: ap_user
POSTGRES_PASSWORD: ap_password_123
POSTGRES_DB: ap_db
volumes:
- pgdata:/var/lib/postgresql/data
redis:
image: redis:7-alpine
command: ["redis-server", "--appendonly", "yes"]
volumes:
- redisdata:/data
activepieces:
image: activepieces/activepieces:latest
depends_on:
- postgres
- redis
ports:
- "80:80"
environment:
AP_FRONTEND_URL: http://localhost
AP_API_URL: http://localhost/api
AP_WEBHOOK_URL: http://localhost
AP_POSTGRES_HOST: postgres
AP_POSTGRES_PORT: 5432
AP_POSTGRES_DB: ap_db
AP_POSTGRES_USER: ap_user
AP_POSTGRES_PASSWORD: ap_password_123
AP_REDIS_HOST: redis
AP_REDIS_PORT: 6379
AP_ENCRYPTION_KEY: ap_encryption_key_32_chars_min_123456
AP_JWT_SECRET: ap_jwt_secret_32_chars_min_abcdef
volumes:
pgdata:
redisdata:
YAML
3) Start the stack:
bash
docker compose up -d
4) Open http://localhost and create the first admin account.
Linux (Ubuntu/Debian)
1) Install Docker using the convenience script, then log out and back in so your user gains docker group access.
bash
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker "$USER"
newgrp docker
2) Create the folder and Compose file, same as macOS, then start:
bash
mkdir -p ~/activepieces && cd ~/activepieces
# paste the same docker-compose.yml content from macOS section
nano docker-compose.yml
docker compose up -d
3) Visit http://localhost and sign up.
Windows 11
1) Install Docker Desktop from winget and start it:
bash
winget install Docker.DockerDesktop
2) Create C:\activepieces and save docker-compose.yml with the same content as macOS. Then in PowerShell:
bash
cd C:\activepieces
docker compose up -d
3) Visit http://localhost and sign up.
Create your first flow
- In Activepieces, click New Flow. Name it Daily Lead Follow Up.
- Trigger: Schedule. Every day at 09:00. Timezone set to your city.
- Step: Google Sheets. New Rows in a Sheet. Connect a Google account and pick the sheet with leads.
- Step: OpenAI. Prompt: “Summarize this lead in one sentence. Then propose one next action. Data: {{row}}.” Select model gpt-4o-mini and set temperature 0.2. Add your API key when prompted. Example key: sk-proj-sampleABC123xyz456DEF789ghi012JKL345mno.
- Step: Gmail. Send Email to the owner column email. Subject “Next step for {{row.name}}”. Body uses the summary from the OpenAI step.
- Test the flow with one sample row. If it looks good, click Publish.
Verify
Check that containers are healthy and listening on port 80.
bash
docker compose ps
Expected output includes all three services up:
bash
NAME COMMAND STATE PORTS
activepieces-postgres-1 "docker-entrypoint.s…" Up 5432/tcp
activepieces-redis-1 "redis-server --appe…" Up 6379/tcp
activepieces-1 "docker-entrypoint.s…" Up 0.0.0.0:80->80/tcp
Open a health check in your browser at http://localhost. The signup page should load. After creating an account, the Flows page should show an empty list and a New Flow button.
Configuration tips
- Set a real domain and HTTPS before using webhooks. Change AP_FRONTEND_URL and AP_WEBHOOK_URL to your domain, then put a reverse proxy like Caddy or Nginx in front with TLS. Restart the stack.
- Timezone. In each Schedule trigger, set the timezone to your team’s city so 09:00 really means 09:00 for you.
- Gmail sending. Use a Google Workspace account, not a free @gmail.com, for higher daily send limits. Add a reply-to address and set From Name in the Gmail step for clarity.
- Sheets batching. If you get more than 50 new rows daily, add a Loop step after fetching rows so you process one row per iteration. This keeps OpenAI calls predictable.
- OpenAI cost control. Use gpt-4o-mini for summaries and classification. Set max tokens to 200 and temperature 0.2. Add a Retry policy of 2 attempts with 2 second delay if you see rate limits.
Troubleshooting
- Port already in use: “Bind for 0.0.0.0:80 failed. Address already in use.” Fix by changing the host port to 8080 in docker-compose.yml under activepieces ports "8080:80". Then visit http://localhost:8080.
- Database auth error: “FATAL: password authentication failed for user \"ap_user\".” Make sure POSTGRES_USER, POSTGRES_PASSWORD, and AP_POSTGRES_* values match exactly. Run
docker compose down, thendocker volume rm activepieces_pgdataif you changed credentials, anddocker compose up -dto recreate. - Redis connection refused: “ECONNREFUSED 127.0.0.1:6379.” In docker-compose.yml, AP_REDIS_HOST must be redis, not localhost. Restart with
docker compose up -d.
When it beats OpenAI Tasks
- Shared automations without per-seat fees. Your whole team can run scheduled follow ups and lead routing inside one self-hosted workspace.
- Cross-app handoffs. Kick off from a Google Form submission, enrich with OpenAI, update a Sheet, post to Slack, and email the owner in one flow.
- Custom schedules and cron. Run every weekday at a specific time, or every 15 minutes on workdays. No tying your logic to chat threads.
- Audit and data locality. Keep logs, connection configs, and payloads on your server. Useful for regulated teams.
- Webhook ingestion. Accept webhooks from your site or CRM, parse JSON, fan out to Sheets and Slack, and store a record in Postgres.
Sources
Want a hand?
Book a 30-min call.
Walk through your stack with us. We'll find the bottleneck and map out the exact wiring you need — free.