원클릭으로
whatsapp-extract-members
Extract all community-level members from a WhatsApp Web community into a CSV file using agent-browser
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Extract all community-level members from a WhatsApp Web community into a CSV file using agent-browser
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
| name | whatsapp:extract-members |
| description | Extract all community-level members from a WhatsApp Web community into a CSV file using agent-browser |
| argument-hint | [output_path] |
Extract all community-level members from a WhatsApp Web community into a CSV file with columns: phone, display_name.
This skill uses agent-browser (Vercel Labs Rust CLI) to drive a real Chrome session via CDP. The admin authenticates by scanning a QR code with their phone. The extraction is read-only -- no messages are sent, no members are added or removed.
npm install -g agent-browser && agent-browser install
Verify agent-browser is installed before proceeding:
agent-browser --version
If the command fails, instruct the user to install it with the command above and retry.
This skill accepts one optional argument:
| Argument | Required | Default | Description |
|---|---|---|---|
output_path | No | User's Downloads folder | Full path or directory for CSV output |
Community name: Always use Sociedad de Astronomía del Caribe. This is hardcoded — do not ask the user.
Output path resolution:
output_path is provided, use it directly (if it is a directory, append the filename).$USERPROFILE/Downloads$HOME/Downloadswhatsapp-members-{slug}-{YYYY-MM-DD}.csv
{slug} = community name lowercased, spaces replaced with hyphens, non-alphanumeric characters removed{YYYY-MM-DD} = current dateDetermine the output path early and confirm it to the user before starting extraction.
Always extract members from the "Comité de Viajes Astronómicos" sub-channel and flag them in the CSV with a sub_channels column. Members found in this sub-channel get the value viajes_astronomicos in the sub_channels column. This is hardcoded — do not ask the user.
Follow these steps sequentially. Use the Bash tool to run agent-browser commands and the Read tool to view screenshots.
IMPORTANT: agent-browser runs headless by default. You MUST use --headed so the user can see the browser and scan the QR code. You also MUST override the user-agent string -- WhatsApp Web blocks the default agent-browser UA.
agent-browser open "https://web.whatsapp.com" --headed --user-agent "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.7727.50 Safari/537.36"
Wait for the page to load, then take a screenshot:
agent-browser wait 4000
agent-browser screenshot "$TEMP/wa-qr.png"
Show the screenshot to the user using the Read tool and tell them:
"Please scan the QR code with your WhatsApp mobile app. Say done when you are logged in."
STOP here and wait for the user to confirm they have scanned the QR code. Do NOT proceed until the user confirms.
After confirmation, wait for the session to load and verify login:
agent-browser wait 3000
agent-browser snapshot -i
Check the snapshot output for chat list elements (e.g., a "Chats" button, conversation entries, a search bar). If login indicators are not present, take a screenshot and ask the user to verify. If WhatsApp shows "Use phone to verify" or a multi-device confirmation prompt, tell the user to approve it on their phone, wait, and retry.
The correct navigation path is: Communities tab -> Community entry -> Navigation menu -> View members.
First, click the Communities tab in the left sidebar. It is a button labeled "Communities" in the navigation banner:
agent-browser snapshot -i
Find the "Communities" button and click it:
agent-browser click @eN # The "Communities" button
agent-browser wait 1500
agent-browser snapshot -i
In the communities panel, look for a button labeled "Community: {community_name}" and click it:
agent-browser click @eN # The community entry button
agent-browser wait 1500
Take a snapshot to verify the community view is open. You should see:
If the community is not found:
Click the "Navigation menu" button (NOT the community heading -- clicking the heading does nothing):
agent-browser snapshot -i
agent-browser click @eN # The "Navigation menu" button
agent-browser wait 1000
agent-browser snapshot -i
A dropdown menu will appear with options including "View members". Click it:
agent-browser click @eN # The "View members" button
agent-browser wait 2000
agent-browser snapshot -i
A dialog will open showing "Members (N)" with the member count. Verify this dialog is visible. You should see:
role=button elementsRecord the total member count from the heading for later verification.
IMPORTANT: The member list is virtualized -- WhatsApp Web only renders members visible in the scroll viewport. Standard agent-browser scroll commands DO NOT work on this virtualized list. You MUST use agent-browser eval with JavaScript to scroll the container.
Run the following JavaScript via agent-browser eval to scroll through the entire list and extract all member data:
agent-browser eval "
(async function(){
const dialog = document.querySelector('[role=dialog]');
if (!dialog) return JSON.stringify({error: 'no dialog'});
let scroller = null;
for (const el of dialog.querySelectorAll('div')) {
const s = getComputedStyle(el);
if ((s.overflowY === 'auto' || s.overflowY === 'scroll') && el.scrollHeight > 5000) { scroller = el; break; }
}
if (!scroller) return JSON.stringify({error: 'no scroller'});
const allMembers = new Map();
let scrollPos = 0;
const step = 700;
for (let i = 0; i < 60 && scrollPos <= scroller.scrollHeight + step; i++) {
const btns = Array.from(dialog.querySelectorAll('[role=button]')).filter(b => b.className === '');
for (const btn of btns) {
const spans = btn.querySelectorAll('span');
let name = '';
let phone = '';
for (const sp of spans) {
const parts = Array.from(sp.childNodes).filter(n => n.nodeType === 3).map(n => n.textContent.trim()).join('');
if (!parts) continue;
const clean = parts.replace(/^~ /, '');
if (clean.match(/^\+?\d[\d\s\(\)\-]{7,}/)) { if (!phone) phone = clean; }
else if (clean === 'Community owner' || clean === 'Community admin') { continue; }
else if (clean.match(/^(Hey there|Available|Disponible|Modah ani|Loading|Busy|At work|At school|Sleeping|Urgent|At the gym|Battery about|I can)/i)) { continue; }
else if (!name && clean.length > 0 && clean !== 'You') { name = clean; }
}
if (!name && !phone) continue;
if (name === 'You') continue;
name = name.replace(/^Maybe /, '').trim();
const key = name + '|' + phone;
if (!allMembers.has(key)) { allMembers.set(key, {name, phone}); }
}
scrollPos += step;
scroller.scrollTop = scrollPos;
scroller.dispatchEvent(new Event('scroll', {bubbles: true}));
await new Promise(r => setTimeout(r, 250));
}
return JSON.stringify({total: allMembers.size, members: Array.from(allMembers.values())});
})()
"
Save the output (a JSON string) for processing. Parse it to get the members array.
Understanding the member data structure:
WhatsApp's member list shows different information depending on whether a member is in the admin's phone contacts:
This means after the scroll extraction, some members will have names but no phone numbers.
For members extracted WITHOUT a phone number, you must click into each member's profile to retrieve their phone number. These are the admin's phone contacts whose numbers WhatsApp hides in the list view.
After the scroll extraction completes, close the members dialog first:
agent-browser snapshot -i
agent-browser click @eN # The "Close" button on the Members dialog
agent-browser wait 1000
Then for EACH member missing a phone number:
agent-browser snapshot -i
agent-browser click @eN # The "Search members" textbox
agent-browser fill @eN "{member_name}"
agent-browser wait 1500
agent-browser snapshot -i
agent-browser click @eN # The member's button in search results
agent-browser wait 1500
agent-browser snapshot -i
agent-browser click @eN # Back button or close the profile
agent-browser wait 1000
Update the member's record with the retrieved phone number.
Optimization: If many members are missing phones, batch the lookups efficiently. Clear the search field between lookups rather than closing and reopening the dialog.
After completing the community-level extraction and phone lookups, extract members from the "Comité de Viajes Astronómicos" sub-channel to flag them in the CSV.
Steps:
agent-browser click @eN # The sub-channel button
agent-browser wait 1500
sub_channels field to viajes_astronomicos.Always close the browser session when done (or on error):
agent-browser close
After extraction is complete, process the collected member data:
For each phone number:
+ prefix and country code (e.g., +17875551234).+ prefix exists, keep the number as-is (do not guess the country code).Sort the final list alphabetically by display_name (case-insensitive).
Write the CSV file using the Write tool (NOT agent-browser).
CSV format:
phone,display_name,sub_channels
+17875551234,Ana Rivera,viajes_astronomicos
+17875559876,Carlos Lopez,
,Hidden User,
Rules:
phone,display_name,sub_channels,Display Name,). This should only happen if the profile lookup also failed to find a phone number.sub_channels: the sub-channel name if the member belongs to it, or empty.Write the file to the output path determined during argument handling.
After writing the CSV, report to the user:
Extraction complete.
- Total members extracted: {total}
- Members with phone numbers: {with_phone}
- Members without phone numbers: {without_phone}
- Phone numbers retrieved via profile lookup: {profile_lookups}
- CSV saved to: {output_path}
| Error | Action |
|---|---|
| agent-browser not installed | Tell user to run npm install -g agent-browser && agent-browser install |
| WhatsApp blocks Chrome version | Ensure --user-agent flag is set with a recent Chrome UA string |
| QR code not visible | Wait longer, retry screenshot, ask user to refresh WhatsApp Web |
| "Use phone to verify" prompt | Tell user to approve on their phone, wait 5 seconds, retry snapshot |
| Community not found | Ask user to verify the exact community name; try searching from the Chats search bar |
| Member list dialog not opening | Ensure you click "Navigation menu" then "View members", not the community heading |
| JS eval scroll returns no scroller | Take a screenshot to debug; the dialog may have closed unexpectedly |
| Scrolling yields fewer members than expected | Increase the loop iteration count (default 60); try smaller step sizes |
| Profile lookup fails to show phone | Member may have hidden their phone; record with empty phone field |
| Unexpected page state | Take a screenshot, show it to the user, ask for guidance |
| Any unrecoverable error | Always run agent-browser close before stopping |
--headed so the user can see the browser window and interact with it (QR scan, etc.).--user-agent flag with a recent Chrome version string.agent-browser eval). Standard agent-browser scroll commands do not work on this list.