Files
meowlib/client/helpers/messageHelper.go
ycc 0fdf5dd9c7
Some checks failed
continuous-integration/drone/push Build is failing
simplify send message bg helper
2026-03-01 21:15:17 +01:00

184 lines
6.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package helpers
import (
"os"
"path/filepath"
"strconv"
"strings"
"time"
"forge.redroom.link/yves/meowlib"
"forge.redroom.link/yves/meowlib/client"
)
func PackMessageForServer(packedMsg *meowlib.PackedUserMessage, srvuid string) ([]byte, string, error) {
// Get the message server
srv, err := client.GetConfig().GetIdentity().MessageServers.LoadServer(srvuid)
if err != nil {
return nil, "messageBuildPostprocess : LoadServer", err
}
// Creating Server message for transporting the user message
toServerMessage := srv.BuildToServerMessageFromUserMessage(packedMsg)
data, err := srv.ProcessOutboundMessage(toServerMessage)
if err != nil {
return nil, "messageBuildPostprocess : ProcessOutboundMessage", err
}
return data, "", nil
}
func CreateStorePackUserMessageForServer(message string, srvuid string, peer_uid string, replyToUid string, filelist []string) ([]byte, string, error) {
usermessage, _, _, errtxt, err := CreateAndStoreUserMessage(message, peer_uid, replyToUid, filelist)
if err != nil {
return nil, errtxt, err
}
return PackMessageForServer(usermessage, srvuid)
}
// CreateAndStoreUserMessage creates, signs, and stores an outbound message for
// peer_uid. It returns the packed (encrypted) form ready for server transport,
// the peer DB file UUID (dbFile), the SQLite row ID (dbId), an error context
// string, and any error.
func CreateAndStoreUserMessage(message string, peer_uid string, replyToUid string, filelist []string) (*meowlib.PackedUserMessage, string, int64, string, error) {
peer := client.GetConfig().GetIdentity().Peers.GetFromUid(peer_uid)
// Creating User message
usermessage, err := peer.BuildSimpleUserMessage([]byte(message))
if err != nil {
return nil, "", 0, "PrepareServerMessage : BuildSimpleUserMessage", err
}
for _, file := range filelist {
err = usermessage.AddFile(file, client.GetConfig().Chunksize)
if err != nil {
return nil, "", 0, "PrepareServerMessage : AddFile", err
}
}
usermessage.Status.Sent = uint64(time.Now().UTC().Unix())
usermessage.Status.AnswerToUuid = replyToUid
// Store message
err = peer.StoreMessage(usermessage, nil)
if err != nil {
return nil, "", 0, "messageBuildPostprocess : StoreMessage", err
}
dbFile := peer.LastMessage.Dbfile
dbId := peer.LastMessage.Dbid
// Prepare cyphered + packed user message
packedMsg, err := peer.ProcessOutboundUserMessage(usermessage)
if err != nil {
return nil, "", 0, "messageBuildPostprocess : ProcessOutboundUserMessage", err
}
return packedMsg, dbFile, dbId, "", nil
}
func BuildAckMessage(messageUid string, srvuid string, peer_uid string, received int64, processed int64) ([]byte, string, error) {
peer := client.GetConfig().GetIdentity().Peers.GetFromUid(peer_uid)
srv, err := client.GetConfig().GetIdentity().MessageServers.LoadServer(srvuid)
if err != nil {
return nil, "PrepareServerMessage : LoadServer", err
}
// Creating User message
usermessage, err := peer.BuildSimpleUserMessage(nil)
if err != nil {
return nil, "PrepareServerMessage : BuildSimpleUserMessage", err
}
usermessage.Status.Uuid = messageUid
usermessage.Status.Received = uint64(received)
usermessage.Status.Processed = uint64(processed)
// Prepare cyphered + packed user message
packedMsg, err := peer.ProcessOutboundUserMessage(usermessage)
if err != nil {
return nil, "PrepareServerMessage : ProcessOutboundUserMessage", err
}
// Creating Server message for transporting the user message
toServerMessage := srv.BuildToServerMessageFromUserMessage(packedMsg)
data, err := srv.ProcessOutboundMessage(toServerMessage)
if err != nil {
return nil, "PrepareServerMessage : ProcessOutboundMessage", err
}
return data, "", nil
}
func ReadAckMessageResponse() {
//! update the status in message store
}
// ProcessSentMessages scans every send queue under storagePath/queues/, updates
// the message storage entry with server delivery info for each sent job, then
// removes the job from the queue. Returns the number of messages updated.
//
// The message DB location is recovered from the job's File basename, which must
// follow the naming convention produced by CreateUserMessageAndSendJob:
//
// outbox/{dbFile}_{dbId}
func ProcessSentMessages(storagePath string) int {
password, _ := client.GetConfig().GetMemPass()
queueDir := filepath.Join(storagePath, "queues")
entries, err := os.ReadDir(queueDir)
if err != nil {
logger.Warn().Err(err).Str("dir", queueDir).Msg("ProcessSentMessages: ReadDir")
return 0
}
updated := 0
for _, entry := range entries {
if entry.IsDir() {
continue
}
queue := entry.Name()
jobs, err := client.GetSentJobs(storagePath, queue)
if err != nil {
logger.Error().Err(err).Str("queue", queue).Msg("ProcessSentMessages: GetSentJobs")
continue
}
for _, job := range jobs {
if job.SuccessfulServer == nil || job.SentAt == nil {
// No delivery info discard the job so it doesn't block the queue
if err := client.DeleteSendJob(storagePath, queue, job.ID); err != nil {
logger.Error().Err(err).Int64("id", job.ID).Msg("ProcessSentMessages: DeleteSendJob (incomplete)")
}
continue
}
// Recover dbFile and dbId from the outbox filename: {dbFile}_{dbId}
base := filepath.Base(job.File)
sep := strings.LastIndex(base, "_")
if sep <= 0 {
logger.Error().Int64("id", job.ID).Str("file", job.File).
Msg("ProcessSentMessages: cannot parse dbFile/dbId from job filename — use CreateUserMessageAndSendJob to build jobs")
continue
}
dbFile := base[:sep]
dbId, parseErr := strconv.ParseInt(base[sep+1:], 10, 64)
if parseErr != nil || dbFile == "" || dbId == 0 {
logger.Error().Int64("id", job.ID).Str("file", job.File).
Msg("ProcessSentMessages: invalid dbFile/dbId in job filename")
continue
}
serverUid := job.Servers[*job.SuccessfulServer].GetUid()
receiveTime := uint64(job.SentAt.Unix())
if err := client.SetMessageServerDelivery(dbFile, dbId, serverUid, receiveTime, password); err != nil {
logger.Error().Err(err).Str("queue", queue).
Str("dbFile", dbFile).Int64("dbId", dbId).
Msg("ProcessSentMessages: SetMessageServerDelivery")
continue
}
if err := client.DeleteSendJob(storagePath, queue, job.ID); err != nil {
logger.Error().Err(err).Int64("id", job.ID).Msg("ProcessSentMessages: DeleteSendJob")
}
updated++
}
}
return updated
}