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

View file

@ -60,6 +60,9 @@ bridge:
# WhatsApp connection timeout in seconds.
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.
max_connection_attempts: 3
# Number of seconds to wait between connection attempts.

78
user.go
View file

@ -221,11 +221,11 @@ func (user *User) IsLoggedIn() bool {
return user.Session != nil || user.Conn != nil
}
func (user *User) Login(ce *CommandEvent) {
qrChan := make(chan string, 2)
go func() {
code := <-qrChan
if code == "error" {
func (user *User) loginQrChannel(ce *CommandEvent, qrChan <-chan string, eventIDChan chan<- string) {
var qrEventID string
for code := range qrChan {
fmt.Println("qrChan:", code)
if code == "stop" {
return
}
qrCode, err := qrcode.Encode(code, qrcode.Low, 256)
@ -244,24 +244,70 @@ func (user *User) Login(ce *CommandEvent) {
return
}
_, err = bot.SendImage(ce.RoomID, string(code), resp.ContentURI)
if err != nil {
user.log.Errorln("Failed to send QR code to user:", err)
if qrEventID == "" {
sendResp, err := bot.SendImage(ce.RoomID, code, resp.ContentURI)
if err != nil {
user.log.Errorln("Failed to send QR code to user:", err)
return
}
qrEventID = sendResp.EventID
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 {
user.log.Errorln("Failed to send edited QR code to user:", err)
}
}
}()
session, err := user.Conn.Login(qrChan)
}
}
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 {
qrChan <- "error"
var eventID string
select {
case eventID = <-eventIDChan:
default:
}
reply := mautrix.Content{
MsgType: mautrix.MsgText,
}
if err == whatsapp.ErrAlreadyLoggedIn {
ce.Reply("You're already logged in.")
reply.Body = "You're already logged in"
} else if err == whatsapp.ErrLoginInProgress {
ce.Reply("You have a login in progress already.")
} else if err.Error() == "qr code scan timed out" {
ce.Reply("QR code scan timed out. Please try again.")
reply.Body = "You have a login in progress already."
} else if err == whatsapp.ErrLoginTimedOut {
reply.Body = "QR code scan timed out. Please try again."
} else {
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
}
user.Connected = true