Basic backlogging
This commit is contained in:
parent
e1b838d304
commit
b0644c3a17
5 changed files with 51 additions and 5 deletions
|
@ -230,7 +230,7 @@ func (a *Account) eventInternal(event *Event) error {
|
|||
err = mx.RoomInvite(mx_room_id, mx_user_id)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "already in the room") {
|
||||
err = nil
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
@ -260,6 +260,16 @@ func (a *Account) eventInternal(event *Event) error {
|
|||
}
|
||||
}
|
||||
|
||||
if event.Id != "" {
|
||||
cache_key := fmt.Sprintf("%s/event_seen/%s/%s",
|
||||
a.Protocol, mx_room_id, event.Id)
|
||||
if !dbCacheTestAndSet(cache_key, "yes") {
|
||||
// false: cache key was not modified, meaning we
|
||||
// already saw the event
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
typ := "m.text"
|
||||
if event.Type == EVENT_ACTION {
|
||||
typ = "m.emote"
|
||||
|
|
|
@ -98,6 +98,11 @@ const (
|
|||
type Event struct {
|
||||
Type EventType
|
||||
|
||||
// If non-empty, the event Id is used to deduplicate events in a channel
|
||||
// This is usefull for backends that provide a backlog of channel messages
|
||||
// when (re-)joining a room
|
||||
Id string
|
||||
|
||||
// UserID of the user that sent the event
|
||||
// If this is a direct message event, this event can only have been authored
|
||||
// by the user we are talking to (and not by ourself)
|
||||
|
@ -120,12 +125,18 @@ type Event struct {
|
|||
|
||||
type UserInfo struct {
|
||||
DisplayName string
|
||||
|
||||
// If non-empty, the Filename of the avatar object will be used by Easybridge
|
||||
// to deduplicate the update events and prevent needless reuploads.
|
||||
// Example strategy that works for the mattermost backend: use the update timestamp as fictious file name
|
||||
Avatar MediaObject
|
||||
}
|
||||
|
||||
type RoomInfo struct {
|
||||
Name string
|
||||
Topic string
|
||||
|
||||
// Same deduplication comment as for UserInfo.Avatar
|
||||
Picture MediaObject
|
||||
}
|
||||
|
||||
|
|
|
@ -354,6 +354,22 @@ func (mm *Mattermost) handleConnected() {
|
|||
} else {
|
||||
log.Warnf("Could not get channel members: %s", resp.Error)
|
||||
}
|
||||
|
||||
// Read backlog
|
||||
// TODO: remember what was the last seen post in this channel
|
||||
backlog, resp := mm.conn.Client.GetPostsForChannel(ch.Id, 0, 1000, "")
|
||||
if resp.Error == nil {
|
||||
for i := 0; i < len(backlog.Order); i++ {
|
||||
post_id := backlog.Order[len(backlog.Order)-i-1]
|
||||
post := backlog.Posts[post_id]
|
||||
post_time := time.Unix(post.CreateAt/1000, 0)
|
||||
post.Message = fmt.Sprintf("[%s] %s",
|
||||
post_time.Format("2006-01-02 15:04:05 MST"), post.Message)
|
||||
mm.handlePost(ch.Name, post, true)
|
||||
}
|
||||
} else {
|
||||
log.Warnf("Could not get channel backlog: %s", resp.Error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -425,6 +441,10 @@ func (mm *Mattermost) handlePosted(msg *model.WebSocketEvent) error {
|
|||
return err
|
||||
}
|
||||
|
||||
return mm.handlePost(channel_name, &post, false)
|
||||
}
|
||||
|
||||
func (mm *Mattermost) handlePost(channel_name string, post *model.Post, only_messages bool) error {
|
||||
// Skip self messages
|
||||
if post.UserId == mm.conn.User.Id {
|
||||
return nil
|
||||
|
@ -440,6 +460,7 @@ func (mm *Mattermost) handlePosted(msg *model.WebSocketEvent) error {
|
|||
|
||||
// Build message event
|
||||
msg_ev := &Event{
|
||||
Id: post.Id,
|
||||
Author: userId,
|
||||
Text: post.Message,
|
||||
Type: EVENT_MESSAGE,
|
||||
|
@ -489,10 +510,12 @@ func (mm *Mattermost) handlePosted(msg *model.WebSocketEvent) error {
|
|||
mm.ensureJoined(user, roomId)
|
||||
|
||||
if post.Type == "system_header_change" {
|
||||
if !only_messages {
|
||||
new_header := post.Props["new_header"].(string)
|
||||
mm.handler.RoomInfoUpdated(roomId, userId, &RoomInfo{
|
||||
Topic: new_header,
|
||||
})
|
||||
}
|
||||
} else if post.Type == "" || post.Type == "me" {
|
||||
msg_ev.Room = roomId
|
||||
mm.handler.Event(msg_ev)
|
||||
|
|
1
main.go
1
main.go
|
@ -102,6 +102,7 @@ func readRegistration(file string) mxlib.Registration {
|
|||
AsToken: hex.EncodeToString(rnd[:32]),
|
||||
HsToken: hex.EncodeToString(rnd[32:]),
|
||||
SenderLocalpart: "_ezbr_",
|
||||
RateLimited: false,
|
||||
Namespaces: mxlib.RegistrationNamespaceSet{
|
||||
Users: []mxlib.RegistrationNamespace{
|
||||
mxlib.RegistrationNamespace{
|
||||
|
|
|
@ -10,6 +10,7 @@ type Registration struct {
|
|||
AsToken string `yaml:"as_token"`
|
||||
HsToken string `yaml:"hs_token"`
|
||||
SenderLocalpart string `yaml:"sender_localpart"`
|
||||
RateLimited bool `yaml:"rate_limited"`
|
||||
Namespaces RegistrationNamespaceSet `yaml:"namespaces"`
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue