]> git.giacomolli.uk - onechat/blobdiff - whatsapp_inbox.go
Send stored images to WhatsApp chats
[onechat] / whatsapp_inbox.go
index 5121976c6d00307e8e227a57cdca558a11a64a9b..9d2183e7d5e282a96442f35ba13d0a7cf58ec1a1 100644 (file)
@@ -16,12 +16,20 @@ import (
 )
 
 const (
 )
 
 const (
+       // whatsappContactLookupTimeout is the longest time of a read of names
+       // in the session.
+       whatsappContactLookupTimeout = 10 * time.Second
+
+       // whatsappImageDownloadTimeout is the longest time of an image
+       // download.
+       whatsappImageDownloadTimeout = 2 * time.Minute
+
        // whatsappSource is the source of the work events of the batches.
        whatsappSource = "whatsapp"
 
        // whatsappSource is the source of the work events of the batches.
        whatsappSource = "whatsapp"
 
-       // whatsappCatchupLimit is the longest wait for the end of the catch-up
-       // after a connection.
-       whatsappCatchupLimit = time.Minute
+       // whatsappCatchupTimeout is the longest wait for the end of the
+       // catch-up after a connection.
+       whatsappCatchupTimeout = time.Minute
 )
 
 // newWhatsAppInbox returns the inbox of the batches in state, with clock for
 )
 
 // newWhatsAppInbox returns the inbox of the batches in state, with clock for
@@ -29,16 +37,13 @@ const (
 // holds shared images, and logger gets image failures.
 func newWhatsAppInbox(state *WhatsAppState, clock func() time.Time, groups *WhatsAppGroups, images *ImageStore, logger *slog.Logger) *WhatsAppInbox {
        return &WhatsAppInbox{
 // holds shared images, and logger gets image failures.
 func newWhatsAppInbox(state *WhatsAppState, clock func() time.Time, groups *WhatsAppGroups, images *ImageStore, logger *slog.Logger) *WhatsAppInbox {
        return &WhatsAppInbox{
-               state:        state,
-               clock:        clock,
-               groups:       groups,
-               images:       images,
-               logger:       logger,
-               lookupTime:   whatsappLookupTime,
-               imageTime:    whatsappImageTime,
-               catchupLimit: whatsappCatchupLimit,
-               wake:         make(chan struct{}, 1),
-               failures:     make(chan error, 1),
+               state:    state,
+               clock:    clock,
+               groups:   groups,
+               images:   images,
+               logger:   logger,
+               wake:     make(chan struct{}, 1),
+               failures: make(chan error, 1),
        }
 }
 
        }
 }
 
@@ -48,16 +53,16 @@ func newWhatsAppInbox(state *WhatsAppState, clock func() time.Time, groups *What
 //
 // After each connection, the servers send the messages that came while the
 // daemon was away, and then OfflineSyncCompleted. Until then, or until
 //
 // After each connection, the servers send the messages that came while the
 // daemon was away, and then OfflineSyncCompleted. Until then, or until
-// catchupLimit passes, the closed batches wait in the state file. At the end of
-// the catch-up, deliver closes all batches and logs them. It wakes the root
-// once for its batches, so their catch-up gives one turn, not one for each
-// chat. The batches of the state file at the start wait for the first catch-up
-// in the same way. The event handler acknowledges a message only after the
-// state file holds it, so the servers send again a message that a crash lost. A
-// batch leaves the state file only after its work message is durable in the log
-// or agent queue. A crash between the two can repeat an unrouted batch once. A
-// routed batch enters the durable agent queue, which prevents a second log
-// entry and wakes only the child. A missing child uses the root.
+// whatsappCatchupTimeout passes, the closed batches wait in the state file. At
+// the end of the catch-up, deliver closes all batches and logs them. It wakes
+// the root once for its batches, so their catch-up gives one turn, not one for
+// each chat. The batches of the state file at the start wait for the first
+// catch-up in the same way. The event handler acknowledges a message only after
+// the state file holds it, so the servers send again a message that a crash
+// lost. A batch leaves the state file only after its work message is durable in
+// the log or agent queue. A crash between the two can repeat an unrouted batch
+// once. A routed batch enters the durable agent queue, which prevents a second
+// log entry and wakes only the child. A missing child uses the root.
 //
 // The state file is the one of WhatsApp, which keeps the send records in it
 // too. groups gives the names of the groups. The mutex protects the state of
 //
 // The state file is the one of WhatsApp, which keeps the send records in it
 // too. groups gives the names of the groups. The mutex protects the state of
@@ -65,16 +70,13 @@ func newWhatsAppInbox(state *WhatsAppState, clock func() time.Time, groups *What
 // goroutines. wake tells Run that a batch can be due or that a catch-up ended,
 // and failures gives Run the error of a write of the state file.
 type WhatsAppInbox struct {
 // goroutines. wake tells Run that a batch can be due or that a catch-up ended,
 // and failures gives Run the error of a write of the state file.
 type WhatsAppInbox struct {
-       state        *WhatsAppState
-       clock        func() time.Time
-       groups       *WhatsAppGroups
-       images       *ImageStore
-       logger       *slog.Logger
-       lookupTime   time.Duration
-       imageTime    time.Duration
-       catchupLimit time.Duration
-       wake         chan struct{}
-       failures     chan error
+       state    *WhatsAppState
+       clock    func() time.Time
+       groups   *WhatsAppGroups
+       images   *ImageStore
+       logger   *slog.Logger
+       wake     chan struct{}
+       failures chan error
 
        mutex        sync.Mutex
        catchingUp   bool
 
        mutex        sync.Mutex
        catchingUp   bool
@@ -206,7 +208,7 @@ func (i *WhatsAppInbox) waitForCatchup() {
 }
 
 // startCatchup starts the catch-up of a new connection, which ends at
 }
 
 // startCatchup starts the catch-up of a new connection, which ends at
-// endCatchup or after catchupLimit.
+// endCatchup or after whatsappCatchupTimeout.
 func (i *WhatsAppInbox) startCatchup() {
        i.mutex.Lock()
        defer i.mutex.Unlock()
 func (i *WhatsAppInbox) startCatchup() {
        i.mutex.Lock()
        defer i.mutex.Unlock()
@@ -218,7 +220,7 @@ func (i *WhatsAppInbox) startCatchup() {
                i.catchupTimer.Stop()
        }
 
                i.catchupTimer.Stop()
        }
 
-       i.catchupTimer = time.AfterFunc(i.catchupLimit, func() {
+       i.catchupTimer = time.AfterFunc(whatsappCatchupTimeout, func() {
                i.caughtUpBy(catchups)
        })
 }
                i.caughtUpBy(catchups)
        })
 }
@@ -228,17 +230,17 @@ func (i *WhatsAppInbox) startCatchup() {
 // message, so that the library does not acknowledge it, and Run stops the
 // daemon. An image that cannot be downloaded or stored gets a text marker. A
 // message that the batches do not take is handled with nothing to do.
 // message, so that the library does not acknowledge it, and Run stops the
 // daemon. An image that cannot be downloaded or stored gets a text marker. A
 // message that the batches do not take is handled with nothing to do.
-func (i *WhatsAppInbox) receive(link WhatsAppLink, event *events.Message) bool {
-       ctx, cancel := context.WithTimeout(context.Background(), i.lookupTime)
+func (i *WhatsAppInbox) receive(ctx context.Context, link WhatsAppLink, event *events.Message) bool {
+       lookupCtx, cancel := context.WithTimeout(ctx, whatsappContactLookupTimeout)
        defer cancel()
 
        defer cancel()
 
-       chat, message, found := whatsappMessage(ctx, link.device, link.own, event)
+       chat, message, found := whatsappMessage(lookupCtx, link.device, link.own, event)
        if !found {
                return true
        }
 
        if event.Message.GetImageMessage() != nil {
        if !found {
                return true
        }
 
        if event.Message.GetImageMessage() != nil {
-               ctx, cancel := context.WithTimeout(context.Background(), i.imageTime)
+               ctx, cancel := context.WithTimeout(ctx, whatsappImageDownloadTimeout)
                defer cancel()
 
                message.Text = i.imageText(ctx, link, event, message.Text)
                defer cancel()
 
                message.Text = i.imageText(ctx, link, event, message.Text)