aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Auvolat <alex@adnab.me>2020-02-17 16:28:32 +0100
committerAlex Auvolat <alex@adnab.me>2020-02-17 16:28:32 +0100
commit86942a34a2aa086dee76c9e4e0b6942848e1b979 (patch)
treee004efb1a284e6d158ed9aaab7f3a582df19026f
parent584312f30805680711557ff6fbe291d2404367fb (diff)
downloadeasybridge-86942a34a2aa086dee76c9e4e0b6942848e1b979.tar.gz
easybridge-86942a34a2aa086dee76c9e4e0b6942848e1b979.zip
Fix XMPP && transmit nicknames from bridges to matrix
-rw-r--r--appservice/account.go23
-rw-r--r--appservice/matrix.go13
-rw-r--r--appservice/server.go7
-rw-r--r--connector/connector.go3
-rw-r--r--connector/irc/irc.go12
-rw-r--r--connector/xmpp/xmpp.go110
-rw-r--r--main.go2
7 files changed, 114 insertions, 56 deletions
diff --git a/appservice/account.go b/appservice/account.go
index ae9716f..a20751f 100644
--- a/appservice/account.go
+++ b/appservice/account.go
@@ -89,7 +89,17 @@ func (a *Account) Left(roomId RoomID) {
}
func (a *Account) UserInfoUpdated(user UserID, info *UserInfo) {
- // TODO
+ 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
+ }
}
func (a *Account) RoomInfoUpdated(roomId RoomID, author UserID, info *RoomInfo) {
@@ -98,7 +108,7 @@ func (a *Account) RoomInfoUpdated(roomId RoomID, author UserID, info *RoomInfo)
return
}
- as_mxid := fmt.Sprintf("@%s:%s", registration.SenderLocalpart, config.MatrixDomain)
+ as_mxid := ezbrMxId()
if len(author) > 0 {
mx_user_id, err := dbGetMxUser(a.Protocol, author)
if err == nil {
@@ -109,7 +119,14 @@ func (a *Account) RoomInfoUpdated(roomId RoomID, author UserID, info *RoomInfo)
if info.Topic != "" {
mxRoomTopicAs(mx_room_id, info.Topic, as_mxid)
}
- // TODO
+
+ if info.Name != "" {
+ mxRoomNameAs(mx_room_id, info.Name, as_mxid)
+ }
+
+ if info.Picture != nil {
+ // TODO
+ }
}
func (a *Account) Event(event *Event) {
diff --git a/appservice/matrix.go b/appservice/matrix.go
index 75bcaa1..2c4562e 100644
--- a/appservice/matrix.go
+++ b/appservice/matrix.go
@@ -13,6 +13,12 @@ import (
. "git.deuxfleurs.fr/Deuxfleurs/easybridge/mxlib"
)
+func ezbrMxId() string {
+ return fmt.Sprintf("@%s:%s", registration.SenderLocalpart, config.MatrixDomain)
+}
+
+// ----
+
var httpClient *http.Client
func init() {
@@ -234,6 +240,13 @@ func mxPutStateAs(room string, event_type string, key string, content map[string
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 {
content := map[string]interface{} {
"topic": topic,
diff --git a/appservice/server.go b/appservice/server.go
index 2690e58..b67e813 100644
--- a/appservice/server.go
+++ b/appservice/server.go
@@ -34,12 +34,11 @@ func Start(r *mxlib.Registration, c *Config) (chan error, error) {
return nil, err
}
- svc_mxid := fmt.Sprintf("@%s:%s", registration.SenderLocalpart, config.MatrixDomain)
err = mxRegisterUser(registration.SenderLocalpart)
if mxe, ok := err.(*mxlib.MxError); !ok || mxe.ErrCode != "M_USER_IN_USE" {
return nil, err
}
- err = mxProfileDisplayname(svc_mxid, "Easybridge")
+ err = mxProfileDisplayname(ezbrMxId(), "Easybridge")
if err != nil {
return nil, err
}
@@ -123,6 +122,8 @@ func handleTxnEvent(e *mxlib.Event) {
ev.Author = acct.Conn.User()
ev.Room = room.RoomID
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" {
@@ -141,6 +142,8 @@ func handleTxnEvent(e *mxlib.Event) {
if acct != nil {
acct.Conn.Leave(room.RoomID)
// 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)
}
}
}
diff --git a/connector/connector.go b/connector/connector.go
index 0afcd1c..9ff5d49 100644
--- a/connector/connector.go
+++ b/connector/connector.go
@@ -113,8 +113,7 @@ type Event struct {
}
type UserInfo struct {
- Nickname string
- Status string
+ DisplayName string
Avatar MediaObject
}
diff --git a/connector/irc/irc.go b/connector/irc/irc.go
index b673498..a57a2e2 100644
--- a/connector/irc/irc.go
+++ b/connector/irc/irc.go
@@ -263,12 +263,16 @@ func (irc *IRC) ircJoin(c *girc.Client, e girc.Event) {
if e.Source.Name == irc.nick {
irc.handler.Joined(room)
} else {
+ user := UserID(e.Source.Name + "@" + irc.server)
ev := &Event{
Type: EVENT_JOIN,
- Author: UserID(e.Source.Name + "@" + irc.server),
+ Author: user,
Room: room,
}
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 {
irc.handler.Left(room)
} else {
+ user := UserID(e.Source.Name + "@" + irc.server)
ev := &Event{
Type: EVENT_LEAVE,
- Author: UserID(e.Source.Name + "@" + irc.server),
+ Author: user,
Room: room,
}
irc.handler.Event(ev)
+ irc.handler.UserInfoUpdated(user, &UserInfo{
+ DisplayName: e.Source.Name,
+ })
}
}
diff --git a/connector/xmpp/xmpp.go b/connector/xmpp/xmpp.go
index 7516ebc..e50bb58 100644
--- a/connector/xmpp/xmpp.go
+++ b/connector/xmpp/xmpp.go
@@ -181,74 +181,73 @@ func (xm *XMPP) handleXMPP() error {
switch v := m.(type) {
case gxmpp.Chat:
- log.Printf("== Receiving %#v\n", v)
+ remote_sp := strings.Split(v.Remote, "/")
- 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, "/")
- if len(remote_sp) == 2 {
- author = UserID(remote_sp[1] + "@" + remote_sp[0])
- }
- xm.handler.RoomInfoUpdated(RoomID(v.Remote), author, &RoomInfo{
- Topic: v.Subject,
- })
- }
- continue
- }
-
- if v.Text == "" || v.Remote == xm.jid {
+ // Skip self-sent events
+ if v.Remote == xm.jid || (v.Type == "groupchat" && len(remote_sp) == 2 && remote_sp[1] == xm.nickname) {
continue
}
- event := &Event{
- Type: EVENT_MESSAGE,
- Text: v.Text,
+ // 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]))
}
- log.Printf("Remote: %s\n", v.Remote)
- if strings.HasPrefix(event.Text, "/me ") {
- event.Type = EVENT_ACTION
- event.Text = strings.Replace(event.Text, "/me ", "", 1)
+ // Handle subject change in group chats
+ if v.Subject != "" && v.Type == "groupchat" {
+ author := UserID("")
+ if len(remote_sp) == 2 {
+ author = UserID(remote_sp[1] + "@" + remote_sp[0])
+ }
+ xm.handler.RoomInfoUpdated(RoomID(remote_sp[0]), author, &RoomInfo{
+ Topic: v.Subject,
+ })
}
- if v.Type == "chat" {
- remote_jid := strings.Split(v.Remote, "/")[0]
- event.Author = UserID(remote_jid)
- xm.handler.Event(event)
- }
- if v.Type == "groupchat" {
- remote := strings.Split(v.Remote, "/")
- if len(remote) != 2 {
- log.Printf("Invalid remote: %s\n", v.Remote)
- continue
+ // Handle text message
+ if v.Text != "" {
+ event := &Event{
+ Type: EVENT_MESSAGE,
+ Text: v.Text,
}
- event.Room = RoomID(remote[0])
- event.Author = UserID(remote[1] + "@" + remote[0])
- if strings.Contains(v.Text, "has set the subject to:") {
- // TODO
- continue
+ if strings.HasPrefix(event.Text, "/me ") {
+ event.Type = EVENT_ACTION
+ event.Text = strings.Replace(event.Text, "/me ", "", 1)
}
- xm.handler.Event(event)
+ if v.Type == "chat" {
+ event.Author = UserID(remote_sp[0])
+ xm.handler.Event(event)
+ }
+ if v.Type == "groupchat" && len(remote_sp) == 2 {
+ event.Room = RoomID(remote_sp[0])
+ event.Author = UserID(remote_sp[1] + "@" + remote_sp[0])
+ xm.handler.Event(event)
+ }
}
case gxmpp.Presence:
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{
Type: EVENT_JOIN,
Room: RoomID(remote[0]),
- Author: UserID(remote[1] + "@" + remote[0]),
+ Author: user,
}
if v.Type == "unavailable" {
event.Type = EVENT_LEAVE
}
xm.handler.Event(event)
+ xm.handler.UserInfoUpdated(user, &UserInfo{
+ DisplayName: remote[1],
+ })
}
// Do nothing.
}
@@ -264,8 +263,24 @@ func (xm *XMPP) SetUserInfo(info *UserInfo) error {
}
func (xm *XMPP) SetRoomInfo(roomId RoomID, info *RoomInfo) error {
- // TODO
- return fmt.Errorf("Not implemented")
+ if info.Topic != "" {
+ xm.conn.Send(gxmpp.Chat{
+ Type: "groupchat",
+ Remote: string(roomId),
+ Subject: info.Topic,
+ })
+ }
+
+ if info.Picture != nil {
+ // TODO
+ 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 {
@@ -286,6 +301,7 @@ func (xm *XMPP) Leave(roomId RoomID) {
}
func (xm *XMPP) Send(event *Event) error {
+ fmt.Printf("xm *XMPP Send %#v\n", event)
if len(event.Recipient) > 0 {
xm.conn.Send(gxmpp.Chat{
Type: "chat",
diff --git a/main.go b/main.go
index 105d798..14ec229 100644
--- a/main.go
+++ b/main.go
@@ -185,6 +185,8 @@ func main() {
conn = &irc.IRC{}
case "xmpp":
conn = &xmpp.XMPP{}
+ default:
+ log.Fatalf("Invalid protocol %s", params.Protocol)
}
account := &appservice.Account{
MatrixUser: fmt.Sprintf("@%s:%s", user, config.MatrixDomain),