evolution-api / src /utils /use-multi-file-auth-state-provider-files.ts
oex2003's picture
Deploy Evolution API to Hugging Face Space
5e518ea
/**
* β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
* β”‚ @author jrCleber β”‚
* β”‚ @filename use-multi-file-auth-state-provider-files.ts β”‚
* β”‚ Developed by: Cleber Wilson β”‚
* β”‚ Creation date: May 31, 2024 β”‚
* β”‚ Contact: contato@codechat.dev β”‚
* β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
* β”‚ @copyright Β© Cleber Wilson 2023. All rights reserved. β”‚
* β”‚ Licensed under the Apache License, Version 2.0 β”‚
* β”‚ β”‚
* β”‚ @license "https://github.com/code-chat-br/whatsapp-api/blob/main/LICENSE" β”‚
* β”‚ β”‚
* β”‚ You may not use this file except in compliance with the License. β”‚
* β”‚ You may obtain a copy of the License at β”‚
* β”‚ β”‚
* β”‚ http://www.apache.org/licenses/LICENSE-2.0 β”‚
* β”‚ β”‚
* β”‚ Unless required by applicable law or agreed to in writing, software β”‚
* β”‚ distributed under the License is distributed on an "AS IS" BASIS, β”‚
* β”‚ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. β”‚
* β”‚ β”‚
* β”‚ See the License for the specific language governing permissions and β”‚
* β”‚ limitations under the License. β”‚
* β”‚ β”‚
* β”‚ @type {AuthState} β”‚
* β”‚ @function useMultiFileAuthStateRedisDb β”‚
* β”‚ @returns {Promise<AuthState>} β”‚
* β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
* β”‚ @important β”‚
* β”‚ For any future changes to the code in this file, it is recommended to β”‚
* β”‚ contain, together with the modification, the information of the developer β”‚
* β”‚ who changed it and the date of modification. β”‚
* β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
*/
import { ProviderFiles } from '@api/provider/sessions';
import { Logger } from '@config/logger.config';
import { AuthenticationCreds, AuthenticationState, BufferJSON, initAuthCreds, proto, SignalDataTypeMap } from 'baileys';
import { isNotEmpty } from 'class-validator';
export type AuthState = { state: AuthenticationState; saveCreds: () => Promise<void> };
export class AuthStateProvider {
constructor(private readonly providerFiles: ProviderFiles) {}
private readonly logger = new Logger('AuthStateProvider');
public async authStateProvider(instance: string): Promise<AuthState> {
const [, error] = await this.providerFiles.create(instance);
if (error) {
this.logger.error(['Failed to create folder on file server', error?.message, error?.stack]);
return;
}
const writeData = async (data: any, key: string): Promise<any> => {
const json = JSON.stringify(data, BufferJSON.replacer);
const [response, error] = await this.providerFiles.write(instance, key, {
data: json,
});
if (error) {
// this.logger.error(['writeData', error?.message, error?.stack]);
return;
}
return response;
};
const readData = async (key: string): Promise<any> => {
const [response, error] = await this.providerFiles.read(instance, key);
if (error) {
// this.logger.error(['readData', error?.message, error?.stack]);
return;
}
if (isNotEmpty(response?.data)) {
return JSON.parse(JSON.stringify(response.data), BufferJSON.reviver);
}
};
const removeData = async (key: string) => {
const [response, error] = await this.providerFiles.delete(instance, key);
if (error) {
// this.logger.error(['removeData', error?.message, error?.stack]);
return;
}
return response;
};
const creds: AuthenticationCreds = (await readData('creds')) || initAuthCreds();
return {
state: {
creds,
keys: {
get: async (type, ids: string[]) => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
const data: { [_: string]: SignalDataTypeMap[type] } = {};
await Promise.all(
ids.map(async (id) => {
let value = await readData(`${type}-${id}`);
if (type === 'app-state-sync-key' && value) {
value = proto.Message.AppStateSyncKeyData.fromObject(value);
}
data[id] = value;
}),
);
return data;
},
set: async (data: any) => {
const tasks: Promise<void>[] = [];
for (const category in data) {
for (const id in data[category]) {
const value = data[category][id];
const key = `${category}-${id}`;
tasks.push(value ? await writeData(value, key) : await removeData(key));
}
}
await Promise.all(tasks);
},
},
},
saveCreds: async () => {
return await writeData(creds, 'creds');
},
};
}
}