Skip to content

Commit

Permalink
Improve bot features (#12)
Browse files Browse the repository at this point in the history
This PR adds small improvements to the bot feature.

- Censor messages depending on the recipient group (CRF internal or not)
- Handle concurrent usage of the whatsapp client (cronned runs will always disconnect the client)
  • Loading branch information
fabien-chebel authored Jun 21, 2022
1 parent f60bf7e commit 39351e4
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 14 deletions.
2 changes: 1 addition & 1 deletion bot-service.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func (b *BotService) SendActivitySummary(recipient types.JID, kind ActivityKind)

day := time.Now().AddDate(0, 0, 1).Format("2006-01-02")
log.Info("Fetching activity summary for day ", day)
summary, err := b.pegassClient.GetActivityOnDay(day, kind)
summary, err := b.pegassClient.GetActivityOnDay(day, kind, false)
if err != nil {
log.Errorf("failed to generate activity summary for day '%s' and kind '%d'", day, kind)
return
Expand Down
9 changes: 5 additions & 4 deletions config.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package main

type Config struct {
Username string `json:"username"`
Password string `json:"password"`
TotpSecretKey string `json:"totp_secret_key"`
WhatsAppNotificationGroup string `json:"whatsapp_notification_group"`
Username string `json:"username"`
Password string `json:"password"`
TotpSecretKey string `json:"totp_secret_key"`
WhatsAppNotificationGroup string `json:"whatsapp_notification_group"`
WhatsAppBotGroups []string `json:"whatsapp_bot_groups"`
}

type AuthTicket struct {
Expand Down
31 changes: 24 additions & 7 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -239,8 +239,14 @@ func main() {
}

day := time.Now().AddDate(0, 0, 1).Format("2006-01-02")

var shouldCensorData = true
if isGroupOwnedByCRF(conf.WhatsAppBotGroups, conf.WhatsAppNotificationGroup) {
shouldCensorData = false
}

log.Info("Fetching activity summary for day ", day)
summary, err := pegassClient.GetActivityOnDay(day, SAMU)
summary, err := pegassClient.GetActivityOnDay(day, SAMU, shouldCensorData)
if err != nil {
return err
}
Expand All @@ -250,8 +256,8 @@ func main() {
if conf.WhatsAppNotificationGroup == "" {
return fmt.Errorf("no WhatsApp group Id provided. Skipping WhatsApp notification")
}
whatsAppClient := whatsapp.NewClient()
jid, err := types.ParseJID(conf.WhatsAppNotificationGroup)
whatsAppClient := whatsapp.NewClient()
if err != nil {
return err
}
Expand Down Expand Up @@ -285,7 +291,7 @@ func main() {
{
Name: "start-bot",
Action: func(c *cli.Context) error {
_, err := initClient()
config, err := initClient()
if err != nil {
return err
}
Expand All @@ -296,11 +302,13 @@ func main() {
chatClient: &whatsAppClient,
}
whatsAppClient.SetMessageCallback(func(senderName string, senderId types.JID, chatId types.JID, content string) {
log.Infof("Received message from '%s': %s", senderName, content)
var recipient = senderId
if chatId != (types.JID{}) {
recipient = chatId
if !isGroupOwnedByCRF(config.WhatsAppBotGroups, chatId.String()) {
// Security: only whitelisted groups are able to use bot features
return
}
log.Infof("Received message from '%s': %s", senderName, content)

var recipient = chatId
lowerMessage := strings.ToLower(content)

if strings.HasPrefix(lowerMessage, "!psr") {
Expand Down Expand Up @@ -337,3 +345,12 @@ func parseConfig() Config {
}
return configData
}

func isGroupOwnedByCRF(allowedGroups []string, groupId string) bool {
for _, allowedId := range allowedGroups {
if allowedId == groupId {
return true
}
}
return false
}
4 changes: 2 additions & 2 deletions pegass-client.go
Original file line number Diff line number Diff line change
Expand Up @@ -830,7 +830,7 @@ func (p *PegassClient) lintActivity(activity redcross.Activity) (string, error)
return buf.String(), nil
}

func (p *PegassClient) GetActivityOnDay(day string, kind ActivityKind) (string, error) {
func (p *PegassClient) GetActivityOnDay(day string, kind ActivityKind, shouldCensorData bool) (string, error) {
err := p.init()
if err != nil {
return "", err
Expand Down Expand Up @@ -893,7 +893,7 @@ func (p *PegassClient) GetActivityOnDay(day string, kind ActivityKind) (string,
}

var comment string
if isCRFActivity {
if isCRFActivity && !shouldCensorData {
comment, err = p.lintActivity(act)
if err != nil {
return "", err
Expand Down
15 changes: 15 additions & 0 deletions whatsapp/whatsapp-client.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"os"
"os/signal"
"syscall"
"time"
)

type WhatsAppClient struct {
Expand Down Expand Up @@ -144,6 +145,20 @@ func (w *WhatsAppClient) eventHandler(evt interface{}) {
if w.onMessageReceived != nil {
w.onMessageReceived(v.Info.PushName, v.Info.Sender, v.Info.Chat, v.Message.GetConversation())
}
case *events.Disconnected:
log.Warn("WhatsApp client was disconnected")
case *events.ConnectFailure:
log.Warnf("failed to connect to whatsapp: %#v", v.Reason)
case *events.LoggedOut:
log.Warnf("Received 'loged out' event: %#v", v.Reason)
case *events.StreamReplaced:
log.Warnf("Another WhatsApp client connected and stole our session! Will reconnect in a few seconds")
w.client.Disconnect()
time.Sleep(5 * time.Second)
err := w.initAndConnectIfNecessary()
if err != nil {
log.Error("failed to reconnect to whatsapp", err)
}
}
}

Expand Down

0 comments on commit 39351e4

Please sign in to comment.