How to make a Discord bot show typing status in a channel based on DM activity?

I am developing a Discord bot that should display a typing status in a particular channel when a user is typing in the bot’s direct messages. The aim is to create the illusion that the user is typing in that channel through the bot.

Current Status

Currently, I have implemented a feature where the bot shows the typing status in the designated channel when a user begins typing in DMs. However, I am facing an issue where the bot does not stop typing once the user ceases to type.

Issues Encountered

I am also attempting to add the opposite functionality, but I keep receiving the following error:
TypeError: targetDM.startTyping is not a function

Code Example

Here is my current implementation:

bot.on("typingStart", async function(channel, user){
    if(user.bot){
        return;
    }

    let targetChannel = bot.channels.cache.get(activeTickets[user.id].channelID)
    if(channel.type === "dm"){
        if(activeTickets[user.id]){
            console.log("detected typing")
            targetChannel.startTyping()
        } else{
            return;
        }   
    }
})

Here’s the problematic part:

if(activeTickets[channel.id]){
    let targetDM = bot.users.fetch(activeTickets[channel.id].memberID)
    targetDM.startTyping();
}

Any ideas on correctly managing the typing indicators in both directions?

I hit the same issue building a support ticket system. Discord’s typing indicators expire after ~10 seconds and there’s no way to detect when someone stops typing. I fixed it with a cleanup system using setTimeout and clearTimeout. Every time someone starts typing, I clear their existing timer and set a new one for 8-9 seconds. Stops the indicator from getting stuck. For your DM issue - you’re calling startTyping() on a Promise. You need to await the user fetch first, then create the DM: const user = await bot.users.fetch(id); const dm = await user.createDM(); dm.startTyping(); Also heads up - Discord rate limits typing indicators. If you’ve got high activity, add some throttling so you don’t hit those limits.

The issue arises because bot.users.fetch() returns a Promise, and you cannot directly call startTyping() on User objects. To achieve the desired outcome, first create a DM channel and then call startTyping() on that channel.

Additionally, since Discord.js does not provide a typingStop event, you’ll need to implement your own mechanism, such as using a timer. After the typing starts, initiate a timeout to end the typing indicator after an appropriate period (like 10 seconds, which aligns with Discord’s default behavior).

Here’s an adjusted approach for the DM part:

if(activeTickets[channel.id]){
    const user = await bot.users.fetch(activeTickets[channel.id].memberID);
    const dmChannel = await user.createDM();
    dmChannel.startTyping();
}

To manage the typing indicator, keep track of the typing state and utilize setTimeout() to turn it off. This way, if a user starts typing again before the timeout expires, the timer can be cleared.

discord.js doesn’t have a typingStop event, so you’ll need to handle timeouts yourself. also, startTyping() only works on channels, not user objects - that’s why you’re getting the error. try storing typing timers in a Map and clearing them when new typing starts.