diff --git a/appservice/account.go b/appservice/account.go index faf491d..ae9716f 100644 --- a/appservice/account.go +++ b/appservice/account.go @@ -92,7 +92,23 @@ func (a *Account) UserInfoUpdated(user UserID, info *UserInfo) { // TODO } -func (a *Account) RoomInfoUpdated(roomId RoomID, info *RoomInfo) { +func (a *Account) RoomInfoUpdated(roomId RoomID, author UserID, info *RoomInfo) { + mx_room_id, err := dbGetMxRoom(a.Protocol, roomId) + if err != nil { + return + } + + as_mxid := fmt.Sprintf("@%s:%s", registration.SenderLocalpart, config.MatrixDomain) + if len(author) > 0 { + mx_user_id, err := dbGetMxUser(a.Protocol, author) + if err == nil { + as_mxid = mx_user_id + } + } + + if info.Topic != "" { + mxRoomTopicAs(mx_room_id, info.Topic, as_mxid) + } // TODO } diff --git a/appservice/matrix.go b/appservice/matrix.go index 88c4b5d..75bcaa1 100644 --- a/appservice/matrix.go +++ b/appservice/matrix.go @@ -138,6 +138,10 @@ func mxCreateRoom(name string, alias string, invite []string) (string, error) { }, PowerLevels: map[string]interface{} { "invite": 100, + "events": map[string]interface{} { + "m.room.topic": 0, + "m.room.avatar": 0, + }, }, } var rep CreateRoomResponse @@ -203,16 +207,36 @@ func mxRoomLeaveAs(room string, user string) error { return err } -func mxSendMessageAs(room string, typ string, body string, user string) error { +func mxSendAs(room string, event_type string, content map[string]interface{}, user string) error { txn_id := time.Now().UnixNano() - rq := RoomSendMessageRequest{ - MsgType: typ, - Body: body, - } var rep RoomSendResponse err := mxPutApiCall(fmt.Sprintf( - "/_matrix/client/r0/rooms/%s/send/m.room.message/%d?user_id=%s", - url.QueryEscape(room), txn_id, url.QueryEscape(user)), - &rq, &rep) + "/_matrix/client/r0/rooms/%s/send/%s/%d?user_id=%s", + url.QueryEscape(room), event_type, txn_id, url.QueryEscape(user)), + &content, &rep) return err } + +func mxSendMessageAs(room string, typ string, body string, user string) error { + content := map[string]interface{} { + "msgtype": typ, + "body": body, + } + return mxSendAs(room, "m.room.message", content, user) +} + +func mxPutStateAs(room string, event_type string, key string, content map[string]interface{}, as_user string) error { + var rep RoomSendResponse + err := mxPutApiCall(fmt.Sprintf( + "/_matrix/client/r0/rooms/%s/state/%s/%s?user_id=%s", + url.QueryEscape(room), event_type, key, url.QueryEscape(as_user)), + &content, &rep) + return err +} + +func mxRoomTopicAs(room string, topic string, as_user string) error { + content := map[string]interface{} { + "topic": topic, + } + return mxPutStateAs(room, "m.room.topic", "", content, as_user) +} diff --git a/appservice/server.go b/appservice/server.go index 00f23f1..2690e58 100644 --- a/appservice/server.go +++ b/appservice/server.go @@ -144,5 +144,14 @@ func handleTxnEvent(e *mxlib.Event) { } } } + } else if e.Type == "m.room.topic" { + if room := dbIsPublicRoom(e.RoomId); room != nil { + acct := FindJoinedAccount(e.Sender, room.Protocol, room.RoomID) + if acct != nil { + acct.Conn.SetRoomInfo(room.RoomID, &connector.RoomInfo{ + Topic: e.Content["topic"].(string), + }) + } + } } } diff --git a/connector/connector.go b/connector/connector.go index 92b1adc..0afcd1c 100644 --- a/connector/connector.go +++ b/connector/connector.go @@ -74,7 +74,7 @@ type Handler interface { // Called when a room's info was updated, // or the first tome a room's info is retreived - RoomInfoUpdated(roomId RoomID, info *RoomInfo) + RoomInfoUpdated(roomId RoomID, author UserID, info *RoomInfo) // Called when an event occurs in a room // This must not be called for events authored by the user of the connection @@ -120,7 +120,7 @@ type UserInfo struct { type RoomInfo struct { Name string - Description string + Topic string Picture MediaObject } diff --git a/connector/irc/irc.go b/connector/irc/irc.go index 8e5cdb0..b673498 100644 --- a/connector/irc/irc.go +++ b/connector/irc/irc.go @@ -78,7 +78,8 @@ func (irc *IRC) Configure(c Configuration) error { client.Handlers.Add(girc.JOIN, irc.ircJoin) client.Handlers.Add(girc.PART, irc.ircPart) client.Handlers.Add(girc.RPL_NAMREPLY, irc.ircNamreply) - client.Handlers.Add(girc.RPL_TOPIC, irc.ircTopic) + client.Handlers.Add(girc.TOPIC, irc.ircTopic) + client.Handlers.Add(girc.RPL_TOPIC, irc.ircRplTopic) irc.conn = client go irc.connectLoop(client) @@ -131,7 +132,9 @@ func (irc *IRC) SetRoomInfo(roomId RoomID, info *RoomInfo) error { if info.Picture != nil { return fmt.Errorf("Room picture not supported on IRC") } - irc.conn.Cmd.Topic(ch, info.Description) + if info.Topic != "" { + irc.conn.Cmd.Topic(ch, info.Topic) + } return nil } @@ -302,10 +305,18 @@ func (irc *IRC) ircNamreply(c *girc.Client, e girc.Event) { } func (irc *IRC) ircTopic(c *girc.Client, e girc.Event) { - room := RoomID(e.Params[1] + "@" + irc.server) + source := UserID(e.Source.Name + "@" + irc.server) + room := RoomID(e.Params[0] + "@" + irc.server) topic := e.Last() - irc.handler.RoomInfoUpdated(room, &RoomInfo{ - Name: string(room), - Description: topic, + irc.handler.RoomInfoUpdated(room, source, &RoomInfo{ + Topic: topic, + }) +} + +func (irc *IRC) ircRplTopic(c *girc.Client, e girc.Event) { + room := RoomID(e.Params[1] + "@" + irc.server) + topic := e.Last() + irc.handler.RoomInfoUpdated(room, "", &RoomInfo{ + Topic: topic, }) } diff --git a/connector/xmpp/xmpp.go b/connector/xmpp/xmpp.go index 5b1c71a..7516ebc 100644 --- a/connector/xmpp/xmpp.go +++ b/connector/xmpp/xmpp.go @@ -183,12 +183,19 @@ func (xm *XMPP) handleXMPP() error { case gxmpp.Chat: log.Printf("== Receiving %#v\n", v) - if v.Text == "" && v.Type == "groupchat" && !strings.Contains(v.Remote, "/") { + if v.Text == "" && v.Type == "groupchat" { // Empty message when we joined group chat - xm.handler.Joined(RoomID(v.Remote)) + if !strings.Contains(v.Remote, "/") { + xm.handler.Joined(RoomID(v.Remote)) + } if v.Subject != "" { - xm.handler.RoomInfoUpdated(RoomID(v.Remote), &RoomInfo{ - Description: 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 @@ -253,7 +260,6 @@ func (xm *XMPP) User() UserID { } func (xm *XMPP) SetUserInfo(info *UserInfo) error { - //TODO return fmt.Errorf("Not implemented") } diff --git a/mxlib/api.go b/mxlib/api.go index 84c125b..de5b424 100644 --- a/mxlib/api.go +++ b/mxlib/api.go @@ -81,10 +81,6 @@ type RoomJoinResponse struct { RoomId string `json:"room_id"` } -type RoomSendMessageRequest struct { - MsgType string `json:"msgtype"` - Body string `json:"body"` -} type RoomSendResponse struct { EventId string `json:"event_id"` }