c61b0b3968
It reaches the daemon through ipc.CoreAPI and nothing else, so a telegram turn takes the path POST /api/chat already takes: Chat returns the reply and the trace id it collected off the context (V-630), and CorrectTurn writes the label. Nothing in internal/delivery learns what a handler is. Wired on the unlocked start and on the passkey unlock, like the mail intake, so telegram behaves the same either way. A sink that will not build is logged rather than fatal here, because wireDispatcher already failed the boot on the same config.
60 lines
2.0 KiB
Go
60 lines
2.0 KiB
Go
// mavend/telegramintake.go — wiring the inbound telegram poller (V-637).
|
|
//
|
|
// The poller reaches the daemon through ipc.CoreAPI and nothing else, so a
|
|
// telegram turn takes exactly the path the web's POST /api/chat takes: Chat
|
|
// returns the reply and the persisted trace id, and CorrectTurn writes the
|
|
// label. Nothing in internal/delivery knows what a handler is.
|
|
package main
|
|
|
|
import (
|
|
"context"
|
|
"log"
|
|
"sync"
|
|
|
|
"github.com/kami/maven/internal/config"
|
|
"github.com/kami/maven/internal/delivery/telegramsink"
|
|
"github.com/kami/maven/internal/ipc"
|
|
)
|
|
|
|
// wireTelegramIntake starts the poller, or returns having done nothing. It is
|
|
// nil-safe in every argument, because it is called from both boot paths — the
|
|
// unlocked start and the passkey unlock — and telegram must behave the same on
|
|
// either.
|
|
//
|
|
// A sink that will not build is logged rather than fatal here. The push half
|
|
// already failed the boot in wireDispatcher for the same config, so a second
|
|
// hard failure would only lose that message.
|
|
func wireTelegramIntake(ctx context.Context, wg *sync.WaitGroup, api ipc.CoreAPI, cfg *config.Config) {
|
|
if cfg == nil || cfg.Telegram == nil || !cfg.Telegram.Intake || api == nil {
|
|
return
|
|
}
|
|
sink, err := telegramsink.New(*cfg.Telegram)
|
|
if err != nil {
|
|
log.Printf("telegram intake: %v", err)
|
|
return
|
|
}
|
|
poller, err := telegramsink.NewPoller(sink, chatTurnFn(api), api.CorrectTurn)
|
|
if err != nil {
|
|
log.Printf("telegram intake: %v", err)
|
|
return
|
|
}
|
|
wg.Add(1)
|
|
go func() {
|
|
defer wg.Done()
|
|
poller.Run(ctx)
|
|
}()
|
|
}
|
|
|
|
// chatTurnFn adapts ipc.Chat to the poller's Turn. The trace id comes back on
|
|
// the reply because the daemon's Chat collects it off the context (V-630), so
|
|
// the chat can offer the same correction the web does without a second op.
|
|
func chatTurnFn(api ipc.CoreAPI) telegramsink.Turn {
|
|
return func(ctx context.Context, conversation, text string) (string, int64, error) {
|
|
reply, err := api.Chat(ctx, conversation, text)
|
|
if err != nil {
|
|
return "", 0, err
|
|
}
|
|
return reply.Reply, reply.TraceID, nil
|
|
}
|
|
}
|