Kinda work dms

This commit is contained in:
Karmanyaah Malhotra 2021-04-27 22:49:01 -04:00
parent b35a6be635
commit 0ff534c2df
7 changed files with 155 additions and 106 deletions

View File

@ -654,7 +654,7 @@ func (handler *CommandHandler) CommandHelp(ce *CommandEvent) {
cmdPrefix + cmdSyncHelp,
cmdPrefix + cmdListHelp,
cmdPrefix + cmdOpenHelp,
// cmdPrefix + cmdPMHelp,
cmdPrefix + cmdPMHelp,
// cmdPrefix + cmdInviteLinkHelp,
// cmdPrefix + cmdJoinHelp,
// cmdPrefix + cmdCreateHelp,
@ -762,21 +762,11 @@ func (handler *CommandHandler) CommandDeleteAllPortals(ce *CommandEvent) {
}()
}
const cmdListHelp = `list groups [page] [items per page] - Get a list of all contacts and groups.`
//<contacts|groups> //TODO
const cmdListHelp = `list <contacts|groups> [page] [items per page] - Get a list of all contacts and groups.`
func formatContacts(contacts bool, input map[string]string) (result []string) {
for jid, contact := range input {
if strings.HasSuffix(jid, whatsappExt.NewUserSuffix) != contacts {
continue
}
if contacts {
result = append(result, fmt.Sprintf("* %s / %s - `%s`", contact, jid))
} else {
result = append(result, fmt.Sprintf("* %s - `%s`", contact, jid))
}
result = append(result, fmt.Sprintf("* %s - `%s`", contact, jid))
}
sort.Sort(sort.StringSlice(result))
return
@ -886,44 +876,36 @@ func (handler *CommandHandler) CommandOpen(ce *CommandEvent) {
_, _ = portal.MainIntent().InviteUser(portal.MXID, &mautrix.ReqInviteUser{UserID: user.MXID})
}
const cmdPMHelp = `pm [--force] <_international phone number_> - Open a private chat with the given phone number.`
const cmdPMHelp = `pm - To direct message someone already in a shared group start a direct chat with them in Matrix`
func (handler *CommandHandler) CommandPM(ce *CommandEvent) {
// if len(ce.Args) == 0 {
// ce.Reply("**Usage:** `pm [--force] <international phone number>`")
// return
// }
ce.Reply(fmt.Sprintf("**DEPRECATED COMMAND:** `%s`", cmdPMHelp))
return
if len(ce.Args) == 0 {
ce.Reply(fmt.Sprintf("**DEPRECATED COMMAND:** `%s`", cmdPMHelp))
return
}
// force := ce.Args[0] == "--force"
// if force {
// ce.Args = ce.Args[1:]
// }
// user := ce.User
// number := strings.Join(ce.Args, "")
// if number[0] == '+' {
// number = number[1:]
// }
// for _, char := range number {
// if char < '0' || char > '9' {
// ce.Reply("Invalid phone number.")
// return
// }
// }
// jid := number + whatsappExt.NewUserSuffix
// handler.log.Debugln("Importing", jid, "for", user)
// contact, ok := user.Conn.Store.Contacts[jid]
// if !ok {
// if !force {
// ce.Reply("Phone number not found in contacts. Try syncing contacts with `sync` first. " +
// "To create a portal anyway, use `pm --force <number>`.")
// return
// }
// contact = whatsapp.Contact{Jid: jid}
// }
// force := ce.Args[0] == "--force"
// if force {
// ce.Args = ce.Args[1:]
// }
//
// user := ce.User
//
// jid := ce.Args[0]
//
// handler.log.Debugln("Importing", jid, "for", user.MXID)
//
// contact, ok := user.Conn.Store.Contacts[jid]
// if !ok {
// if !force {
// ce.Reply("Phone number not found in contacts. Try syncing contacts with `sync` first. " +
// "To create a portal anyway, use `pm --force <number>`.")
// return
// }
// contact = whatsapp.Contact{Jid: jid}
// }
// puppet := user.bridge.GetPuppetByJID(contact.Jid)
// puppet.Sync(user, contact)
// portal := user.bridge.GetPortalByJID(database.NewPortalKey(contact.Jid, user.JID))

View File

@ -57,7 +57,7 @@ func New(dbType string, uri string, baseLog log.Logger) (*Database, error) {
}
gdb, err := gorm.Open(conn, &gorm.Config{
//Logger: logger.Default.LogMode(logger.Info),
// Logger: logger.Default.LogMode(logger.Info),
// Logger: baseLog,
DisableForeignKeyConstraintWhenMigrating: true,

View File

@ -24,6 +24,8 @@ import (
"github.com/karmanyaahm/matrix-groupme-go/types"
)
// JID is the puppet or the group
// Receiver is the "Other Person" in a DM or the group itself in a group
type PortalKey struct {
JID types.GroupMeID `gorm:"primaryKey"`
Receiver types.GroupMeID `gorm:"primaryKey"`
@ -50,6 +52,11 @@ func (key PortalKey) String() string {
return key.JID + "-" + key.Receiver
}
func (key PortalKey) IsPrivate() bool {
//also see FindPrivateChats
return key.JID != key.Receiver
}
type PortalQuery struct {
db *Database
log log.Logger
@ -82,8 +89,8 @@ func (pq *PortalQuery) GetAllByJID(jid types.GroupMeID) []*Portal {
}
func (pq *PortalQuery) FindPrivateChats(receiver types.GroupMeID) []*Portal {
print("aaaaaaaaaaaaaaaaaa wrong portal stuff")
return pq.getAll(pq.db.DB.Where("receiver = ? AND jid LIKE '%@s.whatsapp.net'", receiver))
//also see IsPrivate
return pq.getAll(pq.db.DB.Where("receiver = ? AND receiver <> jid", receiver))
}

View File

@ -178,8 +178,8 @@ type UserPortal struct {
func (user *User) SetPortalKeys(newKeys []PortalKeyWithMeta) error {
tx := user.db.Begin()
ans := tx.Where("user_jid = ?", *user.jidPtr()).Delete(&UserPortal{})
print("make sure all are deletede")
ans := tx.Where("user_jid = ?", *user.jidPtr()).Delete(UserPortal{})
if ans.Error != nil {
_ = tx.Rollback()
return ans.Error

View File

@ -25,30 +25,61 @@ func (c Client) IndexAllGroups() ([]*groupme.Group, error) {
})
}
func (c Client) LoadMessagesAfter(groupID, lastMessageID string, lastMessageFromMe bool, num int) ([]*groupme.Message, error) {
//TODO: limit max 100
i, e := c.IndexMessages(context.TODO(), groupme.ID(groupID), &groupme.IndexMessagesQuery{
AfterID: groupme.ID(lastMessageID),
Limit: num,
func (c Client) IndexAllChats() ([]*groupme.Chat, error) {
return c.IndexChats(context.TODO(), &groupme.IndexChatsQuery{
PerPage: 100, //TODO?
})
if e != nil {
return nil, e
}
return i.Messages, nil
}
func (c Client) LoadMessagesBefore(groupID, lastMessageID string, num int) ([]*groupme.Message, error) {
//TODO: limit max 100
i, e := c.IndexMessages(context.TODO(), groupme.ID(groupID), &groupme.IndexMessagesQuery{
BeforeID: groupme.ID(lastMessageID),
Limit: num,
})
//fmt.Println(groupID, lastMessageID, num, i.Count, e)
if e != nil {
return nil, e
func (c Client) LoadMessagesAfter(groupID, lastMessageID string, lastMessageFromMe bool, private bool) ([]*groupme.Message, error) {
if private {
i, e := c.IndexDirectMessages(context.TODO(), groupID, &groupme.IndexDirectMessagesQuery{
SinceID: groupme.ID(lastMessageID),
//Limit: num,
})
//fmt.Println(groupID, lastMessageID, num, i.Count, e)
if e != nil {
return nil, e
}
return i.Messages, nil
} else {
i, e := c.IndexMessages(context.TODO(), groupme.ID(groupID), &groupme.IndexMessagesQuery{
AfterID: groupme.ID(lastMessageID),
//20 for consistency with dms
Limit: 20,
})
//fmt.Println(groupID, lastMessageID, num, i.Count, e)
if e != nil {
return nil, e
}
return i.Messages, nil
}
}
func (c Client) LoadMessagesBefore(groupID, lastMessageID string, private bool) ([]*groupme.Message, error) {
if private {
i, e := c.IndexDirectMessages(context.TODO(), groupID, &groupme.IndexDirectMessagesQuery{
BeforeID: groupme.ID(lastMessageID),
//Limit: num,
})
//fmt.Println(groupID, lastMessageID, num, i.Count, e)
if e != nil {
return nil, e
}
return i.Messages, nil
} else {
//TODO: limit max 100
i, e := c.IndexMessages(context.TODO(), groupme.ID(groupID), &groupme.IndexMessagesQuery{
BeforeID: groupme.ID(lastMessageID),
//20 for consistency with dms
Limit: 20,
})
//fmt.Println(groupID, lastMessageID, num, i.Count, e)
if e != nil {
return nil, e
}
return i.Messages, nil
}
return i.Messages, nil
}
func (c *Client) RemoveFromGroup(uid, groupID types.GroupMeID) error {

View File

@ -186,7 +186,6 @@ type Portal struct {
messages chan PortalMessage
isPrivate *bool
hasRelaybot *bool
}
@ -549,7 +548,12 @@ func (portal *Portal) Sync(user *User, group groupme.Group) {
portal.hasRelaybot = &yes
}
err := user.Conn.SubscribeToGroup(context.TODO(), group.ID, user.Token)
var err error
if portal.IsPrivateChat() {
err = user.Conn.SubscribeToUser(context.TODO(), groupme.ID(portal.Key.JID), user.Token)
} else {
err = user.Conn.SubscribeToGroup(context.TODO(), groupme.ID(portal.Key.JID), user.Token)
}
if err != nil {
portal.log.Errorln("Subscribing failed, live metadata updates won't work", err)
}
@ -698,7 +702,7 @@ func (portal *Portal) BackfillHistory(user *User, lastMessageTime uint64) error
portal.log.Infoln("Backfilling history since", lastMessageID, "for", user.MXID)
for len(lastMessageID) > 0 {
portal.log.Debugln("Fetching 50 messages of history after", lastMessageID)
messages, err := user.Client.LoadMessagesAfter(portal.Key.JID, lastMessageID, lastMessageFromMe, 50)
messages, err := user.Client.LoadMessagesAfter(portal.Key.JID, lastMessageID, lastMessageFromMe, portal.IsPrivateChat())
if err != nil {
return err
}
@ -799,12 +803,12 @@ func (portal *Portal) FillInitialHistory(user *User) error {
before := ""
chunkNum := 1
for n > 0 {
count := 50
count := 20
if n < count {
count = n
}
portal.log.Debugfln("Fetching chunk %d (%d messages / %d cap) before message %s", chunkNum, count, n, before)
chunk, err := user.Client.LoadMessagesBefore(portal.Key.JID, before, count)
chunk, err := user.Client.LoadMessagesBefore(portal.Key.JID, before, portal.IsPrivateChat())
if err != nil {
return err
}
@ -1062,11 +1066,7 @@ func (portal *Portal) CreateMatrixRoom(user *User) error {
}
func (portal *Portal) IsPrivateChat() bool {
if portal.isPrivate == nil {
val := strings.HasSuffix(portal.Key.JID, whatsappExt.NewUserSuffix)
portal.isPrivate = &val
}
return *portal.isPrivate
return portal.Key.IsPrivate()
}
func (portal *Portal) HasRelaybot() bool {

75
user.go
View File

@ -378,9 +378,15 @@ func (user *User) Login(ce *CommandEvent) {
type Chat struct {
Portal *Portal
LastMessageTime uint64
Group groupme.Group
Group *groupme.Group
DM *groupme.Chat
}
////returns private chat assuming one of group or dm have been initialized properly
//func (c Chat) IsPrivate() bool {
// return c.Group == nil
//}
type ChatList []Chat
func (cl ChatList) Len() int {
@ -536,44 +542,67 @@ func (user *User) HandleChatList() {
chatMap := make(map[string]groupme.Group)
chats, err := user.Client.IndexAllGroups()
if err != nil {
log.Fatal(err) //TODO: handle
user.log.Errorln("chat sync error", err) //TODO: handle
return
}
for _, chat := range chats {
chatMap[chat.ID.String()] = *chat
}
user.chatListReceived <- struct{}{}
user.log.Infoln("Chat list received")
user.GroupList = chatMap
go user.syncPortals(chatMap, false)
dmMap := make(map[string]groupme.Chat)
dms, err := user.Client.IndexAllChats()
if err != nil {
user.log.Errorln("chat sync error", err) //TODO: handle
return
}
for _, dm := range dms {
dmMap[dm.OtherUser.ID.String()] = *dm
}
user.ChatList = dmMap
user.log.Infoln("Chat list received")
user.chatListReceived <- struct{}{}
go user.syncPortals(false)
}
func (user *User) syncPortals(chatMap map[string]groupme.Group, createAll bool) {
if chatMap == nil {
// chatMap = user.Conn.Store.Chats
log.Fatal("chatmap nil major oops")
}
func (user *User) syncPortals(createAll bool) {
user.log.Infoln("Reading chat list")
chats := make(ChatList, 0, len(chatMap))
chats := make(ChatList, 0, len(user.GroupList)+len(user.ChatList))
existingKeys := user.GetInCommunityMap()
portalKeys := make([]database.PortalKeyWithMeta, 0, len(chatMap))
for _, chat := range chatMap {
portal := user.bridge.GetPortalByJID(database.GroupPortalKey(chat.ID.String()))
portalKeys := make([]database.PortalKeyWithMeta, 0, cap(chats))
for _, group := range user.GroupList {
portal := user.bridge.GetPortalByJID(database.GroupPortalKey(group.ID.String()))
chats = append(chats, Chat{
Portal: portal,
LastMessageTime: uint64(chat.UpdatedAt.ToTime().Unix()),
Group: chat,
LastMessageTime: uint64(group.UpdatedAt.ToTime().Unix()),
Group: &group,
})
}
for _, dm := range user.ChatList {
portal := user.bridge.GetPortalByJID(database.NewPortalKey(dm.OtherUser.ID.String(), user.JID))
chats = append(chats, Chat{
Portal: portal,
LastMessageTime: uint64(dm.UpdatedAt.ToTime().Unix()),
DM: &dm,
})
}
for _, chat := range chats {
var inCommunity, ok bool
if inCommunity, ok = existingKeys[portal.Key]; !ok || !inCommunity {
inCommunity = user.addPortalToCommunity(portal)
if portal.IsPrivateChat() {
puppet := user.bridge.GetPuppetByJID(portal.Key.JID)
if inCommunity, ok = existingKeys[chat.Portal.Key]; !ok || !inCommunity {
inCommunity = user.addPortalToCommunity(chat.Portal)
if chat.Portal.IsPrivateChat() {
puppet := user.bridge.GetPuppetByJID(chat.Portal.Key.JID)
user.addPuppetToCommunity(puppet)
}
}
portalKeys = append(portalKeys, database.PortalKeyWithMeta{PortalKey: portal.Key, InCommunity: inCommunity})
portalKeys = append(portalKeys, database.PortalKeyWithMeta{PortalKey: chat.Portal.Key, InCommunity: inCommunity})
}
user.log.Infoln("Read chat list, updating user-portal mapping")
@ -594,11 +623,11 @@ func (user *User) syncPortals(chatMap map[string]groupme.Group, createAll bool)
if chat.LastMessageTime+user.bridge.Config.Bridge.SyncChatMaxAge < now {
break
}
wg.Add(1)
go func(chat Chat) {
wg.Add(1)
create := (chat.LastMessageTime >= user.LastConnection && user.LastConnection > 0) || i < limit
if len(chat.Portal.MXID) > 0 || create || createAll {
chat.Portal.Sync(user, chat.Group)
chat.Portal.Sync(user, *chat.Group)
err := chat.Portal.BackfillHistory(user, chat.LastMessageTime)
if err != nil {
chat.Portal.log.Errorln("Error backfilling history:", err)