Fix revUserId (messenger) and implement search (messenger only for now)
This commit is contained in:
parent
0d6fa02a78
commit
f9e0c58f3c
7 changed files with 86 additions and 11 deletions
|
@ -59,6 +59,9 @@ type Connector interface {
|
|||
// Leave a channel
|
||||
Leave(roomId RoomID)
|
||||
|
||||
// Search for users
|
||||
SearchForUsers(query string) ([]UserSearchResult, error)
|
||||
|
||||
// Send an event. Returns the ID of the created remote message.
|
||||
// This ID is used to deduplicate messages: if it comes back, it should have the same Id
|
||||
// than the one returned here.
|
||||
|
@ -153,6 +156,11 @@ type RoomInfo struct {
|
|||
Picture SMediaObject `json:"picture"`
|
||||
}
|
||||
|
||||
type UserSearchResult struct {
|
||||
ID UserID `json:"id"`
|
||||
DisplayName string `json:"display_name"`
|
||||
}
|
||||
|
||||
type MediaObject interface {
|
||||
Filename() string
|
||||
Size() int64
|
||||
|
|
29
connector/external/external.go
vendored
29
connector/external/external.go
vendored
|
@ -49,6 +49,7 @@ const (
|
|||
JOIN = "join"
|
||||
INVITE = "invite"
|
||||
LEAVE = "leave"
|
||||
SEARCH = "search"
|
||||
SEND = "send"
|
||||
CLOSE = "close"
|
||||
|
||||
|
@ -64,8 +65,9 @@ const (
|
|||
// reply messages
|
||||
// ezbr -> external: all must wait for a reply!
|
||||
// external -> ezbr: only CACHE_GET produces a reply
|
||||
REP_OK = "rep_ok"
|
||||
REP_ERROR = "rep_error"
|
||||
REP_OK = "rep_ok"
|
||||
REP_SEARCH_RESULTS = "rep_search_results"
|
||||
REP_ERROR = "rep_error"
|
||||
)
|
||||
|
||||
// ----
|
||||
|
@ -226,6 +228,16 @@ func (m *extMessageWithData) UnmarshalJSON(jj []byte) error {
|
|||
}
|
||||
m.Data = &ev.Data
|
||||
return nil
|
||||
case REP_SEARCH_RESULTS:
|
||||
var ev struct {
|
||||
Data []UserSearchResult `json:"data"`
|
||||
}
|
||||
err := json.Unmarshal(jj, &ev)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
m.Data = ev.Data
|
||||
return nil
|
||||
case JOINED, LEFT, CACHE_PUT, CACHE_GET, REP_OK, REP_ERROR:
|
||||
return nil
|
||||
default:
|
||||
|
@ -428,6 +440,19 @@ func (ext *External) Leave(room RoomID) {
|
|||
}
|
||||
}
|
||||
|
||||
func (ext *External) SearchForUsers(query string) ([]UserSearchResult, error) {
|
||||
rep, err := ext.cmd(extMessage{
|
||||
MsgType: SEARCH,
|
||||
}, query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if rep.MsgType != REP_SEARCH_RESULTS {
|
||||
return nil, fmt.Errorf("Invalid result type from external: %s", rep.MsgType)
|
||||
}
|
||||
return rep.Data.([]UserSearchResult), nil
|
||||
}
|
||||
|
||||
func (ext *External) Send(event *Event) (string, error) {
|
||||
rep, err := ext.cmd(extMessage{
|
||||
MsgType: SEND,
|
||||
|
|
|
@ -198,6 +198,11 @@ func (irc *IRC) Leave(roomId RoomID) {
|
|||
irc.conn.Cmd.Part(ch)
|
||||
}
|
||||
|
||||
func (irc *IRC) SearchForUsers(query string) ([]UserSearchResult, error) {
|
||||
// TODO
|
||||
return nil, fmt.Errorf("Not implemented")
|
||||
}
|
||||
|
||||
func (irc *IRC) Send(event *Event) (string, error) {
|
||||
if irc.conn == nil {
|
||||
return "", fmt.Errorf("Not connected")
|
||||
|
|
|
@ -253,6 +253,11 @@ func (mm *Mattermost) Leave(roomId RoomID) {
|
|||
// Not supported? TODO
|
||||
}
|
||||
|
||||
func (mm *Mattermost) SearchForUsers(query string) ([]UserSearchResult, error) {
|
||||
// TODO
|
||||
return nil, fmt.Errorf("Not implemented")
|
||||
}
|
||||
|
||||
func (mm *Mattermost) Send(event *Event) (string, error) {
|
||||
post := &model.Post{
|
||||
Message: event.Text,
|
||||
|
|
|
@ -306,6 +306,11 @@ func (xm *XMPP) Leave(roomId RoomID) {
|
|||
xm.conn.LeaveMUC(string(roomId))
|
||||
}
|
||||
|
||||
func (xm *XMPP) SearchForUsers(query string) ([]UserSearchResult, error) {
|
||||
// TODO: search roster
|
||||
return nil, fmt.Errorf("Not implemented")
|
||||
}
|
||||
|
||||
func (xm *XMPP) Send(event *Event) (string, error) {
|
||||
if event.Attachments != nil && len(event.Attachments) > 0 {
|
||||
for _, at := range event.Attachments {
|
||||
|
|
29
external/messenger.py
vendored
29
external/messenger.py
vendored
|
@ -1,8 +1,6 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
# @FIXME: make revUserId work correctly (e.g.: talking to a contact not in your top 20 recent threads will fail) - could we do this with a search request?
|
||||
# @FIXME: store the client pickle in the config automatically
|
||||
# @FIXME: add a way to search for users and initiate a discussion
|
||||
|
||||
import sys
|
||||
import json
|
||||
|
@ -31,6 +29,7 @@ SET_ROOM_INFO = "set_room_info"
|
|||
JOIN = "join"
|
||||
INVITE = "invite"
|
||||
LEAVE = "leave"
|
||||
SEARCH = "search"
|
||||
SEND = "send"
|
||||
CLOSE = "close"
|
||||
|
||||
|
@ -47,6 +46,7 @@ CACHE_GET = "cache_get"
|
|||
# ezbr -> external: all must wait for a reply!
|
||||
# external -> ezbr: only CACHE_GET produces a reply
|
||||
REP_OK = "rep_ok"
|
||||
REP_SEARCH_RESULTS = "rep_search_results"
|
||||
REP_ERROR = "rep_error"
|
||||
|
||||
# Event types
|
||||
|
@ -168,13 +168,14 @@ class MessengerBridge:
|
|||
return self.getUserId(user)
|
||||
|
||||
def revUserId(self, user_id):
|
||||
if user_id in self.rev_uid:
|
||||
return self.rev_uid[user_id]
|
||||
else:
|
||||
# TODO this doesn't work always...
|
||||
# we should try to find the api endpoint that resolves usernames ?
|
||||
# or do a search request and try to find a user that has that username
|
||||
return user_id
|
||||
if user_id not in self.rev_uid:
|
||||
for user in self.client.searchForUsers(user_id):
|
||||
self.getUserId(user)
|
||||
|
||||
if user_id not in self.rev_uid:
|
||||
raise ValueError("User not found: {}".format(user_id))
|
||||
|
||||
return self.rev_uid[user_id]
|
||||
|
||||
def getUserShortName(self, user):
|
||||
if user.first_name != None:
|
||||
|
@ -277,6 +278,16 @@ class MessengerBridge:
|
|||
uid = self.revUserId(cmd["user"])
|
||||
self.client.addUsersToGroup([uid], cmd["room"])
|
||||
|
||||
elif ty == SEARCH:
|
||||
users = self.client.searchForUsers(cmd["data"])
|
||||
rep = []
|
||||
for user in users:
|
||||
rep.append({
|
||||
"id": self.getUserId(user),
|
||||
"display_name": user.name,
|
||||
})
|
||||
return {"_type": REP_SEARCH_RESULTS, "data": rep}
|
||||
|
||||
elif ty == SEND:
|
||||
event = cmd["data"]
|
||||
if event["type"] in [EVENT_MESSAGE, EVENT_ACTION]:
|
||||
|
|
16
server.go
16
server.go
|
@ -228,6 +228,7 @@ func handleSystemMessage(mxid string, msg string) {
|
|||
ezbrSystemSend(mxid, "- accounts: list accounts")
|
||||
ezbrSystemSend(mxid, "- join <protocol or account> <room id>: join public chat room")
|
||||
ezbrSystemSend(mxid, "- talk <protocol or account> <user id>: open private conversation to contact")
|
||||
ezbrSystemSend(mxid, "- search <protocol or account> <name>: search for users by name")
|
||||
case "list", "account", "accounts":
|
||||
one := false
|
||||
if accts, ok := registeredAccounts[mxid]; ok {
|
||||
|
@ -271,6 +272,21 @@ func handleSystemMessage(mxid string, msg string) {
|
|||
} else {
|
||||
ezbrSystemSendf(mxid, "No account with name or using protocol %s", cmd[1])
|
||||
}
|
||||
case "search":
|
||||
account := findAccount(mxid, cmd[1])
|
||||
if account != nil {
|
||||
rep, err := account.Conn.SearchForUsers(cmd[2])
|
||||
if err != nil {
|
||||
ezbrSystemSendf(mxid, "Search error: %s", err)
|
||||
} else {
|
||||
ezbrSystemSendf(mxid, "%d users found", len(rep))
|
||||
for i, user := range rep {
|
||||
ezbrSystemSendf(mxid, "- %s (%s)", i+1, user.DisplayName, user.ID)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ezbrSystemSendf(mxid, "No account with name or using protocol %s", cmd[1])
|
||||
}
|
||||
default:
|
||||
ezbrSystemSend(mxid, "Unrecognized command. Type `help` if you need some help!")
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue