mirror of
https://github.com/tulir/mautrix-whatsapp
synced 2024-11-17 23:43:10 +01:00
Re-add call start notices
This commit is contained in:
parent
817cd21550
commit
e0d79f2de1
7 changed files with 78 additions and 16 deletions
|
@ -34,11 +34,7 @@ type BridgeConfig struct {
|
|||
|
||||
DeliveryReceipts bool `yaml:"delivery_receipts"`
|
||||
PortalMessageBuffer int `yaml:"portal_message_buffer"`
|
||||
|
||||
CallNotices struct {
|
||||
Start bool `yaml:"start"`
|
||||
End bool `yaml:"end"`
|
||||
} `yaml:"call_notices"`
|
||||
CallStartNotices bool `yaml:"call_start_notices"`
|
||||
|
||||
HistorySync struct {
|
||||
CreatePortals bool `yaml:"create_portals"`
|
||||
|
|
|
@ -124,6 +124,10 @@ func (msg *Message) IsFakeMXID() bool {
|
|||
return strings.HasPrefix(msg.MXID.String(), "net.maunium.whatsapp.fake::")
|
||||
}
|
||||
|
||||
func (msg *Message) IsFakeJID() bool {
|
||||
return strings.HasPrefix(msg.JID, "FAKE::")
|
||||
}
|
||||
|
||||
func (msg *Message) Scan(row Scannable) *Message {
|
||||
var ts int64
|
||||
err := row.Scan(&msg.Chat.JID, &msg.Chat.Receiver, &msg.JID, &msg.MXID, &msg.Sender, &ts, &msg.Sent, &msg.DecryptionError)
|
||||
|
|
|
@ -85,11 +85,8 @@ bridge:
|
|||
|
||||
# Should the bridge send a read receipt from the bridge bot when a message has been sent to WhatsApp?
|
||||
delivery_receipts: false
|
||||
|
||||
# Should notices of incoming calls be sent to Matrix?
|
||||
call_notices:
|
||||
start: true
|
||||
end: true
|
||||
# Should incoming calls send a message to the Matrix room?
|
||||
call_start_notices: true
|
||||
|
||||
# Settings for handling history sync payloads. These settings only apply right after login,
|
||||
# because the phone only sends the history sync data once, and there's no way to re-request it
|
||||
|
|
2
go.mod
2
go.mod
|
@ -8,7 +8,7 @@ require (
|
|||
github.com/mattn/go-sqlite3 v1.14.9
|
||||
github.com/prometheus/client_golang v1.11.0
|
||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
|
||||
go.mau.fi/whatsmeow v0.0.0-20211101191317-2837c184bbfe
|
||||
go.mau.fi/whatsmeow v0.0.0-20211102134251-7e0b153d9c9e
|
||||
golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d
|
||||
google.golang.org/protobuf v1.27.1
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
|
|
4
go.sum
4
go.sum
|
@ -139,8 +139,8 @@ github.com/tidwall/sjson v1.2.3 h1:5+deguEhHSEjmuICXZ21uSSsXotWMA0orU783+Z7Cp8=
|
|||
github.com/tidwall/sjson v1.2.3/go.mod h1:5WdjKx3AQMvCJ4RG6/2UYT7dLrGvJUV1x4jdTAyGvZs=
|
||||
go.mau.fi/libsignal v0.0.0-20211024113310-f9fc6a1855f2 h1:xpQTMgJGGaF+c8jV/LA/FVXAPJxZbSAGeflOc+Ly6uQ=
|
||||
go.mau.fi/libsignal v0.0.0-20211024113310-f9fc6a1855f2/go.mod h1:3XlVlwOfp8f9Wri+C1D4ORqgUsN4ZvunJOoPjQMBhos=
|
||||
go.mau.fi/whatsmeow v0.0.0-20211101191317-2837c184bbfe h1:ohSAIsW4Jg5GD2r0b+827vgQmheMKCMyhb7AGFppBDg=
|
||||
go.mau.fi/whatsmeow v0.0.0-20211101191317-2837c184bbfe/go.mod h1:ODEmmqeUn9eBDQHFc1S902YA3YFLtmaBujYRRFl53jI=
|
||||
go.mau.fi/whatsmeow v0.0.0-20211102134251-7e0b153d9c9e h1:HVlRWzEEmWkgInvj8VGxB3epRSd7ryRvLdAA2X0fbGk=
|
||||
go.mau.fi/whatsmeow v0.0.0-20211102134251-7e0b153d9c9e/go.mod h1:ODEmmqeUn9eBDQHFc1S902YA3YFLtmaBujYRRFl53jI=
|
||||
golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
|
|
44
portal.go
44
portal.go
|
@ -161,9 +161,17 @@ func (bridge *Bridge) NewPortal(dbPortal *database.Portal) *Portal {
|
|||
|
||||
const recentlyHandledLength = 100
|
||||
|
||||
type fakeMessage struct {
|
||||
Sender types.JID
|
||||
Text string
|
||||
ID string
|
||||
Time time.Time
|
||||
}
|
||||
|
||||
type PortalMessage struct {
|
||||
evt *events.Message
|
||||
undecryptable *events.UndecryptableMessage
|
||||
fake *fakeMessage
|
||||
source *User
|
||||
}
|
||||
|
||||
|
@ -196,7 +204,7 @@ type Portal struct {
|
|||
func (portal *Portal) handleMessageLoop() {
|
||||
for msg := range portal.messages {
|
||||
if len(portal.MXID) == 0 {
|
||||
if msg.evt == nil || !containsSupportedMessage(msg.evt.Message) {
|
||||
if msg.fake == nil && (msg.evt == nil || !containsSupportedMessage(msg.evt.Message)) {
|
||||
portal.log.Debugln("Not creating portal room for incoming message: message is not a chat message")
|
||||
continue
|
||||
}
|
||||
|
@ -211,6 +219,9 @@ func (portal *Portal) handleMessageLoop() {
|
|||
portal.handleMessage(msg.source, msg.evt)
|
||||
} else if msg.undecryptable != nil {
|
||||
portal.handleUndecryptableMessage(msg.source, msg.undecryptable)
|
||||
} else if msg.fake != nil {
|
||||
msg.fake.ID = "FAKE::" + msg.fake.ID
|
||||
portal.handleFakeMessage(*msg.fake)
|
||||
} else {
|
||||
portal.log.Warnln("Unexpected PortalMessage with no message: %+v", msg)
|
||||
}
|
||||
|
@ -336,6 +347,32 @@ func (portal *Portal) handleUndecryptableMessage(source *User, evt *events.Undec
|
|||
portal.finishHandling(nil, &evt.Info, resp.EventID, true)
|
||||
}
|
||||
|
||||
func (portal *Portal) handleFakeMessage(msg fakeMessage) {
|
||||
if portal.isRecentlyHandled(msg.ID, false) {
|
||||
portal.log.Debugfln("Not handling %s (fake): message was recently handled", msg.ID)
|
||||
return
|
||||
} else if existingMsg := portal.bridge.DB.Message.GetByJID(portal.Key, msg.ID); existingMsg != nil {
|
||||
portal.log.Debugfln("Not handling %s (fake): message is duplicate", msg.ID)
|
||||
return
|
||||
}
|
||||
intent := portal.bridge.GetPuppetByJID(msg.Sender).IntentFor(portal)
|
||||
resp, err := portal.sendMessage(intent, event.EventMessage, &event.MessageEventContent{
|
||||
MsgType: event.MsgText,
|
||||
Body: msg.Text,
|
||||
}, nil, msg.Time.UnixMilli())
|
||||
if err != nil {
|
||||
portal.log.Errorln("Failed to send %s to Matrix: %v", msg.ID, err)
|
||||
} else {
|
||||
portal.finishHandling(nil, &types.MessageInfo{
|
||||
ID: msg.ID,
|
||||
Timestamp: msg.Time,
|
||||
MessageSource: types.MessageSource{
|
||||
Sender: msg.Sender,
|
||||
},
|
||||
}, resp.EventID, false)
|
||||
}
|
||||
}
|
||||
|
||||
func (portal *Portal) handleMessage(source *User, evt *events.Message) {
|
||||
if len(portal.MXID) == 0 {
|
||||
portal.log.Warnln("handleMessage called even though portal.MXID is empty")
|
||||
|
@ -2140,7 +2177,7 @@ func (portal *Portal) convertMatrixMessage(sender *User, evt *event.Event) (*waP
|
|||
replyToID := content.GetReplyTo()
|
||||
if len(replyToID) > 0 {
|
||||
replyToMsg := portal.bridge.DB.Message.GetByMXID(replyToID)
|
||||
if replyToMsg != nil {
|
||||
if replyToMsg != nil && !replyToMsg.IsFakeJID() {
|
||||
ctxInfo.StanzaId = &replyToMsg.JID
|
||||
ctxInfo.Participant = proto.String(replyToMsg.Sender.ToNonAD().String())
|
||||
// Using blank content here seems to work fine on all official WhatsApp apps.
|
||||
|
@ -2360,6 +2397,9 @@ func (portal *Portal) HandleMatrixRedaction(sender *User, evt *event.Event) {
|
|||
if msg == nil {
|
||||
portal.log.Debugfln("Ignoring redaction %s of unknown event by %s", msg, senderLogIdentifier)
|
||||
return
|
||||
} else if msg.IsFakeJID() {
|
||||
portal.log.Debugfln("Ignoring redaction %s of fake event by %s", msg, senderLogIdentifier)
|
||||
return
|
||||
} else if msg.Sender.User != sender.JID.User {
|
||||
portal.log.Debugfln("Ignoring redaction %s of %s/%s by %s: message was sent by someone else (%s, not %s)", evt.ID, msg.MXID, msg.JID, senderLogIdentifier, msg.Sender, sender.JID)
|
||||
return
|
||||
|
|
27
user.go
27
user.go
|
@ -358,7 +358,7 @@ func containsSupportedMessages(conv *waProto.Conversation) bool {
|
|||
|
||||
type portalToBackfill struct {
|
||||
portal *Portal
|
||||
conv *waProto.Conversation
|
||||
conv *waProto.Conversation
|
||||
}
|
||||
|
||||
func (user *User) handleHistorySync(evt *waProto.HistorySync) {
|
||||
|
@ -423,6 +423,25 @@ func (user *User) handleHistorySync(evt *waProto.HistorySync) {
|
|||
user.log.Infofln("Finished handling history sync with type %s, chunk order %d, progress %d%%", evt.GetSyncType(), evt.GetChunkOrder(), evt.GetProgress())
|
||||
}
|
||||
|
||||
func (user *User) handleCallStart(sender types.JID, id, callType string) {
|
||||
if !user.bridge.Config.Bridge.CallStartNotices {
|
||||
return
|
||||
}
|
||||
portal := user.GetPortalByJID(sender)
|
||||
text := "Incoming call"
|
||||
if callType != "" {
|
||||
text = fmt.Sprintf("Incoming %s call", text)
|
||||
}
|
||||
portal.messages <- PortalMessage{
|
||||
fake: &fakeMessage{
|
||||
Sender: sender,
|
||||
Text: text,
|
||||
ID: id,
|
||||
},
|
||||
source: user,
|
||||
}
|
||||
}
|
||||
|
||||
func (user *User) HandleEvent(event interface{}) {
|
||||
switch v := event.(type) {
|
||||
case *events.LoggedOut:
|
||||
|
@ -482,6 +501,12 @@ func (user *User) HandleEvent(event interface{}) {
|
|||
case *events.Message:
|
||||
portal := user.GetPortalByJID(v.Info.Chat)
|
||||
portal.messages <- PortalMessage{evt: v, source: user}
|
||||
case *events.CallOffer:
|
||||
user.handleCallStart(v.CallCreator, v.CallID, "")
|
||||
case *events.CallOfferNotice:
|
||||
user.handleCallStart(v.CallCreator, v.CallID, v.Type)
|
||||
case *events.CallTerminate, *events.CallRelayLatency, *events.CallAccept, *events.UnknownCallEvent:
|
||||
// ignore
|
||||
case *events.UndecryptableMessage:
|
||||
portal := user.GetPortalByJID(v.Info.Chat)
|
||||
portal.messages <- PortalMessage{undecryptable: v, source: user}
|
||||
|
|
Loading…
Reference in a new issue