We build custom applications 5x faster and cheaper 🚀
Book a Free Consultation
Stuck on an error? Book a 30-minute call with an engineer and get a direct fix + next steps. No pressure, no commitment.
To integrate Replit with Slack, you create a small web service inside a Repl that handles Slack’s API calls and events through HTTP endpoints. Slack communicates via webhooks — Replit can host such endpoints since any web server running on port 0.0.0.0:3000 (or other mapped port) becomes publicly reachable via the Replit-generated URL. You then configure your Slack app to send messages or events to that URL. Secrets like Slack tokens or signing secrets must never be hardcoded — you store them in Replit Secrets. The Repl can use the official Slack SDK or just regular HTTP calls to Slack’s REST API.
0.0.0.0 and a port (e.g., 3000). Replit automatically makes it accessible via an HTTPS URL you can find in the Repl’s browser preview.
import express from "express"
import bodyParser from "body-parser"
import fetch from "node-fetch" // Available by default in modern Node.js >18
import crypto from "crypto"
const app = express()
app.use(bodyParser.json())
// Use environment variables managed by Replit Secrets
const SLACK_SIGNING_SECRET = process.env.SLACK_SIGNING_SECRET
const SLACK_BOT_TOKEN = process.env.SLACK_BOT_TOKEN
// Verify Slack signature to ensure authenticity
function verifySlackRequest(req) {
const timestamp = req.headers["x-slack-request-timestamp"]
const sigBaseString = `v0:${timestamp}:${JSON.stringify(req.body)}`
const mySig = "v0=" + crypto.createHmac("sha256", SLACK_SIGNING_SECRET)
.update(sigBaseString, "utf8")
.digest("hex")
const slackSig = req.headers["x-slack-signature"]
return crypto.timingSafeEqual(Buffer.from(mySig), Buffer.from(slackSig))
}
// Endpoint for Slack events
app.post("/slack/events", async (req, res) => {
// Slack verification challenge
if (req.body.type === "url_verification") {
return res.json({ challenge: req.body.challenge })
}
if (!verifySlackRequest(req)) {
return res.status(400).send("Verification failed")
}
// Example: handle a message event
const event = req.body.event
if (event && event.type === "message" && !event.bot_id) {
await fetch("https://slack.com/api/chat.postMessage", {
method: "POST",
headers: {
"Authorization": `Bearer ${SLACK_BOT_TOKEN}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
channel: event.channel,
text: `Hello <@${event.user}>! You said: ${event.text}`
})
})
}
res.sendStatus(200)
})
// Start server bound to 0.0.0.0 so Replit exposes it publicly
const PORT = process.env.PORT || 3000
app.listen(PORT, "0.0.0.0", () => {
console.log(`Server running on port ${PORT}`)
})
From here, you can build richer workflows — automate notifications, respond to commands, or connect to your backend APIs. Always mind Replit’s ephemeral filesystem and occasional restarts: keep any persistent data outside Replit (a small database or external storage). Control secrets exclusively via Replit Secrets, never commit them into code. That’s all a complete, real, working Slack–Replit integration path.
1
When you deploy or restart your Replit project, a small Node.js script can send a Slack message into a specific channel. This gives your team clear visibility into updates without opening Replit. You use Slack’s Incoming Webhook feature — a special URL that accepts JSON payloads. The workflow is explicit: you configure the webhook URL as a Replit Secret, then trigger the script via a Replit Workflow step or directly after deployment.
SLACK_WEBHOOK_URL.// send-deploy-notification.js
import fetch from "node-fetch"
await fetch(process.env.SLACK_WEBHOOK_URL, {
method: "POST",
headers: {"Content-Type": "application/json"},
body: JSON.stringify({
text: `🚀 Repl updated: ${process.env.REPL_SLUG} is now live.`,
}),
})
2
You can create a Slash Command in Slack (like /status) that calls your running Replit server. The Replit project exposes an HTTP endpoint — for example /status — bound to 0.0.0.0 and mapped via the Replit Port. Slack sends a POST request to your Repl’s public URL when the command is used. This setup lets you trigger lightweight administrative actions or fetch real-time information directly from Slack.
// index.js
import express from "express"
const app = express()
app.use(express.urlencoded({ extended: true }))
app.post("/status", (req, res) => {
res.send("âś… Repl is running and responding from Slack command!")
})
app.listen(3000, "0.0.0.0", () =>
console.log("Server ready on port 3000")
)
3
Replit’s always-on environment is ideal for testing Slack event subscriptions or bot webhooks. You run an Express.js server, expose a route like /slack/events, and provide its public Replit URL in your Slack App configuration. Every time Slack sends a user message event, you see the request live in the Replit console, making event data visible for debugging. Store tokens and signing secrets safely in Replit Secrets, never in code. Once verified, you can react to events or forward them to persistent systems.
// server.js
import express from "express"
import crypto from "crypto"
const app = express()
app.use(express.json())
app.post("/slack/events", (req, res) => {
const sig = req.headers["x-slack-signature"]
const ts = req.headers["x-slack-request-timestamp"]
const hmac = crypto
.createHmac("sha256", process.env.SLACK_SIGNING_SECRET)
.update(`v0:${ts}:${JSON.stringify(req.body)}`)
.digest("hex")
if (`v0=${hmac}` !== sig) return res.status(403).send("Invalid signature")
res.sendStatus(200)
console.log("Slack event received:", req.body)
})
app.listen(3000, "0.0.0.0", () => console.log("Listening for Slack events"))
Speak one‑on‑one with a senior engineer about your no‑code app, migration goals, and budget. In just half an hour you’ll leave with clear, actionable next steps—no strings attached.
1
Usually, Replit environment variables not being recognized by a Slack bot means your code isn’t reading from Replit Secrets correctly, or the process where your bot runs doesn’t have those variables available. Slack credentials such as SLACK_BOT_TOKEN or SLACK_SIGNING_SECRET must be stored inside Replit’s “Secrets” tab, not in a .env file. Then, you access them through process.env in Node.js. Make sure the Repl is restarted after adding secrets.
console.log(process.env.SLACK_BOT_TOKEN) (never show in production logs).
// Slack Bot using @slack/bolt reading secrets from Replit
import { App } from "@slack/bolt";
const app = new App({
token: process.env.SLACK_BOT_TOKEN,
signingSecret: process.env.SLACK_SIGNING_SECRET
});
app.message("hi", async ({ say }) => {
await say("Hello from Replit!");
});
await app.start(process.env.PORT || 3000);
console.log("⚡ Slack bot running!");
If still undefined, double-check variable names match exactly and confirm you’re not running inside a Workflow or shell where the Secrets aren’t mounted. For those, inject them explicitly in workflow YAML using env section.
2
Your Replit Flask server isn’t receiving Slack event requests because Slack can’t reach your running Repl via a proper public HTTPS endpoint. By default, Replit’s app only accepts plain HTTP traffic on a mapped port (usually 0.0.0.0:8000), and if the Repl isn’t actively running or sleeping, Slack’s POST request fails. You must expose the server through Replit’s HTTPS URL and ensure the verification endpoint matches exactly what Slack expects.
from flask import Flask, request, jsonify
import os
app = Flask(__name__)
@app.route("/slack/events", methods=["POST"])
def slack_events():
data = request.get_json()
if "challenge" in data: // Slack verifies endpoint
return jsonify({"challenge": data["challenge"]})
return "", 200
app.run(host="0.0.0.0", port=int(os.environ.get("PORT", 8000)))
3
On Replit, a Slack bot won’t stay online forever unless it runs as a Deployment. Regular Repls sleep when idle, but deployed apps keep running because Replit provisions a persistent container for them. So, to keep your Slack bot continuously active, you must either deploy it as an Always On Deployment or let Slack periodically invoke it via webhooks (which wakes it on demand). Don’t rely on “pingers” — they no longer work reliably on Replit’s free hosting.
// Example Node.js Slack bot on Replit
import express from "express"
const app = express()
app.post("/slack/events", (req, res) => {
// Handle event or command from Slack
res.sendStatus(200)
})
app.listen(3000, "0.0.0.0", () => console.log("Bot running"))
Slack must reach your Replit-hosted server through an external URL, but Replit exposes endpoints only when your app runs and listens on 0.0.0.0. Forgetting to bind to that address or not mapping the correct port makes Slack fail to send events. In Replit, the preview URL automatically uses your assigned port, typically process.env.PORT. Always verify that your Repl is running live when you test Slack’s webhooks.
import express from "express"
const app = express()
app.post("/slack/events", (req, res) => { res.send("ok") })
app.listen(process.env.PORT, "0.0.0.0") // Required for Replit public URL
Slack adds a signature header (X-Slack-Signature, X-Slack-Request-Timestamp) to every request. Ignoring this means your endpoint might process fake or replayed requests. Slack provides a verification process using your Signing Secret, which must be stored as a Replit Secret (process.env.SLACK_SIGNING_SECRET). This verification should happen before executing any logic.
import crypto from "crypto"
function verifySlack(req) {
const sig = req.get("x-slack-signature")
const ts = req.get("x-slack-request-timestamp")
const body = req.rawBody // capture unparsed body
const base = `v0:${ts}:${body}`
const hash = "v0=" + crypto.createHmac("sha256", process.env.SLACK_SIGNING_SECRET).update(base).digest("hex")
return hash === sig
}
Storing Slack tokens directly in your code exposes them to anyone viewing your Repl. These tokens must be kept private, since they can change settings or post messages on behalf of your workspace. Replit provides Secrets for this purpose — you set them in the Secrets panel, and they’re available as environment variables during runtime.
// Retrieve securely from environment
const token = process.env.SLACK_BOT_TOKEN
Replit Repls can sleep or restart after inactivity, breaking Slack event delivery if the endpoint goes offline. Slack retries a few times, but eventually stops. To avoid data loss, either run the bot as a Replit Deployment (which keeps it up continuously) or use a small queueing service externally. Testing interactions only when your Repl is live ensures consistent behavior.
# In Replit shell, deploy your always-on process
npx replit deploy --run "node index.js"
This prompt helps an AI assistant understand your setup and guide you through the fix step by step, without assuming technical knowledge.
From startups to enterprises and everything in between, see for yourself our incredible impact.
Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We’ll discuss your project and provide a custom quote at no cost.Â