Get your dream built 10x faster

Replit and Smooch (now Zendesk Sunshine Conversations) Integration: 2026 Guide

We build custom applications 5x faster and cheaper 🚀

Book a Free Consultation
4.9
Clutch rating 🌟
600+
Happy partners
17+
Countries served
190+
Team members
Matt Graham, CEO of Rapid Developers

Book a call with an Expert

Stuck on an error? Book a 30-minute call with an engineer and get a direct fix + next steps. No pressure, no commitment.

Book a free consultation

How to Integrate Replit with Smooch (now Zendesk Sunshine Conversations)

Replit can integrate directly with Zendesk Sunshine Conversations (formerly Smooch) through its REST API and webhooks. You’ll run a Node.js (or Python) web server inside a Repl that connects to Smooch via HTTPS requests. Your Repl server receives messages from users through a webhook configured in Sunshine Conversations, processes them, and replies by calling Smooch’s API with valid credentials. The connection uses an OAuth or Service Account key, stored safely as a Replit Secret (environment variable), not hardcoded. Once your Repl is running, the exposed port (usually 3000) is publicly available, making webhook callbacks from Sunshine Conversations possible without additional tunneling tools.

 

Step-by-step Practical Integration

 

The flow is straightforward but explicit:

  • Create a Sunshine Conversations app in your Zendesk account. This gives you an App ID and lets you create a Service Account key. Save the key\_id and secret — these will authenticate your Replit app to the Smooch API.
  • Store credentials as Replit Secrets: in the left sidebar, open the "Secrets" tab and add variables:
    • SMOOCH_APP_ID = your Sunshine Conversations App ID
    • SMOOCH_KEY_ID = your Service Account key ID
    • SMOOCH\_SECRET = the secret string for that key
  • Install Smooch SDK or use Axios. Sunshine Conversations provides an official npm client called sunshine-conversations-client, or you can work directly through axios for raw REST calls.
  • Expose a webhook endpoint in your Repl — this is a publicly accessible URL where Sunshine Conversations can POST messages. In Replit, your running server is publicly reachable at https://<your-repl-name>.<your-username>.repl.co.

 

Example: Node.js Integration

 

This example shows how to set up a minimal Repl server that connects to Sunshine Conversations using the REST API. It listens for incoming messages and sends a simple automated reply back through the Smooch API.

 

// Load required packages
import express from "express"
import bodyParser from "body-parser"
import axios from "axios"

const app = express()
app.use(bodyParser.json())

// Read credentials from Replit Secrets (Environment Variables)
const { SMOOCH_APP_ID, SMOOCH_KEY_ID, SMOOCH_SECRET } = process.env

// Sunshine Conversations API base
const SMOOCH_BASE_URL = `https://api.smooch.io/v2/apps/${SMOOCH_APP_ID}`

// Build the Basic Auth header from key_id and secret
const authHeader = "Basic " + Buffer.from(`${SMOOCH_KEY_ID}:${SMOOCH_SECRET}`).toString("base64")

// Route to handle webhook messages from Smooch
app.post("/webhook", async (req, res) => {
  console.log("Webhook received:", req.body)

  // Extract the message text if available
  const message = req.body.messages && req.body.messages[0]
  if (message && message.text) {
    const userId = message.author.userId

    // Compose a reply message back to the same user
    await axios.post(
      `${SMOOCH_BASE_URL}/messages`,
      {
        author: { type: "business" },
        content: { type: "text", text: `You said: ${message.text}` },
        destination: { type: "user", userId }
      },
      { headers: { Authorization: authHeader, "Content-Type": "application/json" } }
    )
  }

  res.sendStatus(200)
})

// Start the server on port 3000 and bind to 0.0.0.0 for Replit
app.listen(3000, "0.0.0.0", () => console.log("Repl listening on port 3000"))

 

Registering the Webhook in Sunshine Conversations

 

Once your Repl is live, you must tell Sunshine Conversations where to deliver webhook events. Run a one-time API call using your credentials:

 

curl -X POST "https://api.smooch.io/v2/apps/$SMOOCH_APP_ID/webhooks" \
  -u "$SMOOCH_KEY_ID:$SMOOCH_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
        "target": "https://your-repl-name.your-username.repl.co/webhook",
        "triggers": ["message:appUser"]
      }'

 

Verification and Testing

 

  • Send yourself a message using any channel (Messenger, WhatsApp, Web Messenger) connected to your Sunshine Conversations app.
  • Open the Replit Console — it should log the incoming payload.
  • The automation replies immediately with “You said: ...” confirming bidirectional communication works.

 

Good Practices

 

  • Never leak secrets. Always read from environment variables via Replit Secrets.
  • Use Workflow tasks (for example, for message broadcasting or scheduled functions) to run background jobs safely inside Replit.
  • Move production workloads off Replit once you need guaranteed uptime or scaling; Replit’s runtime can reboot on inactivity.

 

That’s the full working model: explicit REST calls, real endpoints, correct authentication, and an endpoint bound to 0.0.0.0 so Replit’s network proxy can expose your Sunshine Conversations integration publicly and safely.

Use Cases for Integrating Smooch (now Zendesk Sunshine Conversations) and Replit

1

Real-Time Chatbot Backend

Build and host a chatbot service directly inside Replit that connects Sunshine Conversations (formerly Smooch) to a custom logic API. When a user sends a message through a channel (like WhatsApp, Messenger, or your website widget), Sunshine triggers a webhook. Your Repl receives this webhook on a bound port (for example, 0.0.0.0:8000) and processes it live. You manage the Zendesk app and secret keys with Replit Secrets so they remain secure across sessions. The chat logic, such as generating automated replies or integrating with OpenAI’s API, runs inside the Repl runtime. Replit Workflows let you restart or test the service automatically when code changes. This use case turns Replit into a lightweight, cloud-based chat processor without deploying external servers.

  • Webhook endpoint receives new messages.
  • Replit Secrets store Sunshine credentials.
  • Express server handles routes and replies to users in real time.
import express from "express"
import fetch from "node-fetch"

const app = express()
app.use(express.json())

app.post("/webhook", async (req, res) => {
  const msg = req.body.messages?.[0]
  if (msg?.text) {
    await fetch("https://api.smooch.io/v2/apps/YOUR_APP_ID/messages", {
      method: "POST",
      headers: {
        "Authorization": `Bearer ${process.env.ZENDESK_API_KEY}`,
        "Content-Type": "application/json"
      },
      body: JSON.stringify({
        author: { type: "business" },
        text: `You said: ${msg.text}`
      })
    })
  }
  res.sendStatus(200)
})

app.listen(8000, "0.0.0.0", () => console.log("Webhook listening"))

2

Real-Time Chatbot Backend

Use Replit as a quick sandboxed environment to experiment with support dashboards that query Sunshine Conversations’ REST API. An agent-facing dashboard (built with HTML/JS inside a Repl) can list active conversations, display message histories, and let staff send responses. This prototype mirrors the logic of a full enterprise environment without deploying it permanently. Because Replit runs both client (static HTML files) and backend (Express/Node) in one workspace, you can fetch data securely through your backend using stored credentials. This setup helps new developers or non-tech operators visualize and test integrations safely before moving to a production Zendesk environment.

  • Replit hosting handles both front-end preview and backend API proxy.
  • REST calls fetch user conversations or send messages.
  • Env secrets isolate API tokens securely.
import express from "express"
import fetch from "node-fetch"

const app = express()
app.get("/conversations", async (req, res) => {
  const resp = await fetch("https://api.smooch.io/v2/apps/YOUR_APP_ID/conversations", {
    headers: { "Authorization": `Bearer ${process.env.ZENDESK_API_KEY}` }
  })
  const data = await resp.json()
  res.json(data)
})
app.listen(8000, "0.0.0.0")

3

Webhook Verification and Testing Sandbox

Create a Webhook verification sandbox in Replit for Sunshine Conversations to validate real message events and signatures safely. You expose a public port through Replit’s live URL (e.g., https://your-repl-name.your-username.repl.co/webhook) and configure it in Zendesk as the webhook endpoint. When new messages or delivery receipts arrive, you log events in Replit’s console and verify authenticity using HMAC signatures from the header. This lets developers confirm their webhook signing process, event structure, and rate handling before pushing the code into a production server or cloud function.

  • Receives real webhook payloads through Replit’s hosted URL.
  • Verifies HMAC signature locally using Node’s crypto module.
  • Monitors real-time logs directly in console for debugging.
import crypto from "crypto"
import express from "express"
const app = express()
app.use(express.json({ verify: (req, res, buf) => (req.rawBody = buf) }))

app.post("/webhook", (req, res) => {
  const sig = req.headers["x-smooch-signature"]
  const hash = crypto
    .createHmac("sha256", process.env.ZENDESK_WEBHOOK_SECRET)
    .update(req.rawBody)
    .digest("hex")

  if (sig !== hash) return res.status(401).send("Invalid signature")

  console.log("Valid event:", JSON.stringify(req.body, null, 2))
  res.sendStatus(200)
})

app.listen(8000, "0.0.0.0", () => console.log("Verifier active"))

Book Your Free 30‑Minute Migration Call

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.

Book a Free Consultation

Troubleshooting Smooch (now Zendesk Sunshine Conversations) and Replit Integration

1

Why is the Smooch (Zendesk Sunshine Conversations) webhook not receiving messages when running the Replit server?

The Smooch (Zendesk Sunshine Conversations) webhook isn’t receiving messages because the Replit server URL is not publicly reachable in the persistent way the webhook service expects. Replit gives you a temporary HTTPS URL only while your Repl is running. Once the Repl sleeps or restarts, the URL changes, and the webhook endpoint breaks. Additionally, Sunshine Conversations requires a valid HTTPS endpoint that responds with HTTP 2xx quickly — if your app is bound incorrectly (not to 0.0.0.0 or wrong port), or not handling POST JSON body properly, the messages fail silently.

 

How to fix this properly

 

Ensure your Express (or any HTTP) server binds to 0.0.0.0 and listens on the Replit-assigned PORT. Use Replit Secrets for your API tokens. Then, copy the current public URL from Replit’s “Webview” button and configure it in the Sunshine Conversations dashboard webhook settings.

  • Keep the Repl awake when debugging — you can’t receive webhooks if it’s inactive.
  • Check Sunshine’s logs in their dashboard to confirm delivery and status codes.

 

import express from "express"
const app = express()
app.use(express.json())

app.post("/webhook", (req,res)=>{
  console.log(req.body)  // log incoming webhook data
  res.sendStatus(200)    // respond fast with 200 OK
})

app.listen(process.env.PORT, "0.0.0.0", ()=>{
  console.log("Server running on", process.env.PORT)
})

 

Once working, migrate the same code to a stable hosting (like a deployment or external server) for production webhooks.

2

How to correctly set up environment variables for Smooch API keys in Replit Secrets?

To correctly set Smooch (Sunshine Conversations) API keys in Replit, store them as Secrets so they become environment variables accessible only by your running code. Open the “Secrets” tab in Replit (🔑 icon on left panel), add a key name like SMOOCH_APP_ID and another for SMOOCH_API_KEY, then reference them in your code through process.env. This keeps credentials safe and ensures they persist across restarts without exposing them in your code.

 

Detailed Explanation

 

Replit’s Secrets manager securely injects key/value pairs into the runtime environment. They act as temporary environment variables visible only to your Repl. Once you define your Smooch credentials there, they automatically load whenever your app starts — no file configuration needed. You simply call them via Node.js process environment access. Never commit raw credentials to your repository; Replit automatically masks their values in logs or console output.

  • Go to Tools → Secrets panel and add entries manually.
  • Set key name: SMOOCH_APP_ID → value: your actual Smooch App ID.
  • Set key name: SMOOCH_API_KEY → value: your Smooch API key string.

 

// Example Node.js usage inside index.js

const appId = process.env.SMOOCH_APP_ID
const apiKey = process.env.SMOOCH_API_KEY

console.log("Using Smooch App:", appId)
// Initialize client using official SDK or REST calls with Authorization header

 

3

Why does the Replit server URL not stay active for incoming Smooch webhook requests?

The Replit server URL doesn’t stay active for Smooch webhook requests because Replit free-hosted Repls enter “sleep” mode or restart when inactive. When this happens, the temporary preview URL (the one ending with replit.app or repl.co) is deactivated, and no background process remains to keep your server listening for incoming requests. Webhooks require a constant, publicly reachable endpoint, but Replit containers stop running once you close the tab or stop the Repl.

 

Detailed explanation

 

When you run Express or another web framework, it only responds while the Repl runtime stays awake. Once idle, the container shuts down to free resources. That’s why the webhook sender (like Smooch) gets “connection refused” or “timeout” errors — it can’t reach your temporary URL anymore.

  • To keep it alive: Use Replit Deployments (Always-On or Autoscale) instead of a normal Repl run. These stay online even without your browser open.
  • Alternatively: Tunnel requests through a free service like ngrok for temporary testing.
  • Bind: always use app.listen(3000, '0.0.0.0') so the Repl exposes the correct port.

 

import express from "express"
const app = express()

app.post("/webhook", (req, res) => {
  console.log("Webhook received!")
  res.sendStatus(200)
})

// Bind to 0.0.0.0 so Replit maps port externally
app.listen(3000, "0.0.0.0", () => console.log("Server running"))

 

Book a Free Consultation

Schedule a 30‑Minute No‑Code‑to‑Code Consultation

Grab a quick video call to discuss the fastest, most cost‑efficient path from no‑code to production‑ready code. Zero sales fluff—just practical advice tailored to your project.

Contact us

Common Integration Mistakes: Replit + Smooch (now Zendesk Sunshine Conversations)

Missing Publicly Accessible Webhook Endpoint

Sunshine Conversations (formerly Smooch) pushes webhook events — like new messages — to your app’s public endpoint. On Replit, a server must bind to 0.0.0.0 and you must open the listening port (usually process.env.PORT) in the Workspace or Deployment configuration. If you only listen on localhost or forget to expose the port, Sunshine can’t reach your endpoint.

  • Check the exposed port: it must match your server’s bind port.
  • Use Workflows or Deployments to ensure the server stays running during webhook verification.
import express from "express"
const app = express()
app.use(express.json())

app.post("/webhook", (req, res) => {
  console.log(req.body)
  res.sendStatus(200)
})

app.listen(process.env.PORT || 3000, "0.0.0.0") // Needed for Replit

Hardcoding API Keys Instead of Using Replit Secrets

Directly embedding your Sunshine Conversations appId or API key inside code makes it publicly visible to anyone viewing your Repl. Replit’s public Repls expose source files by default. Store credentials using Secrets (on the left panel → Secrets) and access them from process.env in Node.js. This prevents leaking sensitive tokens if you fork or share the Repl.

  • Define secrets: add SMOOCH_APP_ID and SMOOCH_KEY_ID via Replit Secrets.
  • Never commit .env files; Replit already maps secrets to environment variables safely.
import fetch from "node-fetch"

const { SMOOCH_APP_ID, SMOOCH_KEY_ID, SMOOCH_SECRET } = process.env

// Properly using environment variables
fetch(`https://api.smooch.io/v2/apps/${SMOOCH_APP_ID}/messages`, {
  headers: {
    "Content-Type": "application/json",
    Authorization: `Basic ${Buffer.from(`${SMOOCH_KEY_ID}:${SMOOCH_SECRET}`).toString("base64")}`
  }
})

Ignoring Webhook Signature Verification

Developers often skip verifying Sunshine Conversations’ webhook signatures, assuming internal Replit traffic is private. It isn’t — every Repl has a public URL. To trust incoming requests, validate headers X-Smooch-Signature using your Secret Key. Without this, anyone can spoof events to your app. Node’s crypto module works well to compare signatures securely.

  • Use raw request body for digest; body-parsers can alter payloads.
  • Compare using constant-time check to avoid subtle timing leaks.
import crypto from "crypto"

function verifySmoochSignature(rawBody, signature, secret) {
  const expected = crypto.createHmac("sha256", secret).update(rawBody).digest("hex")
  return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected))
}

Not Handling Replit Restarts or Ephemeral State

Replit free Repls sleep when idle; even Deployments restart on new pushes. If your Sunshine Conversations integration stores conversation IDs or auth tokens in memory or local files only, they vanish after restart. You must persist important state externally — for example, in Replit Database, or ideally an external database like Postgres or Redis.

  • Check persistence: in-memory caches disappear on restart.
  • Externalize state: store cross-session data off Replit to keep conversations intact.
// Simple use of Replit DB for message mapping
import Database from "@replit/database"
const db = new Database()

await db.set("conversation:12345", { lastMessageId: "abc" })
const conv = await db.get("conversation:12345")
console.log(conv)

Still stuck?
Copy this prompt into ChatGPT and get a clear, personalized explanation.

This prompt helps an AI assistant understand your setup and guide you through the fix step by step, without assuming technical knowledge.

AI AI Prompt


Recognized by the best

Trusted by 600+ businesses globally

From startups to enterprises and everything in between, see for yourself our incredible impact.

RapidDev was an exceptional project management organization and the best development collaborators I've had the pleasure of working with.

They do complex work on extremely fast timelines and effectively manage the testing and pre-launch process to deliver the best possible product. I'm extremely impressed with their execution ability.

Arkady
CPO, Praction
Working with Matt was comparable to having another co-founder on the team, but without the commitment or cost.

He has a strategic mindset and willing to change the scope of the project in real time based on the needs of the client. A true strategic thought partner!

Donald Muir
Co-Founder, Arc
RapidDev are 10/10, excellent communicators - the best I've ever encountered in the tech dev space.

They always go the extra mile, they genuinely care, they respond quickly, they're flexible, adaptable and their enthusiasm is amazing.

Mat Westergreen-Thorne
Co-CEO, Grantify
RapidDev is an excellent developer for custom-code solutions.

We’ve had great success since launching the platform in November 2023. In a few months, we’ve gained over 1,000 new active users. We’ve also secured several dozen bookings on the platform and seen about 70% new user month-over-month growth since the launch.

Emmanuel Brown
Co-Founder, Church Real Estate Marketplace
Matt’s dedication to executing our vision and his commitment to the project deadline were impressive. 

This was such a specific project, and Matt really delivered. We worked with a really fast turnaround, and he always delivered. The site was a perfect prop for us!

Samantha Fekete
Production Manager, Media Production Company
The pSEO strategy executed by RapidDev is clearly driving meaningful results.

Working with RapidDev has delivered measurable, year-over-year growth. Comparing the same period, clicks increased by 129%, impressions grew by 196%, and average position improved by 14.6%. Most importantly, qualified contact form submissions rose 350%, excluding spam.

Appreciation as well to Matt Graham for championing the collaboration!

Michael W. Hammond
Principal Owner, OCD Tech

We put the rapid in RapidDev

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.Â