Restore forgotten channels before sending something into them
This commit is contained in:
parent
b9eb4ce0ac
commit
66262caa63
|
@ -49,7 +49,7 @@ from ..types.request import (
|
|||
CommandResultDoneValue
|
||||
)
|
||||
|
||||
from .types import PortalChannelInfo, UserInfoUnion
|
||||
from .types import PortalChannelInfo, UserInfoUnion, ChannelProps
|
||||
|
||||
from .errors import InvalidAccessToken
|
||||
from .error_helper import raise_unsuccessful_response
|
||||
|
@ -207,34 +207,34 @@ class Client:
|
|||
)
|
||||
return profile_req_struct.profile
|
||||
|
||||
async def get_portal_channel_info(self, channel_id: Long) -> PortalChannelInfo:
|
||||
async def get_portal_channel_info(self, channel_props: ChannelProps) -> PortalChannelInfo:
|
||||
return await self._api_user_request_result(
|
||||
PortalChannelInfo,
|
||||
"get_portal_channel_info",
|
||||
channel_id=channel_id.serialize()
|
||||
channel_props=channel_props.serialize(),
|
||||
)
|
||||
|
||||
async def get_participants(self, channel_id: Long) -> list[UserInfoUnion]:
|
||||
async def get_participants(self, channel_props: ChannelProps) -> list[UserInfoUnion]:
|
||||
return await self._api_user_request_result(
|
||||
ResultListType(UserInfoUnion),
|
||||
"get_participants",
|
||||
channel_id=channel_id.serialize()
|
||||
channel_props=channel_props.serialize()
|
||||
)
|
||||
|
||||
async def get_chats(self, channel_id: Long, sync_from: Long | None, limit: int | None) -> list[Chatlog]:
|
||||
async def get_chats(self, channel_props: ChannelProps, sync_from: Long | None, limit: int | None) -> list[Chatlog]:
|
||||
return await self._api_user_request_result(
|
||||
ResultListType(Chatlog),
|
||||
"get_chats",
|
||||
channel_id=channel_id.serialize(),
|
||||
channel_props=channel_props.serialize(),
|
||||
sync_from=sync_from.serialize() if sync_from else None,
|
||||
limit=limit
|
||||
)
|
||||
|
||||
async def send_message(self, channel_id: Long, text: str) -> Chatlog:
|
||||
async def send_message(self, channel_props: ChannelProps, text: str) -> Chatlog:
|
||||
return await self._api_user_request_result(
|
||||
Chatlog,
|
||||
"send_message",
|
||||
channel_id=channel_id.serialize(),
|
||||
channel_props=channel_props.serialize(),
|
||||
text=text
|
||||
)
|
||||
|
||||
|
|
|
@ -21,7 +21,9 @@ from attr import dataclass
|
|||
|
||||
from mautrix.types import SerializableAttrs, JSON, deserializer
|
||||
|
||||
from ..types.bson import Long
|
||||
from ..types.channel.channel_info import NormalChannelInfo
|
||||
from ..types.channel.channel_type import ChannelType
|
||||
from ..types.openlink.open_channel_info import OpenChannelInfo
|
||||
from ..types.user.channel_user_info import NormalChannelUserInfo, OpenChannelUserInfo
|
||||
|
||||
|
@ -56,3 +58,9 @@ class PortalChannelInfo(SerializableAttrs):
|
|||
participants: list[UserInfoUnion]
|
||||
# TODO Image
|
||||
channel_info: Optional[ChannelInfoUnion] = None # Should be set manually by caller
|
||||
|
||||
|
||||
@dataclass
|
||||
class ChannelProps(SerializableAttrs):
|
||||
id: Long
|
||||
type: ChannelType
|
||||
|
|
|
@ -52,7 +52,7 @@ from .kt.types.channel.channel_info import ChannelInfo
|
|||
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.types import UserInfoUnion, PortalChannelInfo, ChannelProps
|
||||
from .kt.client.errors import CommandException
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
@ -194,6 +194,13 @@ class Portal(DBPortal, BasePortal):
|
|||
raise ValueError(f"Non-direct chat portal should have no sender, but has sender {self._kt_sender}")
|
||||
return self._kt_sender
|
||||
|
||||
@property
|
||||
def channel_props(self) -> ChannelProps:
|
||||
return ChannelProps(
|
||||
id=self.ktid,
|
||||
type=self.kt_type
|
||||
)
|
||||
|
||||
@property
|
||||
def main_intent(self) -> IntentAPI:
|
||||
if not self._main_intent:
|
||||
|
@ -245,7 +252,7 @@ class Portal(DBPortal, BasePortal):
|
|||
) -> PortalChannelInfo:
|
||||
if not info:
|
||||
self.log.debug("Called update_info with no info, fetching channel info...")
|
||||
info = await source.client.get_portal_channel_info(self.ktid)
|
||||
info = await source.client.get_portal_channel_info(self.channel_props)
|
||||
changed = False
|
||||
if not self.is_direct:
|
||||
changed = any(
|
||||
|
@ -400,7 +407,7 @@ class Portal(DBPortal, BasePortal):
|
|||
async def _update_participants(self, source: u.User, participants: list[UserInfoUnion] | None = None) -> bool:
|
||||
if participants is None:
|
||||
self.log.debug("Called _update_participants with no participants, fetching them now...")
|
||||
participants = await source.client.get_participants(self.ktid)
|
||||
participants = await source.client.get_participants(self.channel_props)
|
||||
changed = False
|
||||
if not self._main_intent:
|
||||
assert self.is_direct, "_main_intent for non-direct chat portal should have been set already"
|
||||
|
@ -736,7 +743,7 @@ class Portal(DBPortal, BasePortal):
|
|||
converted = await matrix_to_kakaotalk(message, self.mxid, self.log)
|
||||
try:
|
||||
chatlog = await sender.client.send_message(
|
||||
self.ktid,
|
||||
self.channel_props,
|
||||
text=converted.text,
|
||||
# TODO
|
||||
#mentions=converted.mentions,
|
||||
|
@ -959,7 +966,7 @@ class Portal(DBPortal, BasePortal):
|
|||
self.log.debug(f"Backfilling history through {source.mxid}")
|
||||
self.log.debug(f"Fetching {f'up to {limit}' if limit else 'all'} messages through {source.ktid}")
|
||||
messages = await source.client.get_chats(
|
||||
channel_info.channelId,
|
||||
self.channel_props,
|
||||
after_log_id,
|
||||
limit
|
||||
)
|
||||
|
@ -989,7 +996,6 @@ class Portal(DBPortal, BasePortal):
|
|||
# TODO Save kt_sender in DB instead? Depends on if DM channels are shared...
|
||||
user = await u.User.get_by_ktid(self.kt_receiver)
|
||||
assert user, f"Found no user for this portal's receiver of {self.kt_receiver}"
|
||||
# TODO Should this backfill? Useful for forgotten channels
|
||||
await self._update_participants(user)
|
||||
else:
|
||||
self.log.debug("Not setting _main_intent of new direct chat until after checking participant list")
|
||||
|
|
|
@ -499,7 +499,7 @@ class User(DBUser, BaseUser):
|
|||
kt_receiver=self.ktid,
|
||||
kt_type=channel_info.type
|
||||
)
|
||||
portal_info = await self.client.get_portal_channel_info(channel_info.channelId)
|
||||
portal_info = await self.client.get_portal_channel_info(portal.channel_props)
|
||||
portal_info.channel_info = channel_info
|
||||
if not portal.mxid:
|
||||
await portal.create_matrix_room(self, portal_info)
|
||||
|
|
|
@ -24,6 +24,8 @@ import {
|
|||
util,
|
||||
} from "node-kakao"
|
||||
/** @typedef {import("node-kakao").OAuthCredential} OAuthCredential */
|
||||
/** @typedef {import("node-kakao/dist/talk").TalkChannelList} TalkChannelList */
|
||||
/** @typedef {import("node-kakao").ChannelType} ChannelType */
|
||||
|
||||
import chat from "node-kakao/chat"
|
||||
const { KnownChatType } = chat
|
||||
|
@ -68,6 +70,30 @@ class UserClient {
|
|||
return userClient
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Object} channel_props
|
||||
* @param {Long} channel_props.id
|
||||
* @param {ChannelType} channel_props.type
|
||||
*/
|
||||
async getChannel(channel_props) {
|
||||
let channel = this.#talkClient.channelList.get(channel_props.id)
|
||||
if (channel) {
|
||||
return channel
|
||||
} else {
|
||||
const channelList = getChannelListForType(
|
||||
this.#talkClient.channelList,
|
||||
channel_props.type
|
||||
)
|
||||
const res = await channelList.addChannel({
|
||||
channelId: channel_props.id,
|
||||
})
|
||||
if (!res.success) {
|
||||
throw new Error(`Unable to add ${channel_props.type} channel ${channel_props.id}`)
|
||||
}
|
||||
return res.result
|
||||
}
|
||||
}
|
||||
|
||||
close() {
|
||||
this.#talkClient.close()
|
||||
}
|
||||
|
@ -337,11 +363,11 @@ export default class PeerClient {
|
|||
/**
|
||||
* @param {Object} req
|
||||
* @param {string} req.mxid
|
||||
* @param {Long} req.channel_id
|
||||
* @param {Object} req.channel_props
|
||||
*/
|
||||
getPortalChannelInfo = async (req) => {
|
||||
const userClient = this.#getUser(req.mxid)
|
||||
const talkChannel = userClient.talkClient.channelList.get(req.channel_id)
|
||||
const talkChannel = await userClient.getChannel(req.channel_props)
|
||||
|
||||
const res = await talkChannel.updateAll()
|
||||
if (!res.success) return res
|
||||
|
@ -356,24 +382,24 @@ export default class PeerClient {
|
|||
/**
|
||||
* @param {Object} req
|
||||
* @param {string} req.mxid
|
||||
* @param {Long} req.channel_id
|
||||
* @param {Object} req.channel_props
|
||||
*/
|
||||
getParticipants = async (req) => {
|
||||
const userClient = this.#getUser(req.mxid)
|
||||
const talkChannel = userClient.getChannel(req.channel_id)
|
||||
const talkChannel = await userClient.getChannel(req.channel_props)
|
||||
return await talkChannel.getAllLatestUserInfo()
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Object} req
|
||||
* @param {string} req.mxid
|
||||
* @param {Long} req.channel_id
|
||||
* @param {Object} req.channel_props
|
||||
* @param {Long?} req.sync_from
|
||||
* @param {Number?} req.limit
|
||||
*/
|
||||
getChats = async (req) => {
|
||||
const userClient = this.#getUser(req.mxid)
|
||||
const talkChannel = userClient.talkClient.channelList.get(req.channel_id)
|
||||
const talkChannel = await userClient.getChannel(req.channel_props)
|
||||
|
||||
const res = await talkChannel.getChatListFrom(req.sync_from)
|
||||
if (res.success && 0 < req.limit && req.limit < res.result.length) {
|
||||
|
@ -385,12 +411,12 @@ export default class PeerClient {
|
|||
/**
|
||||
* @param {Object} req
|
||||
* @param {string} req.mxid
|
||||
* @param {Long} req.channel_id
|
||||
* @param {Object} req.channel_props
|
||||
* @param {string} req.text
|
||||
*/
|
||||
sendMessage = async (req) => {
|
||||
const userClient = this.#getUser(req.mxid)
|
||||
const talkChannel = userClient.talkClient.channelList.get(req.channel_id)
|
||||
const talkChannel = await userClient.getChannel(req.channel_props)
|
||||
|
||||
return await talkChannel.sendChat({
|
||||
type: KnownChatType.TEXT,
|
||||
|
@ -517,3 +543,18 @@ export default class PeerClient {
|
|||
return value
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param {TalkChannelList} channelList
|
||||
* @param {ChannelType} channelType
|
||||
*/
|
||||
function getChannelListForType(channelList, channelType) {
|
||||
switch (channelType) {
|
||||
case "OM":
|
||||
case "OD":
|
||||
return channelList.open
|
||||
default:
|
||||
return channelList.normal
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue