Skip to content

Commit

Permalink
Add welcome message functionality
Browse files Browse the repository at this point in the history
(Telegram and whatsapp for now)
  • Loading branch information
yousefmansy1 committed Mar 15, 2023
1 parent 08692ee commit 5bc8231
Show file tree
Hide file tree
Showing 7 changed files with 211 additions and 26 deletions.
1 change: 1 addition & 0 deletions bridge/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
)

const (
EventWelcomeMsg = "welcome"
EventJoinLeave = "join_leave"
EventTopicChange = "topic_change"
EventFailure = "failure"
Expand Down
2 changes: 2 additions & 0 deletions bridge/telegram/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,9 @@ func (b *Btelegram) handleUserJoin(update tgbotapi.Update) {
Event: config.EventJoinLeave,
Text: "joined chat",
}
b.Remote <- rmsg

rmsg.Event = config.EventWelcomeMsg
b.Remote <- rmsg
}
}
Expand Down
2 changes: 2 additions & 0 deletions bridge/whatsappmulti/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,9 @@ func (b *Bwhatsapp) handleUserJoin(event *events.GroupInfo) {
Event: config.EventJoinLeave,
Text: "joined chat",
}
b.Remote <- rmsg

rmsg.Event = config.EventWelcomeMsg
b.Remote <- rmsg
}
}
Expand Down
68 changes: 68 additions & 0 deletions gateway/channelstore.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package gateway

import (
"encoding/gob"

"github.com/42wim/matterbridge/bridge/config"
"github.com/philippgille/gokv"
"github.com/philippgille/gokv/bbolt"
"github.com/philippgille/gokv/encoding"
)

type ChannelData struct {
HasWelcomeMessage bool
WelcomeMessage config.Message
}

func (r *Router) getChannelStore(path string) gokv.Store {
gob.Register(map[string]interface{}{})
gob.Register(config.FileInfo{})

options := bbolt.Options{
BucketName: "ChannelData",
Path: path,
Codec: encoding.Gob,
}

gob.Register(map[string]interface{}{})

store, err := bbolt.NewStore(options)
if err != nil {
r.logger.Errorf("Could not connect to db: %s", path)
}

return store
}

func (r *Router) getWelcomeMessage(Channel string) *config.Message {
channelData := new(ChannelData)
found, err := r.ChannelStore.Get(Channel, channelData)
if err != nil {
r.logger.Error(err)
}

if found && channelData.HasWelcomeMessage {
return &channelData.WelcomeMessage
}

return nil
}

func (r *Router) setWelcomeMessage(Channel string, newWelcomeMessage *config.Message) error {
channelData := new(ChannelData)
r.ChannelStore.Get(Channel, channelData)

if newWelcomeMessage == nil {
channelData.HasWelcomeMessage = false
channelData.WelcomeMessage = config.Message{}
} else {
channelData.HasWelcomeMessage = true
channelData.WelcomeMessage = *newWelcomeMessage
}

err := r.ChannelStore.Set(Channel, channelData)
if err != nil {
r.logger.Errorf(err.Error())
}
return err
}
130 changes: 109 additions & 21 deletions gateway/command.go
Original file line number Diff line number Diff line change
@@ -1,43 +1,82 @@
package gateway

import (
"strings"

"github.com/42wim/matterbridge/bridge/config"
)

// returns true if a command was registered (therefore a should not be relayed
func (r *Router) handleCommand(msg *config.Message) bool {
switch text := msg.Text; text {
case "!chatId":
help := `!optout - opt out from all message relaying
!optoutmedia - only opt out from relaying attachments
!optin - opt back into chat relaying
!setwelcome - set channel welcome message (admin)
!unsetwelcome - clear channel welcome message (admin)
!help - display this message`

isAdmin := r.isAdmin(msg)
addTextFromCaptions(msg)
cmd := msg.Text

switch {
case cmd == "!help":
r.logger.Debug("!help")
r.replyCmd(msg, help)
case cmd == "!chatId":
r.logger.Infof("!chatId: %s", msg.Channel)
case "!optin":
case cmd == "!userId":
r.logger.Infof("!userId: %s", msg.UserID)
case cmd == "!ping":
r.logger.Debug("!pong: %s,%s", msg.Channel, msg.UserID)
r.replyCmd(msg, "pong!")
case cmd == "!pingdm":
r.logger.Debug("!pongdm: %s,%s", msg.Channel, msg.UserID)
r.replyDM(msg, "pong!")
case cmd == "!optin":
r.logger.Debugf("!optin: %s", msg.UserID)
r.handleOptOutCmd(msg, OptIn)
case "!optout":
case cmd == "!optout":
r.logger.Debugf("!optout: %s", msg.UserID)
r.handleOptOutCmd(msg, OptOut)
case "!optoutmedia":
case cmd == "!optoutmedia":
r.logger.Debugf("!optoutmedia: %s", msg.UserID)
r.handleOptOutCmd(msg, OptOutMediaOnly)
case "!help":
r.logger.Debug("!help")
help := `!optout - opt out from all message relaying
!optoutmedia - only opt out from relaying attachments
!optin - opt back into chat relaying
!help - display this message`

r.replyCmd(msg, help)
case "!ping":
r.logger.Debug("!pong")
r.replyCmd(msg, "pong!")
case "!pingdm":
r.logger.Debug("!pongdm")
r.replyDM(msg, "pong!")
case isAdmin && strings.HasPrefix(cmd, "!setwelcome"):
r.logger.Debugf("!setwelcome: %s - %+v", msg.Channel, msg)
r.handleWelcomeCmd(msg, msg)
case isAdmin && strings.HasPrefix(cmd, "!unsetwelcome"):
r.logger.Debugf("!unsetwelcome: %s", msg.Channel)
r.handleWelcomeCmd(msg, nil)
case cmd == "!echowelcome":
r.logger.Debugf("!echowelcome: %s,%s", msg.Channel, msg.UserID)
r.handleEchoWelcomeCmd(msg)
default:
return false
}

return true
}

func (r *Router) isAdmin(msg *config.Message) bool {
admins, _ := r.GetStringSlice("Admins")

for _, ID := range admins {
if msg.UserID == ID {
return true
}
}
return false
}

func addTextFromCaptions(msg *config.Message) {
for _, f := range msg.Extra["file"] {
fi := f.(config.FileInfo)

msg.Text += fi.Comment
}
}

func (r *Router) replyCmd(msg *config.Message, str string) {
srcBridge := r.getBridge(msg.Account)

Expand Down Expand Up @@ -71,8 +110,20 @@ func (r *Router) replyDM(msg *config.Message, str string) {
srcBridge.Send(reply)
}

func (r *Router) handleOptOutCmd(msg *config.Message, newStaus OptOutStatus) {
err := r.setOptOutStatus(msg.UserID, newStaus)
func (r *Router) sendDM(msg *config.Message, dmChannel string) {
srcBridge := r.getBridge(msg.Account)

msg.Channel = dmChannel
msg.Username = ""
msg.UserID = ""
msg.ID = ""
msg.Event = ""

srcBridge.Send(*msg)
}

func (r *Router) handleOptOutCmd(msg *config.Message, newStatus OptOutStatus) {
err := r.setOptOutStatus(msg.UserID, newStatus)

reply := "Successfully set message relay preferences."
if err != nil {
Expand All @@ -81,3 +132,40 @@ func (r *Router) handleOptOutCmd(msg *config.Message, newStaus OptOutStatus) {

r.replyCmd(msg, reply)
}

func (r *Router) handleWelcomeCmd(msg *config.Message, welcomeMsg *config.Message) {

if welcomeMsg != nil {
welcomeMsg.Text = strings.Replace(welcomeMsg.Text, "!setwelcome ", "", 1)

for i, f := range welcomeMsg.Extra["file"] {
fi := f.(config.FileInfo)
fi.Comment = strings.Replace(fi.Comment, "!setwelcome ", "", 1)

welcomeMsg.Extra["file"][i] = fi
}
}

err := r.setWelcomeMessage(msg.Channel, welcomeMsg)

reply := "Successfully set welcome message for channel."
if welcomeMsg == nil {
reply = "Successfully removed welcome message for channel."
}
if err != nil {
reply = "Error setting channel welcome message, try again later or contact the moderators."
}

r.replyCmd(msg, reply)
}

func (r *Router) handleEchoWelcomeCmd(msg *config.Message) {
msg.Event = config.EventWelcomeMsg

if r.getWelcomeMessage(msg.Channel) == nil {
r.replyCmd(msg, "No welcome message configured, set with !setwelcome")
return
}

r.handleEventWelcome(msg)
}
14 changes: 14 additions & 0 deletions gateway/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,20 @@ func (r *Router) handleEventGetChannelMembers(msg *config.Message) {
}
}

func (r *Router) handleEventWelcome(msg *config.Message) bool {
if msg.Event != config.EventWelcomeMsg {
return false
}

welcomeMsg := r.getWelcomeMessage(msg.Channel)

if welcomeMsg != nil {
r.sendDM(welcomeMsg, msg.UserID)
}

return true
}

// handleEventRejoinChannels handles rejoining of channels.
func (r *Router) handleEventRejoinChannels(msg *config.Message) {
if msg.Event != config.EventRejoinChannels {
Expand Down
20 changes: 15 additions & 5 deletions gateway/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ type Router struct {
Message chan config.Message
MattermostPlugin chan config.Message
UserStore gokv.Store
ChannelStore gokv.Store

logger *logrus.Entry
}
Expand Down Expand Up @@ -101,9 +102,13 @@ func (r *Router) Start() error {
}
}
}
userStorePath, exists := r.Config.GetString("UserStorePath")
dataStorePath, exists := r.Config.GetString("UserStore")
if exists {
r.UserStore = r.getUserStore(userStorePath)
r.UserStore = r.getUserStore(dataStorePath)
}
dataStorePath, exists = r.Config.GetString("ChannelStore")
if exists {
r.ChannelStore = r.getChannelStore(dataStorePath)
}

go r.handleReceive()
Expand Down Expand Up @@ -137,14 +142,19 @@ func (r *Router) getBridge(account string) *bridge.Bridge {
func (r *Router) handleReceive() {
for msg := range r.Message {
msg := msg // scopelint
if r.handleCommand(&msg) {
continue
}

skipMsg := false
skipMsg = skipMsg || r.handleCommand(&msg)
skipMsg = skipMsg || r.handleEventWelcome(&msg)
r.handleEventGetChannelMembers(&msg)
r.handleEventFailure(&msg)
r.handleEventRejoinChannels(&msg)
r.handleOptOutUser(&msg)

if skipMsg {
continue
}

// Set message protocol based on the account it came from
msg.Protocol = r.getBridge(msg.Account).Protocol

Expand Down

0 comments on commit 5bc8231

Please sign in to comment.