Whatsapp image bridging

This commit is contained in:
imShara
2019-05-19 20:02:44 +03:00
committed by Guillaume Lazzara
parent 31dd538c0b
commit 3459f2062c
2 changed files with 157 additions and 35 deletions

View File

@@ -3,9 +3,13 @@ package bwhatsapp
import (
"strings"
"time"
"mime"
"fmt"
"github.com/42wim/matterbridge/bridge/config"
"github.com/Rhymen/go-whatsapp"
"github.com/42wim/matterbridge/bridge/helper"
whatsappExt "github.com/matterbridge/mautrix-whatsapp/whatsapp-ext"
)
/*
@@ -76,7 +80,7 @@ func (b *Bwhatsapp) HandleTextMessage(message whatsapp.TextMessage) {
Account: b.Account,
Protocol: b.Protocol,
Extra: make(map[string][]interface{}),
// ParentID: TODO, // TODO handle thread replies // map from Info.QuotedMessageID string
// ParentID: TODO, // TODO handle thread replies // map from Info.QuotedMessageID string
// Event string `json:"event"`
// Gateway string // will be added during message processing
ID: message.Info.Id}
@@ -89,11 +93,75 @@ func (b *Bwhatsapp) HandleTextMessage(message whatsapp.TextMessage) {
b.Remote <- rmsg
}
//
//func (b *Bwhatsapp) HandleImageMessage(message whatsapp.ImageMessage) {
// fmt.Println(message) // TODO implement
//}
//
// HandleImageMessage sent from WhatsApp, relay it to the brige
func (b *Bwhatsapp) HandleImageMessage(message whatsapp.ImageMessage) {
if message.Info.FromMe { // || !strings.Contains(strings.ToLower(message.Text), "@echo") {
return
}
// whatsapp sends last messages to show context , cut them
if message.Info.Timestamp < b.startedAt {
return
}
messageTime := time.Unix(int64(message.Info.Timestamp), 0) // TODO check how behaves between timezones
groupJid := message.Info.RemoteJid
senderJid := message.Info.SenderJid
// if len(senderJid) == 0 {
// // TODO workaround till https://github.com/Rhymen/go-whatsapp/issues/86 resolved
// senderJid = *message.Info.Source.Participant
// }
// translate sender's Jid to the nicest username we can get
senderName := b.getSenderName(senderJid)
if senderName == "" {
senderName = "Someone" // don't expose telephone number
}
b.Log.Debugf("<= Sending message from %s on %s to gateway", senderJid, b.Account)
rmsg := config.Message{
UserID: senderJid,
Username: senderName,
Timestamp: messageTime,
Channel: groupJid,
Account: b.Account,
Protocol: b.Protocol,
Extra: make(map[string][]interface{}),
// ParentID: TODO, // TODO handle thread replies // map from Info.QuotedMessageID string
// Event string `json:"event"`
// Gateway string // will be added during message processing
ID: message.Info.Id}
if avatarURL, exists := b.userAvatars[senderJid]; exists {
rmsg.Avatar = avatarURL
}
// Download and unencrypt content
data, err := message.Download()
if err != nil {
b.Log.Errorf("%v", err)
return
}
// Get file extension by mimetype
fileext, err := mime.ExtensionsByType(message.Type)
if err != nil {
b.Log.Errorf("%v", err)
return
}
filename := fmt.Sprintf("%v%v", message.Info.Id, fileext[0])
b.Log.Debugf("<= Image downloaded and unencrypted")
// Move file to bridge storage
helper.HandleDownloadData(b.Log, &rmsg, filename, message.Caption, "", &data, b.General)
b.Log.Debugf("<= Image Message is %#v", rmsg)
b.Remote <- rmsg
}
//func (b *Bwhatsapp) HandleVideoMessage(message whatsapp.VideoMessage) {
// fmt.Println(message) // TODO implement
//}

View File

@@ -8,6 +8,9 @@ import (
"os"
"strings"
"time"
"bytes"
"mime"
"path/filepath"
"github.com/42wim/matterbridge/bridge"
"github.com/42wim/matterbridge/bridge/config"
@@ -259,37 +262,88 @@ func (b *Bwhatsapp) Send(msg config.Message) (string, error) {
// TODO handle edit as a message reply with updated text
}
//// TODO Handle Upload a file
//if msg.Extra != nil {
// for _, rmsg := range helper.HandleExtra(&msg, b.General) {
// b.c.SendMessage(roomID, rmsg.Username+rmsg.Text)
// }
// if len(msg.Extra["file"]) > 0 {
// return b.handleUploadFile(&msg, roomID)
// }
//}
// Handle Upload a file
if msg.Extra["file"] != nil {
fi := msg.Extra["file"][0].(config.FileInfo)
// Post text message
text := whatsapp.TextMessage{
Info: whatsapp.MessageInfo{
RemoteJid: msg.Channel, // which equals to group id
},
Text: msg.Username + msg.Text,
filetype := mime.TypeByExtension(filepath.Ext(fi.Name))
b.Log.Debugf("Extra file is %#v", filetype)
// TODO: add different types
// TODO: add webp conversion
if filetype == "image/jpeg" || filetype == "image/png" || filetype == "image/gif" {
// Post image message
message := whatsapp.ImageMessage{
Info: whatsapp.MessageInfo{
RemoteJid: msg.Channel,
},
Type: filetype,
Caption: msg.Username + fi.Comment,
Content: bytes.NewReader(*fi.Data),
}
b.Log.Debugf("=> Sending %#v", msg)
// create message ID
// TODO follow and act if https://github.com/Rhymen/go-whatsapp/issues/101 implemented
idbytes := make([]byte, 10)
if _, err := rand.Read(idbytes); err != nil {
b.Log.Warn(err.Error())
}
message.Info.Id = strings.ToUpper(hex.EncodeToString(idbytes))
err := b.conn.Send(message)
return message.Info.Id, err
} else {
// Post document message
message := whatsapp.DocumentMessage{
Info: whatsapp.MessageInfo{
RemoteJid: msg.Channel,
},
Title: fi.Name,
FileName: fi.Name,
Type: filetype,
Content: bytes.NewReader(*fi.Data),
}
b.Log.Debugf("=> Sending %#v", msg)
// create message ID
// TODO follow and act if https://github.com/Rhymen/go-whatsapp/issues/101 implemented
idbytes := make([]byte, 10)
if _, err := rand.Read(idbytes); err != nil {
b.Log.Warn(err.Error())
}
_, err := b.conn.Send(text)
return message.Info.Id, err
}
} else {
// Post text message
message := whatsapp.TextMessage{
Info: whatsapp.MessageInfo{
RemoteJid: msg.Channel, // which equals to group id
},
Text: msg.Username + msg.Text,
}
b.Log.Debugf("=> Sending %#v", msg)
// create message ID
// TODO follow and act if https://github.com/Rhymen/go-whatsapp/issues/101 implemented
idbytes := make([]byte, 10)
if _, err := rand.Read(idbytes); err != nil {
b.Log.Warn(err.Error())
}
message.Info.Id = strings.ToUpper(hex.EncodeToString(idbytes))
err := b.conn.Send(message)
return message.Info.Id, err
}
b.Log.Debugf("=> Sending %#v", msg)
// create message ID
// TODO follow and act if https://github.com/Rhymen/go-whatsapp/issues/101 implemented
bytes := make([]byte, 10)
if _, err := rand.Read(bytes); err != nil {
b.Log.Warn(err.Error())
}
text.Info.Id = strings.ToUpper(hex.EncodeToString(bytes))
_, err := b.conn.Send(text)
return text.Info.Id, err
}
// TODO do we want that? to allow login with QR code from a bridged channel? https://github.com/tulir/mautrix-whatsapp/blob/513eb18e2d59bada0dd515ee1abaaf38a3bfe3d5/commands.go#L76