]> git.giacomolli.uk - onechat/blobdiff - telegram.go
Open the chat when no command is given
[onechat] / telegram.go
index c560104c52b83cb4d590d60b939c2de04af277f2..e77ea69de90e5a69c3047b6bb2c7a20a5f8273c3 100644 (file)
@@ -160,10 +160,15 @@ type TelegramBot struct {
 }
 
 // Notify queues event for the chat. It never blocks, so a slow network does not
 }
 
 // Notify queues event for the chat. It never blocks, so a slow network does not
-// stop the agent.
+// stop the agent. The WhatsApp batches and the runs of the schedules do not go
+// to the chat: the reply of the agent tells the user what needs the user.
 func (b *TelegramBot) Notify(event Event) {
        switch event.Kind {
 func (b *TelegramBot) Notify(event Event) {
        switch event.Kind {
-       case "busy", "idle", "reply", "error", "notice", "subagent", "work":
+       case "busy", "idle", "reply", "error", "notice", "subagent":
+       case "work":
+               if event.Source == whatsappSource || event.Source == scheduleSource {
+                       return
+               }
        case "user":
                if event.Source == telegramSource {
                        return
        case "user":
                if event.Source == telegramSource {
                        return
@@ -185,7 +190,7 @@ func (b *TelegramBot) Notify(event Event) {
 // Run polls for the messages of the owner and sends the queued events to the
 // chat until ctx ends. It returns an error only when a message or the offset
 // cannot be written, because then the bot would lose or repeat messages.
 // Run polls for the messages of the owner and sends the queued events to the
 // chat until ctx ends. It returns an error only when a message or the offset
 // cannot be written, because then the bot would lose or repeat messages.
-func (b *TelegramBot) Run(ctx context.Context, l *TurnLoop) error {
+func (b *TelegramBot) Run(ctx context.Context, l *TurnLoop, whatsapp *WhatsApp) error {
        ctx, cancel := context.WithCancel(ctx)
        defer cancel()
 
        ctx, cancel := context.WithCancel(ctx)
        defer cancel()
 
@@ -197,7 +202,7 @@ func (b *TelegramBot) Run(ctx context.Context, l *TurnLoop) error {
                b.send(ctx)
        }()
 
                b.send(ctx)
        }()
 
-       err := b.poll(ctx, l)
+       err := b.poll(ctx, l, whatsapp)
        cancel()
        sender.Wait()
 
        cancel()
        sender.Wait()
 
@@ -247,7 +252,7 @@ func (b *TelegramBot) send(ctx context.Context) {
 // poll gets the updates from the stored offset on and handles each one, until
 // ctx ends. Each update is handled to its end also when ctx ends during it, so
 // a stop does not repeat its message.
 // poll gets the updates from the stored offset on and handles each one, until
 // ctx ends. Each update is handled to its end also when ctx ends during it, so
 // a stop does not repeat its message.
-func (b *TelegramBot) poll(ctx context.Context, l *TurnLoop) error {
+func (b *TelegramBot) poll(ctx context.Context, l *TurnLoop, whatsapp *WhatsApp) error {
        offset, err := telegramLoadOffset(b.offsetPath)
        if err != nil {
                return err
        offset, err := telegramLoadOffset(b.offsetPath)
        if err != nil {
                return err
@@ -273,7 +278,7 @@ func (b *TelegramBot) poll(ctx context.Context, l *TurnLoop) error {
                                return nil
                        }
 
                                return nil
                        }
 
-                       err = b.handle(context.WithoutCancel(ctx), l, update)
+                       err = b.handle(context.WithoutCancel(ctx), l, whatsapp, update)
                        if err != nil {
                                return err
                        }
                        if err != nil {
                                return err
                        }
@@ -349,10 +354,12 @@ func (b *TelegramBot) pause(ctx context.Context, err error, wait, asked time.Dur
 
 // handle runs one update. A text message of the owner in the private chat goes
 // to the agent, and handle returns when it is durable in the log. The line
 
 // handle runs one update. A text message of the owner in the private chat goes
 // to the agent, and handle returns when it is durable in the log. The line
-// /stop interrupts the turn, and the line /stop NAME stops the subagent NAME.
-// Any other message of the owner gets the answer that only text is supported.
-// Every other update is ignored, and its content is not logged.
-func (b *TelegramBot) handle(ctx context.Context, l *TurnLoop, update TelegramUpdate) error {
+// /stop interrupts the turn, the line /stop NAME stops the subagent NAME, and a
+// line that starts with /whatsapp runs a WhatsApp command on whatsapp, whose
+// answers go to the chat only. Any other message of the owner gets the answer
+// that only text is supported. Every other update is ignored, and its content
+// is not logged.
+func (b *TelegramBot) handle(ctx context.Context, l *TurnLoop, whatsapp *WhatsApp, update TelegramUpdate) error {
        message := update.Message
        if message == nil || message.Chat.Type != "private" || message.Chat.ID != b.owner || message.From == nil || message.From.ID != b.owner {
                b.logger.Print("update ignored: not a message of the owner in the private chat")
        message := update.Message
        if message == nil || message.Chat.Type != "private" || message.Chat.ID != b.owner || message.From == nil || message.From.ID != b.owner {
                b.logger.Print("update ignored: not a message of the owner in the private chat")
@@ -360,6 +367,7 @@ func (b *TelegramBot) handle(ctx context.Context, l *TurnLoop, update TelegramUp
        }
 
        name, stop := stopSubagentName(message.Text)
        }
 
        name, stop := stopSubagentName(message.Text)
+       args, isWhatsApp := whatsappCommandArgs(message.Text)
        switch {
        case message.Text == "":
                b.notice(telegramTextOnly)
        switch {
        case message.Text == "":
                b.notice(telegramTextOnly)
@@ -376,6 +384,8 @@ func (b *TelegramBot) handle(ctx context.Context, l *TurnLoop, update TelegramUp
                if !found {
                        b.notice("No subagent " + name + " runs.")
                }
                if !found {
                        b.notice("No subagent " + name + " runs.")
                }
+       case isWhatsApp:
+               whatsapp.Command(args, b.notice)
        default:
                _, err := l.Submit(telegramSource, message.Text)
                if err != nil {
        default:
                _, err := l.Submit(telegramSource, message.Text)
                if err != nil {