From 6e6c6f5c481134ae3ea786fa4750dfb320f654ef Mon Sep 17 00:00:00 2001 From: Andrew Ferrazzutti Date: Wed, 9 Mar 2022 20:26:39 -0500 Subject: [PATCH] Message sending --- .../kt/client/client.py | 8 ++++ matrix_appservice_kakaotalk/portal.py | 40 ++++++++++++++++++- node/src/client.js | 32 +++++++++------ 3 files changed, 65 insertions(+), 15 deletions(-) diff --git a/matrix_appservice_kakaotalk/kt/client/client.py b/matrix_appservice_kakaotalk/kt/client/client.py index c415414..d1729ed 100644 --- a/matrix_appservice_kakaotalk/kt/client/client.py +++ b/matrix_appservice_kakaotalk/kt/client/client.py @@ -225,6 +225,14 @@ class Client: sync_from=sync_from.serialize() if sync_from else None ))[-limit if limit else 0:] + async def send_message(self, channel_id: Long, text: str) -> Chatlog: + return await self._api_user_request_result( + Chatlog, + "send_message", + channel_id=channel_id.serialize(), + text=text + ) + async def stop(self) -> None: # TODO Stop all event handlers await self._api_user_request_void("stop") diff --git a/matrix_appservice_kakaotalk/portal.py b/matrix_appservice_kakaotalk/portal.py index c47c14b..8dc8913 100644 --- a/matrix_appservice_kakaotalk/portal.py +++ b/matrix_appservice_kakaotalk/portal.py @@ -19,6 +19,7 @@ from typing import TYPE_CHECKING, Any, AsyncGenerator, Pattern, cast from collections import deque import asyncio import re +import time from mautrix.appservice import IntentAPI from mautrix.bridge import BasePortal, NotificationDisabler, async_getter_lock @@ -45,7 +46,7 @@ from .db import ( Message as DBMessage, Portal as DBPortal, ) -from .formatter.from_kakaotalk import kakaotalk_to_matrix +from .formatter import kakaotalk_to_matrix, matrix_to_kakaotalk from .kt.types.bson import Long, IntLong from .kt.types.channel.channel_info import ChannelInfo @@ -53,6 +54,7 @@ from .kt.types.channel.channel_type import KnownChannelType, ChannelType from .kt.types.chat.chat import Chatlog from .kt.client.types import UserInfoUnion, PortalChannelInfo +from .kt.client.errors import CommandException if TYPE_CHECKING: from .__main__ import KakaoTalkBridge @@ -649,10 +651,44 @@ class Portal(DBPortal, BasePortal): else: raise NotImplementedError(f"Unsupported message type {message.msgtype}") + async def _make_dbm(self, sender: u.User, event_id: EventID, ktid: Long) -> None: + await DBMessage( + mxid=event_id, + mx_room=self.mxid, + ktid=ktid, + index=0, + kt_chat=self.ktid, + kt_receiver=self.kt_receiver, + # TODO? + #kt_sender=sender.ktid, + timestamp=int(time.time() * 1000), + ).insert() + async def _handle_matrix_text( self, event_id: EventID, sender: u.User, message: TextMessageEventContent ) -> None: - self.log.info("TODO: _handle_matrix_text") + converted = await matrix_to_kakaotalk(message, self.mxid, self.log) + try: + chatlog = await sender.client.send_message( + self.ktid, + text=converted.text, + # TODO + #mentions=converted.mentions, + #reply_to=converted.reply_to, + ) + except CommandException: + self.log.debug(f"Error handling Matrix message {event_id}") + raise + + await self._make_dbm(sender, event_id, chatlog.logId) + self.log.debug(f"Handled Matrix message {event_id} -> {chatlog.logId}") + sender.send_remote_checkpoint( + MessageSendCheckpointStatus.SUCCESS, + event_id, + self.mxid, + EventType.ROOM_MESSAGE, + message.msgtype, + ) async def _handle_matrix_media( self, event_id: EventID, sender: u.User, message: MediaMessageEventContent, is_relay: bool diff --git a/node/src/client.js b/node/src/client.js index 521f317..474af59 100644 --- a/node/src/client.js +++ b/node/src/client.js @@ -23,6 +23,8 @@ import { KnownAuthStatusCode, util, } from "node-kakao" +import chat from "node-kakao/chat" +const { KnownChatType } = chat /** @typedef {import("node-kakao").OAuthCredential} OAuthCredential */ /** @typedef {import("./clientmanager.js").default} ClientManager} */ @@ -341,6 +343,22 @@ export default class PeerClient { return await talkChannel.getChatListFrom(req.sync_from) } + /** + * @param {Object} req + * @param {string} req.mxid + * @param {Long} req.channel_id + * @param {string} req.text + */ + sendMessage = async (req) => { + const userClient = this.#getUser(req.mxid) + const talkChannel = userClient.talkClient.channelList.get(req.channel_id) + + return await talkChannel.sendChat({ + type: KnownChatType.TEXT, + text: req.text, + }) + } + /** * @param {Object} req * @param {string} req.mxid @@ -434,19 +452,7 @@ export default class PeerClient { get_portal_channel_info: this.getPortalChannelInfo, get_chats: this.getChats, get_profile: this.getProfile, - /* - send: req => this.puppet.sendMessage(req.chat_id, req.text), - send_file: req => this.puppet.sendFile(req.chat_id, req.file_path), - set_last_message_ids: req => this.puppet.setLastMessageIDs(req.msg_ids, req.own_msg_ids, req.rct_ids), - forget_chat: req => this.puppet.forgetChat(req.chat_id), - pause: () => this.puppet.stopObserving(), - resume: () => this.puppet.startObserving(), - get_contacts: () => this.puppet.getContacts(), - get_chats: () => this.puppet.getRecentChats(), - get_chat: req => this.puppet.getChatInfo(req.chat_id, req.force_view), - get_messages: req => this.puppet.getMessages(req.chat_id), - read_image: req => this.puppet.readImage(req.image_url), - */ + send_message: this.sendMessage, //is_connected: async () => ({ is_connected: !await this.puppet.isDisconnected() }), }[req.command] || this.handleUnknownCommand }