diff options
| author | Elvis Claros Castro <elvis@claros.ar> | 2026-09-26 19:26:33 -0300 |
|---|---|---|
| committer | Elvis Claros Castro <elvis@claros.ar> | 2026-09-26 19:26:33 -0300 |
| commit | d80640d01eeb84907e36ff4af33add9081eda17c (patch) | |
| tree | 27698b34e06e28d111c2196700015d9c82f78274 /src/api/contacts.js | |
| download | wa-cli-d80640d01eeb84907e36ff4af33add9081eda17c.tar.gz wa-cli-d80640d01eeb84907e36ff4af33add9081eda17c.zip | |
Diffstat (limited to 'src/api/contacts.js')
| -rw-r--r-- | src/api/contacts.js | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/src/api/contacts.js b/src/api/contacts.js new file mode 100644 index 0000000..b7ef6df --- /dev/null +++ b/src/api/contacts.js @@ -0,0 +1,86 @@ +import * as ser from '../serialize.js'; + +const contactParam = { type: 'chat', required: true, description: 'Contact: JID (549...@c.us), phone number or exact name' }; + +export default { + 'contacts.list': { + description: 'Lists contacts (users; no groups).', + params: { + query: { type: 'string', description: 'Filters by name or number' }, + saved: { type: 'boolean', description: 'true: only contacts saved on the phone' }, + limit: { type: 'integer', description: 'Maximum to return' }, + }, + columns: ['id', 'displayName', 'number', 'isMyContact'], + handler: async (ctx, p) => { + const q = p.query && ctx.normalize(p.query); + let list = (await ctx.client.getContacts()) + .filter((c) => !c.isGroup && c.id.server !== 'broadcast') + .filter((c) => p.saved === undefined || Boolean(c.isMyContact) === p.saved) + .map(ser.contact) + .filter((c) => !q || [c.name, c.pushname, c.shortName, c.number] + .some((v) => v && ctx.normalize(v).includes(q))) + .sort((a, b) => (a.displayName || '').localeCompare(b.displayName || '')); + if (p.limit) list = list.slice(0, p.limit); + return list; + }, + }, + + 'contacts.get': { + description: 'Details of a contact (includes "about").', + params: { contactId: contactParam }, + handler: async (ctx, p) => { + const c = await ctx.client.getContactById(p.contactId); + const out = ser.contact(c); + out.about = await c.getAbout().catch(() => null); + return out; + }, + }, + + 'contacts.resolve': { + description: 'Checks whether a number is on WhatsApp and returns its JID.', + params: { number: { type: 'string', required: true, description: 'International number (e.g. +54 9 11 2233-4455)' } }, + handler: async (ctx, p) => { + const digits = p.number.replace(/\D/g, ''); + const id = await ctx.client.getNumberId(digits); + return { number: digits, registered: Boolean(id), id: id?._serialized ?? null }; + }, + }, + + 'contacts.picture': { + description: 'Profile picture URL (if privacy allows it).', + params: { contactId: contactParam }, + handler: async (ctx, p) => ({ url: (await ctx.client.getProfilePicUrl(p.contactId)) ?? null }), + }, + + 'groups.list': { + description: 'Lists groups.', + params: { query: { type: 'string', description: 'Filters by name' } }, + columns: ['id', 'name', 'participantCount', 'unreadCount', 'date'], + handler: async (ctx, p) => (await ctx.client.getChats()) + .filter((c) => c.isGroup) + .filter((c) => !p.query || ctx.normalize(c.name || '').includes(ctx.normalize(p.query))) + .sort((a, b) => (b.timestamp ?? 0) - (a.timestamp ?? 0)) + .map((c) => ser.chat(c, ctx.ser)), + }, + + 'groups.get': { + description: 'Details of a group: description, owner and participants.', + params: { groupId: { ...contactParam, description: 'Grupo: JID (...@g.us) o nombre exacto' } }, + handler: async (ctx, p) => { + const c = await ctx.getChat(p.groupId); + if (!c.isGroup) throw new ctx.WaError('EINVAL', `${p.groupId} is not a group`); + return ser.group(c, ctx.ser); + }, + }, + + 'groups.invite': { + description: 'Group invite link (requires being an admin).', + params: { groupId: { ...contactParam, description: 'Grupo: JID (...@g.us) o nombre exacto' } }, + handler: async (ctx, p) => { + const c = await ctx.getChat(p.groupId); + if (!c.isGroup) throw new ctx.WaError('EINVAL', `${p.groupId} is not a group`); + const code = await c.getInviteCode(); + return { code, link: `https://chat.whatsapp.com/${code}` }; + }, + }, +}; |