aboutsummaryrefslogtreecommitdiffstats
path: root/src/api/contacts.js
diff options
context:
space:
mode:
authorElvis Claros Castro <elvis@claros.ar>2026-09-26 19:26:33 -0300
committerElvis Claros Castro <elvis@claros.ar>2026-09-26 19:26:33 -0300
commitd80640d01eeb84907e36ff4af33add9081eda17c (patch)
tree27698b34e06e28d111c2196700015d9c82f78274 /src/api/contacts.js
downloadwa-cli-main.tar.gz
wa-cli-main.zip
wa-cli: WhatsApp from the terminal, with a neomutt Maildir bridgeHEADmain
Diffstat (limited to 'src/api/contacts.js')
-rw-r--r--src/api/contacts.js86
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}` };
+ },
+ },
+};