]> git.giacomolli.uk - onechat/blob - whatsapp_batch.go
Retry the first WhatsApp connection
[onechat] / whatsapp_batch.go
1 package main
2
3 import (
4         "slices"
5         "strings"
6         "time"
7 )
8
9 const (
10         // whatsappBatchEmptyReply is the last line of a batch that starts a
11         // turn.
12         whatsappBatchEmptyReply = "If nothing in this batch needs the user, end your turn with an empty reply."
13
14         // whatsappBatchDayLayout is the layout of the day in the first line of
15         // a batch.
16         whatsappBatchDayLayout = "Monday 2006-01-02"
17 )
18
19 // WhatsAppBatch is one batch of the messages of one chat, with the arrival
20 // times of its first and its last message.
21 type WhatsAppBatch struct {
22         Number   int               `json:"number"`
23         Chat     WhatsAppChat      `json:"chat"`
24         Closed   bool              `json:"closed"`
25         First    time.Time         `json:"first"`
26         Last     time.Time         `json:"last"`
27         Messages []WhatsAppMessage `json:"messages"`
28 }
29
30 // Turn tells if the batch starts a turn: a private batch with a message of
31 // another person, or a group batch with a message of another person that
32 // mentions the user or replies to a message of the user.
33 func (b WhatsAppBatch) Turn() bool {
34         return slices.ContainsFunc(b.Messages, func(message WhatsAppMessage) bool {
35                 return !message.Mine && (!b.Chat.Group || message.Mention || message.Reply)
36         })
37 }
38
39 // Text returns the text of the batch for the log, with the times in location.
40 // The first line starts with [WhatsApp] and names the chat, its ID, and the day
41 // of the first message. Each message has a line with its time and its sender,
42 // and the messages of the user have the sender You. A batch that starts a turn
43 // ends with the line about the empty reply.
44 func (b WhatsAppBatch) Text(location *time.Location) string {
45         kind := "private chat"
46         if b.Chat.Group {
47                 kind = "group"
48         }
49
50         lines := []string{"[WhatsApp] " + b.Chat.Name + ", " + kind + " " + b.Chat.ID + ", " + b.Messages[0].Time.In(location).Format(whatsappBatchDayLayout)}
51         for _, message := range b.Messages {
52                 sender := message.Sender
53                 switch {
54                 case message.Mine:
55                         sender = "You"
56                 case message.Mention:
57                         sender += " (mentions you)"
58                 case message.Reply:
59                         sender += " (replies to you)"
60                 }
61
62                 lines = append(lines, message.Time.In(location).Format("15:04")+" "+sender+": "+message.Text)
63         }
64
65         if b.Turn() {
66                 lines = append(lines, whatsappBatchEmptyReply)
67         }
68
69         return strings.Join(lines, "\n")
70 }
71
72 // WhatsAppChat is a chat: its ID, its name, and whether it is a group.
73 type WhatsAppChat struct {
74         ID    string `json:"id"`
75         Name  string `json:"name"`
76         Group bool   `json:"group,omitempty"`
77 }
78
79 // WhatsAppMessage is one text message of a batch: its ID, the name of its
80 // sender, its WhatsApp time, and its text. Mine marks a message of the user.
81 // Mention and Reply mark a message that mentions the user or replies to a
82 // message of the user.
83 type WhatsAppMessage struct {
84         ID      string    `json:"id"`
85         Sender  string    `json:"sender"`
86         Time    time.Time `json:"time"`
87         Text    string    `json:"text"`
88         Mine    bool      `json:"mine,omitempty"`
89         Mention bool      `json:"mention,omitempty"`
90         Reply   bool      `json:"reply,omitempty"`
91 }