fix: Generate pairing code and update Baileys repository

Update package.json to use the new Baileys repository and modify the Whatsapp Baileys service to generate a pairing code. This change fixes the issue with the previous Baileys repository and improves the pairing process for Whatsapp.

Changes:
- Update package.json to use the new Baileys repository
- Modify Whatsapp Baileys service to generate a pairing code
- Fix issue with previous Baileys repository
- Improve pairing process for Whatsapp
This commit is contained in:
Davidson Gomes 2024-07-03 13:45:05 -03:00
parent 14ea5d959f
commit b63b7b0b7b
2 changed files with 142 additions and 230 deletions

View File

@ -49,7 +49,7 @@
"amqplib": "^0.10.3",
"@aws-sdk/client-sqs": "^3.569.0",
"axios": "^1.6.5",
"baileys": "github:bobslavtriev/Baileys",
"baileys": "github:EvolutionAPI/Baileys",
"class-validator": "^0.14.1",
"compression": "^1.7.4",
"cors": "^2.8.5",

View File

@ -20,6 +20,7 @@ import makeWASocket, {
GroupMetadata,
isJidBroadcast,
isJidGroup,
isJidNewsletter,
isJidUser,
makeCacheableSignalKeyStore,
MessageUpsertType,
@ -517,6 +518,143 @@ export class BaileysStartupService extends ChannelStartupService {
return await useMultiFileAuthState(join(INSTANCE_DIR, this.instance.name));
}
private async createClient(number?: string, mobile?: boolean): Promise<WASocket> {
this.instance.authState = await this.defineAuthState();
if (!mobile) {
this.mobile = false;
} else {
this.mobile = mobile;
}
const session = this.configService.get<ConfigSessionPhone>('CONFIG_SESSION_PHONE');
let browserOptions = {};
if (number || this.phoneNumber) {
this.phoneNumber = number;
this.logger.info(`Phone number: ${number}`);
} else {
const browser: WABrowserDescription = [session.CLIENT, session.NAME, release()];
browserOptions = { browser };
this.logger.info(`Browser: ${browser}`);
}
let version;
let log;
if (session.VERSION) {
version = session.VERSION.split(',');
log = `Baileys version env: ${version}`;
} else {
const baileysVersion = await fetchLatestBaileysVersion();
version = baileysVersion.version;
log = `Baileys version: ${version}`;
}
this.logger.info(log);
let options;
if (this.localProxy.enabled) {
this.logger.info('Proxy enabled: ' + this.localProxy.proxy?.host);
if (this.localProxy?.proxy?.host?.includes('proxyscrape')) {
try {
const response = await axios.get(this.localProxy.proxy?.host);
const text = response.data;
const proxyUrls = text.split('\r\n');
const rand = Math.floor(Math.random() * Math.floor(proxyUrls.length));
const proxyUrl = 'http://' + proxyUrls[rand];
options = {
agent: makeProxyAgent(proxyUrl),
fetchAgent: makeProxyAgent(proxyUrl),
};
} catch (error) {
this.localProxy.enabled = false;
}
} else {
options = {
agent: makeProxyAgent(this.localProxy.proxy),
fetchAgent: makeProxyAgent(this.localProxy.proxy),
};
}
}
const socketConfig: UserFacingSocketConfig = {
...options,
auth: {
creds: this.instance.authState.state.creds,
keys: makeCacheableSignalKeyStore(this.instance.authState.state.keys, P({ level: 'error' }) as any),
},
logger: P({ level: this.logBaileys }),
printQRInTerminal: false,
mobile,
...browserOptions,
version,
markOnlineOnConnect: this.localSettings.always_online,
retryRequestDelayMs: 350,
maxMsgRetryCount: 4,
fireInitQueries: true,
connectTimeoutMs: 20_000,
keepAliveIntervalMs: 30_000,
qrTimeout: 45_000,
defaultQueryTimeoutMs: undefined,
emitOwnEvents: false,
shouldIgnoreJid: (jid) => {
const isGroupJid = this.localSettings.groups_ignore && isJidGroup(jid);
const isBroadcast = !this.localSettings.read_status && isJidBroadcast(jid);
const isNewsletter = isJidNewsletter(jid);
return isGroupJid || isBroadcast || isNewsletter;
},
msgRetryCounterCache: this.msgRetryCounterCache,
getMessage: async (key) => (await this.getMessage(key)) as Promise<proto.IMessage>,
generateHighQualityLinkPreview: true,
syncFullHistory: this.localSettings.sync_full_history,
shouldSyncHistoryMessage: (msg: proto.Message.IHistorySyncNotification) => {
return this.historySyncNotification(msg);
},
userDevicesCache: this.userDevicesCache,
transactionOpts: { maxCommitRetries: 5, delayBetweenTriesMs: 2500 },
patchMessageBeforeSending(message) {
if (
message.deviceSentMessage?.message?.listMessage?.listType === proto.Message.ListMessage.ListType.PRODUCT_LIST
) {
message = JSON.parse(JSON.stringify(message));
message.deviceSentMessage.message.listMessage.listType = proto.Message.ListMessage.ListType.SINGLE_SELECT;
}
if (message.listMessage?.listType == proto.Message.ListMessage.ListType.PRODUCT_LIST) {
message = JSON.parse(JSON.stringify(message));
message.listMessage.listType = proto.Message.ListMessage.ListType.SINGLE_SELECT;
}
return message;
},
};
this.endSession = false;
this.logger.verbose('Creating socket');
this.client = makeWASocket(socketConfig);
this.logger.verbose('Socket created');
this.eventHandler();
this.logger.verbose('Socket event handler initialized');
this.phoneNumber = number;
return this.client;
}
public async connectToWhatsapp(number?: string, mobile?: boolean): Promise<WASocket> {
this.logger.verbose('Connecting to whatsapp');
try {
@ -530,130 +668,7 @@ export class BaileysStartupService extends ChannelStartupService {
this.loadProxy();
this.loadChamaai();
this.instance.authState = await this.defineAuthState();
if (!mobile) {
this.mobile = false;
} else {
this.mobile = mobile;
}
const session = this.configService.get<ConfigSessionPhone>('CONFIG_SESSION_PHONE');
const browser: WABrowserDescription = [session.CLIENT, session.NAME, release()];
this.logger.verbose('Browser: ' + JSON.stringify(browser));
let version;
let log;
if (session.VERSION) {
version = session.VERSION.split(',');
log = `Baileys version env: ${version}`;
} else {
const baileysVersion = await fetchLatestBaileysVersion();
version = baileysVersion.version;
log = `Baileys version: ${version}`;
}
this.logger.info(log);
let options;
if (this.localProxy.enabled) {
this.logger.info('Proxy enabled: ' + this.localProxy.proxy?.host);
if (this.localProxy?.proxy?.host?.includes('proxyscrape')) {
try {
const response = await axios.get(this.localProxy.proxy?.host);
const text = response.data;
const proxyUrls = text.split('\r\n');
const rand = Math.floor(Math.random() * Math.floor(proxyUrls.length));
const proxyUrl = 'http://' + proxyUrls[rand];
options = {
agent: makeProxyAgent(proxyUrl),
fetchAgent: makeProxyAgent(proxyUrl),
};
} catch (error) {
this.localProxy.enabled = false;
}
} else {
options = {
agent: makeProxyAgent(this.localProxy.proxy),
fetchAgent: makeProxyAgent(this.localProxy.proxy),
};
}
}
const socketConfig: UserFacingSocketConfig = {
...options,
auth: {
creds: this.instance.authState.state.creds,
keys: makeCacheableSignalKeyStore(this.instance.authState.state.keys, P({ level: 'error' }) as any),
},
logger: P({ level: this.logBaileys }),
printQRInTerminal: false,
mobile,
browser: number ? ['Chrome (Linux)', session.NAME, release()] : browser,
version,
markOnlineOnConnect: this.localSettings.always_online,
retryRequestDelayMs: 350,
maxMsgRetryCount: 4,
fireInitQueries: true,
connectTimeoutMs: 20_000,
keepAliveIntervalMs: 30_000,
qrTimeout: 45_000,
defaultQueryTimeoutMs: undefined,
emitOwnEvents: false,
shouldIgnoreJid: (jid) => {
const isGroupJid = this.localSettings.groups_ignore && isJidGroup(jid);
const isBroadcast = !this.localSettings.read_status && isJidBroadcast(jid);
return isGroupJid || isBroadcast;
},
msgRetryCounterCache: this.msgRetryCounterCache,
getMessage: async (key) => (await this.getMessage(key)) as Promise<proto.IMessage>,
generateHighQualityLinkPreview: true,
syncFullHistory: this.localSettings.sync_full_history,
shouldSyncHistoryMessage: (msg: proto.Message.IHistorySyncNotification) => {
return this.historySyncNotification(msg);
},
userDevicesCache: this.userDevicesCache,
transactionOpts: { maxCommitRetries: 5, delayBetweenTriesMs: 2500 },
cachedGroupMetadata: this.getGroupMetadataCache,
patchMessageBeforeSending(message) {
if (
message.deviceSentMessage?.message?.listMessage?.listType ===
proto.Message.ListMessage.ListType.PRODUCT_LIST
) {
message = JSON.parse(JSON.stringify(message));
message.deviceSentMessage.message.listMessage.listType = proto.Message.ListMessage.ListType.SINGLE_SELECT;
}
if (message.listMessage?.listType == proto.Message.ListMessage.ListType.PRODUCT_LIST) {
message = JSON.parse(JSON.stringify(message));
message.listMessage.listType = proto.Message.ListMessage.ListType.SINGLE_SELECT;
}
return message;
},
};
this.endSession = false;
this.logger.verbose('Creating socket');
this.client = makeWASocket(socketConfig);
this.logger.verbose('Socket created');
this.eventHandler();
this.logger.verbose('Socket event handler initialized');
this.phoneNumber = number;
return this.client;
return await this.createClient(number, mobile);
} catch (error) {
this.logger.error(error);
throw new InternalServerErrorException(error?.toString());
@ -720,110 +735,7 @@ export class BaileysStartupService extends ChannelStartupService {
public async reloadConnection(): Promise<WASocket> {
try {
this.instance.authState = await this.defineAuthState();
const session = this.configService.get<ConfigSessionPhone>('CONFIG_SESSION_PHONE');
const browser: WABrowserDescription = [session.CLIENT, session.NAME, release()];
let version;
let log;
if (session.VERSION) {
version = session.VERSION.split(',');
log = `Baileys version env: ${version}`;
} else {
const baileysVersion = await fetchLatestBaileysVersion();
version = baileysVersion.version;
log = `Baileys version: ${version}`;
}
this.logger.info(log);
let options;
if (this.localProxy.enabled) {
this.logger.info('Proxy enabled: ' + this.localProxy.proxy?.host);
if (this.localProxy?.proxy?.host?.includes('proxyscrape')) {
try {
const response = await axios.get(this.localProxy.proxy?.host);
const text = response.data;
const proxyUrls = text.split('\r\n');
const rand = Math.floor(Math.random() * Math.floor(proxyUrls.length));
const proxyUrl = 'http://' + proxyUrls[rand];
options = {
agent: makeProxyAgent(proxyUrl),
fetchAgent: makeProxyAgent(proxyUrl),
};
} catch (error) {
this.localProxy.enabled = false;
}
} else {
options = {
agent: makeProxyAgent(this.localProxy.proxy),
fetchAgent: makeProxyAgent(this.localProxy.proxy),
};
}
}
const socketConfig: UserFacingSocketConfig = {
...options,
auth: {
creds: this.instance.authState.state.creds,
keys: makeCacheableSignalKeyStore(this.instance.authState.state.keys, P({ level: 'error' }) as any),
},
logger: P({ level: this.logBaileys }),
printQRInTerminal: false,
mobile: this.mobile,
browser: this.phoneNumber ? ['Chrome (Linux)', session.NAME, release()] : browser,
version,
markOnlineOnConnect: this.localSettings.always_online,
retryRequestDelayMs: 350,
maxMsgRetryCount: 4,
fireInitQueries: true,
connectTimeoutMs: 20_000,
keepAliveIntervalMs: 30_000,
qrTimeout: 45_000,
defaultQueryTimeoutMs: undefined,
emitOwnEvents: false,
shouldIgnoreJid: (jid) => {
const isGroupJid = this.localSettings.groups_ignore && isJidGroup(jid);
const isBroadcast = !this.localSettings.read_status && isJidBroadcast(jid);
return isGroupJid || isBroadcast;
},
msgRetryCounterCache: this.msgRetryCounterCache,
getMessage: async (key) => (await this.getMessage(key)) as Promise<proto.IMessage>,
generateHighQualityLinkPreview: true,
syncFullHistory: this.localSettings.sync_full_history,
shouldSyncHistoryMessage: (msg: proto.Message.IHistorySyncNotification) => {
return this.historySyncNotification(msg);
},
userDevicesCache: this.userDevicesCache,
transactionOpts: { maxCommitRetries: 5, delayBetweenTriesMs: 2500 },
patchMessageBeforeSending(message) {
if (
message.deviceSentMessage?.message?.listMessage?.listType ===
proto.Message.ListMessage.ListType.PRODUCT_LIST
) {
message = JSON.parse(JSON.stringify(message));
message.deviceSentMessage.message.listMessage.listType = proto.Message.ListMessage.ListType.SINGLE_SELECT;
}
if (message.listMessage?.listType == proto.Message.ListMessage.ListType.PRODUCT_LIST) {
message = JSON.parse(JSON.stringify(message));
message.listMessage.listType = proto.Message.ListMessage.ListType.SINGLE_SELECT;
}
return message;
},
};
this.client = makeWASocket(socketConfig);
return this.client;
return await this.createClient(this.phoneNumber, this.mobile);
} catch (error) {
this.logger.error(error);
throw new InternalServerErrorException(error?.toString());
@ -1061,7 +973,7 @@ export class BaileysStartupService extends ChannelStartupService {
m.messageTimestamp = m.messageTimestamp?.toNumber();
}
if (m.messageTimestamp <= timestampLimitToImport) {
if ((m.messageTimestamp as number) <= timestampLimitToImport) {
continue;
}