diff --git a/telegram/utils.go b/telegram/utils.go index c12321d..a281a90 100644 --- a/telegram/utils.go +++ b/telegram/utils.go @@ -301,6 +301,17 @@ func (c *Client) SendMUCStatuses(chatID int64) { Filter: &client.ChatMembersFilterMembers{}, }) if err == nil { + chatIDString := strconv.FormatInt(chatID, 10) + + myNickname := "me" + if c.me != nil { + myNickname := c.me.FirstName + if c.me.LastName != "" { + myNickname = myNickname + " " + c.me.LastName + } + } + myAffiliation := "member" + for _, member := range members.Members { var senderId int64 switch member.MemberId.MessageSenderType() { @@ -311,15 +322,35 @@ func (c *Client) SendMUCStatuses(chatID int64) { memberChat, _ := member.MemberId.(*client.MessageSenderChat) senderId = memberChat.ChatId } + + nickname := c.formatContact(senderId) + affiliation := c.memberStatusToAffiliation(member.Status) + if c.me != nil && senderId == c.me.Id { + myNickname = nickname + myAffiliation = affiliation + continue + } + gateway.SendPresence( c.xmpp, c.jid, - gateway.SPFrom(strconv.FormatInt(chatID, 10)), - gateway.SPResource(c.formatContact(senderId)), + gateway.SPFrom(chatIDString), + gateway.SPResource(nickname), gateway.SPImmed(true), - gateway.SPAffiliation(c.memberStatusToAffiliation(member.Status)), + gateway.SPAffiliation(affiliation), ) } + + // according to the spec, own member entry should be sent the last + gateway.SendPresence( + c.xmpp, + c.jid, + gateway.SPFrom(chatIDString), + gateway.SPResource(myNickname), + gateway.SPImmed(true), + gateway.SPAffiliation(myAffiliation), + gateway.SPMUCStatusCodes([]uint16{110, 210}), + ) } } diff --git a/xmpp/extensions/extensions.go b/xmpp/extensions/extensions.go index 0b7269f..1c32fcd 100644 --- a/xmpp/extensions/extensions.go +++ b/xmpp/extensions/extensions.go @@ -215,8 +215,9 @@ type QueryRegisterRemove struct { // PresenceXMucUserExtension is from XEP-0045 type PresenceXMucUserExtension struct { - XMLName xml.Name `xml:"http://jabber.org/protocol/muc#user x"` - Item PresenceXMucUserItem + XMLName xml.Name `xml:"http://jabber.org/protocol/muc#user x"` + Item PresenceXMucUserItem + Statuses []PresenceXMucUserStatus } // PresenceXMucUserItem is from XEP-0045 @@ -226,6 +227,12 @@ type PresenceXMucUserItem struct { Role string `xml:"role,attr"` } +// PresenceXMucUserStatus is from XEP-0045 +type PresenceXMucUserStatus struct { + XMLName xml.Name `xml:"status"` + Code uint16 `xml:"code,attr"` +} + // Namespace is a namespace! func (c PresenceNickExtension) Namespace() string { return c.XMLName.Space diff --git a/xmpp/gateway/gateway.go b/xmpp/gateway/gateway.go index c09a061..e4a1be7 100644 --- a/xmpp/gateway/gateway.go +++ b/xmpp/gateway/gateway.go @@ -243,6 +243,9 @@ var SPImmed = args.NewBool(args.Default(true)) // SPAffiliation is a XEP-0045 MUC affiliation var SPAffiliation = args.NewString() +// SPMUCStatusCodes is a set of XEP-0045 MUC status codes +var SPMUCStatusCodes = args.New() + func newPresence(bareJid string, to string, args ...args.V) stanza.Presence { var presenceFrom string if SPFrom.IsSet(args) { @@ -301,12 +304,21 @@ func newPresence(bareJid string, to string, args ...args.V) stanza.Presence { if SPAffiliation.IsSet(args) { affiliation := SPAffiliation.Get(args) if affiliation != "" { - presence.Extensions = append(presence.Extensions, extensions.PresenceXMucUserExtension{ + userExt := extensions.PresenceXMucUserExtension{ Item: extensions.PresenceXMucUserItem{ Affiliation: affiliation, Role: affilationToRole(affiliation), }, - }) + } + if SPMUCStatusCodes.IsSet(args) { + statusCodes := SPMUCStatusCodes.Get(args).([]uint16) + for _, statusCode := range statusCodes { + userExt.Statuses = append(userExt.Statuses, extensions.PresenceXMucUserStatus{ + Code: statusCode, + }) + } + } + presence.Extensions = append(presence.Extensions, userExt) } }