Command for outbound leaves

This commit is contained in:
Andrew Ferrazzutti 2022-04-28 03:22:14 -04:00
parent e952c05d35
commit cf4f40efa2
4 changed files with 48 additions and 2 deletions

View File

@ -28,6 +28,7 @@ from .typehint import CommandEvent
from ..kt.client.errors import CommandException from ..kt.client.errors import CommandException
SECTION_FRIENDS = HelpSection("Friends management", 40, "") SECTION_FRIENDS = HelpSection("Friends management", 40, "")
SECTION_CHANNELS = HelpSection("Channel management", 45, "")
if TYPE_CHECKING: if TYPE_CHECKING:
from ..kt.types.api.struct import FriendStruct from ..kt.types.api.struct import FriendStruct
@ -67,3 +68,21 @@ async def list_friends(evt: CommandEvent) -> None:
await evt.reply(f"{results}") await evt.reply(f"{results}")
else: else:
await evt.reply("No friends found.") await evt.reply("No friends found.")
@command_handler(
needs_auth=True,
management_only=False,
help_section=SECTION_CHANNELS,
help_text="Leave this KakaoTalk channel",
)
async def leave(evt: CommandEvent) -> None:
if not evt.sender.is_connected:
await evt.reply("You are not connected to KakaoTalk chats")
return
if not evt.is_portal:
await evt.reply("This command may only be used in a KakaoTalk channel portal room")
return
await evt.mark_read()
await evt.sender.client.leave_channel(evt.portal.channel_props)
await evt.sender.on_channel_left(evt.portal.ktid, evt.portal.kt_type)

View File

@ -450,6 +450,15 @@ class Client:
photo_url=photo_url, photo_url=photo_url,
) )
def leave_channel(
self,
channel_props: ChannelProps,
) -> Awaitable[None]:
return self._api_user_request_void(
"leave_channel",
channel_props=channel_props.serialize(),
)
# TODO Combine each of these pairs into one # TODO Combine each of these pairs into one

View File

@ -1750,11 +1750,13 @@ class Portal(DBPortal, BasePortal):
) -> None: ) -> None:
sender_intent = sender.intent_for(self) if sender else self.main_intent sender_intent = sender.intent_for(self) if sender else self.main_intent
if sender == removed: if sender == removed:
await removed.intent_for(self).leave_room(self.mxid) removed_intent = removed.intent_for(self)
if removed_intent != self.main_intent:
await removed_intent.leave_room(self.mxid)
if not removed.is_real_user: if not removed.is_real_user:
user = await u.User.get_by_ktid(removed.ktid) user = await u.User.get_by_ktid(removed.ktid)
if user: if user:
await sender_intent.kick_user(self.mxid, user.mxid, "Left channel from KakaoTalk") await self.main_intent.kick_user(self.mxid, user.mxid, "Left channel from KakaoTalk")
else: else:
for removed_mxid in (r.mxid for r in ( for removed_mxid in (r.mxid for r in (
removed, removed,
@ -1770,6 +1772,7 @@ class Portal(DBPortal, BasePortal):
await self.main_intent.ban_user( await self.main_intent.ban_user(
self.mxid, removed_mxid, reason=f"Kicked by {sender.name}" self.mxid, removed_mxid, reason=f"Kicked by {sender.name}"
) )
# TODO Clean and delete if removed is real user and portal is direct / not open
# TODO Find when or if there is a listener for this # TODO Find when or if there is a listener for this
# TODO Confirm whether this can refer to any user that was kicked, or only to the current user # TODO Confirm whether this can refer to any user that was kicked, or only to the current user

View File

@ -998,6 +998,20 @@ export default class PeerClient {
}) })
} }
/**
* @param {Object} req
* @param {string} req.mxid
* @param {ChannelProps} req.channel_props
*/
leaveChannel = async (req) => {
const userClient = this.#getUser(req.mxid)
const channelList = getChannelListForType(
userClient.talkClient.channelList,
req.channel_props.type
)
return channelList.leaveChannel({ channelId: req.channel_props.id })
}
handleUnknownCommand = () => { handleUnknownCommand = () => {
throw new Error("Unknown command") throw new Error("Unknown command")
} }
@ -1086,6 +1100,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,
leave_channel: this.leaveChannel,
}[req.command] || this.handleUnknownCommand }[req.command] || this.handleUnknownCommand
} }
const resp = { id: req.id } const resp = { id: req.id }