Create new direct chat if necessary when creating new DM portal

Might fail on first attempt, though
This commit is contained in:
Andrew Ferrazzutti 2022-05-06 04:25:08 -04:00
parent c3726220de
commit 4e6498f777
5 changed files with 48 additions and 11 deletions

View File

@ -73,10 +73,7 @@
* [x] At startup * [x] At startup
* [x] When added to chat * [x] When added to chat
* [x] When receiving message * [x] When receiving message
* [ ] Private chat creation by inviting Matrix puppet of KakaoTalk user to new room * [x] Direct chat creation by inviting Matrix puppet of KakaoTalk user to new room
* [x] For existing recently-updated KakaoTalk channels
* [ ] For existing long-idled KakaoTalk channels
* [ ] For new KakaoTalk channels
* [x] Option to use own Matrix account for messages sent from other KakaoTalk clients * [x] Option to use own Matrix account for messages sent from other KakaoTalk clients
* [ ] KakaoTalk friends list management * [ ] KakaoTalk friends list management
* [x] List friends * [x] List friends

View File

@ -505,6 +505,13 @@ class Client:
photo_url=photo_url, photo_url=photo_url,
) )
def create_direct_chat(self, ktid: Long) -> Awaitable[Long]:
return self._api_user_request_result(
Long,
"create_direct_chat",
user_id=ktid.serialize(),
)
def leave_channel( def leave_channel(
self, self,
channel_props: ChannelProps, channel_props: ChannelProps,

View File

@ -30,7 +30,7 @@ from mautrix.types import (
UserID, UserID,
) )
from . import portal as po, user as u from . import portal as po, puppet as pu, user as u
from .db import Message as DBMessage from .db import Message as DBMessage
if TYPE_CHECKING: if TYPE_CHECKING:
@ -63,6 +63,19 @@ class MatrixHandler(BaseMatrixHandler):
room_id, "This room has been marked as your KakaoTalk bridge notice room." room_id, "This room has been marked as your KakaoTalk bridge notice room."
) )
async def handle_puppet_dm_invite(
self, room_id: RoomID, puppet: pu.Puppet, invited_by: u.User, evt: StateEvent
) -> None:
# TODO Make upstream request to return custom failure message,
# instead of having to reimplement the entire function
portal = await invited_by.get_portal_with(puppet)
if portal:
await portal.accept_matrix_dm(room_id, invited_by, puppet)
else:
await puppet.default_mxid_intent.leave_room(
room_id, reason="Unable to create a DM for this KakaoTalk user"
)
async def handle_invite( async def handle_invite(
self, room_id: RoomID, user_id: UserID, invited_by: u.User, event_id: EventID self, room_id: RoomID, user_id: UserID, invited_by: u.User, event_id: EventID
) -> None: ) -> None:

View File

@ -685,14 +685,18 @@ class User(DBUser, BaseUser):
else: else:
ktid = memo_ids[0] ktid = memo_ids[0]
if len(memo_ids) > 1: if len(memo_ids) > 1:
self.log.info("Found multiple memo chats, so using the first one as a fallback") self.log.warning("Found multiple memo chats, so using the first one as a fallback")
if ktid: if ktid:
self.log.debug(f"Found existing direct chat with KakaoTalk user {puppet.ktid}")
else:
self.log.debug(f"Didn't find an existing direct chat with KakaoTalk user {puppet.ktid}, so will create one")
try:
ktid = await self.client.create_direct_chat(puppet.ktid)
except:
self.log.exception(f"Failed to create direct chat with {puppet.ktid}")
return await po.Portal.get_by_ktid( return await po.Portal.get_by_ktid(
ktid, kt_receiver=self.ktid, create=create, kt_type=kt_type ktid, kt_receiver=self.ktid, create=create, kt_type=kt_type
) ) if ktid else None
else:
self.log.warning(f"Didn't find an existing DM channel with KakaoTalk user {puppet.ktid}, so not creating one")
return None
# region KakaoTalk event handling # region KakaoTalk event handling

View File

@ -959,6 +959,7 @@ export default class PeerClient {
/** @type Long[] */ /** @type Long[] */
const channelIds = [] const channelIds = []
const channelList = this.#getUser(req.mxid).talkClient.channelList const channelList = this.#getUser(req.mxid).talkClient.channelList
// TODO channelList.all() doesn't really return *all* channels...
for (const channel of channelList.all()) { for (const channel of channelList.all()) {
if (channel.info.type == "MemoChat") { if (channel.info.type == "MemoChat") {
channelIds.push(channel.channelId) channelIds.push(channel.channelId)
@ -1128,6 +1129,20 @@ export default class PeerClient {
}) })
} }
/**
* @param {Object} req
* @param {string} req.mxid
* @param {Long} req.user_id
*/
createDirectChat = async (req) => {
const channelList = this.#getUser(req.mxid).talkClient.channelList.normal
const res = await channelList.createChannel({
userList: [{ userId: req.user_id }],
})
if (!res.success) return res
return makeCommandResult(res.result.channelId)
}
/** /**
* @param {Object} req * @param {Object} req
* @param {string} req.mxid * @param {string} req.mxid
@ -1236,6 +1251,7 @@ export default class PeerClient {
set_channel_name: this.setChannelName, set_channel_name: this.setChannelName,
set_channel_description: this.setChannelDescription, set_channel_description: this.setChannelDescription,
set_channel_photo: this.setChannelPhoto, set_channel_photo: this.setChannelPhoto,
create_direct_chat: this.createDirectChat,
leave_channel: this.leaveChannel, leave_channel: this.leaveChannel,
}[req.command] || this.handleUnknownCommand }[req.command] || this.handleUnknownCommand
} }