Edit message with regenerated QR code when logging in

This commit is contained in:
Tulir Asokan 2019-07-18 00:14:04 +03:00
parent 7f0a0df7de
commit 91e8000c14
3 changed files with 67 additions and 16 deletions

View file

@ -34,6 +34,7 @@ type BridgeConfig struct {
DisplaynameTemplate string `yaml:"displayname_template"` DisplaynameTemplate string `yaml:"displayname_template"`
ConnectionTimeout int `yaml:"connection_timeout"` ConnectionTimeout int `yaml:"connection_timeout"`
LoginQRRegenCount int `yaml:"login_qr_regen_count"`
MaxConnectionAttempts int `yaml:"max_connection_attempts"` MaxConnectionAttempts int `yaml:"max_connection_attempts"`
ConnectionRetryDelay int `yaml:"connection_retry_delay"` ConnectionRetryDelay int `yaml:"connection_retry_delay"`
ReportConnectionRetry bool `yaml:"report_connection_retry"` ReportConnectionRetry bool `yaml:"report_connection_retry"`
@ -62,6 +63,7 @@ type BridgeConfig struct {
func (bc *BridgeConfig) setDefaults() { func (bc *BridgeConfig) setDefaults() {
bc.ConnectionTimeout = 20 bc.ConnectionTimeout = 20
bc.LoginQRRegenCount = 2
bc.MaxConnectionAttempts = 3 bc.MaxConnectionAttempts = 3
bc.ConnectionRetryDelay = -1 bc.ConnectionRetryDelay = -1
bc.ReportConnectionRetry = true bc.ReportConnectionRetry = true

View file

@ -60,6 +60,9 @@ bridge:
# WhatsApp connection timeout in seconds. # WhatsApp connection timeout in seconds.
connection_timeout: 20 connection_timeout: 20
# Number of times to regenerate QR code when logging in.
# The regenerated QR code is sent as an edit and essentially multiplies the login timeout (20 seconds)
login_qr_regen_count: 2
# Maximum number of times to retry connecting on connection error. # Maximum number of times to retry connecting on connection error.
max_connection_attempts: 3 max_connection_attempts: 3
# Number of seconds to wait between connection attempts. # Number of seconds to wait between connection attempts.

74
user.go
View file

@ -221,11 +221,11 @@ func (user *User) IsLoggedIn() bool {
return user.Session != nil || user.Conn != nil return user.Session != nil || user.Conn != nil
} }
func (user *User) Login(ce *CommandEvent) { func (user *User) loginQrChannel(ce *CommandEvent, qrChan <-chan string, eventIDChan chan<- string) {
qrChan := make(chan string, 2) var qrEventID string
go func() { for code := range qrChan {
code := <-qrChan fmt.Println("qrChan:", code)
if code == "error" { if code == "stop" {
return return
} }
qrCode, err := qrcode.Encode(code, qrcode.Low, 256) qrCode, err := qrcode.Encode(code, qrcode.Low, 256)
@ -244,24 +244,70 @@ func (user *User) Login(ce *CommandEvent) {
return return
} }
_, err = bot.SendImage(ce.RoomID, string(code), resp.ContentURI) if qrEventID == "" {
sendResp, err := bot.SendImage(ce.RoomID, code, resp.ContentURI)
if err != nil { if err != nil {
user.log.Errorln("Failed to send QR code to user:", err) user.log.Errorln("Failed to send QR code to user:", err)
return
} }
}() qrEventID = sendResp.EventID
session, err := user.Conn.Login(qrChan) eventIDChan <- qrEventID
} else {
_, err = bot.SendMessageEvent(ce.RoomID, mautrix.EventMessage, &mautrix.Content{
MsgType: mautrix.MsgImage,
Body: code,
URL: resp.ContentURI,
NewContent: &mautrix.Content{
MsgType: mautrix.MsgImage,
Body: code,
URL: resp.ContentURI,
},
RelatesTo: &mautrix.RelatesTo{
Type: mautrix.RelReplace,
EventID: qrEventID,
},
})
if err != nil { if err != nil {
qrChan <- "error" user.log.Errorln("Failed to send edited QR code to user:", err)
}
}
}
}
func (user *User) Login(ce *CommandEvent) {
qrChan := make(chan string, 3)
eventIDChan := make(chan string, 1)
go user.loginQrChannel(ce, qrChan, eventIDChan)
session, err := user.Conn.LoginWithRetry(qrChan, user.bridge.Config.Bridge.LoginQRRegenCount)
qrChan <- "stop"
if err != nil {
var eventID string
select {
case eventID = <-eventIDChan:
default:
}
reply := mautrix.Content{
MsgType: mautrix.MsgText,
}
if err == whatsapp.ErrAlreadyLoggedIn { if err == whatsapp.ErrAlreadyLoggedIn {
ce.Reply("You're already logged in.") reply.Body = "You're already logged in"
} else if err == whatsapp.ErrLoginInProgress { } else if err == whatsapp.ErrLoginInProgress {
ce.Reply("You have a login in progress already.") reply.Body = "You have a login in progress already."
} else if err.Error() == "qr code scan timed out" { } else if err == whatsapp.ErrLoginTimedOut {
ce.Reply("QR code scan timed out. Please try again.") reply.Body = "QR code scan timed out. Please try again."
} else { } else {
user.log.Warnln("Failed to log in:", err) user.log.Warnln("Failed to log in:", err)
ce.Reply("Unknown error while logging in: %v", err) reply.Body = fmt.Sprintf("Unknown error while logging in: %v", err)
} }
msg := reply
if eventID != "" {
msg.NewContent = &reply
msg.RelatesTo = &mautrix.RelatesTo{
Type: mautrix.RelReplace,
EventID: eventID,
}
}
_, _ = ce.Bot.SendMessageEvent(ce.RoomID, mautrix.EventMessage, &msg)
return return
} }
user.Connected = true user.Connected = true