Skip to content

Instantly share code, notes, and snippets.

@kylemcdonald
Created October 4, 2023 01:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kylemcdonald/c9df6e5a9e09370311246bdfd500d826 to your computer and use it in GitHub Desktop.
Save kylemcdonald/c9df6e5a9e09370311246bdfd500d826 to your computer and use it in GitHub Desktop.
Twilio app for repeating everything someone has said once they say the word "repeat".
const WebSocket = require("ws");
const express = require("express");
const app = express();
const server = require("http").createServer(app);
const wss = new WebSocket.Server({ server });
const path = require("path");
const fs = require("fs");
require("dotenv").config();
const speech = require("@google-cloud/speech");
const client = new speech.SpeechClient();
const request = {
config: {
encoding: "MULAW",
sampleRateHertz: 8000,
languageCode: "en-US",
},
interimResults: true
};
wss.on("connection", function connection(ws) {
console.log("New Connection Initiated");
let recognizeStream = null;
let recording = Buffer.from([]);
let repeated = false;
ws.on("message", function incoming(message) {
const msg = JSON.parse(message);
switch (msg.event) {
case "connected":
console.log(`A new call has connected.`);
break;
case "start":
const streamSid = msg.streamSid;
console.log(`Starting Media Stream ${streamSid}`);
recognizeStream = client
.streamingRecognize(request)
.on("error", console.error)
.on("data", (data) => {
const transcript = data.results[0].alternatives[0].transcript;
console.log(transcript);
wss.clients.forEach((client) => {
if (client.readyState === WebSocket.OPEN) {
if (transcript.toLowerCase().includes("repeat") && !repeated) {
repeated = true;
client.send(
JSON.stringify({
event: "media",
streamSid,
media: {
payload: Buffer.from(recording).toString("base64"),
},
})
);
client.send(
JSON.stringify({
event: "mark",
streamSid,
mark: {
name: "repeat",
},
})
);
}
client.send(
JSON.stringify({
event: "interim-transcription",
text: transcript,
})
);
}
});
});
break;
case "media":
let payload = msg.media.payload;
let decoded = Buffer.from(payload, "base64");
recording = Buffer.concat([recording, decoded]);
recognizeStream.write(msg.media.payload);
break;
case "stop":
console.log(`Call Has Ended`);
recognizeStream.destroy();
let filename = "audio.pcm";
fs.writeFileSync(filename, recording);
break;
}
});
});
app.use(express.static("public"));
app.get("/", (req, res) => res.sendFile(path.join(__dirname, "/index.html")));
app.post("/", (req, res) => {
res.set("Content-Type", "text/xml");
res.send(`
<Response>
<Say>Let's go!</Say>
<Connect>
<Stream url="wss://${req.headers.host}/"/>
</Connect>
<Pause length="60" />
</Response>
`);
});
console.log("Listening on Port 8080");
server.listen(8080);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment