Skip to content

Commit

Permalink
[Presence] Add option to send online presence and read receipts to
Browse files Browse the repository at this point in the history
others

Completes #38
  • Loading branch information
akshettrj committed Oct 3, 2023
2 parents 8a78de6 + 8912039 commit fed4780
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 1 deletion.
42 changes: 42 additions & 0 deletions database/helpers.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package database

import (
"database/sql"

"watgbridge/state"

"go.mau.fi/whatsmeow/types"
Expand All @@ -22,6 +24,7 @@ func MsgIdAddNewPair(waMsgId, participantId, waChatId string, tgChatId, tgMsgId,
bridgePair.TgChatId = tgChatId
bridgePair.TgMsgId = tgMsgId
bridgePair.TgThreadId = tgThreadId
bridgePair.MarkRead = sql.NullBool{Valid: true, Bool: false}
res = db.Save(&bridgePair)
return res.Error
}
Expand All @@ -33,6 +36,7 @@ func MsgIdAddNewPair(waMsgId, participantId, waChatId string, tgChatId, tgMsgId,
TgChatId: tgChatId,
TgMsgId: tgMsgId,
TgThreadId: tgThreadId,
MarkRead: sql.NullBool{Valid: true, Bool: false},
})
return res.Error
}
Expand All @@ -57,6 +61,44 @@ func MsgIdGetWaFromTg(tgChatId, tgMsgId, tgThreadId int64) (msgId, participantId
return bridgePair.ID, bridgePair.ParticipantId, bridgePair.WaChatId, res.Error
}

func MsgIdGetUnread(waChatId string) (map[string]([]string), error) {

db := state.State.Database

var bridgePairs []MsgIdPair
res := db.Where("wa_chat_id = ? AND mark_read = false", waChatId).Find(&bridgePairs)

var msgIds = make(map[string]([]string))

for _, pair := range bridgePairs {
if _, found := msgIds[pair.ParticipantId]; !found {
msgIds[pair.ParticipantId] = []string{}
}
msgIds[pair.ParticipantId] = append(msgIds[pair.ParticipantId], pair.ID)
}

return msgIds, res.Error
}

func MsgIdMarkRead(waChatId, waMsgId string) error {

db := state.State.Database

var bridgePair MsgIdPair
res := db.Where("id = ? AND wa_chat_id = ?", waMsgId, waChatId).Find(&bridgePair)
if res.Error != nil {
return res.Error
}

if bridgePair.ID == waMsgId {
bridgePair.MarkRead = sql.NullBool{Valid: true, Bool: true}
res = db.Save(&bridgePair)
return res.Error
}

return nil
}

func MsgIdDeletePair(tgChatId, tgMsgId int64) error {

db := state.State.Database
Expand Down
8 changes: 7 additions & 1 deletion database/types.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package database

import "watgbridge/state"
import (
"database/sql"

"watgbridge/state"
)

type MsgIdPair struct {
// WhatsApp
Expand All @@ -12,6 +16,8 @@ type MsgIdPair struct {
TgChatId int64
TgThreadId int64
TgMsgId int64

MarkRead sql.NullBool
}

type ChatThreadPair struct {
Expand Down
3 changes: 3 additions & 0 deletions sample_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ telegram:
skip_video_stickers: false # Setting this as true will stop trying to convert telegram video stickers to webp and sending them
skip_setting_commands: false # This will not show you list of commands when you start typing / in telegram

send_my_presence: false # Setting this to true will show your account as online to others whenever you send a message using Telegram
send_my_read_receipts: false # Setting this to true will mark all unread messages in a chat as read when you send a new message using Telegram

whatsapp:
session_name: watgbridge # This will appear in your Linked Devices in mobile app
# All these values can be obtained by running /findcontacts and /getwagroups commands
Expand Down
2 changes: 2 additions & 0 deletions state/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ type Config struct {
SelfHostedAPI bool `yaml:"self_hosted_api"`
SkipVideoStickers bool `yaml:"skip_video_stickers"`
SkipSettingCommands bool `yaml:"skip_setting_commands"`
SendMyPresence bool `yaml:"send_my_presence"`
SendMyReadReceipts bool `yaml:"send_my_read_receipts"`
} `yaml:"telegram"`

WhatsApp struct {
Expand Down
49 changes: 49 additions & 0 deletions utils/telegram.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"go.mau.fi/whatsmeow"
waProto "go.mau.fi/whatsmeow/binary/proto"
waTypes "go.mau.fi/whatsmeow/types"
"go.uber.org/zap"
"golang.org/x/exp/slices"
"google.golang.org/protobuf/proto"
)
Expand Down Expand Up @@ -170,6 +171,7 @@ func TgSendToWhatsApp(b *gotgbot.Bot, c *ext.Context,

var (
cfg = state.State.Config
logger = state.State.Logger
waClient = state.State.WhatsAppClient
mentions = []string{}
)
Expand All @@ -196,6 +198,27 @@ func TgSendToWhatsApp(b *gotgbot.Bot, c *ext.Context,
}
}

if cfg.Telegram.SendMyPresence {
err := waClient.SendPresence(waTypes.PresenceAvailable)
if err != nil {
logger.Warn("failed to send presence",
zap.Error(err),
zap.String("presence", string(waTypes.PresenceAvailable)),
)
}

go func() {
time.Sleep(10 * time.Second)
err := waClient.SendPresence(waTypes.PresenceUnavailable)
if err != nil {
logger.Warn("failed to send presence",
zap.Error(err),
zap.String("presence", string(waTypes.PresenceUnavailable)),
)
}
}()
}

if msgToForward.Photo != nil && len(msgToForward.Photo) > 0 {

bestPhoto := msgToForward.Photo[0]
Expand Down Expand Up @@ -871,6 +894,32 @@ func TgSendToWhatsApp(b *gotgbot.Bot, c *ext.Context,

}

if cfg.Telegram.SendMyReadReceipts {
unreadMsgs, err := database.MsgIdGetUnread(waChatJID.String())
if err != nil {
return TgReplyWithErrorByContext(b, c, "Message sent but failed to get unread messages to mark them read", err)
}

for sender, msgIds := range unreadMsgs {
senderJID, _ := WaParseJID(sender)
err := waClient.MarkRead(msgIds, time.Now(), waChatJID, senderJID)
if err != nil {
logger.Warn(
"failed to mark messages as read",
zap.String("chat_id", waChatJID.String()),
zap.Any("msg_ids", msgIds),
zap.String("sender", senderJID.String()),
)
} else {
for _, msgId := range msgIds {
database.MsgIdMarkRead(waChatJID.String(), msgId)
}
}
}

// waClient.MarkRead(unreadMsgs, time.Now(), waChatJID, )
}

return nil
}

Expand Down
11 changes: 11 additions & 0 deletions whatsapp/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ func WhatsAppEventHandler(evt interface{}) {

switch v := evt.(type) {

case *events.Receipt:
ReceiptEventHandler(v)

case *events.PushName:
PushNameEventHandler(v)

Expand Down Expand Up @@ -1120,6 +1123,14 @@ func CallOfferEventHandler(v *events.CallOffer) {
utils.TgSendTextById(tgBot, cfg.Telegram.TargetChatID, callThreadId, bridgeText)
}

func ReceiptEventHandler(v *events.Receipt) {
if v.Type == events.ReceiptTypeReadSelf {
for _, msgId := range v.MessageIDs {
database.MsgIdMarkRead(v.Chat.String(), msgId)
}
}
}

func PushNameEventHandler(v *events.PushName) {
logger := state.State.Logger
defer logger.Sync()
Expand Down

0 comments on commit fed4780

Please sign in to comment.