Fix XMPP && transmit nicknames from bridges to matrix
This commit is contained in:
parent
584312f308
commit
86942a34a2
|
@ -89,8 +89,18 @@ func (a *Account) Left(roomId RoomID) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Account) UserInfoUpdated(user UserID, info *UserInfo) {
|
func (a *Account) UserInfoUpdated(user UserID, info *UserInfo) {
|
||||||
|
mx_user_id, err := dbGetMxUser(a.Protocol, user)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if info.DisplayName != "" {
|
||||||
|
mxProfileDisplayname(mx_user_id, fmt.Sprintf("%s (%s)", info.DisplayName, a.Protocol))
|
||||||
|
}
|
||||||
|
if info.Avatar != nil {
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (a *Account) RoomInfoUpdated(roomId RoomID, author UserID, info *RoomInfo) {
|
func (a *Account) RoomInfoUpdated(roomId RoomID, author UserID, info *RoomInfo) {
|
||||||
mx_room_id, err := dbGetMxRoom(a.Protocol, roomId)
|
mx_room_id, err := dbGetMxRoom(a.Protocol, roomId)
|
||||||
|
@ -98,7 +108,7 @@ func (a *Account) RoomInfoUpdated(roomId RoomID, author UserID, info *RoomInfo)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
as_mxid := fmt.Sprintf("@%s:%s", registration.SenderLocalpart, config.MatrixDomain)
|
as_mxid := ezbrMxId()
|
||||||
if len(author) > 0 {
|
if len(author) > 0 {
|
||||||
mx_user_id, err := dbGetMxUser(a.Protocol, author)
|
mx_user_id, err := dbGetMxUser(a.Protocol, author)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
@ -109,8 +119,15 @@ func (a *Account) RoomInfoUpdated(roomId RoomID, author UserID, info *RoomInfo)
|
||||||
if info.Topic != "" {
|
if info.Topic != "" {
|
||||||
mxRoomTopicAs(mx_room_id, info.Topic, as_mxid)
|
mxRoomTopicAs(mx_room_id, info.Topic, as_mxid)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if info.Name != "" {
|
||||||
|
mxRoomNameAs(mx_room_id, info.Name, as_mxid)
|
||||||
|
}
|
||||||
|
|
||||||
|
if info.Picture != nil {
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (a *Account) Event(event *Event) {
|
func (a *Account) Event(event *Event) {
|
||||||
mx_user_id, err := dbGetMxUser(a.Protocol, event.Author)
|
mx_user_id, err := dbGetMxUser(a.Protocol, event.Author)
|
||||||
|
|
|
@ -13,6 +13,12 @@ import (
|
||||||
. "git.deuxfleurs.fr/Deuxfleurs/easybridge/mxlib"
|
. "git.deuxfleurs.fr/Deuxfleurs/easybridge/mxlib"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func ezbrMxId() string {
|
||||||
|
return fmt.Sprintf("@%s:%s", registration.SenderLocalpart, config.MatrixDomain)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----
|
||||||
|
|
||||||
var httpClient *http.Client
|
var httpClient *http.Client
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -234,6 +240,13 @@ func mxPutStateAs(room string, event_type string, key string, content map[string
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func mxRoomNameAs(room string, name string, as_user string) error {
|
||||||
|
content := map[string]interface{} {
|
||||||
|
"name": name,
|
||||||
|
}
|
||||||
|
return mxPutStateAs(room, "m.room.name", "", content, as_user)
|
||||||
|
}
|
||||||
|
|
||||||
func mxRoomTopicAs(room string, topic string, as_user string) error {
|
func mxRoomTopicAs(room string, topic string, as_user string) error {
|
||||||
content := map[string]interface{} {
|
content := map[string]interface{} {
|
||||||
"topic": topic,
|
"topic": topic,
|
||||||
|
|
|
@ -34,12 +34,11 @@ func Start(r *mxlib.Registration, c *Config) (chan error, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
svc_mxid := fmt.Sprintf("@%s:%s", registration.SenderLocalpart, config.MatrixDomain)
|
|
||||||
err = mxRegisterUser(registration.SenderLocalpart)
|
err = mxRegisterUser(registration.SenderLocalpart)
|
||||||
if mxe, ok := err.(*mxlib.MxError); !ok || mxe.ErrCode != "M_USER_IN_USE" {
|
if mxe, ok := err.(*mxlib.MxError); !ok || mxe.ErrCode != "M_USER_IN_USE" {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
err = mxProfileDisplayname(svc_mxid, "Easybridge")
|
err = mxProfileDisplayname(ezbrMxId(), "Easybridge")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -123,6 +122,8 @@ func handleTxnEvent(e *mxlib.Event) {
|
||||||
ev.Author = acct.Conn.User()
|
ev.Author = acct.Conn.User()
|
||||||
ev.Room = room.RoomID
|
ev.Room = room.RoomID
|
||||||
acct.Conn.Send(ev)
|
acct.Conn.Send(ev)
|
||||||
|
} else {
|
||||||
|
log.Debugf("Could not find room account for %s %s %s", e.Sender, room.Protocol, room.RoomID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if e.Type == "m.room.member" {
|
} else if e.Type == "m.room.member" {
|
||||||
|
@ -141,6 +142,8 @@ func handleTxnEvent(e *mxlib.Event) {
|
||||||
if acct != nil {
|
if acct != nil {
|
||||||
acct.Conn.Leave(room.RoomID)
|
acct.Conn.Leave(room.RoomID)
|
||||||
// TODO: manage autojoin list, remove this room
|
// TODO: manage autojoin list, remove this room
|
||||||
|
} else {
|
||||||
|
log.Debugf("Could not find room account for %s %s %s", e.Sender, room.Protocol, room.RoomID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -113,8 +113,7 @@ type Event struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type UserInfo struct {
|
type UserInfo struct {
|
||||||
Nickname string
|
DisplayName string
|
||||||
Status string
|
|
||||||
Avatar MediaObject
|
Avatar MediaObject
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -263,12 +263,16 @@ func (irc *IRC) ircJoin(c *girc.Client, e girc.Event) {
|
||||||
if e.Source.Name == irc.nick {
|
if e.Source.Name == irc.nick {
|
||||||
irc.handler.Joined(room)
|
irc.handler.Joined(room)
|
||||||
} else {
|
} else {
|
||||||
|
user := UserID(e.Source.Name + "@" + irc.server)
|
||||||
ev := &Event{
|
ev := &Event{
|
||||||
Type: EVENT_JOIN,
|
Type: EVENT_JOIN,
|
||||||
Author: UserID(e.Source.Name + "@" + irc.server),
|
Author: user,
|
||||||
Room: room,
|
Room: room,
|
||||||
}
|
}
|
||||||
irc.handler.Event(ev)
|
irc.handler.Event(ev)
|
||||||
|
irc.handler.UserInfoUpdated(user, &UserInfo{
|
||||||
|
DisplayName: e.Source.Name,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -277,12 +281,16 @@ func (irc *IRC) ircPart(c *girc.Client, e girc.Event) {
|
||||||
if e.Source.Name == irc.nick {
|
if e.Source.Name == irc.nick {
|
||||||
irc.handler.Left(room)
|
irc.handler.Left(room)
|
||||||
} else {
|
} else {
|
||||||
|
user := UserID(e.Source.Name + "@" + irc.server)
|
||||||
ev := &Event{
|
ev := &Event{
|
||||||
Type: EVENT_LEAVE,
|
Type: EVENT_LEAVE,
|
||||||
Author: UserID(e.Source.Name + "@" + irc.server),
|
Author: user,
|
||||||
Room: room,
|
Room: room,
|
||||||
}
|
}
|
||||||
irc.handler.Event(ev)
|
irc.handler.Event(ev)
|
||||||
|
irc.handler.UserInfoUpdated(user, &UserInfo{
|
||||||
|
DisplayName: e.Source.Name,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -181,35 +181,36 @@ func (xm *XMPP) handleXMPP() error {
|
||||||
|
|
||||||
switch v := m.(type) {
|
switch v := m.(type) {
|
||||||
case gxmpp.Chat:
|
case gxmpp.Chat:
|
||||||
log.Printf("== Receiving %#v\n", v)
|
|
||||||
|
|
||||||
if v.Text == "" && v.Type == "groupchat" {
|
|
||||||
// Empty message when we joined group chat
|
|
||||||
if !strings.Contains(v.Remote, "/") {
|
|
||||||
xm.handler.Joined(RoomID(v.Remote))
|
|
||||||
}
|
|
||||||
if v.Subject != "" {
|
|
||||||
author := UserID("")
|
|
||||||
remote_sp := strings.Split(v.Remote, "/")
|
remote_sp := strings.Split(v.Remote, "/")
|
||||||
|
|
||||||
|
// Skip self-sent events
|
||||||
|
if v.Remote == xm.jid || (v.Type == "groupchat" && len(remote_sp) == 2 && remote_sp[1] == xm.nickname) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// If empty text, make sure we joined the room
|
||||||
|
// We would do this at every incoming message if it were not so costly
|
||||||
|
if v.Text == "" && v.Type == "groupchat" {
|
||||||
|
xm.handler.Joined(RoomID(remote_sp[0]))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle subject change in group chats
|
||||||
|
if v.Subject != "" && v.Type == "groupchat" {
|
||||||
|
author := UserID("")
|
||||||
if len(remote_sp) == 2 {
|
if len(remote_sp) == 2 {
|
||||||
author = UserID(remote_sp[1] + "@" + remote_sp[0])
|
author = UserID(remote_sp[1] + "@" + remote_sp[0])
|
||||||
}
|
}
|
||||||
xm.handler.RoomInfoUpdated(RoomID(v.Remote), author, &RoomInfo{
|
xm.handler.RoomInfoUpdated(RoomID(remote_sp[0]), author, &RoomInfo{
|
||||||
Topic: v.Subject,
|
Topic: v.Subject,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if v.Text == "" || v.Remote == xm.jid {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Handle text message
|
||||||
|
if v.Text != "" {
|
||||||
event := &Event{
|
event := &Event{
|
||||||
Type: EVENT_MESSAGE,
|
Type: EVENT_MESSAGE,
|
||||||
Text: v.Text,
|
Text: v.Text,
|
||||||
}
|
}
|
||||||
log.Printf("Remote: %s\n", v.Remote)
|
|
||||||
|
|
||||||
if strings.HasPrefix(event.Text, "/me ") {
|
if strings.HasPrefix(event.Text, "/me ") {
|
||||||
event.Type = EVENT_ACTION
|
event.Type = EVENT_ACTION
|
||||||
|
@ -217,38 +218,36 @@ func (xm *XMPP) handleXMPP() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if v.Type == "chat" {
|
if v.Type == "chat" {
|
||||||
remote_jid := strings.Split(v.Remote, "/")[0]
|
event.Author = UserID(remote_sp[0])
|
||||||
event.Author = UserID(remote_jid)
|
|
||||||
xm.handler.Event(event)
|
xm.handler.Event(event)
|
||||||
}
|
}
|
||||||
if v.Type == "groupchat" {
|
if v.Type == "groupchat" && len(remote_sp) == 2 {
|
||||||
remote := strings.Split(v.Remote, "/")
|
event.Room = RoomID(remote_sp[0])
|
||||||
if len(remote) != 2 {
|
event.Author = UserID(remote_sp[1] + "@" + remote_sp[0])
|
||||||
log.Printf("Invalid remote: %s\n", v.Remote)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
event.Room = RoomID(remote[0])
|
|
||||||
event.Author = UserID(remote[1] + "@" + remote[0])
|
|
||||||
|
|
||||||
if strings.Contains(v.Text, "has set the subject to:") {
|
|
||||||
// TODO
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
xm.handler.Event(event)
|
xm.handler.Event(event)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
case gxmpp.Presence:
|
case gxmpp.Presence:
|
||||||
remote := strings.Split(v.From, "/")
|
remote := strings.Split(v.From, "/")
|
||||||
if muc, ok := xm.isMUC[remote[0]]; ok && muc && len(remote) == 2 {
|
if ismuc, ok := xm.isMUC[remote[0]]; ok && ismuc {
|
||||||
|
// skip presence with no user and self-presence
|
||||||
|
if len(remote) < 2 || remote[1] == xm.nickname {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
user := UserID(remote[1] + "@" + remote[0])
|
||||||
event := &Event{
|
event := &Event{
|
||||||
Type: EVENT_JOIN,
|
Type: EVENT_JOIN,
|
||||||
Room: RoomID(remote[0]),
|
Room: RoomID(remote[0]),
|
||||||
Author: UserID(remote[1] + "@" + remote[0]),
|
Author: user,
|
||||||
}
|
}
|
||||||
if v.Type == "unavailable" {
|
if v.Type == "unavailable" {
|
||||||
event.Type = EVENT_LEAVE
|
event.Type = EVENT_LEAVE
|
||||||
}
|
}
|
||||||
xm.handler.Event(event)
|
xm.handler.Event(event)
|
||||||
|
xm.handler.UserInfoUpdated(user, &UserInfo{
|
||||||
|
DisplayName: remote[1],
|
||||||
|
})
|
||||||
}
|
}
|
||||||
// Do nothing.
|
// Do nothing.
|
||||||
}
|
}
|
||||||
|
@ -264,8 +263,24 @@ func (xm *XMPP) SetUserInfo(info *UserInfo) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (xm *XMPP) SetRoomInfo(roomId RoomID, info *RoomInfo) error {
|
func (xm *XMPP) SetRoomInfo(roomId RoomID, info *RoomInfo) error {
|
||||||
|
if info.Topic != "" {
|
||||||
|
xm.conn.Send(gxmpp.Chat{
|
||||||
|
Type: "groupchat",
|
||||||
|
Remote: string(roomId),
|
||||||
|
Subject: info.Topic,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if info.Picture != nil {
|
||||||
// TODO
|
// TODO
|
||||||
return fmt.Errorf("Not implemented")
|
return fmt.Errorf("Room picture change not implemented on xmpp")
|
||||||
|
}
|
||||||
|
|
||||||
|
if info.Name != "" && info.Name != string(roomId) {
|
||||||
|
// TODO
|
||||||
|
return fmt.Errorf("Room name change not implemented on xmpp")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (xm *XMPP) Join(roomId RoomID) error {
|
func (xm *XMPP) Join(roomId RoomID) error {
|
||||||
|
@ -286,6 +301,7 @@ func (xm *XMPP) Leave(roomId RoomID) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (xm *XMPP) Send(event *Event) error {
|
func (xm *XMPP) Send(event *Event) error {
|
||||||
|
fmt.Printf("xm *XMPP Send %#v\n", event)
|
||||||
if len(event.Recipient) > 0 {
|
if len(event.Recipient) > 0 {
|
||||||
xm.conn.Send(gxmpp.Chat{
|
xm.conn.Send(gxmpp.Chat{
|
||||||
Type: "chat",
|
Type: "chat",
|
||||||
|
|
2
main.go
2
main.go
|
@ -185,6 +185,8 @@ func main() {
|
||||||
conn = &irc.IRC{}
|
conn = &irc.IRC{}
|
||||||
case "xmpp":
|
case "xmpp":
|
||||||
conn = &xmpp.XMPP{}
|
conn = &xmpp.XMPP{}
|
||||||
|
default:
|
||||||
|
log.Fatalf("Invalid protocol %s", params.Protocol)
|
||||||
}
|
}
|
||||||
account := &appservice.Account{
|
account := &appservice.Account{
|
||||||
MatrixUser: fmt.Sprintf("@%s:%s", user, config.MatrixDomain),
|
MatrixUser: fmt.Sprintf("@%s:%s", user, config.MatrixDomain),
|
||||||
|
|
Loading…
Reference in a new issue