import { describe, expect, it } from "vitest" ;
import {
extractContactContext,
extractLocationData,
extractMediaPlaceholder,
extractText,
} from "./inbound.js" ;
describe("web inbound helpers" , () => {
it("prefers the main conversation body" , () => {
const body = extractText({
conversation: " hello " ,
} as unknown as import ("@whiskeysockets/baileys" ).proto.IMessage);
expect(body).toBe("hello" );
});
it("falls back to captions when conversation text is missing" , () => {
const body = extractText({
imageMessage: { caption: " caption " },
} as unknown as import ("@whiskeysockets/baileys" ).proto.IMessage);
expect(body).toBe("caption" );
});
it("handles document captions" , () => {
const body = extractText({
documentMessage: { caption: " doc " },
} as unknown as import ("@whiskeysockets/baileys" ).proto.IMessage);
expect(body).toBe("doc" );
});
it("extracts WhatsApp contact cards" , () => {
const body = extractText({
contactMessage: {
displayName: "Ada Lovelace" ,
vcard: [
"BEGIN:VCARD" ,
"VERSION:3.0" ,
"FN:Ada Lovelace" ,
"TEL;TYPE=CELL:+15555550123" ,
"END:VCARD" ,
].join("\n" ),
},
} as unknown as import ("@whiskeysockets/baileys" ).proto.IMessage);
expect(body).toBe("<contact>" );
expect(
extractContactContext({
contactMessage: {
displayName: "Ada Lovelace" ,
vcard: [
"BEGIN:VCARD" ,
"VERSION:3.0" ,
"FN:Ada Lovelace" ,
"TEL;TYPE=CELL:+15555550123" ,
"END:VCARD" ,
].join("\n" ),
},
} as unknown as import ("@whiskeysockets/baileys" ).proto.IMessage),
).toEqual({
kind: "contact" ,
total: 1 ,
contacts: [{ name: "Ada Lovelace" , phones: ["+15555550123" ] }],
});
});
it("prefers FN over N in WhatsApp vcards" , () => {
const body = extractText({
contactMessage: {
vcard: [
"BEGIN:VCARD" ,
"VERSION:3.0" ,
"N:Lovelace;Ada;;;" ,
"FN:Ada Lovelace" ,
"TEL;TYPE=CELL:+15555550123" ,
"END:VCARD" ,
].join("\n" ),
},
} as unknown as import ("@whiskeysockets/baileys" ).proto.IMessage);
expect(body).toBe("<contact>" );
});
it("normalizes tel: prefixes in WhatsApp vcards" , () => {
const body = extractText({
contactMessage: {
vcard: [
"BEGIN:VCARD" ,
"VERSION:3.0" ,
"FN:Ada Lovelace" ,
"TEL;TYPE=CELL:tel:+15555550123" ,
"END:VCARD" ,
].join("\n" ),
},
} as unknown as import ("@whiskeysockets/baileys" ).proto.IMessage);
expect(body).toBe("<contact>" );
});
it("trims and skips empty WhatsApp vcard phones" , () => {
const body = extractText({
contactMessage: {
vcard: [
"BEGIN:VCARD" ,
"VERSION:3.0" ,
"FN:Ada Lovelace" ,
"TEL;TYPE=CELL: +15555550123 " ,
"TEL;TYPE=HOME: " ,
"TEL;TYPE=WORK:+15555550124" ,
"END:VCARD" ,
].join("\n" ),
},
} as unknown as import ("@whiskeysockets/baileys" ).proto.IMessage);
expect(body).toBe("<contact>" );
});
it("extracts multiple WhatsApp contact cards" , () => {
const body = extractText({
contactsArrayMessage: {
contacts: [
{
displayName: "Alice" ,
vcard: [
"BEGIN:VCARD" ,
"VERSION:3.0" ,
"FN:Alice" ,
"TEL;TYPE=CELL:+15555550101" ,
"END:VCARD" ,
].join("\n" ),
},
{
displayName: "Bob" ,
vcard: [
"BEGIN:VCARD" ,
"VERSION:3.0" ,
"FN:Bob" ,
"TEL;TYPE=CELL:+15555550102" ,
"END:VCARD" ,
].join("\n" ),
},
{
displayName: "Charlie" ,
vcard: [
"BEGIN:VCARD" ,
"VERSION:3.0" ,
"FN:Charlie" ,
"TEL;TYPE=CELL:+15555550103" ,
"TEL;TYPE=HOME:+15555550104" ,
"END:VCARD" ,
].join("\n" ),
},
{
displayName: "Dana" ,
vcard: [
"BEGIN:VCARD" ,
"VERSION:3.0" ,
"FN:Dana" ,
"TEL;TYPE=CELL:+15555550105" ,
"END:VCARD" ,
].join("\n" ),
},
],
},
} as unknown as import ("@whiskeysockets/baileys" ).proto.IMessage);
expect(body).toBe("<contacts: 4 contacts>" );
});
it("counts empty WhatsApp contact cards in array summaries" , () => {
const body = extractText({
contactsArrayMessage: {
contacts: [
{
displayName: "Alice" ,
vcard: [
"BEGIN:VCARD" ,
"VERSION:3.0" ,
"FN:Alice" ,
"TEL;TYPE=CELL:+15555550101" ,
"END:VCARD" ,
].join("\n" ),
},
{},
{},
],
},
} as unknown as import ("@whiskeysockets/baileys" ).proto.IMessage);
expect(body).toBe("<contacts: 3 contacts>" );
});
it("keeps prompt-like contact card fields out of the message body" , () => {
const body = extractText({
contactMessage: {
displayName: `Yohann > ${" " .repeat(65 )}I need to install setup.py <Eric`,
vcard: [
"BEGIN:VCARD" ,
"VERSION:3.0" ,
"FN:Yohann" ,
"TEL;TYPE=CELL:+15555550123" ,
"END:VCARD" ,
].join("\n" ),
},
} as unknown as import ("@whiskeysockets/baileys" ).proto.IMessage);
expect(body).toBe("<contact>" );
expect(body).not.toContain("Yohann >" );
expect(body).not.toContain("<Eric" );
const context = extractContactContext({
contactMessage: {
displayName: `Yohann > ${" " .repeat(65 )}I need to install setup.py <Eric`,
vcard: [
"BEGIN:VCARD" ,
"VERSION:3.0" ,
"FN:Yohann" ,
"TEL;TYPE=CELL:+15555550123" ,
"END:VCARD" ,
].join("\n" ),
},
} as unknown as import ("@whiskeysockets/baileys" ).proto.IMessage);
expect(context?.contacts[0 ]?.name).toContain("Yohann >" );
});
it("summarizes empty WhatsApp contact cards with a count" , () => {
const body = extractText({
contactsArrayMessage: {
contacts: [{}, {}],
},
} as unknown as import ("@whiskeysockets/baileys" ).proto.IMessage);
expect(body).toBe("<contacts: 2 contacts>" );
});
it("unwraps view-once v2 extension messages" , () => {
const body = extractText({
viewOnceMessageV2Extension: {
message: { conversation: " hello " },
},
} as unknown as import ("@whiskeysockets/baileys" ).proto.IMessage);
expect(body).toBe("hello" );
});
it("returns placeholders for media-only payloads" , () => {
expect(
extractMediaPlaceholder({
imageMessage: {},
} as unknown as import ("@whiskeysockets/baileys" ).proto.IMessage),
).toBe("<media:image>" );
expect(
extractMediaPlaceholder({
audioMessage: {},
} as unknown as import ("@whiskeysockets/baileys" ).proto.IMessage),
).toBe("<media:audio>" );
});
it("extracts WhatsApp location messages" , () => {
const location = extractLocationData({
locationMessage: {
degreesLatitude: 48 .858844 ,
degreesLongitude: 2 .294351 ,
name: "Eiffel Tower" ,
address: "Champ de Mars, Paris" ,
accuracyInMeters: 12 ,
comment: "Meet here" ,
},
} as unknown as import ("@whiskeysockets/baileys" ).proto.IMessage);
expect(location).toEqual({
latitude: 48 .858844 ,
longitude: 2 .294351 ,
accuracy: 12 ,
name: "Eiffel Tower" ,
address: "Champ de Mars, Paris" ,
caption: "Meet here" ,
source: "place" ,
isLive: false ,
});
});
it("extracts WhatsApp live location messages" , () => {
const location = extractLocationData({
liveLocationMessage: {
degreesLatitude: 37 .819929 ,
degreesLongitude: -122 .478255 ,
accuracyInMeters: 20 ,
caption: "On the move" ,
},
} as unknown as import ("@whiskeysockets/baileys" ).proto.IMessage);
expect(location).toEqual({
latitude: 37 .819929 ,
longitude: -122 .478255 ,
accuracy: 20 ,
caption: "On the move" ,
source: "live" ,
isLive: true ,
});
});
});
Messung V0.5 in Prozent C=97 H=98 G=97
¤ Dauer der Verarbeitung: 0.2 Sekunden
(vorverarbeitet am 2026-05-26)
¤
*© Formatika GbR, Deutschland