func yourHandler() { // the "recording audio" notification will be sent if we're not able to get the voice generated within 2 seconds. cancelNotify := b.sendNotifyAction(ctx, chat, notifyGraceTime) voice, cl, genErr := gen.ForUser(ctx, user, text) cancelNotify() // ... } // sendNotifyAction sends the "recording" notification if the gracePeriod expires // before cancelFn function is called. func (b *Bot) sendNotifyAction(ctx context.Context, r tb.Recipient, gracePeriod time.Duration) (cancelFn func()) { timeoutCtx, cancel := context.WithTimeout(ctx, 5*time.Minute) // this should never happen, just in case go func() { region := trace.StartRegion(timeoutCtx, "sendNotifyAction") defer region.End() select { case <-time.After(gracePeriod): trace.Logf(ctx, "notify", "sending notify action") if err := b.bot.Notify(r, tb.RecordingAudio); err != nil { dlog.Printf("%s: notification error: %s", caller(0), err) } case <-timeoutCtx.Done(): trace.Logf(timeoutCtx, "notify", timeoutCtx.Err().Error()) return } }() return cancel }