You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

291 lines
6.1 KiB
Go

package whappdc
import (
"fmt"
"io/ioutil"
"mime"
"github.com/Rhymen/go-whatsapp"
"github.com/hugot/go-deltachat/deltachat"
"github.com/hugot/whapp-deltachat/core"
)
type MessageHandler struct {
Action MessageAction
Jid string
}
type MessageAction func() error
func MakeTextMessageAction(w *WhappContext, m whatsapp.TextMessage) MessageAction {
return func() error {
if !w.ShouldMessageBeSent(m.Info) {
return nil
}
JID := m.Info.RemoteJid
DCID, err := w.GetOrCreateDCIDForJID(JID)
if err != nil {
w.BridgeCtx.SendLog(err.Error())
return err
}
senderName := DetermineSenderName(w.BridgeCtx, m.Info)
w.DCCtx().SendTextMessage(
DCID,
fmt.Sprintf("%s:\n%s", senderName, m.Text),
)
return w.MessageTracker.MarkSent(&m.Info.Id)
}
}
func MakeImageMessageAction(w *WhappContext, m whatsapp.ImageMessage) MessageAction {
return func() error {
if !w.ShouldMessageBeSent(m.Info) {
return nil
}
JID := m.Info.RemoteJid
DCID, err := w.GetOrCreateDCIDForJID(JID)
if err != nil {
w.BridgeCtx.SendLog(err.Error())
return err
}
senderName := DetermineSenderName(w.BridgeCtx, m.Info)
imageData, err := m.Download()
if err != nil {
w.BridgeCtx.SendLog(err.Error())
w.markSentIf404Download(&m.Info.Id, err)
return err
}
filename, err := WriteTempFile(w.BridgeCtx, imageData, "img")
if err != nil {
w.BridgeCtx.SendLog(err.Error())
return err
}
message := w.DCCtx().NewMessage(deltachat.DC_MSG_IMAGE)
defer message.Unref()
message.SetText(fmt.Sprintf("%s:\n%s", senderName, m.Caption))
message.SetFile(filename, m.Type)
w.DCCtx().SendMessage(DCID, message)
return w.MessageTracker.MarkSent(&m.Info.Id)
}
}
func MakeDocumentMessageAction(w *WhappContext, m whatsapp.DocumentMessage) MessageAction {
return func() error {
if !w.ShouldMessageBeSent(m.Info) {
return nil
}
JID := m.Info.RemoteJid
DCID, err := w.GetOrCreateDCIDForJID(JID)
if err != nil {
w.BridgeCtx.SendLog(err.Error())
return err
}
senderName := DetermineSenderName(w.BridgeCtx, m.Info)
documentData, err := m.Download()
if err != nil {
w.BridgeCtx.SendLog(err.Error())
w.markSentIf404Download(&m.Info.Id, err)
return err
}
filename, err := WriteTempFile(w.BridgeCtx, documentData, "doc")
if err != nil {
w.BridgeCtx.SendLog(err.Error())
return err
}
message := w.DCCtx().NewMessage(deltachat.DC_MSG_FILE)
defer message.Unref()
message.SetText(fmt.Sprintf("%s:\n%s", senderName, m.Title))
message.SetFile(filename, m.Type)
w.DCCtx().SendMessage(DCID, message)
return w.MessageTracker.MarkSent(&m.Info.Id)
}
}
func MakeAudioMessageAction(w *WhappContext, m whatsapp.AudioMessage) MessageAction {
return func() error {
if !w.ShouldMessageBeSent(m.Info) {
return nil
}
JID := m.Info.RemoteJid
DCID, err := w.GetOrCreateDCIDForJID(JID)
if err != nil {
w.BridgeCtx.SendLog(err.Error())
return err
}
senderName := DetermineSenderName(w.BridgeCtx, m.Info)
audioData, err := m.Download()
if err != nil {
w.BridgeCtx.SendLog(err.Error())
w.markSentIf404Download(&m.Info.Id, err)
return err
}
filename, err := WriteTempFile(w.BridgeCtx, audioData, "audio")
if err != nil {
w.BridgeCtx.SendLog(err.Error())
return err
}
message := w.DCCtx().NewMessage(deltachat.DC_MSG_AUDIO)
defer message.Unref()
message.SetText(fmt.Sprintf("%s:", senderName))
message.SetFile(filename, m.Type)
w.DCCtx().SendMessage(DCID, message)
return w.MessageTracker.MarkSent(&m.Info.Id)
}
}
func MakeVideoMessageAction(w *WhappContext, m whatsapp.VideoMessage) MessageAction {
return func() error {
if !w.ShouldMessageBeSent(m.Info) {
return nil
}
JID := m.Info.RemoteJid
DCID, err := w.GetOrCreateDCIDForJID(JID)
if err != nil {
w.BridgeCtx.SendLog(err.Error())
return err
}
senderName := DetermineSenderName(w.BridgeCtx, m.Info)
videoData, err := m.Download()
if err != nil {
w.BridgeCtx.SendLog(err.Error())
w.markSentIf404Download(&m.Info.Id, err)
return err
}
filename, err := WriteTempFile(w.BridgeCtx, videoData, "vid")
if err != nil {
w.BridgeCtx.SendLog(err.Error())
return err
}
message := w.DCCtx().NewMessage(deltachat.DC_MSG_VIDEO)
defer message.Unref()
message.SetText(fmt.Sprintf("%s:", senderName))
message.SetFile(filename, m.Type)
w.DCCtx().SendMessage(DCID, message)
return w.MessageTracker.MarkSent(&m.Info.Id)
}
}
// 2020-01-14 10:34 TODO: Find out why this doesn't work.
func MakeContactMessageAction(w *WhappContext, m whatsapp.ContactMessage) MessageAction {
return func() error {
if !w.ShouldMessageBeSent(m.Info) {
return nil
}
JID := m.Info.RemoteJid
DCID, err := w.GetOrCreateDCIDForJID(JID)
if err != nil {
w.BridgeCtx.SendLog(err.Error())
return err
}
senderName := DetermineSenderName(w.BridgeCtx, m.Info)
filename, err := WriteTempFile(w.BridgeCtx, []byte(m.Vcard), "vcf")
if err != nil {
w.BridgeCtx.SendLog(err.Error())
return err
}
message := w.DCCtx().NewMessage(deltachat.DC_MSG_FILE)
defer message.Unref()
message.SetText(fmt.Sprintf("%s:", senderName))
message.SetFile(filename, mime.TypeByExtension(".vcf"))
w.DCCtx().SendMessage(DCID, message)
return w.MessageTracker.MarkSent(&m.Info.Id)
}
}
////
// Helpers
func DetermineSenderName(b *core.BridgeContext, info whatsapp.MessageInfo) string {
senderName := info.Source.GetParticipant()
// No participant probably means that this isn't a group chat.
if senderName == "" {
senderName = info.RemoteJid
}
if info.FromMe == true {
dcContact := b.DCContext.GetContact(b.DCUserID)
defer dcContact.Unref()
return dcContact.GetDisplayName()
}
contact, ok := b.WhappConn.Store.Contacts[senderName]
if ok && contact.Name != "" {
senderName = contact.Name
}
return senderName
}
func WriteTempFile(b *core.BridgeContext, data []byte, template string) (string, error) {
tmpFile, err := ioutil.TempFile(
b.Config.App.DataFolder+"/tmp",
template,
)
if err != nil {
b.SendLog(err.Error())
return "", err
}
return tmpFile.Name(), ioutil.WriteFile(tmpFile.Name(), data, 0600)
}