da5e399333
Because the Bridge Bot doesn't participate in the rooms it can't send any messages to this room. Hence, we should send all replies to the management room.
170 lines
4.6 KiB
Go
170 lines
4.6 KiB
Go
// mautrix-whatsapp - A Matrix-WhatsApp puppeting bridge.
|
|
// Copyright (C) 2018 Tulir Asokan
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU Affero General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU Affero General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU Affero General Public License
|
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
package main
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"github.com/Rhymen/go-whatsapp"
|
|
"maunium.net/go/maulogger"
|
|
"maunium.net/go/mautrix-appservice"
|
|
"maunium.net/go/mautrix-whatsapp/database"
|
|
"maunium.net/go/mautrix-whatsapp/types"
|
|
"maunium.net/go/mautrix-whatsapp/whatsapp-ext"
|
|
)
|
|
|
|
type CommandHandler struct {
|
|
bridge *Bridge
|
|
log maulogger.Logger
|
|
}
|
|
|
|
// NewCommandHandler creates a CommandHandler
|
|
func NewCommandHandler(bridge *Bridge) *CommandHandler {
|
|
return &CommandHandler{
|
|
bridge: bridge,
|
|
log: bridge.Log.Sub("Command handler"),
|
|
}
|
|
}
|
|
|
|
// CommandEvent stores all data which might be used to handle commands
|
|
type CommandEvent struct {
|
|
Bot *appservice.IntentAPI
|
|
Bridge *Bridge
|
|
Handler *CommandHandler
|
|
RoomID types.MatrixRoomID
|
|
User *User
|
|
Args []string
|
|
}
|
|
|
|
// Reply sends a reply to command as notice
|
|
func (ce *CommandEvent) Reply(msg string) {
|
|
_, err := ce.Bot.SendNotice(string(ce.User.ManagementRoom), msg)
|
|
if err != nil {
|
|
ce.Handler.log.Warnfln("Failed to reply to command from %s: %v", ce.User.MXID, err)
|
|
}
|
|
}
|
|
|
|
// Handle handles messages to the bridge
|
|
func (handler *CommandHandler) Handle(roomID types.MatrixRoomID, user *User, message string) {
|
|
args := strings.Split(message, " ")
|
|
cmd := strings.ToLower(args[0])
|
|
ce := &CommandEvent{
|
|
Bot: handler.bridge.Bot,
|
|
Bridge: handler.bridge,
|
|
Handler: handler,
|
|
RoomID: roomID,
|
|
User: user,
|
|
Args: args[1:],
|
|
}
|
|
switch cmd {
|
|
case "login":
|
|
handler.CommandLogin(ce)
|
|
case "logout":
|
|
handler.CommandLogout(ce)
|
|
case "help":
|
|
handler.CommandHelp(ce)
|
|
case "import":
|
|
handler.CommandImport(ce)
|
|
default:
|
|
ce.Reply("Unknown Command")
|
|
}
|
|
}
|
|
|
|
const cmdLoginHelp = `login - Authenticate this Bridge as WhatsApp Web Client`
|
|
|
|
// CommandLogin handles login command
|
|
func (handler *CommandHandler) CommandLogin(ce *CommandEvent) {
|
|
if ce.User.Session != nil {
|
|
ce.Reply("You're already logged in.")
|
|
return
|
|
}
|
|
|
|
ce.User.Connect(true)
|
|
ce.User.Login(ce.RoomID)
|
|
}
|
|
|
|
const cmdLogoutHelp = `logout - Logout from WhatsApp`
|
|
|
|
// CommandLogout handles !logout command
|
|
func (handler *CommandHandler) CommandLogout(ce *CommandEvent) {
|
|
if ce.User.Session == nil {
|
|
ce.Reply("You're not logged in.")
|
|
return
|
|
}
|
|
err := ce.User.Conn.Logout()
|
|
if err != nil {
|
|
ce.User.log.Warnln("Error while logging out:", err)
|
|
ce.Reply("Error while logging out (see logs for details)")
|
|
return
|
|
}
|
|
ce.User.Conn = nil
|
|
ce.User.Session = nil
|
|
ce.User.Update()
|
|
ce.Reply("Logged out successfully.")
|
|
}
|
|
|
|
const cmdHelpHelp = `help - Prints this help`
|
|
|
|
// CommandHelp handles help command
|
|
func (handler *CommandHandler) CommandHelp(ce *CommandEvent) {
|
|
cmdPrefix := handler.bridge.Config.Bridge.CommandPrefix + " "
|
|
ce.Reply(strings.Join([]string{
|
|
cmdPrefix + cmdHelpHelp,
|
|
cmdPrefix + cmdLoginHelp,
|
|
cmdPrefix + cmdLogoutHelp,
|
|
cmdPrefix + cmdImportHelp,
|
|
}, "\n"))
|
|
}
|
|
|
|
const cmdImportHelp = `import JID|contacts - Open up a room for JID or for each WhatsApp contact`
|
|
|
|
// CommandImport handles import command
|
|
func (handler *CommandHandler) CommandImport(ce *CommandEvent) {
|
|
// ensure all messages go to the management room
|
|
ce.RoomID = ce.User.ManagementRoom
|
|
|
|
user := ce.User
|
|
|
|
if ce.Args[0] == "contacts" {
|
|
handler.log.Debugln("Importing all contacts of", user)
|
|
_, err := user.Conn.Contacts()
|
|
if err != nil {
|
|
handler.log.Errorln("Error on update of contacts of user", user, ":", err)
|
|
return
|
|
}
|
|
|
|
for jid, contact := range user.Conn.Store.Contacts {
|
|
if strings.HasSuffix(jid, whatsappExt.NewUserSuffix) {
|
|
puppet := user.bridge.GetPuppetByJID(contact.Jid)
|
|
puppet.Sync(user, contact)
|
|
} else {
|
|
portal := user.bridge.GetPortalByJID(database.GroupPortalKey(contact.Jid))
|
|
portal.Sync(user, contact)
|
|
}
|
|
}
|
|
|
|
ce.Reply("Importing all contacts done")
|
|
} else {
|
|
jid := ce.Args[0] + whatsappExt.NewUserSuffix
|
|
handler.log.Debugln("Importing", jid, "for", user)
|
|
puppet := user.bridge.GetPuppetByJID(jid)
|
|
|
|
contact := whatsapp.Contact { Jid: jid }
|
|
puppet.Sync(user, contact)
|
|
}
|
|
}
|