Skip to content

onThreadReply

Patches may optionally define an onThreadReply function that will be called when a user replies in the comments (or thread) of the patch message. onThreadReply should be defined at the top level of the patch code, outside of any other functions.

The function is passed an event object with the following properties:

function onThreadReply(e: {
user: SupUser;
input: SupInput;
}) => SupOutput | undefined;

Basic Usage

function onThreadReply(e) {
console.log(`${e.user.username} replied: ${e.input.text}`);
}

Responding to a user’s reply

You can return a value from onThreadReply to send a response message. The return value can be text, images, audio, video, or any other supported patch output format.

function onThreadReply(e) {
return `sup ${e.user.username}!`;
}

You can also return rich content like images, audio, or video:

function onThreadReply(e) {
// Return an image
return sup.image("https://example.com/welcome.jpg");
// Or return audio
// return sup.audio("https://example.com/greeting.mp3");
// Or return video
// return sup.video("https://example.com/welcome.mp4");
}

Return Value Types

onThreadReply can return any valid patch output, including:

  • Text: Simple strings or formatted text
  • Images: Using sup.image(url) or sup.image(blob)
  • Audio: Using sup.audio(url) or sup.audio(blob)
  • Video: Using sup.video(url) or sup.video(blob)
  • Complex content: Arrays or objects containing multiple elements
  • undefined: When no response is needed
function onThreadReply(e) {
if (e.input.text.includes("photo")) {
return sup.image("https://example.com/response.jpg");
} else if (e.input.text.includes("music")) {
return sup.audio("https://example.com/song.mp3");
} else if (e.input.text.includes("video")) {
return sup.video("https://example.com/clip.mp4");
} else {
return `Thanks for your message: "${e.input.text}"`;
}
}

Updating the initial message

The main function will be re-run every time onThreadReply completes, so you can use onThreadReply to update state or perform other side effects in response to user input. This will update the initial message with the new content.

function main() {
const replyCount = sup.get("replyCount") || 0;
return `This message has been replied to ${replyCount} times`;
}
function onThreadReply(e) {
let count = sup.get("replyCount") || 0;
count++;
sup.set("replyCount", count);
}

Accessing reply content and attachments

The input property contains the full reply content and any attachments:

function onThreadReply(e) {
// Access the text content
const replyText = e.input.text;
// Access images in the reply
if (e.input.images.length > 0) {
return `Thanks for the image, ${e.user.username}!`;
}
// Access files in the reply
if (e.input.files.length > 0) {
return `Got your file: ${e.input.files[0].name}`;
}
// Access videos in the reply
if (e.input.videos.length > 0) {
return `Cool video, ${e.user.username}!`;
}
// Access audio in the reply
if (e.input.audios.length > 0) {
return `Nice audio message!`;
}
// Default response
return `Thanks for your reply: "${replyText}"`;
}

Context-aware responses

You can create more intelligent responses by analyzing the reply content:

function onThreadReply(e) {
const reply = e.input.text.toLowerCase();
if (reply.includes("help")) {
return "Here are the available commands: /status, /info, /reset";
} else if (reply.includes("thanks") || reply.includes("thank you")) {
return "You're welcome! 😊";
} else if (reply.includes("?")) {
return "That's a great question! Let me think about that...";
}
// Return undefined if no specific response is needed
return undefined;
}