-
-
Notifications
You must be signed in to change notification settings - Fork 844
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[🐛]Al usar base de datos postgres no ingresa al flujo de respuesta esperada #1102
Comments
Tuve el mismo problema. |
Tengo exactamente el mismo problema builderbot/packages/database-postgres/src/types.ts Lines 1 to 8 in 27d700d
Pero lo que se espera en la tabla es: builderbot/packages/database-postgres/src/postgresAdapter.ts Lines 114 to 125 in 27d700d
Un ejemplo donde lo inserta: builderbot/packages/database-postgres/src/postgresAdapter.ts Lines 49 to 51 in 27d700d
Al parecer el error vino de la PR: #1094 en este momento se seguía manteniendo en el dominio |
Dejo el código corregido del adapter, cambios en las lineas 52 y 62 📝 Saving history entry: {
ref: 'ans_8a771232-7f84-4077-85f3-7182c4e2128b',
keyword: 'key_5a23aa89-395e-4c39-12af-cdf791a4cb03',
answer: '__call_action__',
options: {
media: undefined,
buttons: [],
capture: false,
delay: 0,
idle: undefined,
ref: undefined,
nested: [],
keyword: {},
callback: true
},
refSerialize: 'bc0a8804f59ee93780e7b4fe65e347af',
from: 'NUMERODECELULAR(borrado para el ejemplo)´
}
Interface: export type HistoryEntry = {
ref: string
keyword?: string
answer: string
refSerialize: string
phone?: string
options?: Record<string, any>
from: string
} Adapter: import { MemoryDB } from "@builderbot/bot";
import pg from "pg";
import type { Contact, Credential, HistoryEntry } from "./types";
class PostgreSQLAdapter extends MemoryDB {
db: any;
listHistory: HistoryEntry[] = [];
credentials: Credential = { host: "localhost", user: "", database: "", password: null, port: 5432 };
constructor(_credentials: Credential) {
super();
this.credentials = _credentials;
this.init().then();
}
async init(): Promise<boolean | undefined> {
try {
const { Pool } = pg;
const pool = new Pool(this.credentials);
const db = await pool.connect();
this.db = db;
console.log("🆗 Successful DB Connection");
this.checkTableExistsAndSP();
return true;
} catch (error) {
console.log("Error", error);
throw error;
}
}
async getPrevByNumber(from: string): Promise<HistoryEntry | undefined> {
const query = "SELECT * FROM public.history WHERE phone = $1 ORDER BY created_at DESC LIMIT 1";
try {
const result = await this.db.query(query, [from]);
const row = result.rows[0];
if (row) {
row["refSerialize"] = row.refserialize;
delete row.refserialize;
}
return row;
} catch (error) {
console.error("Error getting previous entry by number:", error);
throw error;
}
}
async save(ctx: HistoryEntry): Promise<void> {
console.log("📝 Saving history entry:", ctx);
const values = [ctx.ref, ctx.keyword, ctx.answer, ctx.refSerialize, ctx.from, JSON.stringify(ctx.options)];
const query = "SELECT save_or_update_history_and_contact($1, $2, $3, $4, $5, $6)";
try {
await this.db.query(query, values);
} catch (error) {
console.error("Error registering history entry:", error);
throw error;
}
this.listHistory.push(ctx);
}
async getContact(ctx: HistoryEntry): Promise<Contact | undefined> {
const from = ctx.from;
const query = "SELECT * FROM public.contact WHERE phone = $1 LIMIT 1";
try {
const result = await this.db.query(query, [from]);
return result.rows[0];
} catch (error) {
if (error instanceof Error) {
console.error("Error getting contact by number:", error.message);
}
throw error;
}
}
async saveContact(ctx: any): Promise<void> {
// action: u (Actualiza el valor de ctx.values), a (Agrega). Agrega por defecto.
const _contact = await this.getContact(ctx);
let jsValues = {};
if ((ctx?.action ?? "a") === "a") {
jsValues = { ..._contact?.values, ...(ctx?.values ?? {}) };
} else {
jsValues = ctx?.values ?? {};
}
const values = [ctx.from, JSON.stringify(jsValues)];
const query = "SELECT save_or_update_contact($1, $2)";
try {
await this.db.query(query, values);
} catch (error) {
console.error("🚫 Error saving or updating contact:", error);
throw error;
}
}
async checkTableExistsAndSP(): Promise<void> {
const contact = `
CREATE TABLE IF NOT EXISTS contact (
id SERIAL PRIMARY KEY,
phone VARCHAR(255) DEFAULT NULL,
created_at TIMESTAMP DEFAULT current_timestamp,
updated_in TIMESTAMP,
last_interaction TIMESTAMP,
values JSONB
)`;
try {
await this.db.query(contact);
} catch (error) {
console.error("🚫 Error creating the contact table:", error);
throw error;
}
const history = `
CREATE TABLE IF NOT EXISTS history (
id SERIAL PRIMARY KEY,
ref VARCHAR(255) NOT NULL,
keyword VARCHAR(255),
answer TEXT NOT NULL,
refSerialize TEXT NOT NULL,
phone VARCHAR(255) DEFAULT NULL,
options JSONB,
created_at TIMESTAMP DEFAULT current_timestamp,
updated_in TIMESTAMP,
contact_id INTEGER REFERENCES contact(id)
)`;
try {
await this.db.query(history);
} catch (error) {
console.error("🚫 Error creating the history table:", error);
throw error;
}
await this.createSP();
}
async createSP(): Promise<void> {
const sp_suc = `
CREATE OR REPLACE FUNCTION save_or_update_contact(
in_phone VARCHAR(255),
in_values JSONB
)
RETURNS VOID AS
$$
DECLARE
contact_cursor refcursor := 'cur_contact';
contact_id INT;
BEGIN
SELECT id INTO contact_id FROM contact WHERE phone = in_phone;
IF contact_id IS NULL THEN
INSERT INTO contact (phone, "values")
VALUES (in_phone, in_values);
ELSE
UPDATE contact SET "values" = in_values, updated_in = current_timestamp
WHERE id = contact_id;
END IF;
END;
$$ LANGUAGE plpgsql;`;
try {
await this.db.query(sp_suc);
} catch (error) {
console.error("🚫 Error creating the stored procedure for contact:", error);
throw error;
}
const sp_suhc = `
CREATE OR REPLACE FUNCTION save_or_update_history_and_contact(
in_ref VARCHAR(255),
in_keyword VARCHAR(255),
in_answer TEXT,
in_refserialize TEXT,
in_phone VARCHAR(255),
in_options JSONB
)
RETURNS VOID AS
$$
DECLARE
_contact_id INT;
BEGIN
SELECT id INTO _contact_id FROM contact WHERE phone = in_phone;
IF _contact_id IS NULL THEN
INSERT INTO contact (phone)
VALUES (in_phone)
RETURNING id INTO _contact_id;
ELSE
UPDATE contact SET last_interaction = current_timestamp WHERE id = _contact_id;
END IF;
INSERT INTO history (ref, keyword, answer, refserialize, phone, options, contact_id, created_at)
VALUES (in_ref, in_keyword, in_answer, in_refserialize, in_phone, in_options, _contact_id, current_timestamp);
END;
$$ LANGUAGE plpgsql;`;
try {
await this.db.query(sp_suhc);
} catch (error) {
console.error("🚫 Error creating the stored procedure for history:", error);
throw error;
}
}
}
export { PostgreSQLAdapter };
`` |
¿Alguna novedad sobre esta ISSUE? |
¿Que versión estas usando?
v2
¿Sobre que afecta?
Flujo de palabras (Flow)
Describe tu problema
Hola,
De antemano pido disculpas si lo estoy haciendo mal, es la primera vez que hago esto.
No sé si solo pasa en linux o solo sea un caso atipico pero sucede que al encadenar respuestas y almacenar el comportamiento de la respuesta no sigue el flujo, por ejemplo:
const registerFlow = addKeyword<Provider, Database>(['register', utils.setEvent('REGISTER_FLOW')]) .addAnswer(
What is your name?, { capture: true }, async (ctx, { state }) => { await state.update({ name: ctx.body }) }) .addAnswer('What is your age?', { capture: true }, async (ctx, { state }) => { await state.update({ age: ctx.body }) }) .addAction(async (_, { flowDynamic, state }) => { await flowDynamic(
${state.get('name')}, thanks for your information!: Your age: ${state.get('age')}) })
En el anterior código, cuando el usuario escribe register, el bot responde correctamente preguntando
What is your name?
, pero al usuario responder con el nombre, ahí se detiene el flujo.Descubrí que el problema estaba en el archivo base-ts-baileys-postgres/node_modules/@builderbot/database-postgres/dist/index.cjs, mas exactamente en el método save porque en él al armar el array n, se está pasando un parametro t.phone y al parecer este no existe, el que existe es el parámetro t.from
Reproducir error
No response
Información Adicional
No response
The text was updated successfully, but these errors were encountered: