Skip to content

Commit 5ed0ede

Browse files
authored
Fix the issue when fetch the audio url & support parse c2c audio (#28)
* fix(client): support parse c2c audio & fix the issue when fetch the audio url * feat(client): add url field in MediaInfo elem & support fetch audio url automatically - fetch video url still not supported
1 parent 564b3ea commit 5ed0ede

File tree

5 files changed

+30
-14
lines changed

5 files changed

+30
-14
lines changed

lagrange/client/client.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,9 @@ async def upload_grp_audio(self, voice: BinaryIO, grp_id: int) -> Audio:
257257
async def upload_friend_audio(self, voice: BinaryIO, uid: str) -> Audio:
258258
return await self._highway.upload_voice(voice, uid=uid)
259259

260+
async def fetch_audio_url(self, file_key: str, uid=None, gid=None):
261+
return await self._highway.get_audio_down_url(file_key, uid=uid, gid=gid)
262+
260263
async def down_grp_audio(self, audio: Audio, grp_id: int) -> BytesIO:
261264
return await self._highway.download_audio(audio, gid=grp_id)
262265

lagrange/client/highway/highway.py

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
import asyncio
22
import time
3-
import uuid
43
from hashlib import md5
54
from io import BytesIO
6-
from typing import TYPE_CHECKING, BinaryIO, List, Optional, Tuple
5+
from typing import TYPE_CHECKING, BinaryIO, List, Optional, Tuple, overload, Union
76

87
from lagrange.client.message.elems import Audio, Image
98
from lagrange.pb.highway.comm import IndexNode
109
from lagrange.pb.highway.ext import NTV2RichMediaHighwayExt
1110
from lagrange.pb.highway.httpconn import HttpConn0x6ffReq, HttpConn0x6ffRsp
12-
from lagrange.pb.highway.rsp import NTV2RichMediaResp, DownloadInfo, DownloadRsp
11+
from lagrange.pb.highway.rsp import NTV2RichMediaResp, DownloadRsp
1312
from lagrange.utils.binary.protobuf import proto_decode
1413
from lagrange.utils.crypto.tea import qqtea_encrypt
1514
from lagrange.utils.httpcat import HttpCat
@@ -341,25 +340,34 @@ async def upload_voice(self, file: BinaryIO, gid=0, uid="") -> Audio:
341340
size=fl,
342341
file_key=file_key.decode(),
343342
qmsg=None if gid else compat,
343+
url=await self.get_audio_down_url(file_key.decode(), gid, uid),
344344
)
345345

346-
async def get_audio_down_url(self, audio: Audio, gid=0, uid="") -> str:
346+
@overload
347+
async def get_audio_down_url(self, file_key_or_audio: str, gid: int = 0, uid: str = "") -> str: ...
348+
349+
@overload
350+
async def get_audio_down_url(self, file_key_or_audio: Audio, gid: int = 0, uid: str = "") -> str: ...
351+
352+
async def get_audio_down_url(self, file_key_or_audio: Union[str, Audio], gid: int = 0, uid="") -> str:
347353
if not self._session_addr_list:
348354
await self._get_bdh_session()
349355

356+
audio_file_key = file_key_or_audio.file_key if isinstance(file_key_or_audio, Audio) else file_key_or_audio
357+
350358
ret = NTV2RichMediaResp.decode(
351359
(
352360
await self._client.send_oidb_svc(
353361
0x126E if gid else 0x126D,
354362
200,
355363
encode_audio_down_req(
356-
audio.file_key, gid, uid
364+
audio_file_key, gid, uid
357365
).encode(), True
358366
)
359367
).data
360368
)
361369

362-
if not ret:
370+
if not (ret and ret.download):
363371
raise ConnectionError("Internal error, check log for more detail")
364372

365373
return self._down_url(ret.download)

lagrange/client/message/decoder.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import zlib
2-
from typing import List, Tuple, Sequence, TYPE_CHECKING, cast, Literal
2+
from typing import List, Tuple, Sequence, TYPE_CHECKING, cast, Literal, Union
33

44
from lagrange.client.events.group import GroupMessage
55
from lagrange.client.events.friend import FriendMessage
@@ -37,7 +37,8 @@ def parse_friend_info(pkg: MsgPushBody) -> Tuple[int, str, int, str]:
3737
return from_uin, from_uid, to_uin, to_uid
3838

3939

40-
async def parse_msg_new(client: "Client", pkg: MsgPushBody) -> Sequence[Element]:
40+
async def parse_msg_new(client: "Client", pkg: MsgPushBody,
41+
fri_id: Union[str, None] = None, grp_id: Union[int, None] = None) -> Sequence[Element]:
4142
if not pkg.message or not pkg.message.body:
4243
if pkg.content_head.sub_type == 4:
4344
data = FileExtra.decode(pkg.message.buf2)
@@ -53,6 +54,7 @@ async def parse_msg_new(client: "Client", pkg: MsgPushBody) -> Sequence[Element]
5354
rich: RichText = pkg.message.body
5455
if rich.ptt:
5556
ptt = rich.ptt
57+
file_key = ptt.group_file_key if ptt.group_file_key else ptt.friend_file_key
5658
return [
5759
elems.Audio(
5860
name=ptt.name,
@@ -61,8 +63,9 @@ async def parse_msg_new(client: "Client", pkg: MsgPushBody) -> Sequence[Element]
6163
md5=ptt.md5,
6264
text=f"[audio:{ptt.name}]",
6365
time=ptt.time,
64-
file_key=ptt.group_file_key if not ptt.to_uin else ptt.friend_file_key,
66+
file_key=ptt.group_file_key if ptt.group_file_key else ptt.friend_file_key,
6567
qmsg=None,
68+
url=await client.fetch_audio_url(file_key, uid=fri_id, gid=grp_id)
6669
)
6770
]
6871
el: List[Elems] = rich.content
@@ -280,6 +283,7 @@ async def parse_msg_new(client: "Client", pkg: MsgPushBody) -> Sequence[Element]
280283
width=video.width,
281284
height=video.height,
282285
qmsg=None,
286+
url="" # TODO: fetch video url
283287
)
284288
)
285289
else:
@@ -294,7 +298,7 @@ async def parse_friend_msg(client: "Client", pkg: MsgPushBody) -> FriendMessage:
294298
seq = pkg.content_head.seq
295299
msg_id = pkg.content_head.msg_id
296300
timestamp = pkg.content_head.timestamp
297-
parsed_msg = await parse_msg_new(client, pkg)
301+
parsed_msg = await parse_msg_new(client, pkg, fri_id=from_uid, grp_id=None)
298302
msg_text = "".join([getattr(msg, "text", "") for msg in parsed_msg])
299303

300304
return FriendMessage(
@@ -322,7 +326,7 @@ async def parse_grp_msg(client: "Client", pkg: MsgPushBody) -> GroupMessage:
322326
if isinstance(grp_name, bytes): # unexpected end of data
323327
grp_name = grp_name.decode("utf-8", errors="ignore")
324328

325-
parsed_msg = await parse_msg_new(client, pkg)
329+
parsed_msg = await parse_msg_new(client, pkg, fri_id=None, grp_id=grp_id)
326330
msg_text = "".join([getattr(msg, "text", "") for msg in parsed_msg])
327331

328332
return GroupMessage(

lagrange/client/message/elems.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ def type(self) -> str:
2121
class MediaInfo:
2222
name: str
2323
size: int
24+
url: str
2425
id: int = field(repr=False)
2526
md5: bytes = field(repr=False)
2627
qmsg: Optional[bytes] = field(repr=False) # not online image
@@ -86,7 +87,6 @@ def build(cls, ev: GroupMessage) -> "At":
8687
class Image(Text, MediaInfo):
8788
width: int
8889
height: int
89-
url: str
9090
is_emoji: bool
9191

9292

lagrange/client/server_push/msg.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ async def msg_push_handler(client: "Client", sso: SSOPacket):
5757
logger.debug("msg_push received, type: {}.{}".format(typ, sub_typ))
5858
if typ == 82: # grp msg
5959
return await parse_grp_msg(client, pkg)
60-
elif typ in [166, 529]: # frd msg
60+
elif typ in [166, 208, 529]: # frd msg
6161
return await parse_friend_msg(client, pkg)
6262
elif typ == 33: # member joined
6363
pb = MemberChanged.decode(pkg.message.buf2)
@@ -220,8 +220,9 @@ async def msg_push_handler(client: "Client", sso: SSOPacket):
220220
)
221221
else:
222222
logger.debug(
223-
"unknown type %d: %s"
223+
"unknown type %d, sub type %d: %s"
224224
% (
225+
typ,
225226
sub_typ,
226227
pkg.message.buf2.hex() if getattr(pkg.message, "buf2", None) else pkg,
227228
)

0 commit comments

Comments
 (0)