-// deliver logs the closed batches in l in order, each as a work message of
-// whatsappSource that wakes the loop when the batch starts a turn. A batch
-// leaves the state file after its message is durable in the log. A group with
-// no name gets its name from WhatsApp first.
-func (w *WhatsApp) deliver(ctx context.Context, l *TurnLoop) error {
- _, err := w.batches.CloseDue(time.Now())
- if err != nil {
- return err
- }
-
- for _, batch := range w.batches.Closed() {
- if batch.Chat.Group && batch.Chat.Name == "" {
- batch.Chat.Name = w.groupName(ctx, batch.Chat.ID)
- }
-
- _, err = l.Work(whatsappSource, batch.Text(w.clock().Location()), "", batch.Turn())
- if err != nil {
- return fmt.Errorf("log a WhatsApp batch: %w", err)
- }
-
- // A stop of the daemon during the flush is no failure: the
- // batch stays in the state file and repeats once at the next
- // start.
- err = l.Flush(ctx)
- if ctx.Err() != nil {
- return nil
- }
-
- if err != nil {
- return fmt.Errorf("log a WhatsApp batch: %w", err)
- }
-
- err = w.batches.Remove(batch.Number)
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// deliverAll closes every open batch and logs all of them.
-func (w *WhatsApp) deliverAll(ctx context.Context, l *TurnLoop) error {
- err := w.batches.CloseAll()
- if err != nil {
- return err
- }
-
- return w.deliver(ctx, l)
-}
-
-// groupName returns the name of the group id, or whatsappUnknownGroup. A group
-// that is not in the names of the groups reads the groups from WhatsApp again,
-// at most once in whatsappGroupsRefresh.
-func (w *WhatsApp) groupName(ctx context.Context, id string) string {
- w.mutex.Lock()
- name, found := w.groupNames[id]
- client := w.client
- fresh := time.Since(w.groupsAt) < whatsappGroupsRefresh
- w.mutex.Unlock()
-
- if found {
- return name
- }
-
- if client == nil || fresh {
- return whatsappUnknownGroup
- }
-
- ctx, cancel := context.WithTimeout(ctx, whatsappLookupTime)
- defer cancel()
-
- groups, err := client.GetJoinedGroups(ctx)
- if err != nil {
- w.logger.Printf("read the groups: %s", w.redact(err.Error()))
- }
-
- w.mutex.Lock()
- defer w.mutex.Unlock()
-
- w.groupsAt = time.Now()
- for _, group := range groups {
- w.groupNames[group.JID.String()] = group.Name
- }
-
- name, found = w.groupNames[id]
- if !found || name == "" {
- return whatsappUnknownGroup
- }
-
- return name
-}
-