diff --git a/templates/list.json b/templates/list.json
index 65c3680ad..6c56ff07d 100644
--- a/templates/list.json
+++ b/templates/list.json
@@ -6158,6 +6158,23 @@
"Data Security"
]
},
+ {
+ "slug": "openreply",
+ "logo": "logo.svg",
+ "name": "OpenReply",
+ "description": "OpenReply is an open-source Instagram comment-to-DM automation tool and self-hosted ManyChat alternative. It watches Instagram post and reel comments through Meta webhooks, matches configured keywords, queues delivery jobs, and sends private replies through the official Meta API. The app includes a Next.js dashboard, campaign templates, tracked links, DM logs, role-based workspaces, email magic-link login, and a long-running worker process backed by PostgreSQL and Redis.",
+ "tags": [
+ "Instagram",
+ "Automation",
+ "Social Media",
+ "Marketing",
+ "ManyChat Alternative",
+ "Next.js",
+ "PostgreSQL",
+ "Redis",
+ "Open Source"
+ ]
+ },
{
"slug": "openspeedtest",
"logo": "logo.png",
diff --git a/templates/openreply/assets/logo.svg b/templates/openreply/assets/logo.svg
new file mode 100644
index 000000000..f23cad3a2
--- /dev/null
+++ b/templates/openreply/assets/logo.svg
@@ -0,0 +1,6 @@
+
diff --git a/templates/openreply/assets/screenshot.png b/templates/openreply/assets/screenshot.png
new file mode 100644
index 000000000..a3570a211
Binary files /dev/null and b/templates/openreply/assets/screenshot.png differ
diff --git a/templates/openreply/index.ts b/templates/openreply/index.ts
new file mode 100644
index 000000000..0402ead1d
--- /dev/null
+++ b/templates/openreply/index.ts
@@ -0,0 +1,119 @@
+import {
+ Output,
+ randomPassword,
+ randomString,
+ Services,
+} from "~templates-utils";
+import { Input } from "./meta";
+
+function randomHex(length: number) {
+ const chars = "abcdef0123456789";
+ let result = "";
+ for (let i = 0; i < length; i++) {
+ result += chars[Math.floor(Math.random() * chars.length)];
+ }
+ return result;
+}
+
+export function generate(input: Input): Output {
+ const services: Services = [];
+ const databasePassword = randomPassword();
+ const redisPassword = randomPassword();
+ const nextAuthSecret = randomString(48);
+ const cronSecret = randomString(48);
+ const encryptionKey = randomHex(64);
+ const databaseUrl = `postgresql://postgres:${databasePassword}@$(PROJECT_NAME)_${input.appServiceName}-db:5432/$(PROJECT_NAME)`;
+ const redisUrl = `redis://default:${redisPassword}@$(PROJECT_NAME)_${input.appServiceName}-redis:6379`;
+ const appUrl = "https://$(EASYPANEL_DOMAIN)";
+
+ const commonEnv = [
+ `NIXPACKS_NODE_VERSION=24`,
+ `NEXTAUTH_URL=${appUrl}`,
+ `NEXTAUTH_SECRET=${nextAuthSecret}`,
+ `CRON_SECRET=${cronSecret}`,
+ `ENCRYPTION_KEY=${encryptionKey}`,
+ `DATABASE_URL=${databaseUrl}`,
+ `REDIS_URL=${redisUrl}`,
+ `RESEND_API_KEY=${input.resendApiKey}`,
+ `EMAIL_FROM=${input.emailFrom}`,
+ `META_GRAPH_API_VERSION=${input.metaGraphApiVersion}`,
+ `INSTAGRAM_APP_ID=${input.instagramAppId}`,
+ `INSTAGRAM_APP_SECRET=${input.instagramAppSecret}`,
+ `FACEBOOK_APP_SECRET=${input.facebookAppSecret}`,
+ `WEBHOOK_VERIFY_TOKEN=${input.webhookVerifyToken}`,
+ ].join("\n");
+
+ const source = {
+ type: "github" as const,
+ owner: "diwenne",
+ repo: "openreply",
+ ref: input.sourceRef,
+ path: "/",
+ autoDeploy: false,
+ };
+
+ services.push({
+ type: "postgres",
+ data: {
+ serviceName: `${input.appServiceName}-db`,
+ image: "postgres:16",
+ password: databasePassword,
+ },
+ });
+
+ services.push({
+ type: "redis",
+ data: {
+ serviceName: `${input.appServiceName}-redis`,
+ password: redisPassword,
+ },
+ });
+
+ services.push({
+ type: "app",
+ data: {
+ serviceName: input.appServiceName,
+ source,
+ build: {
+ type: "nixpacks",
+ installCommand: "npm ci",
+ buildCommand: "npm run build",
+ startCommand: "npm run start",
+ },
+ env: commonEnv,
+ deploy: {
+ replicas: 1,
+ command: "npx prisma migrate deploy && npm run start",
+ zeroDowntime: true,
+ },
+ domains: [
+ {
+ host: "$(EASYPANEL_DOMAIN)",
+ port: 3000,
+ },
+ ],
+ },
+ });
+
+ services.push({
+ type: "app",
+ data: {
+ serviceName: `${input.appServiceName}-worker`,
+ source,
+ build: {
+ type: "nixpacks",
+ installCommand: "npm ci",
+ buildCommand: "npm run db:generate",
+ startCommand: "npm run worker",
+ },
+ env: commonEnv,
+ deploy: {
+ replicas: 1,
+ command: "npm run worker",
+ zeroDowntime: false,
+ },
+ },
+ });
+
+ return { services };
+}
diff --git a/templates/openreply/meta.yaml b/templates/openreply/meta.yaml
new file mode 100644
index 000000000..51bb977b9
--- /dev/null
+++ b/templates/openreply/meta.yaml
@@ -0,0 +1,126 @@
+name: OpenReply
+description:
+ OpenReply is an open-source Instagram comment-to-DM automation tool and
+ self-hosted ManyChat alternative. It watches Instagram post and reel comments
+ through Meta webhooks, matches configured keywords, queues delivery jobs, and
+ sends private replies through the official Meta API. The app includes a
+ Next.js dashboard, campaign templates, tracked links, DM logs, role-based
+ workspaces, email magic-link login, and a long-running worker process backed
+ by PostgreSQL and Redis.
+instructions:
+ Before deploying, create a Meta developer app and a Resend account. Set the
+ Meta and Resend values in the template form. After deployment, configure Meta
+ with the OAuth redirect URL https://your-domain/api/instagram/callback and
+ webhook callback URL https://your-domain/api/webhook using the same webhook
+ verify token entered here. The web service and worker must both stay running;
+ the worker sends DMs from the queue.
+changeLog:
+ - date: 2026-08-08
+ description: First release
+links:
+ - label: GitHub
+ url: https://github.com/diwenne/openreply
+ - label: Documentation
+ url: https://github.com/diwenne/openreply/blob/main/docs/setup.md
+contributors:
+ - name: Yahya
+ url: https://github.com/yahya
+schema:
+ type: object
+ required:
+ - appServiceName
+ - sourceRef
+ - resendApiKey
+ - emailFrom
+ - instagramAppId
+ - instagramAppSecret
+ - facebookAppSecret
+ - webhookVerifyToken
+ - metaGraphApiVersion
+ properties:
+ appServiceName:
+ type: string
+ title: App Service Name
+ default: openreply
+ sourceRef:
+ type: string
+ title: Source Ref
+ default: main
+ resendApiKey:
+ type: string
+ title: Resend API Key
+ emailFrom:
+ type: string
+ title: Email From
+ default: OpenReply
+ instagramAppId:
+ type: string
+ title: Instagram App ID
+ instagramAppSecret:
+ type: string
+ title: Instagram App Secret
+ facebookAppSecret:
+ type: string
+ title: Facebook App Secret
+ webhookVerifyToken:
+ type: string
+ title: Webhook Verify Token
+ metaGraphApiVersion:
+ type: string
+ title: Meta Graph API Version
+ default: v25.0
+benefits:
+ - title: Self-Hosted Instagram Automation
+ description:
+ Run Instagram comment-to-DM automation on your own infrastructure without
+ seat limits, plan caps, or a managed automation subscription.
+ - title: Official Meta API Flow
+ description:
+ Uses Meta webhooks and Instagram private replies instead of scraping,
+ browser automation, or Instagram password access.
+ - title: Reliable Queue Processing
+ description:
+ Separates the web app from a long-running worker so webhook receipt,
+ keyword matching, rate limiting, retries, and DM delivery are handled
+ reliably.
+ - title: Campaign and Link Tracking
+ description:
+ Build keyword campaigns, send tracked links, monitor clicks, and inspect
+ send logs from the dashboard.
+ - title: Multi-Account Workspaces
+ description:
+ Manage multiple Instagram professional accounts with workspace roles and
+ invite-based team access.
+features:
+ - title: Keyword to DM
+ description:
+ Match one or more keywords on Instagram comments and send private replies
+ through the official API.
+ - title: Public Reply Support
+ description:
+ Optionally post a public reply under the matched comment alongside the
+ private DM.
+ - title: Queue-Backed Worker
+ description:
+ Runs a separate worker process with BullMQ and Redis for delivery,
+ retries, polling reconciliation, and rate limiting.
+ - title: Email Magic-Link Login
+ description: Uses Auth.js and Resend for passwordless sign-in.
+ - title: PostgreSQL Persistence
+ description:
+ Stores workspaces, accounts, campaigns, logs, sessions, and tracked link
+ analytics in PostgreSQL through Prisma.
+ - title: Meta Webhook Endpoint
+ description:
+ Provides a webhook endpoint for Instagram comments and a callback endpoint
+ for Instagram OAuth connection.
+tags:
+ - Instagram
+ - Automation
+ - Social Media
+ - Marketing
+ - ManyChat Alternative
+ - Next.js
+ - PostgreSQL
+ - Redis
+ - Open Source