Commit Graph
24 Commits
Author SHA1 Message Date
DrSmoothl 7c0519f75f lint 2026-10-12 15:43:34 +08:00
DrSmoothl 3068d3ef60 feat(onebot): expose extended account profile information
Add account identifiers, compatible level names, available registration and membership details, and documented account age for group members. Keep unavailable values absent and refresh the action documentation.

Fixes #496
2026-10-04 13:04:42 +08:00
makotowu c1a0091143 feat(onebot): expose qidian enterprise name on stranger info
When a stranger is a qidian account, attach the enterprise name from the corp data card. Non-qidian accounts keep an empty name.

Refs #404
2026-08-26 23:31:15 +08:00
DrSmoothl 2bd2643670 docs(onebot): document qidian flags on stranger info
Fill in the stranger-info action docs, catalog, and remaining profile
fixtures after the qidian flags landed. Ordinary accounts still
default to zero.

Refs #404
2026-08-22 12:41:47 +08:00
makotowu 83f643f01b feat(onebot): expose qidian account flags on stranger info
Return qidian master and crew flags from get_stranger_info so callers can tell a qidian account from a normal one. Ordinary accounts keep the flags at zero. Existing stranger fields are unchanged.

Refs #404
2026-08-22 12:36:22 +08:00
H3CoF6 8fbddf67bf Feat: 发送图文ark卡片 (#355)
* feat(onebot): implement send tuwen ark

* test: add unit tests for send_ark action

* test(onebot): update canonical action docs count expectation to 191

* refactor(protocol,onebot): update 0xdc2_34 ark implementation and test coverage

- Rename action send_ark -> send_tuwen_ark to distinguish from structmsg and contact-share arks.
- Clarify SSO command mapping (OidbSvcTrpcTcp.0xdc2_34) and default param behavior in comments/docs.
- Adjust peerType, field3, and previewUrl to pb_optional to preserve 0/empty values during proton encoding.
- Update OneBot handler, tests, and auto-generated MCP tool catalog specs.

* style(protocol): fix indentation in rich-body-decoder tests
2026-08-20 12:12:39 +08:00
DrSmoothl 8fdd41ea22 fix(onebot): restore group and doubt request accounts
get_group_system_msg now keeps join and invite records, reports the
inviter, and fills a missing requester nick from the user profile.
get_doubt_friends_add_request returns the QQ number plus the request
message, source, and time that QQ actually sends.

Closes #400
Closes #401
Closes #402
Closes #403
2026-08-19 21:45:15 +08:00
DrSmoothl 0a924634b2 fix(protocol): return group join question and answer in admin settings
get_group_admin_settings reported the join mode correctly but left the
question and answer blank. The detail request now asks for those
strings the same way the official client does.

Closes #393
2026-08-19 00:15:32 +08:00
DrSmoothl b3bd68d48d fix(protocol): read group privilege from the matching detail field
Member invite and capability bits come from a different group-detail
field than the history-visibility switch. Reading the wrong one made
later writes carry leftover bits the server rejects.
2026-08-17 20:00:11 +08:00
DrSmoothl cfe61abce6 feat(protocol): read current group admin settings
Group detail and ext-info can now return the join option, search flags,
invite/permission/history bits, and robot-add switch so setters have a
matching read path.
2026-08-17 19:06:03 +08:00
DrSmoothl eee3c49f2d refactor(protocol): map friend and member pages to domain types
FetchFriendListPage and FetchGroupMemberListPage deserialized as
identity functions and leaked Oidb property codes into ContactsApi.

Each page now returns a domain page. Contacts keeps pagination,
category assembly, member cache, and robot classification.
2026-08-16 21:12:59 +08:00
DrSmoothl f100faaeb6 fix(protocol): read group mute expire from official proto tags (#356)
get_group_info / get_group_list mapped FE5 tag 31 and 88D tag 59 as
shutUpAllTimestamp, then treated any >0 value as muted. Official
wrapper.node maps those tags to internal 60259; the real expire
(60027 / groupShutupExpireTime) is FE5 tag 10 and 88D tag 45
(request mask 45). After a group had been muted, 60259 often stayed
nonzero so group_all_shut stuck at -1. Read the 60027 tags and treat
all-mute as expire > now (0xFFFFFFFF is permanent).

Fixes #356
2026-08-13 12:44:56 +08:00
DrSmoothl fe44a2f5bc fix(group-requests): normalize request retrieval and handling
Correct group-request retrieval so requester identities and action metadata remain usable across client and web-originated invitations.

Keep existing live-event behavior compatible, ensure returned requests carry the correct information for approval or rejection, and reject malformed request identifiers instead of emitting unusable flags.

Add regression coverage for both request inboxes and the supported invitation categories.
2026-08-10 00:26:01 +08:00
DrSmoothl e08613062e feat(onebot): configure group history visibility
Fixes #336
2026-08-09 12:53:45 +08:00
DrSmoothl cd6fcadea4 feat(onebot): configure group invite policy
Add validated group member invite policy updates with post-write verification.

Fixes #334
2026-08-09 11:46:04 +08:00
DrSmoothl 634097460c feat(onebot): expose group-wide mute status
Report whether group-wide mute is enabled through the existing group list and group information responses.

Keep standard and extended queries aligned, support explicit refreshes in the SDK, and update the generated action documentation without adding another endpoint.

Preserve established compatibility values, isolate cached non-member results by account, and add coverage across the request, mapping, action, and client layers.

Closes #313
2026-08-04 23:27:58 +08:00
DrSmoothl fb4d7716a1 fix(core): restore group remarks in queries
Request and retain the group remark information needed by group list and group detail queries while preserving the existing safeguards for large rosters.

Synchronize confirmed group remark changes with the local identity roster and persistent cache. Remote failures leave local state untouched, and missing roster entries remain observable without creating phantom groups.

Add regression coverage for query mapping, request scope, persistence, failed updates, unknown groups, and closed identity stores.

Fixes #304
2026-08-01 21:11:02 +08:00
DrSmoothl f0ff8da2fa feat(onebot): support moving friends between categories
Add the set_friends_category action with either an existing category ID or an exact unique category name.

Validate the current friend and category roster before applying a change, reject missing or ambiguous targets, and surface failed updates instead of reporting false success. Expose the action through the SDK types and cover validation, successful updates, repeat requests, service rejection, and registry completeness.

Closes #297
2026-07-30 10:37:16 +08:00
DrSmoothl eed2e692b1 fix(onebot): expose robot status for group members
Fetch QQ's versioned robot UIN ranges, classify and persist member status, and surface is_robot from both group member actions.

Preserve unknown legacy cache entries and fail visibly when classification is unavailable.

Closes #265
2026-07-21 23:27:01 +08:00
DrSmoothl 8cd7d51d80 fix(protocol): preserve friend category metadata 2026-07-13 18:51:11 +08:00
Airline233 39338c3f1d fix(protocol,onebot): generate and send ark of contact cards correctly (#149) 2026-06-26 17:04:40 +08:00
DrSmoothl 43cd4a0b99 feat(onebot): TierB ③ — RE'd OIDB actions (ark share / doubt friends / robot-add)
All recovered from QQNT wrapper.linux.node via IDA — NapCat ships these as
kernel-only with no portable packet wire, so each cmd + protobuf was traced
from the binary (worker ctor cmd/subcmd via BaseOidbWorker::DoSendOidbReq;
field tags from the per-feature EncodeRequest). All uin-form OIDB (envelope
reserved=1, matching the NT worker flag=1). One commit for easy rollback.

New OIDB services + byte-oracle tests (fixed-wire, mutation-resistant):
- 0x9130_0 getBuddyRecommendContactArkJson → share_peer/send_ark_share (user)
- 0x8b7_5  getGroupRecommendContactArkJson → share_peer/send_ark_share (group),
           share_group_ex/send_group_ark_share (NapCat's getArkJsonGroupShare
           was NOT RE'd; routed to this confident equivalent — documented)
- 0xd69_0  getDoubtBuddyReq → get_doubt_friends_add_request
- 0xd69_0  approvalDoubtBuddyReq → set_doubt_friends_add_request (approve only)
- 0xf00_3  modifyGroupExtInfoV2 → set_group_robot_add_option (EXTInfo tags
           30/31; GroupExtFilter is client-side gating, not on the wire)

NOT shipped (kernel-.so-side, no static cmd recoverable from this binary —
honest, no guessed packets): get_robot_uin_range (trpc method-routed),
create_collection/get_collection_list (Weiyun multi-step), trans_group_file.

Doubt-list string field NAMES (nick/source/msg) are medium-confidence
(generic serializer); uid+reqTime are high. READ path, so a mislabel is
cosmetic, never a wire/ban risk. Wired through bridge friend/contacts/
groupAdmin apis; proto-defs + per-file subpath exports registered.
2026-06-18 21:12:29 +08:00
DrSmoothl b0bfb9e6a7 feat(contacts): resolve non-member group name via 0x88D_0 (group invites)
A group invite push carries no group name (confirmed across SnowLuma / Lagrange
/ NapCat — all three invite protos only have groupUin + invitorUid), and
get_group_info only resolved joined groups (fetchGroupList → roster), so an
invited group rendered "未知群名". Add a by-id server lookup so the name
resolves even when the bot isn't a member.

- proto-defs: 0x88D_0 request (field1 + config.uin + a request-mask `flags`
  block) + response (groupInfo.results: name / member counts / owner / …),
  field tags transcribed from
  dev/Lagrange.Core/.../OidbSvcTrpcTcp0x88D_0{,Response}.cs.
- protocol: FetchGroupDetail oidb-service. Envelope reserved=0 (NO uinForm) —
  Lagrange's GetGroupInfoService builds it with isUid=false.
- core: ContactsApi.fetchGroupDetail(gid) → QQGroupInfo | null; deliberately
  NOT remembered into the joined-groups roster (mustn't pollute get_group_list).
- onebot: get_group_info falls back to fetchGroupDetail for non-member groups,
  behind a 5-min per-id TTL cache so a burst of invites for one group can't
  hammer 0x88D_0 (rate-limit / kick risk). noCache bypasses it.
- tests: request/envelope round-trip (reserved=0, uin, command), response
  decode; + non-member resolve / cache-hit / noCache-bypass at the onebot layer.

Live note: byte-identical to Lagrange's 0x88D_0, but not verified against a real
account on this host.
2026-06-15 14:33:06 +08:00
DrSmoothl c16064d7e3 refactor(packages): rename @snowluma/bridge → @snowluma/protocol
The package previously named "bridge" houses the protocol-byte layer
(OIDB cmds, msg-push decoders, highway uploaders, element-builder,
event bus). The name "bridge" suggested transport/lifecycle, which it
isn't — that role lives in core/hook and core/bridge/manager. Rename
to match what's actually inside.

This is a pure rename: zero logic changes, all 73 import sites updated
mechanically and TS-verified. core/onebot dependencies key updated.
ESLint override path adjusted for the moved oidb-services directory.

Rename detection threshold: git log --find-renames=20% recommended
when following history across this commit — content-replacement
(@snowluma/bridge → @snowluma/protocol) dropped per-file similarity
below git's default 50% on import-heavy files.
2026-05-23 23:31:03 +08:00