Add command for listing friends
This commit is contained in:
parent
66262caa63
commit
2d9ae53d89
@ -1,2 +1,3 @@
|
|||||||
from .auth import SECTION_AUTH#, enter_2fa_code
|
from .auth import SECTION_AUTH
|
||||||
from .conn import SECTION_CONNECTION
|
from .conn import SECTION_CONNECTION
|
||||||
|
from .kakaotalk import SECTION_FRIENDS
|
||||||
|
69
matrix_appservice_kakaotalk/commands/kakaotalk.py
Normal file
69
matrix_appservice_kakaotalk/commands/kakaotalk.py
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
# matrix-appservice-kakaotalk - A Matrix-KakaoTalk puppeting bridge.
|
||||||
|
# Copyright (C) 2022 Tulir Asokan, Andrew Ferrazzutti
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Affero General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Affero General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
|
import asyncio
|
||||||
|
|
||||||
|
from mautrix.bridge.commands import HelpSection, command_handler
|
||||||
|
|
||||||
|
from ..kt.types.api.struct import ApiUserType
|
||||||
|
|
||||||
|
from .. import puppet as pu, user as u
|
||||||
|
from .typehint import CommandEvent
|
||||||
|
|
||||||
|
from ..kt.client.errors import CommandException
|
||||||
|
|
||||||
|
SECTION_FRIENDS = HelpSection("Friends management", 40, "")
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from ..kt.types.api.struct import FriendStruct
|
||||||
|
|
||||||
|
|
||||||
|
async def _get_search_result_puppet(source: u.User, friend_struct: FriendStruct) -> pu.Puppet:
|
||||||
|
puppet = await pu.Puppet.get_by_ktid(friend_struct.userId)
|
||||||
|
if not puppet.name_set:
|
||||||
|
await puppet.update_info_from_friend(source, friend_struct)
|
||||||
|
return puppet
|
||||||
|
|
||||||
|
|
||||||
|
@command_handler(
|
||||||
|
needs_auth=True,
|
||||||
|
management_only=False,
|
||||||
|
help_section=SECTION_FRIENDS,
|
||||||
|
help_text="List all KakaoTalk friends",
|
||||||
|
)
|
||||||
|
async def list_friends(evt: CommandEvent) -> None:
|
||||||
|
try:
|
||||||
|
resp = await evt.sender.client.list_friends()
|
||||||
|
await evt.mark_read()
|
||||||
|
except CommandException as e:
|
||||||
|
await evt.reply(f"Error while listing friends: {e!s}")
|
||||||
|
return
|
||||||
|
puppets = await asyncio.gather(
|
||||||
|
*[
|
||||||
|
_get_search_result_puppet(evt.sender, friend_struct)
|
||||||
|
for friend_struct in resp.friends if friend_struct.userType == ApiUserType.NORMAL
|
||||||
|
# NOTE Using NORMAL to avoid listing KakaoTalk bots, which are apparently PLUS users
|
||||||
|
]
|
||||||
|
)
|
||||||
|
results = "".join(
|
||||||
|
f"* [{puppet.name}](https://matrix.to/#/{puppet.default_mxid})\n" for puppet in puppets
|
||||||
|
)
|
||||||
|
if results:
|
||||||
|
await evt.reply(f"{results}")
|
||||||
|
else:
|
||||||
|
await evt.reply("No friends found.")
|
@ -37,6 +37,7 @@ from ...config import Config
|
|||||||
from ...rpc import RPCClient
|
from ...rpc import RPCClient
|
||||||
|
|
||||||
from ..types.api.struct.profile import ProfileReqStruct, ProfileStruct
|
from ..types.api.struct.profile import ProfileReqStruct, ProfileStruct
|
||||||
|
from ..types.api.struct import FriendListStruct
|
||||||
from ..types.bson import Long
|
from ..types.bson import Long
|
||||||
from ..types.client.client_session import LoginResult
|
from ..types.client.client_session import LoginResult
|
||||||
from ..types.chat.chat import Chatlog
|
from ..types.chat.chat import Chatlog
|
||||||
@ -230,6 +231,12 @@ class Client:
|
|||||||
limit=limit
|
limit=limit
|
||||||
)
|
)
|
||||||
|
|
||||||
|
async def list_friends(self) -> FriendListStruct:
|
||||||
|
return await self._api_user_request_result(
|
||||||
|
FriendListStruct,
|
||||||
|
"list_friends",
|
||||||
|
)
|
||||||
|
|
||||||
async def send_message(self, channel_props: ChannelProps, text: str) -> Chatlog:
|
async def send_message(self, channel_props: ChannelProps, text: str) -> Chatlog:
|
||||||
return await self._api_user_request_result(
|
return await self._api_user_request_result(
|
||||||
Chatlog,
|
Chatlog,
|
||||||
|
@ -13,6 +13,8 @@
|
|||||||
#
|
#
|
||||||
# You should have received a copy of the GNU Affero General Public License
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
"""
|
##from .login import *
|
||||||
|
##from .account import *
|
||||||
from .profile import *
|
from .profile import *
|
||||||
"""
|
from .friends import *
|
||||||
|
##from .openlink import *
|
||||||
|
@ -0,0 +1,21 @@
|
|||||||
|
# matrix-appservice-kakaotalk - A Matrix-KakaoTalk puppeting bridge.
|
||||||
|
# Copyright (C) 2022 Tulir Asokan, Andrew Ferrazzutti
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Affero General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Affero General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
from .friend_blocked_list_struct import *
|
||||||
|
from .friend_find_struct import *
|
||||||
|
from .friend_list_struct import *
|
||||||
|
from .friend_req_struct import *
|
||||||
|
from .friend_search_struct import *
|
||||||
|
from .friend_struct import *
|
@ -0,0 +1,31 @@
|
|||||||
|
# matrix-appservice-kakaotalk - A Matrix-KakaoTalk puppeting bridge.
|
||||||
|
# Copyright (C) 2022 Tulir Asokan, Andrew Ferrazzutti
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Affero General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Affero General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
from attr import dataclass
|
||||||
|
|
||||||
|
from mautrix.types import SerializableAttrs
|
||||||
|
|
||||||
|
from .friend_struct import FriendStruct
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class FriendBlockedListStruct(SerializableAttrs):
|
||||||
|
total: int
|
||||||
|
blockedFriends: list[FriendStruct]
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"FriendBlockedListStruct",
|
||||||
|
]
|
@ -0,0 +1,38 @@
|
|||||||
|
# matrix-appservice-kakaotalk - A Matrix-KakaoTalk puppeting bridge.
|
||||||
|
# Copyright (C) 2022 Tulir Asokan, Andrew Ferrazzutti
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Affero General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Affero General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
from attr import dataclass
|
||||||
|
|
||||||
|
from mautrix.types import SerializableAttrs
|
||||||
|
|
||||||
|
from ....bson import Long
|
||||||
|
from .friend_struct import FriendStruct
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class FriendFindIdStruct(SerializableAttrs):
|
||||||
|
token: Long
|
||||||
|
friend: FriendStruct
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class FriendFindUUIDStruct(SerializableAttrs):
|
||||||
|
member: FriendStruct
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"FriendFindIdStruct",
|
||||||
|
"FriendFindUUIDStruct",
|
||||||
|
]
|
@ -0,0 +1,32 @@
|
|||||||
|
# matrix-appservice-kakaotalk - A Matrix-KakaoTalk puppeting bridge.
|
||||||
|
# Copyright (C) 2022 Tulir Asokan, Andrew Ferrazzutti
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Affero General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Affero General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
from attr import dataclass
|
||||||
|
|
||||||
|
from mautrix.types import SerializableAttrs
|
||||||
|
|
||||||
|
from ....bson import Long
|
||||||
|
from .friend_struct import FriendStruct
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class FriendListStruct(SerializableAttrs):
|
||||||
|
token: Long
|
||||||
|
friends: list[FriendStruct]
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"FriendListStruct",
|
||||||
|
]
|
@ -0,0 +1,36 @@
|
|||||||
|
# matrix-appservice-kakaotalk - A Matrix-KakaoTalk puppeting bridge.
|
||||||
|
# Copyright (C) 2022 Tulir Asokan, Andrew Ferrazzutti
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Affero General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Affero General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
from attr import dataclass
|
||||||
|
|
||||||
|
from mautrix.types import SerializableAttrs
|
||||||
|
|
||||||
|
from .friend_struct import FriendStruct
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class FriendReqStruct(SerializableAttrs):
|
||||||
|
friend: FriendStruct
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class FriendReqPhoneNumberStruct(SerializableAttrs):
|
||||||
|
pstn_number: str
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"FriendReqStruct",
|
||||||
|
"FriendReqPhoneNumberStruct",
|
||||||
|
]
|
@ -0,0 +1,43 @@
|
|||||||
|
# matrix-appservice-kakaotalk - A Matrix-KakaoTalk puppeting bridge.
|
||||||
|
# Copyright (C) 2022 Tulir Asokan, Andrew Ferrazzutti
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Affero General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Affero General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
from attr import dataclass
|
||||||
|
|
||||||
|
from mautrix.types import SerializableAttrs
|
||||||
|
|
||||||
|
from .friend_struct import FriendStruct
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class FriendSearchUserListStruct(SerializableAttrs):
|
||||||
|
count: int
|
||||||
|
list: list[FriendStruct]
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(kw_only=True)
|
||||||
|
class FriendSearchStruct(SerializableAttrs):
|
||||||
|
query: str
|
||||||
|
user: Optional[FriendSearchUserListStruct] = None
|
||||||
|
plus: Optional[FriendSearchUserListStruct] = None
|
||||||
|
categories: list[str]
|
||||||
|
total_counts: int
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"FriendSearchUserListStruct",
|
||||||
|
"FriendSearchStruct",
|
||||||
|
]
|
@ -0,0 +1,72 @@
|
|||||||
|
# matrix-appservice-kakaotalk - A Matrix-KakaoTalk puppeting bridge.
|
||||||
|
# Copyright (C) 2022 Tulir Asokan, Andrew Ferrazzutti
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Affero General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Affero General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
from typing import Union, Optional
|
||||||
|
from enum import IntEnum
|
||||||
|
|
||||||
|
from attr import dataclass
|
||||||
|
|
||||||
|
from mautrix.types import SerializableAttrs
|
||||||
|
|
||||||
|
from ....bson import Long
|
||||||
|
|
||||||
|
|
||||||
|
class ApiUserType(IntEnum):
|
||||||
|
NORMAL = 0
|
||||||
|
PLUS = 1
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class FriendExt(SerializableAttrs):
|
||||||
|
addible: bool
|
||||||
|
yellowid: bool
|
||||||
|
consultable: bool
|
||||||
|
friendsCount: int
|
||||||
|
verificationType: str
|
||||||
|
isAdult: bool
|
||||||
|
writable: bool
|
||||||
|
serviceTypeCode: int
|
||||||
|
isOfficial: bool
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(kw_only=True)
|
||||||
|
class FriendStruct(SerializableAttrs):
|
||||||
|
userId: Union[Long, int]
|
||||||
|
nickName: str
|
||||||
|
type: int
|
||||||
|
phoneNumber: str
|
||||||
|
statusMessage: str
|
||||||
|
UUID: str
|
||||||
|
friendNickName: str
|
||||||
|
phoneticName: Optional[str] = None
|
||||||
|
accountId: int
|
||||||
|
profileImageUrl: str
|
||||||
|
fullProfileImageUrl: str
|
||||||
|
originalProfileImageUrl: str
|
||||||
|
userType: ApiUserType;
|
||||||
|
ext: Union[FriendExt, str];
|
||||||
|
hidden: bool
|
||||||
|
purged: bool
|
||||||
|
favorite: bool
|
||||||
|
screenToken: int
|
||||||
|
suspended: bool = False
|
||||||
|
directChatId: int
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"ApiUserType",
|
||||||
|
"FriendExt",
|
||||||
|
"FriendStruct",
|
||||||
|
]
|
@ -22,5 +22,4 @@ class Long(int, Serializable):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def deserialize(cls, raw: JSON) -> "Long":
|
def deserialize(cls, raw: JSON) -> "Long":
|
||||||
assert isinstance(raw, str), f"Long deserialization expected a string, but got non-string value {raw}"
|
|
||||||
return cls(raw)
|
return cls(raw)
|
||||||
|
@ -123,7 +123,7 @@ def deserialize_result(
|
|||||||
result_type: Type[ResultType], data: JSON
|
result_type: Type[ResultType], data: JSON
|
||||||
) -> Union[CommandResultDoneValue[ResultType], RootCommandResult]:
|
) -> Union[CommandResultDoneValue[ResultType], RootCommandResult]:
|
||||||
"""Returns equivalent of CommandResult<T>. Does no consistency checking on success & result properties."""
|
"""Returns equivalent of CommandResult<T>. Does no consistency checking on success & result properties."""
|
||||||
if "result" in data:
|
if "result" in data and data.get("success"):
|
||||||
# TODO Allow arbitrary result object?
|
# TODO Allow arbitrary result object?
|
||||||
return CommandResultDoneValue.deserialize_result(result_type, data)
|
return CommandResultDoneValue.deserialize_result(result_type, data)
|
||||||
else:
|
else:
|
||||||
|
@ -420,7 +420,7 @@ class Portal(DBPortal, BasePortal):
|
|||||||
# TODO nick_map?
|
# TODO nick_map?
|
||||||
for participant in participants:
|
for participant in participants:
|
||||||
puppet = await p.Puppet.get_by_ktid(participant.userId)
|
puppet = await p.Puppet.get_by_ktid(participant.userId)
|
||||||
await puppet.update_info(source, participant)
|
await puppet.update_info_from_participant(source, participant)
|
||||||
if self.is_direct and self._kt_sender == puppet.ktid and self.encrypted:
|
if self.is_direct and self._kt_sender == puppet.ktid and self.encrypted:
|
||||||
changed = await self._update_name(puppet.name) or changed
|
changed = await self._update_name(puppet.name) or changed
|
||||||
changed = await self._update_photo_from_puppet(puppet) or changed
|
changed = await self._update_photo_from_puppet(puppet) or changed
|
||||||
|
@ -33,6 +33,7 @@ from .db import Puppet as DBPuppet
|
|||||||
|
|
||||||
from .kt.types.bson import Long
|
from .kt.types.bson import Long
|
||||||
|
|
||||||
|
from .kt.types.api.struct import FriendStruct
|
||||||
from .kt.types.channel.channel_type import KnownChannelType
|
from .kt.types.channel.channel_type import KnownChannelType
|
||||||
from .kt.client.types import UserInfoUnion
|
from .kt.client.types import UserInfoUnion
|
||||||
|
|
||||||
@ -147,25 +148,51 @@ class Puppet(DBPuppet, BasePuppet):
|
|||||||
|
|
||||||
# region User info updating
|
# region User info updating
|
||||||
|
|
||||||
async def update_info(
|
async def update_info_from_participant(
|
||||||
self,
|
self,
|
||||||
source: u.User,
|
source: u.User,
|
||||||
info: UserInfoUnion,
|
info: UserInfoUnion,
|
||||||
update_avatar: bool = True,
|
update_avatar: bool = True,
|
||||||
|
) -> Puppet:
|
||||||
|
await self._update_info(
|
||||||
|
source,
|
||||||
|
info.nickname,
|
||||||
|
info.profileURL,
|
||||||
|
update_avatar
|
||||||
|
)
|
||||||
|
|
||||||
|
async def update_info_from_friend(
|
||||||
|
self,
|
||||||
|
source: u.User,
|
||||||
|
info: FriendStruct,
|
||||||
|
update_avatar: bool = True,
|
||||||
|
) -> Puppet:
|
||||||
|
await self._update_info(
|
||||||
|
source,
|
||||||
|
info.nickName,
|
||||||
|
info.profileImageUrl,
|
||||||
|
update_avatar
|
||||||
|
)
|
||||||
|
|
||||||
|
async def _update_info(
|
||||||
|
self,
|
||||||
|
source: u.User,
|
||||||
|
name: str,
|
||||||
|
avatar_url: str,
|
||||||
|
update_avatar: bool = True,
|
||||||
) -> Puppet:
|
) -> Puppet:
|
||||||
self._last_info_sync = datetime.now()
|
self._last_info_sync = datetime.now()
|
||||||
try:
|
try:
|
||||||
changed = await self._update_name(info)
|
changed = await self._update_name(name)
|
||||||
if update_avatar:
|
if update_avatar:
|
||||||
changed = await self._update_photo(source, info.profileURL) or changed
|
changed = await self._update_photo(source, avatar_url) or changed
|
||||||
if changed:
|
if changed:
|
||||||
await self.save()
|
await self.save()
|
||||||
except Exception:
|
except Exception:
|
||||||
self.log.exception(f"Failed to update info from source {source.ktid}")
|
self.log.exception(f"Failed to update info from source {source.ktid}")
|
||||||
return self
|
return self
|
||||||
|
|
||||||
async def _update_name(self, info: UserInfoUnion) -> bool:
|
async def _update_name(self, name: str) -> bool:
|
||||||
name = info.nickname
|
|
||||||
if name != self.name or not self.name_set:
|
if name != self.name or not self.name_set:
|
||||||
self.name = name
|
self.name = name
|
||||||
try:
|
try:
|
||||||
|
@ -33,6 +33,23 @@ const { KnownChatType } = chat
|
|||||||
import { emitLines, promisify } from "./util.js"
|
import { emitLines, promisify } from "./util.js"
|
||||||
|
|
||||||
|
|
||||||
|
ServiceApiClient.prototype.requestFriendList = async function() {
|
||||||
|
const res = await this._client.requestData(
|
||||||
|
"POST",
|
||||||
|
`${this.getFriendsApiPath("update.json")}`,
|
||||||
|
{
|
||||||
|
phone_number_type: 1,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
status: res.status,
|
||||||
|
success: res.status === 0,
|
||||||
|
result: res,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class UserClient {
|
class UserClient {
|
||||||
static #initializing = false
|
static #initializing = false
|
||||||
|
|
||||||
@ -270,8 +287,8 @@ export default class PeerClient {
|
|||||||
/**
|
/**
|
||||||
* Get the service client for the specified user ID, or create
|
* Get the service client for the specified user ID, or create
|
||||||
* and return a new service client if no user ID is provided.
|
* and return a new service client if no user ID is provided.
|
||||||
* @param {string} mxid
|
* @param {?string} mxid
|
||||||
* @param {OAuthCredential} oauth_credential
|
* @param {?OAuthCredential} oauth_credential
|
||||||
*/
|
*/
|
||||||
async #getServiceClient(mxid, oauth_credential) {
|
async #getServiceClient(mxid, oauth_credential) {
|
||||||
return this.#tryGetUser(mxid)?.serviceClient ||
|
return this.#tryGetUser(mxid)?.serviceClient ||
|
||||||
@ -341,8 +358,8 @@ export default class PeerClient {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Object} req
|
* @param {Object} req
|
||||||
* @param {string} req.mxid
|
* @param {?string} req.mxid
|
||||||
* @param {OAuthCredential} req.oauth_credential
|
* @param {?OAuthCredential} req.oauth_credential
|
||||||
*/
|
*/
|
||||||
getOwnProfile = async (req) => {
|
getOwnProfile = async (req) => {
|
||||||
const serviceClient = await this.#getServiceClient(req.mxid, req.oauth_credential)
|
const serviceClient = await this.#getServiceClient(req.mxid, req.oauth_credential)
|
||||||
@ -351,8 +368,8 @@ export default class PeerClient {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Object} req
|
* @param {Object} req
|
||||||
* @param {string} req.mxid
|
* @param {?string} req.mxid
|
||||||
* @param {OAuthCredential} req.oauth_credential
|
* @param {?OAuthCredential} req.oauth_credential
|
||||||
* @param {Long} req.user_id
|
* @param {Long} req.user_id
|
||||||
*/
|
*/
|
||||||
getProfile = async (req) => {
|
getProfile = async (req) => {
|
||||||
@ -394,8 +411,8 @@ export default class PeerClient {
|
|||||||
* @param {Object} req
|
* @param {Object} req
|
||||||
* @param {string} req.mxid
|
* @param {string} req.mxid
|
||||||
* @param {Object} req.channel_props
|
* @param {Object} req.channel_props
|
||||||
* @param {Long?} req.sync_from
|
* @param {?Long} req.sync_from
|
||||||
* @param {Number?} req.limit
|
* @param {?Number} req.limit
|
||||||
*/
|
*/
|
||||||
getChats = async (req) => {
|
getChats = async (req) => {
|
||||||
const userClient = this.#getUser(req.mxid)
|
const userClient = this.#getUser(req.mxid)
|
||||||
@ -408,6 +425,16 @@ export default class PeerClient {
|
|||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Object} req
|
||||||
|
* @param {?string} req.mxid
|
||||||
|
* @param {?OAuthCredential} req.oauth_credential
|
||||||
|
*/
|
||||||
|
listFriends = async (req) => {
|
||||||
|
const serviceClient = await this.#getServiceClient(req.mxid, req.oauth_credential)
|
||||||
|
return await serviceClient.requestFriendList()
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Object} req
|
* @param {Object} req
|
||||||
* @param {string} req.mxid
|
* @param {string} req.mxid
|
||||||
@ -500,6 +527,7 @@ export default class PeerClient {
|
|||||||
get_portal_channel_info: this.getPortalChannelInfo,
|
get_portal_channel_info: this.getPortalChannelInfo,
|
||||||
get_participants: this.getParticipants,
|
get_participants: this.getParticipants,
|
||||||
get_chats: this.getChats,
|
get_chats: this.getChats,
|
||||||
|
list_friends: this.listFriends,
|
||||||
send_message: this.sendMessage,
|
send_message: this.sendMessage,
|
||||||
}[req.command] || this.handleUnknownCommand
|
}[req.command] || this.handleUnknownCommand
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user