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 a channel
|
||||||
Leave(roomId RoomID)
|
Leave(roomId RoomID)
|
||||||
|
|
||||||
|
// Search for users
|
||||||
|
SearchForUsers(query string) ([]UserSearchResult, error)
|
||||||
|
|
||||||
// Send an event. Returns the ID of the created remote message.
|
// 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
|
// This ID is used to deduplicate messages: if it comes back, it should have the same Id
|
||||||
// than the one returned here.
|
// than the one returned here.
|
||||||
|
@ -153,6 +156,11 @@ type RoomInfo struct {
|
||||||
Picture SMediaObject `json:"picture"`
|
Picture SMediaObject `json:"picture"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type UserSearchResult struct {
|
||||||
|
ID UserID `json:"id"`
|
||||||
|
DisplayName string `json:"display_name"`
|
||||||
|
}
|
||||||
|
|
||||||
type MediaObject interface {
|
type MediaObject interface {
|
||||||
Filename() string
|
Filename() string
|
||||||
Size() int64
|
Size() int64
|
||||||
|
|
25
connector/external/external.go
vendored
25
connector/external/external.go
vendored
|
@ -49,6 +49,7 @@ const (
|
||||||
JOIN = "join"
|
JOIN = "join"
|
||||||
INVITE = "invite"
|
INVITE = "invite"
|
||||||
LEAVE = "leave"
|
LEAVE = "leave"
|
||||||
|
SEARCH = "search"
|
||||||
SEND = "send"
|
SEND = "send"
|
||||||
CLOSE = "close"
|
CLOSE = "close"
|
||||||
|
|
||||||
|
@ -65,6 +66,7 @@ const (
|
||||||
// ezbr -> external: all must wait for a reply!
|
// ezbr -> external: all must wait for a reply!
|
||||||
// external -> ezbr: only CACHE_GET produces a reply
|
// external -> ezbr: only CACHE_GET produces a reply
|
||||||
REP_OK = "rep_ok"
|
REP_OK = "rep_ok"
|
||||||
|
REP_SEARCH_RESULTS = "rep_search_results"
|
||||||
REP_ERROR = "rep_error"
|
REP_ERROR = "rep_error"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -226,6 +228,16 @@ func (m *extMessageWithData) UnmarshalJSON(jj []byte) error {
|
||||||
}
|
}
|
||||||
m.Data = &ev.Data
|
m.Data = &ev.Data
|
||||||
return nil
|
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:
|
case JOINED, LEFT, CACHE_PUT, CACHE_GET, REP_OK, REP_ERROR:
|
||||||
return nil
|
return nil
|
||||||
default:
|
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) {
|
func (ext *External) Send(event *Event) (string, error) {
|
||||||
rep, err := ext.cmd(extMessage{
|
rep, err := ext.cmd(extMessage{
|
||||||
MsgType: SEND,
|
MsgType: SEND,
|
||||||
|
|
|
@ -198,6 +198,11 @@ func (irc *IRC) Leave(roomId RoomID) {
|
||||||
irc.conn.Cmd.Part(ch)
|
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) {
|
func (irc *IRC) Send(event *Event) (string, error) {
|
||||||
if irc.conn == nil {
|
if irc.conn == nil {
|
||||||
return "", fmt.Errorf("Not connected")
|
return "", fmt.Errorf("Not connected")
|
||||||
|
|
|
@ -253,6 +253,11 @@ func (mm *Mattermost) Leave(roomId RoomID) {
|
||||||
// Not supported? TODO
|
// 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) {
|
func (mm *Mattermost) Send(event *Event) (string, error) {
|
||||||
post := &model.Post{
|
post := &model.Post{
|
||||||
Message: event.Text,
|
Message: event.Text,
|
||||||
|
|
|
@ -306,6 +306,11 @@ func (xm *XMPP) Leave(roomId RoomID) {
|
||||||
xm.conn.LeaveMUC(string(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) {
|
func (xm *XMPP) Send(event *Event) (string, error) {
|
||||||
if event.Attachments != nil && len(event.Attachments) > 0 {
|
if event.Attachments != nil && len(event.Attachments) > 0 {
|
||||||
for _, at := range event.Attachments {
|
for _, at := range event.Attachments {
|
||||||
|
|
27
external/messenger.py
vendored
27
external/messenger.py
vendored
|
@ -1,8 +1,6 @@
|
||||||
#!/usr/bin/env python3
|
#!/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: store the client pickle in the config automatically
|
||||||
# @FIXME: add a way to search for users and initiate a discussion
|
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import json
|
import json
|
||||||
|
@ -31,6 +29,7 @@ SET_ROOM_INFO = "set_room_info"
|
||||||
JOIN = "join"
|
JOIN = "join"
|
||||||
INVITE = "invite"
|
INVITE = "invite"
|
||||||
LEAVE = "leave"
|
LEAVE = "leave"
|
||||||
|
SEARCH = "search"
|
||||||
SEND = "send"
|
SEND = "send"
|
||||||
CLOSE = "close"
|
CLOSE = "close"
|
||||||
|
|
||||||
|
@ -47,6 +46,7 @@ CACHE_GET = "cache_get"
|
||||||
# ezbr -> external: all must wait for a reply!
|
# ezbr -> external: all must wait for a reply!
|
||||||
# external -> ezbr: only CACHE_GET produces a reply
|
# external -> ezbr: only CACHE_GET produces a reply
|
||||||
REP_OK = "rep_ok"
|
REP_OK = "rep_ok"
|
||||||
|
REP_SEARCH_RESULTS = "rep_search_results"
|
||||||
REP_ERROR = "rep_error"
|
REP_ERROR = "rep_error"
|
||||||
|
|
||||||
# Event types
|
# Event types
|
||||||
|
@ -168,13 +168,14 @@ class MessengerBridge:
|
||||||
return self.getUserId(user)
|
return self.getUserId(user)
|
||||||
|
|
||||||
def revUserId(self, user_id):
|
def revUserId(self, user_id):
|
||||||
if user_id in self.rev_uid:
|
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]
|
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
|
|
||||||
|
|
||||||
def getUserShortName(self, user):
|
def getUserShortName(self, user):
|
||||||
if user.first_name != None:
|
if user.first_name != None:
|
||||||
|
@ -277,6 +278,16 @@ class MessengerBridge:
|
||||||
uid = self.revUserId(cmd["user"])
|
uid = self.revUserId(cmd["user"])
|
||||||
self.client.addUsersToGroup([uid], cmd["room"])
|
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:
|
elif ty == SEND:
|
||||||
event = cmd["data"]
|
event = cmd["data"]
|
||||||
if event["type"] in [EVENT_MESSAGE, EVENT_ACTION]:
|
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, "- accounts: list accounts")
|
||||||
ezbrSystemSend(mxid, "- join <protocol or account> <room id>: join public chat room")
|
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, "- 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":
|
case "list", "account", "accounts":
|
||||||
one := false
|
one := false
|
||||||
if accts, ok := registeredAccounts[mxid]; ok {
|
if accts, ok := registeredAccounts[mxid]; ok {
|
||||||
|
@ -271,6 +272,21 @@ func handleSystemMessage(mxid string, msg string) {
|
||||||
} else {
|
} else {
|
||||||
ezbrSystemSendf(mxid, "No account with name or using protocol %s", cmd[1])
|
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:
|
default:
|
||||||
ezbrSystemSend(mxid, "Unrecognized command. Type `help` if you need some help!")
|
ezbrSystemSend(mxid, "Unrecognized command. Type `help` if you need some help!")
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue