Files

53 lines
2.3 KiB
Python

"""Export all locally stored contact records through WhatsApp's JavaScript API."""
import argparse
import datetime as dt
import json
from pathlib import Path
from .live import run_math
from .zip_export import evaluate
PROBE = r'''(async () => {
const table=require('WAWebSchemaContact_DO_NOT_USE_DIRECTLY').getContactTable();
const rows=await table.all();
if(!Array.isArray(rows))throw Error('Unexpected contact table result');
const fields=['id','phoneNumber','name','shortName','pushname','notifyName','verifiedName',
'addressBookName','isAddressBookContact','isMyContact','isBusiness','isEnterprise'];
const contacts=rows.map(row=>{
const out={};for(const field of fields){const value=row[field];
if(value==null||['string','number','boolean'].includes(typeof value))out[field]=value??null;
else if(field==='id')out.id=value.toString();
}
if(typeof out.id!=='string'||!out.id)throw Error('Contact ID unavailable');
return out;
});
return {source:'WAWebSchemaContact_DO_NOT_USE_DIRECTLY.getContactTable().all',
scope:'All local contact rows, not only loaded models or phone address-book entries',
count:contacts.length,contacts,cdp:false,ui_automation:false};
})()'''
def export_contacts(output,pid=None):
output=Path(output)
if output.exists():raise ValueError('Output exists; choose a new --output')
def operation(execute,session,report):
data=evaluate(execute,PROBE,session)
if not isinstance(data.get('contacts'),list) or data.get('count')!=len(data['contacts']):
raise RuntimeError('Incomplete contact export response')
report['data']=data
report=run_math(pid,'contacts-export',_operation=operation)
output.parent.mkdir(parents=True,exist_ok=True)
with output.open('x',encoding='utf-8') as stream:
json.dump(report,stream,ensure_ascii=True,indent=2)
return report
def main(argv=None):
parser=argparse.ArgumentParser(description=__doc__)
parser.add_argument('--pid',type=int)
parser.add_argument('--output',type=Path,default=Path('exports')/('contacts-'+dt.datetime.now().strftime('%Y%m%d-%H%M%S')+'.json'))
args=parser.parse_args(argv)
report=export_contacts(args.output,args.pid)
print(json.dumps({'passed':report['passed'],'error':report.get('error'),'contacts':report.get('data',{}).get('count'),'output':str(args.output)}))
return 0 if report['passed'] else 1