feat: native-mobile-api

This commit is contained in:
SamuelScheit
2023-04-20 13:01:11 +02:00
parent 28be45a9b4
commit ef673f62ca
17 changed files with 940 additions and 74 deletions

View File

@@ -1,13 +1,20 @@
import { Boom } from '@hapi/boom'
import parsePhoneNumber from 'libphonenumber-js'
import NodeCache from 'node-cache'
import makeWASocket, { AnyMessageContent, delay, DisconnectReason, fetchLatestBaileysVersion, getAggregateVotesInPollMessage, makeCacheableSignalKeyStore, makeInMemoryStore, proto, useMultiFileAuthState, WAMessageContent, WAMessageKey } from '../src'
import MAIN_LOGGER from '../src/Utils/logger'
import P from 'pino'
import readline from 'readline'
import makeWASocket, { AnyMessageContent, delay, DisconnectReason, fetchLatestBaileysVersion, getAggregateVotesInPollMessage, makeCacheableSignalKeyStore, makeInMemoryStore, PHONENUMBER_MCC, proto, useMultiFileAuthState, WAMessageContent, WAMessageKey } from '../src'
const logger = MAIN_LOGGER.child({ })
logger.level = 'trace'
const logger = P({
transport: {
target: 'pino-pretty'
},
level: 'trace'
})
const useStore = !process.argv.includes('--no-store')
const doReplies = !process.argv.includes('--no-reply')
const useMobile = process.argv.includes('--mobile')
// external map to store retry counts of messages when decryption/encryption fails
// keep this out of the socket itself, so as to prevent a message decryption/encryption loop across socket restarts
@@ -33,6 +40,7 @@ const startSock = async() => {
version,
logger,
printQRInTerminal: true,
mobile: useMobile,
auth: {
creds: state.creds,
/** caching makes the store faster to send/recv messages */
@@ -49,6 +57,69 @@ const startSock = async() => {
store?.bind(sock.ev)
// If mobile was chosen, ask for the code
if(useMobile && !sock.authState.creds.registered) {
const question = (text: string) => new Promise<string>((resolve) => rl.question(text, resolve))
const rl = readline.createInterface({ input: process.stdin, output: process.stdout })
const { registration } = sock.authState.creds || { registration: {} }
if(!registration.phoneNumber) {
registration.phoneNumber = await question('Please enter your mobile phone number:\n')
} else {
console.log('Your mobile phone number is not registered.')
}
const phoneNumber = parsePhoneNumber(registration!.phoneNumber)
if(!phoneNumber?.isValid()) {
throw new Error('Invalid phone number: ' + registration!.phoneNumber)
}
registration.phoneNumber = phoneNumber.format('E.164')
registration.phoneNumberCountryCode = phoneNumber.countryCallingCode
registration.phoneNumberNationalNumber = phoneNumber.nationalNumber
const mcc = PHONENUMBER_MCC[phoneNumber.countryCallingCode]
if(!mcc) {
throw new Error('Could not find MCC for phone number: ' + registration!.phoneNumber + '\nPlease specify the MCC manually.')
}
registration.phoneNumberMobileCountryCode = mcc
async function enterCode() {
try {
const code = await question('Please enter the one time code:\n')
const response = await sock.register(code.replace(/["']/g, '').trim().toLowerCase())
console.log('Successfully registered your phone number.')
console.log(response)
rl.close()
} catch(error) {
console.error('Failed to register your phone number. Please try again.\n', error)
await askForOTP()
}
}
async function askForOTP() {
let code = await question('How would you like to receive the one time code for registration? "sms" or "voice"\n')
code = code.replace(/["']/g, '').trim().toLowerCase()
if(code !== 'sms' && code !== 'voice') {
return await askForOTP()
}
registration.method = code
try {
await sock.requestRegistrationCode(registration)
await enterCode()
} catch(error) {
console.error('Failed to request registration code. Please try again.\n', error)
await askForOTP()
}
}
askForOTP()
}
const sendMessageWTyping = async(msg: AnyMessageContent, jid: string) => {
await sock.presenceSubscribe(jid)
await delay(500)