Projeto bot pontos

This commit is contained in:
2026-10-23 22:31:02 -03:00
parent 29614855ff
commit b35e1a7d69
116 changed files with 14523 additions and 0 deletions

View File

@@ -0,0 +1,78 @@
package app
import (
"fmt"
"time"
"botpontos/internal/domain"
"botpontos/internal/rules"
)
// Textos enviados pelo Telegram. Ficam juntos para facilitar a revisão.
func msgNewRegistration(u domain.User) string {
return fmt.Sprintf("Novo pedido de cadastro: %s (ID %d).\n"+
"Configure a credencial da PontoMais no painel e ative com /ativarusuario %d ou pelo painel.",
u.DisplayName, u.ID, u.ID)
}
const msgActivated = "Seu cadastro foi aprovado. Envie /ativarponto para ligar os lembretes e /ajuda para ver os comandos."
const msgDisabledByAdmin = "Seu acesso ao Bot de Pontos foi desativado por um administrador."
func msgPausedAPIFailures(failures int) string {
return fmt.Sprintf("Não consegui consultar a PontoMais %d vezes seguidas, então pausei seus lembretes.\n"+
"Confira com o administrador se sua credencial está correta e depois envie /ativarponto.", failures)
}
func msgAdminUserPaused(u domain.User, failures int, err error) string {
return fmt.Sprintf("Lembretes de %s (ID %d) pausados após %d falhas seguidas na PontoMais.\nÚltimo erro: %s",
u.DisplayName, u.ID, failures, shortError(err))
}
func msgOutageStarted(users int, err error) string {
return fmt.Sprintf("A PontoMais parece fora do ar: as consultas de %d usuários falharam no mesmo ciclo.\n"+
"Ninguém foi pausado. Último erro: %s", users, shortError(err))
}
func msgOutageEnded(duration time.Duration) string {
return fmt.Sprintf("A PontoMais voltou a responder. A queda durou cerca de %s.", formatDuration(duration))
}
func msgHolidayFallback(year int, err error) string {
return fmt.Sprintf("Não consegui obter os feriados de %d (%s).\n"+
"Enquanto isso, segunda a sexta contam como dias úteis. Cadastre feriados manualmente no painel se necessário.",
year, shortError(err))
}
func msgScheduleViolations(names []string, interval time.Duration) string {
return fmt.Sprintf("Estes usuários têm almoço − antecedência menor que o intervalo de reconciliação (%s) e podem receber "+
"o lembrete de retorno atrasado: %v. Ajuste a jornada no painel.", formatDuration(interval), names)
}
// msgReminder é o lembrete automático; sempre informa o horário previsto (9.3).
func msgReminder(n domain.Notification, loc *time.Location, schedule domain.WorkSchedule, now time.Time) string {
clock := rules.FormatClock(n.PredictedAt, loc)
late := now.After(n.PredictedAt)
switch n.Type {
case domain.NotificationEntrada2:
if late {
return "⏰ Lembrete: seu retorno do almoço estava previsto para " + clock + "."
}
return "⏰ Lembrete: seu retorno do almoço está previsto para " + clock + "."
default:
jornada := rules.FormatMinutes(schedule.DailyWorkMinutes)
if late {
return "⏰ Lembrete: sua saída estava prevista para " + clock + " (jornada de " + jornada + ")."
}
return "⏰ Lembrete: sua saída está prevista para " + clock + " (jornada de " + jornada + ")."
}
}
func formatDuration(d time.Duration) string {
minutes := int(d.Round(time.Minute) / time.Minute)
if minutes < 60 {
return fmt.Sprintf("%d min", minutes)
}
return rules.FormatMinutes(minutes)
}