mirror of
https://github.com/tulir/mautrix-whatsapp
synced 2024-06-02 11:08:59 +02:00
Updates from CR
Co-authored-by: Tulir Asokan <tulir@maunium.net>
This commit is contained in:
parent
83d397900f
commit
c664e5f107
|
@ -606,9 +606,6 @@ func (handler *CommandHandler) CommandLogout(ce *CommandEvent) {
|
||||||
ce.User.removeFromJIDMap(BridgeState{StateEvent: StateLoggedOut})
|
ce.User.removeFromJIDMap(BridgeState{StateEvent: StateLoggedOut})
|
||||||
ce.User.DeleteConnection()
|
ce.User.DeleteConnection()
|
||||||
ce.User.DeleteSession()
|
ce.User.DeleteSession()
|
||||||
ce.Bridge.DB.BackfillQuery.DeleteAll(ce.User.MXID)
|
|
||||||
ce.Bridge.DB.HistorySyncQuery.DeleteAllConversations(ce.User.MXID)
|
|
||||||
ce.Bridge.DB.HistorySyncQuery.DeleteAllMessages(ce.User.MXID)
|
|
||||||
ce.Reply("Logged out successfully.")
|
ce.Reply("Logged out successfully.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -850,10 +847,7 @@ func (handler *CommandHandler) CommandBackfill(ce *CommandEvent) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !ce.Bridge.Config.Bridge.HistorySync.Backfill {
|
if !ce.Bridge.Config.Bridge.HistorySync.Backfill {
|
||||||
ce.Bot.SendMessageEvent(ce.RoomID, event.EventMessage, &event.MessageEventContent{
|
ce.Reply("Backfill is not enabled for this bridge.")
|
||||||
MsgType: event.MsgNotice,
|
|
||||||
Body: "Backfill is not enabled for this bridge.",
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
batchSize := 100
|
batchSize := 100
|
||||||
|
|
|
@ -1,12 +1,25 @@
|
||||||
package upgrades
|
package upgrades
|
||||||
|
|
||||||
import "database/sql"
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
upgrades[39] = upgrade{"Add backfill queue", func(tx *sql.Tx, ctx context) error {
|
upgrades[39] = upgrade{"Add backfill queue", func(tx *sql.Tx, ctx context) error {
|
||||||
_, err := tx.Exec(`
|
// The queue_id needs to auto-increment every insertion. For SQLite,
|
||||||
|
// INTEGER PRIMARY KEY is an alias for the ROWID, so it will
|
||||||
|
// auto-increment. See https://sqlite.org/lang_createtable.html#rowid
|
||||||
|
// For Postgres, we need to add GENERATED ALWAYS AS IDENTITY for the
|
||||||
|
// same functionality.
|
||||||
|
queueIDColumnTypeModifier := ""
|
||||||
|
if ctx.dialect == Postgres {
|
||||||
|
queueIDColumnTypeModifier = "GENERATED ALWAYS AS IDENTITY"
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := tx.Exec(fmt.Sprintf(`
|
||||||
CREATE TABLE backfill_queue (
|
CREATE TABLE backfill_queue (
|
||||||
queue_id INTEGER PRIMARY KEY,
|
queue_id INTEGER PRIMARY KEY %s,
|
||||||
user_mxid TEXT,
|
user_mxid TEXT,
|
||||||
type INTEGER NOT NULL,
|
type INTEGER NOT NULL,
|
||||||
priority INTEGER NOT NULL,
|
priority INTEGER NOT NULL,
|
||||||
|
@ -22,34 +35,11 @@ func init() {
|
||||||
FOREIGN KEY (user_mxid) REFERENCES "user"(mxid) ON DELETE CASCADE ON UPDATE CASCADE,
|
FOREIGN KEY (user_mxid) REFERENCES "user"(mxid) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||||
FOREIGN KEY (portal_jid, portal_receiver) REFERENCES portal(jid, receiver) ON DELETE CASCADE
|
FOREIGN KEY (portal_jid, portal_receiver) REFERENCES portal(jid, receiver) ON DELETE CASCADE
|
||||||
)
|
)
|
||||||
`)
|
`, queueIDColumnTypeModifier))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// The queue_id needs to auto-increment every insertion. For SQLite,
|
|
||||||
// INTEGER PRIMARY KEY is an alias for the ROWID, so it will
|
|
||||||
// auto-increment. See https://sqlite.org/lang_createtable.html#rowid
|
|
||||||
// For Postgres, we have to manually add the sequence.
|
|
||||||
if ctx.dialect == Postgres {
|
|
||||||
_, err = tx.Exec(`
|
|
||||||
CREATE SEQUENCE backfill_queue_queue_id_seq
|
|
||||||
START WITH 1
|
|
||||||
OWNED BY backfill_queue.queue_id
|
|
||||||
`)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
_, err = tx.Exec(`
|
|
||||||
ALTER TABLE backfill_queue
|
|
||||||
ALTER COLUMN queue_id
|
|
||||||
SET DEFAULT nextval('backfill_queue_queue_id_seq'::regclass)
|
|
||||||
`)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,88 +6,45 @@ import (
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
upgrades[40] = upgrade{"Store history syncs for later backfills", func(tx *sql.Tx, ctx context) error {
|
upgrades[40] = upgrade{"Store history syncs for later backfills", func(tx *sql.Tx, ctx context) error {
|
||||||
if ctx.dialect == Postgres {
|
_, err := tx.Exec(`
|
||||||
_, err := tx.Exec(`
|
CREATE TABLE history_sync_conversation (
|
||||||
CREATE TABLE history_sync_conversation (
|
user_mxid TEXT,
|
||||||
user_mxid TEXT,
|
conversation_id TEXT,
|
||||||
conversation_id TEXT,
|
portal_jid TEXT,
|
||||||
portal_jid TEXT,
|
portal_receiver TEXT,
|
||||||
portal_receiver TEXT,
|
last_message_timestamp TIMESTAMP,
|
||||||
last_message_timestamp TIMESTAMP,
|
archived BOOLEAN,
|
||||||
archived BOOLEAN,
|
pinned INTEGER,
|
||||||
pinned INTEGER,
|
mute_end_time TIMESTAMP,
|
||||||
mute_end_time TIMESTAMP,
|
disappearing_mode INTEGER,
|
||||||
disappearing_mode INTEGER,
|
end_of_history_transfer_type INTEGER,
|
||||||
end_of_history_transfer_type INTEGER,
|
ephemeral_expiration INTEGER,
|
||||||
ephemeral_expiration INTEGER,
|
marked_as_unread BOOLEAN,
|
||||||
marked_as_unread BOOLEAN,
|
unread_count INTEGER,
|
||||||
unread_count INTEGER,
|
|
||||||
|
|
||||||
PRIMARY KEY (user_mxid, conversation_id),
|
PRIMARY KEY (user_mxid, conversation_id),
|
||||||
FOREIGN KEY (user_mxid) REFERENCES "user"(mxid) ON DELETE CASCADE ON UPDATE CASCADE,
|
FOREIGN KEY (user_mxid) REFERENCES "user"(mxid) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||||
FOREIGN KEY (portal_jid, portal_receiver) REFERENCES portal(jid, receiver) ON DELETE CASCADE ON UPDATE CASCADE
|
FOREIGN KEY (portal_jid, portal_receiver) REFERENCES portal(jid, receiver) ON DELETE CASCADE ON UPDATE CASCADE
|
||||||
)
|
)
|
||||||
`)
|
`)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
_, err = tx.Exec(`
|
_, err = tx.Exec(`
|
||||||
CREATE TABLE history_sync_message (
|
CREATE TABLE history_sync_message (
|
||||||
user_mxid TEXT,
|
user_mxid TEXT,
|
||||||
conversation_id TEXT,
|
conversation_id TEXT,
|
||||||
message_id TEXT,
|
message_id TEXT,
|
||||||
timestamp TIMESTAMP,
|
timestamp TIMESTAMP,
|
||||||
data BYTEA,
|
data BYTEA,
|
||||||
|
|
||||||
PRIMARY KEY (user_mxid, conversation_id, message_id),
|
PRIMARY KEY (user_mxid, conversation_id, message_id),
|
||||||
FOREIGN KEY (user_mxid) REFERENCES "user"(mxid) ON DELETE CASCADE ON UPDATE CASCADE,
|
FOREIGN KEY (user_mxid) REFERENCES "user"(mxid) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||||
FOREIGN KEY (user_mxid, conversation_id) REFERENCES history_sync_conversation(user_mxid, conversation_id) ON DELETE CASCADE
|
FOREIGN KEY (user_mxid, conversation_id) REFERENCES history_sync_conversation(user_mxid, conversation_id) ON DELETE CASCADE
|
||||||
)
|
)
|
||||||
`)
|
`)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
|
||||||
} else if ctx.dialect == SQLite {
|
|
||||||
_, err := tx.Exec(`
|
|
||||||
CREATE TABLE history_sync_conversation (
|
|
||||||
user_mxid TEXT,
|
|
||||||
conversation_id TEXT,
|
|
||||||
portal_jid TEXT,
|
|
||||||
portal_receiver TEXT,
|
|
||||||
last_message_timestamp DATETIME,
|
|
||||||
archived INTEGER,
|
|
||||||
pinned INTEGER,
|
|
||||||
mute_end_time DATETIME,
|
|
||||||
disappearing_mode INTEGER,
|
|
||||||
end_of_history_transfer_type INTEGER,
|
|
||||||
ephemeral_expiration INTEGER,
|
|
||||||
marked_as_unread INTEGER,
|
|
||||||
unread_count INTEGER,
|
|
||||||
|
|
||||||
PRIMARY KEY (user_mxid, conversation_id),
|
|
||||||
FOREIGN KEY (user_mxid) REFERENCES "user"(mxid) ON DELETE CASCADE ON UPDATE CASCADE,
|
|
||||||
FOREIGN KEY (portal_jid, portal_receiver) REFERENCES portal(jid, receiver) ON DELETE CASCADE ON UPDATE CASCADE
|
|
||||||
)
|
|
||||||
`)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
_, err = tx.Exec(`
|
|
||||||
CREATE TABLE history_sync_message (
|
|
||||||
user_mxid TEXT,
|
|
||||||
conversation_id TEXT,
|
|
||||||
message_id TEXT,
|
|
||||||
timestamp DATETIME,
|
|
||||||
data BLOB,
|
|
||||||
|
|
||||||
PRIMARY KEY (user_mxid, conversation_id, message_id),
|
|
||||||
FOREIGN KEY (user_mxid) REFERENCES "user"(mxid) ON DELETE CASCADE ON UPDATE CASCADE,
|
|
||||||
FOREIGN KEY (user_mxid, conversation_id) REFERENCES history_sync_conversation(user_mxid, conversation_id) ON DELETE CASCADE
|
|
||||||
)
|
|
||||||
`)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -436,9 +436,6 @@ func (prov *ProvisioningAPI) Logout(w http.ResponseWriter, r *http.Request) {
|
||||||
user.bridge.Metrics.TrackConnectionState(user.JID, false)
|
user.bridge.Metrics.TrackConnectionState(user.JID, false)
|
||||||
user.removeFromJIDMap(BridgeState{StateEvent: StateLoggedOut})
|
user.removeFromJIDMap(BridgeState{StateEvent: StateLoggedOut})
|
||||||
user.DeleteSession()
|
user.DeleteSession()
|
||||||
prov.bridge.DB.BackfillQuery.DeleteAll(user.MXID)
|
|
||||||
prov.bridge.DB.HistorySyncQuery.DeleteAllConversations(user.MXID)
|
|
||||||
prov.bridge.DB.HistorySyncQuery.DeleteAllMessages(user.MXID)
|
|
||||||
jsonResponse(w, http.StatusOK, Response{true, "Logged out successfully."})
|
jsonResponse(w, http.StatusOK, Response{true, "Logged out successfully."})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
12
user.go
12
user.go
|
@ -412,6 +412,11 @@ func (user *User) DeleteSession() {
|
||||||
user.JID = types.EmptyJID
|
user.JID = types.EmptyJID
|
||||||
user.Update()
|
user.Update()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Delete all of the backfill and history sync data.
|
||||||
|
user.bridge.DB.BackfillQuery.DeleteAll(user.MXID)
|
||||||
|
user.bridge.DB.HistorySyncQuery.DeleteAllConversations(user.MXID)
|
||||||
|
user.bridge.DB.HistorySyncQuery.DeleteAllMessages(user.MXID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (user *User) IsConnected() bool {
|
func (user *User) IsConnected() bool {
|
||||||
|
@ -563,11 +568,18 @@ func (user *User) HandleEvent(event interface{}) {
|
||||||
go user.tryAutomaticDoublePuppeting()
|
go user.tryAutomaticDoublePuppeting()
|
||||||
case *events.OfflineSyncPreview:
|
case *events.OfflineSyncPreview:
|
||||||
user.log.Infofln("Server says it's going to send %d messages and %d receipts that were missed during downtime", v.Messages, v.Receipts)
|
user.log.Infofln("Server says it's going to send %d messages and %d receipts that were missed during downtime", v.Messages, v.Receipts)
|
||||||
|
go user.sendBridgeState(BridgeState{
|
||||||
|
StateEvent: StateBackfilling,
|
||||||
|
Message: fmt.Sprintf("backfilling %d messages and %d receipts", v.Messages, v.Receipts),
|
||||||
|
})
|
||||||
case *events.OfflineSyncCompleted:
|
case *events.OfflineSyncCompleted:
|
||||||
if !user.PhoneRecentlySeen(true) {
|
if !user.PhoneRecentlySeen(true) {
|
||||||
user.log.Infofln("Offline sync completed, but phone last seen date is still %s - sending phone offline bridge status", user.PhoneLastSeen)
|
user.log.Infofln("Offline sync completed, but phone last seen date is still %s - sending phone offline bridge status", user.PhoneLastSeen)
|
||||||
go user.sendBridgeState(BridgeState{StateEvent: StateTransientDisconnect, Error: WAPhoneOffline})
|
go user.sendBridgeState(BridgeState{StateEvent: StateTransientDisconnect, Error: WAPhoneOffline})
|
||||||
} else {
|
} else {
|
||||||
|
if user.GetPrevBridgeState().StateEvent == StateBackfilling {
|
||||||
|
user.log.Infoln("Offline sync completed")
|
||||||
|
}
|
||||||
go user.sendBridgeState(BridgeState{StateEvent: StateConnected})
|
go user.sendBridgeState(BridgeState{StateEvent: StateConnected})
|
||||||
}
|
}
|
||||||
case *events.AppStateSyncComplete:
|
case *events.AppStateSyncComplete:
|
||||||
|
|
Loading…
Reference in a new issue