From 728f9a3347ef6c5c2e1230e8557b8d019a05a245 Mon Sep 17 00:00:00 2001 From: botnick Date: Sun, 5 Jul 2026 18:05:15 +0700 Subject: [PATCH 1/2] feat(relation): add findContactBySearchIdOrTicketV3 and addFriendByUserId Resolve a contact from a LINE ID through the current search endpoint on RE4, and add a convenience method that searches then adds the user. Only the legacy findContactByUserid was exposed before. Official Account IDs are supported via the leading "@". --- example/relation/addfriend.ts | 12 +++++++ packages/linejs/base/service/relation/mod.ts | 36 ++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/example/relation/addfriend.ts b/example/relation/addfriend.ts index e2e1bef..5768dc0 100644 --- a/example/relation/addfriend.ts +++ b/example/relation/addfriend.ts @@ -20,3 +20,15 @@ await client.relation.addFriendByMid({ trackingMetaHint: "uhex", trackingMetaType: 4, }) + + +// by LINE ID — searches then adds. Official Accounts include the leading "@" +await client.relation.addFriendByUserId({ + userId: "@livecast", +}) + +// or resolve the mid yourself +const contact = await client.relation.findContactBySearchIdOrTicketV3({ + searchId: "@livecast", +}) +console.log(contact.mid, contact.displayName) diff --git a/packages/linejs/base/service/relation/mod.ts b/packages/linejs/base/service/relation/mod.ts index 51155e2..f3d0f21 100644 --- a/packages/linejs/base/service/relation/mod.ts +++ b/packages/linejs/base/service/relation/mod.ts @@ -130,4 +130,40 @@ export class RelationService implements BaseService { this.requestPath, ); } + + /** + * @description Find a contact by its search id (the user's LINE ID). Official + * Accounts include the leading `@`, e.g. `@livecast`. Throws when nothing matches + * or the id search is rate limited. + */ + public async findContactBySearchIdOrTicketV3(options: { + searchId: string; + }): Promise { + const { searchId } = options; + return await this.client.request.request( + [[12, 1, [[12, 1, [[11, 1, searchId]]]]]], + "findContactBySearchIdOrTicketV3", + this.protocolType, + "Contact", + this.requestPath, + ); + } + + /** + * @description Search a user by their LINE ID and add them as a friend. Official + * Account IDs include the leading `@`. + */ + public async addFriendByUserId(options: { + userId: string; + }): Promise { + const contact = await this.findContactBySearchIdOrTicketV3({ + searchId: options.userId, + }); + return await this.addFriendByMid({ + mid: contact.mid, + reference: '{"screen":"friendAdd:idSearch","spec":"native"}', + trackingMetaType: 2, + trackingMetaHint: options.userId, + }); + } } From bb6de5043339b706ef5e93ee1a84c7bfe02c7c98 Mon Sep 17 00:00:00 2001 From: botnick Date: Sun, 5 Jul 2026 18:22:26 +0700 Subject: [PATCH 2/2] feat(relation): add findContactByPhoneV3 and addFriendByPhone Look up a contact by phone number (E.164) on RE4, plus a convenience method that searches then adds. Mirrors the id-based lookups. --- example/relation/addfriend.ts | 11 +++++++ packages/linejs/base/service/relation/mod.ts | 31 ++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/example/relation/addfriend.ts b/example/relation/addfriend.ts index 5768dc0..41c7b99 100644 --- a/example/relation/addfriend.ts +++ b/example/relation/addfriend.ts @@ -32,3 +32,14 @@ const contact = await client.relation.findContactBySearchIdOrTicketV3({ searchId: "@livecast", }) console.log(contact.mid, contact.displayName) + + +// by phone number (E.164, e.g. + without a leading 0) +await client.relation.addFriendByPhone({ + phone: "+66814298575", +}) + +const byPhone = await client.relation.findContactByPhoneV3({ + phone: "+66814298575", +}) +console.log(byPhone.mid, byPhone.displayName) diff --git a/packages/linejs/base/service/relation/mod.ts b/packages/linejs/base/service/relation/mod.ts index f3d0f21..ae0757d 100644 --- a/packages/linejs/base/service/relation/mod.ts +++ b/packages/linejs/base/service/relation/mod.ts @@ -166,4 +166,35 @@ export class RelationService implements BaseService { trackingMetaHint: options.userId, }); } + + /** + * @description Find a contact by phone number. The number is in E.164 form, + * e.g. `+66814298575`. Throws when nothing matches or the lookup is rate limited. + */ + public async findContactByPhoneV3(options: { + phone: string; + }): Promise { + return await this.client.request.request( + [[12, 1, [[11, 1, options.phone]]]], + "findContactByPhoneV3", + this.protocolType, + "Contact", + this.requestPath, + ); + } + + /** + * @description Look up a user by phone number (E.164) and add them as a friend. + */ + public async addFriendByPhone(options: { + phone: string; + }): Promise { + const contact = await this.findContactByPhoneV3({ phone: options.phone }); + return await this.addFriendByMid({ + mid: contact.mid, + reference: '{"screen":"friendAdd:phoneSearch","spec":"native"}', + trackingMetaType: 2, + trackingMetaHint: options.phone, + }); + } }