feat(whatsapp): align with other channels code; handle reconnects
This commit is contained in:
parent
60c12072d0
commit
49076fdfe8
3 changed files with 42 additions and 16 deletions
|
|
@ -45,12 +45,17 @@ func (c *WhatsmeowChannel) Start(ctx context.Context) error {
|
||||||
dbPath := expandHomePath(c.config.DBPath)
|
dbPath := expandHomePath(c.config.DBPath)
|
||||||
|
|
||||||
// Ensure directory exists
|
// Ensure directory exists
|
||||||
if err := os.MkdirAll(filepath.Dir(dbPath), 0755); err != nil {
|
if err := os.MkdirAll(filepath.Dir(dbPath), 0o755); err != nil {
|
||||||
return fmt.Errorf("failed to create db directory: %w", err)
|
return fmt.Errorf("failed to create db directory: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
dbLog := waLog.Noop
|
dbLog := waLog.Noop
|
||||||
container, err := sqlstore.New(ctx, "sqlite", fmt.Sprintf("file:%s?_pragma=foreign_keys(1)&_pragma=journal_mode(WAL)", dbPath), dbLog)
|
container, err := sqlstore.New(
|
||||||
|
ctx,
|
||||||
|
"sqlite",
|
||||||
|
fmt.Sprintf("file:%s?_pragma=foreign_keys(1)&_pragma=journal_mode(WAL)", dbPath),
|
||||||
|
dbLog,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to open whatsmeow db: %w", err)
|
return fmt.Errorf("failed to open whatsmeow db: %w", err)
|
||||||
}
|
}
|
||||||
|
|
@ -129,16 +134,18 @@ func (c *WhatsmeowChannel) Send(ctx context.Context, msg bus.OutboundMessage) er
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *WhatsmeowChannel) eventHandler(evt interface{}) {
|
func (c *WhatsmeowChannel) eventHandler(evt any) {
|
||||||
switch v := evt.(type) {
|
switch v := evt.(type) {
|
||||||
case *events.Message:
|
case *events.Message:
|
||||||
c.handleIncomingMessage(v)
|
c.handleIncomingMessage(v)
|
||||||
case *events.Connected:
|
case *events.Connected:
|
||||||
logger.InfoC("whatsmeow", "WhatsApp connected")
|
logger.InfoC("whatsmeow", "WhatsApp connected")
|
||||||
|
c.setRunning(true)
|
||||||
case *events.Disconnected:
|
case *events.Disconnected:
|
||||||
logger.WarnC("whatsmeow", "WhatsApp disconnected")
|
logger.WarnC("whatsmeow", "WhatsApp disconnected")
|
||||||
|
c.setRunning(false)
|
||||||
case *events.LoggedOut:
|
case *events.LoggedOut:
|
||||||
logger.ErrorCF("whatsmeow", "WhatsApp logged out", map[string]interface{}{
|
logger.ErrorCF("whatsmeow", "WhatsApp logged out", map[string]any{
|
||||||
"reason": v.Reason,
|
"reason": v.Reason,
|
||||||
})
|
})
|
||||||
c.setRunning(false)
|
c.setRunning(false)
|
||||||
|
|
@ -177,6 +184,16 @@ func (c *WhatsmeowChannel) handleIncomingMessage(msg *events.Message) {
|
||||||
|
|
||||||
// Handle media
|
// Handle media
|
||||||
var mediaPaths []string
|
var mediaPaths []string
|
||||||
|
defer func() {
|
||||||
|
for _, file := range mediaPaths {
|
||||||
|
if err := os.Remove(file); err != nil {
|
||||||
|
logger.DebugCF("whatsmeow", "Failed to cleanup temp file", map[string]any{
|
||||||
|
"file": file,
|
||||||
|
"error": err.Error(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
if img := msg.Message.GetImageMessage(); img != nil {
|
if img := msg.Message.GetImageMessage(); img != nil {
|
||||||
if path, err := c.downloadMedia(img, ".jpg"); err == nil {
|
if path, err := c.downloadMedia(img, ".jpg"); err == nil {
|
||||||
|
|
@ -225,11 +242,11 @@ func (c *WhatsmeowChannel) handleIncomingMessage(msg *events.Message) {
|
||||||
metadata["peer_kind"] = "group"
|
metadata["peer_kind"] = "group"
|
||||||
metadata["peer_id"] = msg.Info.Chat.User
|
metadata["peer_id"] = msg.Info.Chat.User
|
||||||
} else {
|
} else {
|
||||||
metadata["peer_kind"] = "dm"
|
metadata["peer_kind"] = "direct"
|
||||||
metadata["peer_id"] = msg.Info.Sender.User
|
metadata["peer_id"] = msg.Info.Sender.User
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.InfoCF("whatsmeow", "Message received", map[string]interface{}{
|
logger.InfoCF("whatsmeow", "Message received", map[string]any{
|
||||||
"sender": senderID,
|
"sender": senderID,
|
||||||
"chat": chatID,
|
"chat": chatID,
|
||||||
"len": len(content),
|
"len": len(content),
|
||||||
|
|
@ -250,21 +267,21 @@ func (c *WhatsmeowChannel) downloadMedia(msg whatsmeow.DownloadableMessage, ext
|
||||||
|
|
||||||
data, err := client.Download(c.ctx, msg)
|
data, err := client.Download(c.ctx, msg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.ErrorCF("whatsmeow", "Failed to download media", map[string]interface{}{
|
logger.ErrorCF("whatsmeow", "Failed to download media", map[string]any{
|
||||||
"error": err.Error(),
|
"error": err.Error(),
|
||||||
})
|
})
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
dir := filepath.Join(os.TempDir(), "picoclaw_media")
|
dir := filepath.Join(os.TempDir(), "picoclaw_media")
|
||||||
if err := os.MkdirAll(dir, 0700); err != nil {
|
if err := os.MkdirAll(dir, 0o700); err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
filename := fmt.Sprintf("wa_%d%s", time.Now().UnixNano(), ext)
|
filename := fmt.Sprintf("wa_%d%s", time.Now().UnixNano(), ext)
|
||||||
path := filepath.Join(dir, filename)
|
path := filepath.Join(dir, filename)
|
||||||
|
|
||||||
if err := os.WriteFile(path, data, 0600); err != nil {
|
if err := os.WriteFile(path, data, 0o600); err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,6 @@ import (
|
||||||
"go.mau.fi/whatsmeow/store/sqlstore"
|
"go.mau.fi/whatsmeow/store/sqlstore"
|
||||||
"go.mau.fi/whatsmeow/types/events"
|
"go.mau.fi/whatsmeow/types/events"
|
||||||
waLog "go.mau.fi/whatsmeow/util/log"
|
waLog "go.mau.fi/whatsmeow/util/log"
|
||||||
|
|
||||||
_ "modernc.org/sqlite"
|
_ "modernc.org/sqlite"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -23,12 +22,17 @@ func LinkWhatsmeow(dbPath string, mode string) error {
|
||||||
dbPath = expandHomePath(dbPath)
|
dbPath = expandHomePath(dbPath)
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
if err := os.MkdirAll(filepath.Dir(dbPath), 0755); err != nil {
|
if err := os.MkdirAll(filepath.Dir(dbPath), 0o755); err != nil {
|
||||||
return fmt.Errorf("failed to create db directory: %w", err)
|
return fmt.Errorf("failed to create db directory: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
dbLog := waLog.Noop
|
dbLog := waLog.Noop
|
||||||
container, err := sqlstore.New(ctx, "sqlite", fmt.Sprintf("file:%s?_pragma=foreign_keys(1)&_pragma=journal_mode(WAL)", dbPath), dbLog)
|
container, err := sqlstore.New(
|
||||||
|
ctx,
|
||||||
|
"sqlite",
|
||||||
|
fmt.Sprintf("file:%s?_pragma=foreign_keys(1)&_pragma=journal_mode(WAL)", dbPath),
|
||||||
|
dbLog,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to open whatsmeow db: %w", err)
|
return fmt.Errorf("failed to open whatsmeow db: %w", err)
|
||||||
}
|
}
|
||||||
|
|
@ -49,7 +53,7 @@ func LinkWhatsmeow(dbPath string, mode string) error {
|
||||||
|
|
||||||
// Listen for Connected event to know when initial sync is done
|
// Listen for Connected event to know when initial sync is done
|
||||||
connected := make(chan struct{}, 1)
|
connected := make(chan struct{}, 1)
|
||||||
client.AddEventHandler(func(evt interface{}) {
|
client.AddEventHandler(func(evt any) {
|
||||||
switch evt.(type) {
|
switch evt.(type) {
|
||||||
case *events.Connected:
|
case *events.Connected:
|
||||||
select {
|
select {
|
||||||
|
|
@ -120,7 +124,12 @@ func WhatsmeowStatus(dbPath string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
container, err := sqlstore.New(ctx, "sqlite", fmt.Sprintf("file:%s?_pragma=foreign_keys(1)&_pragma=journal_mode(WAL)", dbPath), waLog.Noop)
|
container, err := sqlstore.New(
|
||||||
|
ctx,
|
||||||
|
"sqlite",
|
||||||
|
fmt.Sprintf("file:%s?_pragma=foreign_keys(1)&_pragma=journal_mode(WAL)", dbPath),
|
||||||
|
waLog.Noop,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to open db: %w", err)
|
return fmt.Errorf("failed to open db: %w", err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue