mirror of
https://github.com/cheveguerra/whaticket-community.git
synced 2026-04-20 20:59:16 +00:00
improvement: moved vcard parse logic to backend
This commit is contained in:
@@ -0,0 +1,16 @@
|
|||||||
|
import { QueryInterface, DataTypes } from "sequelize";
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
up: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.addColumn("Messages", "contactId", {
|
||||||
|
type: DataTypes.INTEGER,
|
||||||
|
references: { model: "Contacts", key: "id" },
|
||||||
|
onUpdate: "CASCADE",
|
||||||
|
onDelete: "CASCADE"
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
down: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.removeColumn("Messages", "contactId");
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
import { QueryInterface, DataTypes } from "sequelize";
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
up: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.addColumn("Messages", "vcardContactId", {
|
||||||
|
type: DataTypes.INTEGER,
|
||||||
|
references: { model: "Contacts", key: "id" },
|
||||||
|
onUpdate: "CASCADE",
|
||||||
|
onDelete: "CASCADE"
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
down: (queryInterface: QueryInterface) => {
|
||||||
|
return queryInterface.removeColumn("Messages", "vcardContactId");
|
||||||
|
}
|
||||||
|
};
|
||||||
59
backend/src/helpers/ParseVcardToJson.ts
Normal file
59
backend/src/helpers/ParseVcardToJson.ts
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
interface JCard {
|
||||||
|
[key: string]: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Meta {
|
||||||
|
[key: string]: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ParseVcardToJson = (input: string): JCard => {
|
||||||
|
const Re1 = /^(version|fn|title|org):(.+)$/i;
|
||||||
|
const Re2 = /^([^:;]+);([^:]+):(.+)$/;
|
||||||
|
const ReKey = /item\d{1,2}\./;
|
||||||
|
const fields = {} as JCard;
|
||||||
|
|
||||||
|
input.split(/\r\n|\r|\n/).forEach(line => {
|
||||||
|
let results;
|
||||||
|
let key;
|
||||||
|
|
||||||
|
if (Re1.test(line)) {
|
||||||
|
results = line.match(Re1);
|
||||||
|
if (results) {
|
||||||
|
key = results[1].toLowerCase();
|
||||||
|
const [, , res] = results;
|
||||||
|
fields[key] = res;
|
||||||
|
}
|
||||||
|
} else if (Re2.test(line)) {
|
||||||
|
results = line.match(Re2);
|
||||||
|
if (results) {
|
||||||
|
key = results[1].replace(ReKey, "").toLowerCase();
|
||||||
|
|
||||||
|
const meta = {} as Meta;
|
||||||
|
results[2]
|
||||||
|
.split(";")
|
||||||
|
.map((p, i) => {
|
||||||
|
const match = p.match(/([a-z]+)=(.*)/i);
|
||||||
|
if (match) {
|
||||||
|
return [match[1], match[2]];
|
||||||
|
}
|
||||||
|
return [`TYPE${i === 0 ? "" : i}`, p];
|
||||||
|
})
|
||||||
|
.forEach(p => {
|
||||||
|
const [, m] = p;
|
||||||
|
meta[p[0]] = m;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!fields[key]) fields[key] = [];
|
||||||
|
|
||||||
|
fields[key].push({
|
||||||
|
meta,
|
||||||
|
value: results[3].split(";")
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return fields;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ParseVcardToJson;
|
||||||
@@ -10,6 +10,7 @@ import {
|
|||||||
BelongsTo,
|
BelongsTo,
|
||||||
ForeignKey
|
ForeignKey
|
||||||
} from "sequelize-typescript";
|
} from "sequelize-typescript";
|
||||||
|
import Contact from "./Contact";
|
||||||
import Ticket from "./Ticket";
|
import Ticket from "./Ticket";
|
||||||
|
|
||||||
@Table
|
@Table
|
||||||
@@ -64,6 +65,20 @@ class Message extends Model<Message> {
|
|||||||
|
|
||||||
@BelongsTo(() => Ticket)
|
@BelongsTo(() => Ticket)
|
||||||
ticket: Ticket;
|
ticket: Ticket;
|
||||||
|
|
||||||
|
@ForeignKey(() => Contact)
|
||||||
|
@Column
|
||||||
|
contactId: number;
|
||||||
|
|
||||||
|
@BelongsTo(() => Contact, "contactId")
|
||||||
|
contact: Contact;
|
||||||
|
|
||||||
|
@ForeignKey(() => Contact)
|
||||||
|
@Column
|
||||||
|
vcardContactId: number;
|
||||||
|
|
||||||
|
@BelongsTo(() => Contact, "vcardContactId")
|
||||||
|
vcardContact: Contact;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Message;
|
export default Message;
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ const ListMessagesService = async ({
|
|||||||
const { count, rows: messages } = await Message.findAndCountAll({
|
const { count, rows: messages } = await Message.findAndCountAll({
|
||||||
where: whereCondition,
|
where: whereCondition,
|
||||||
limit,
|
limit,
|
||||||
|
include: ["contact", "vcardContact"],
|
||||||
offset,
|
offset,
|
||||||
order: [["createdAt", "DESC"]]
|
order: [["createdAt", "DESC"]]
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import { getIO } from "../../libs/socket";
|
|||||||
import { getWbot } from "../../libs/wbot";
|
import { getWbot } from "../../libs/wbot";
|
||||||
import AppError from "../../errors/AppError";
|
import AppError from "../../errors/AppError";
|
||||||
import ShowTicketService from "../TicketServices/ShowTicketService";
|
import ShowTicketService from "../TicketServices/ShowTicketService";
|
||||||
|
import ParseVcardToJson from "../../helpers/ParseVcardToJson";
|
||||||
|
|
||||||
const writeFileAsync = promisify(writeFile);
|
const writeFileAsync = promisify(writeFile);
|
||||||
|
|
||||||
@@ -161,9 +162,8 @@ const handlMedia = async (
|
|||||||
|
|
||||||
const newMessage: Message = await ticket.$create("message", {
|
const newMessage: Message = await ticket.$create("message", {
|
||||||
id: msg.id.id,
|
id: msg.id.id,
|
||||||
body: msg.fromMe
|
contactId: msg.fromMe ? null : contact.id,
|
||||||
? `${msg.body ? msg.body : media.filename}`
|
body: msg.body || media.filename,
|
||||||
: `${contact.name}: ${msg.body ? msg.body : media.filename}`,
|
|
||||||
fromMe: msg.fromMe,
|
fromMe: msg.fromMe,
|
||||||
mediaUrl: media.filename,
|
mediaUrl: media.filename,
|
||||||
mediaType: media.mimetype.split("/")[0]
|
mediaType: media.mimetype.split("/")[0]
|
||||||
@@ -175,21 +175,28 @@ const handlMedia = async (
|
|||||||
const handleMessage = async (
|
const handleMessage = async (
|
||||||
msg: WbotMessage,
|
msg: WbotMessage,
|
||||||
ticket: Ticket,
|
ticket: Ticket,
|
||||||
contact: Contact
|
contact: Contact,
|
||||||
|
vcardContact?: Contact
|
||||||
) => {
|
) => {
|
||||||
let newMessage: Message;
|
let newMessage: Message | null;
|
||||||
|
|
||||||
if (msg.hasMedia) {
|
if (msg.hasMedia) {
|
||||||
newMessage = await handlMedia(msg, ticket, contact);
|
newMessage = await handlMedia(msg, ticket, contact);
|
||||||
} else {
|
} else {
|
||||||
newMessage = await ticket.$create("message", {
|
const { id } = await ticket.$create("message", {
|
||||||
id: msg.id.id,
|
id: msg.id.id,
|
||||||
body: msg.fromMe ? msg.body : `${contact.name}: ${msg.body}`,
|
contactId: msg.fromMe ? null : contact.id,
|
||||||
|
vcardContactId: vcardContact ? vcardContact.id : null,
|
||||||
|
body: msg.body,
|
||||||
fromMe: msg.fromMe,
|
fromMe: msg.fromMe,
|
||||||
mediaType: msg.type,
|
mediaType: msg.type,
|
||||||
read: msg.fromMe
|
read: msg.fromMe
|
||||||
});
|
});
|
||||||
await ticket.update({ lastMessage: msg.body });
|
await ticket.update({ lastMessage: msg.body });
|
||||||
|
|
||||||
|
newMessage = await Message.findByPk(id, {
|
||||||
|
include: ["contact", "vcardContact"]
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const io = getIO();
|
const io = getIO();
|
||||||
@@ -234,13 +241,15 @@ const wbotMessageListener = (whatsapp: Whatsapp): void => {
|
|||||||
try {
|
try {
|
||||||
let msgContact: WbotContact;
|
let msgContact: WbotContact;
|
||||||
let groupContact: Contact | undefined;
|
let groupContact: Contact | undefined;
|
||||||
|
let vcardContact: Contact | undefined;
|
||||||
|
|
||||||
if (msg.fromMe) {
|
if (msg.fromMe) {
|
||||||
msgContact = await wbot.getContactById(msg.to);
|
msgContact = await wbot.getContactById(msg.to);
|
||||||
|
|
||||||
// return if it's a media message, it will be handled by media_uploaded event
|
// return if it's a media message, it will be handled by media_uploaded event
|
||||||
|
|
||||||
if (msg.hasMedia || msg.type !== "chat") return;
|
if (msg.hasMedia || (msg.type !== "chat" && msg.type !== "vcard"))
|
||||||
|
return;
|
||||||
} else {
|
} else {
|
||||||
msgContact = await msg.getContact();
|
msgContact = await msg.getContact();
|
||||||
}
|
}
|
||||||
@@ -252,11 +261,20 @@ const wbotMessageListener = (whatsapp: Whatsapp): void => {
|
|||||||
groupContact = await verifyGroup(msgGroupContact);
|
groupContact = await verifyGroup(msgGroupContact);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (msg.type === "vcard") {
|
||||||
|
const { tel } = ParseVcardToJson(msg.body);
|
||||||
|
const vcardWaid = tel[0]?.meta?.waid;
|
||||||
|
const vcardMsgContact = await wbot.getContactById(`${vcardWaid}@c.us`);
|
||||||
|
const profilePicUrl = await vcardMsgContact.getProfilePicUrl();
|
||||||
|
|
||||||
|
vcardContact = await verifyContact(vcardMsgContact, profilePicUrl);
|
||||||
|
}
|
||||||
|
|
||||||
const profilePicUrl = await msgContact.getProfilePicUrl();
|
const profilePicUrl = await msgContact.getProfilePicUrl();
|
||||||
const contact = await verifyContact(msgContact, profilePicUrl);
|
const contact = await verifyContact(msgContact, profilePicUrl);
|
||||||
const ticket = await verifyTicket(contact, whatsappId, groupContact);
|
const ticket = await verifyTicket(contact, whatsappId, groupContact);
|
||||||
|
|
||||||
await handleMessage(msg, ticket, contact);
|
await handleMessage(msg, ticket, contact, vcardContact);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Sentry.captureException(err);
|
Sentry.captureException(err);
|
||||||
console.log(err);
|
console.log(err);
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
Arguments:
|
Arguments:
|
||||||
/usr/bin/node /usr/share/yarn/bin/yarn.js add -D @types/qrcode-terminal
|
/usr/bin/node /usr/share/yarn/bin/yarn.js add -D @types/vdata-parser
|
||||||
|
|
||||||
PATH:
|
PATH:
|
||||||
/home/canove/.vscode-server/bin/58bb7b2331731bf72587010e943852e13e6fd3cf/bin:/home/canove/.zinit/polaris/sbin:/home/canove/.zinit/polaris/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/mnt/c/Windows/system32:/mnt/c/Windows:/mnt/c/Windows/System32/Wbem:/mnt/c/Windows/System32/WindowsPowerShell/v1.0/:/mnt/c/Windows/System32/OpenSSH/:/mnt/c/ProgramData/chocolatey/bin:/mnt/c/Program Files/Microsoft VS Code/bin:/mnt/c/Program Files (x86)/GNU/GnuPG/pub:/mnt/c/Users/cassio/AppData/Local/Microsoft/WindowsApps:/mnt/c/Users/cassio/AppData/Local/GitHubDesktop/bin
|
/home/canove/.vscode-server/bin/e5e9e69aed6e1984f7499b7af85b3d05f9a6883a/bin:/home/canove/.zinit/polaris/sbin:/home/canove/.zinit/polaris/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/mnt/c/Windows/system32:/mnt/c/Windows:/mnt/c/Windows/System32/Wbem:/mnt/c/Windows/System32/WindowsPowerShell/v1.0/:/mnt/c/Windows/System32/OpenSSH/:/mnt/c/ProgramData/chocolatey/bin:/mnt/c/Program Files/Microsoft VS Code/bin:/mnt/c/Program Files (x86)/GNU/GnuPG/pub:/mnt/c/Program Files/Calibre2/:/mnt/c/Users/cassio/AppData/Local/Microsoft/WindowsApps:/mnt/c/Users/cassio/AppData/Local/GitHubDesktop/bin
|
||||||
|
|
||||||
Yarn version:
|
Yarn version:
|
||||||
1.22.4
|
1.22.4
|
||||||
@@ -14,7 +14,7 @@ Platform:
|
|||||||
linux x64
|
linux x64
|
||||||
|
|
||||||
Trace:
|
Trace:
|
||||||
Error: https://registry.yarnpkg.com/@types%2fqrcode-terminal: Not found
|
Error: https://registry.yarnpkg.com/@types%2fvdata-parser: Not found
|
||||||
at Request.params.callback [as _callback] (/usr/share/yarn/lib/cli.js:66987:18)
|
at Request.params.callback [as _callback] (/usr/share/yarn/lib/cli.js:66987:18)
|
||||||
at Request.self.callback (/usr/share/yarn/lib/cli.js:140748:22)
|
at Request.self.callback (/usr/share/yarn/lib/cli.js:140748:22)
|
||||||
at Request.emit (events.js:315:20)
|
at Request.emit (events.js:315:20)
|
||||||
@@ -34,6 +34,7 @@ npm manifest:
|
|||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "tsc",
|
"build": "tsc",
|
||||||
|
"watch": "tsc -w",
|
||||||
"start": "nodemon dist/server.js",
|
"start": "nodemon dist/server.js",
|
||||||
"dev:server": "ts-node-dev --respawn --transpile-only --ignore node_modules src/server.ts"
|
"dev:server": "ts-node-dev --respawn --transpile-only --ignore node_modules src/server.ts"
|
||||||
},
|
},
|
||||||
@@ -42,6 +43,7 @@ npm manifest:
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@sentry/node": "5.22.3",
|
"@sentry/node": "5.22.3",
|
||||||
"bcryptjs": "^2.4.3",
|
"bcryptjs": "^2.4.3",
|
||||||
|
"cookie-parser": "^1.4.5",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"date-fns": "^2.16.1",
|
"date-fns": "^2.16.1",
|
||||||
"dotenv": "^8.2.0",
|
"dotenv": "^8.2.0",
|
||||||
@@ -56,12 +58,14 @@ npm manifest:
|
|||||||
"sequelize-cli": "5",
|
"sequelize-cli": "5",
|
||||||
"sequelize-typescript": "^1.1.0",
|
"sequelize-typescript": "^1.1.0",
|
||||||
"socket.io": "^2.3.0",
|
"socket.io": "^2.3.0",
|
||||||
|
"vdata-parser": "^0.1.5",
|
||||||
"whatsapp-web.js": "^1.8.2",
|
"whatsapp-web.js": "^1.8.2",
|
||||||
"yup": "^0.29.3"
|
"yup": "^0.29.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/bcryptjs": "^2.4.2",
|
"@types/bcryptjs": "^2.4.2",
|
||||||
"@types/bluebird": "^3.5.32",
|
"@types/bluebird": "^3.5.32",
|
||||||
|
"@types/cookie-parser": "^1.4.2",
|
||||||
"@types/cors": "^2.8.7",
|
"@types/cors": "^2.8.7",
|
||||||
"@types/express": "^4.17.8",
|
"@types/express": "^4.17.8",
|
||||||
"@types/jsonwebtoken": "^8.5.0",
|
"@types/jsonwebtoken": "^8.5.0",
|
||||||
@@ -273,6 +277,13 @@ Lockfile:
|
|||||||
dependencies:
|
dependencies:
|
||||||
"@types/node" "*"
|
"@types/node" "*"
|
||||||
|
|
||||||
|
"@types/cookie-parser@^1.4.2":
|
||||||
|
version "1.4.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/cookie-parser/-/cookie-parser-1.4.2.tgz#e4d5c5ffda82b80672a88a4281aaceefb1bd9df5"
|
||||||
|
integrity sha512-uwcY8m6SDQqciHsqcKDGbo10GdasYsPCYkH3hVegj9qAah6pX5HivOnOuI3WYmyQMnOATV39zv/Ybs0bC/6iVg==
|
||||||
|
dependencies:
|
||||||
|
"@types/express" "*"
|
||||||
|
|
||||||
"@types/cors@^2.8.7":
|
"@types/cors@^2.8.7":
|
||||||
version "2.8.7"
|
version "2.8.7"
|
||||||
resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.7.tgz#ab2f47f1cba93bce27dfd3639b006cc0e5600889"
|
resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.7.tgz#ab2f47f1cba93bce27dfd3639b006cc0e5600889"
|
||||||
@@ -1030,6 +1041,14 @@ Lockfile:
|
|||||||
resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b"
|
resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b"
|
||||||
integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==
|
integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==
|
||||||
|
|
||||||
|
cookie-parser@^1.4.5:
|
||||||
|
version "1.4.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/cookie-parser/-/cookie-parser-1.4.5.tgz#3e572d4b7c0c80f9c61daf604e4336831b5d1d49"
|
||||||
|
integrity sha512-f13bPUj/gG/5mDr+xLmSxxDsB9DQiTIfhJS/sqjrmfAWiAN+x2O4i/XguTL9yDZ+/IFDanJ+5x7hC4CXT9Tdzw==
|
||||||
|
dependencies:
|
||||||
|
cookie "0.4.0"
|
||||||
|
cookie-signature "1.0.6"
|
||||||
|
|
||||||
cookie-signature@1.0.6:
|
cookie-signature@1.0.6:
|
||||||
version "1.0.6"
|
version "1.0.6"
|
||||||
resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c"
|
resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c"
|
||||||
@@ -4149,6 +4168,11 @@ Lockfile:
|
|||||||
resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
|
resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
|
||||||
integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=
|
integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=
|
||||||
|
|
||||||
|
vdata-parser@^0.1.5:
|
||||||
|
version "0.1.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/vdata-parser/-/vdata-parser-0.1.5.tgz#e57cf30065cf69d29a9d822e85fd2734c686bcfd"
|
||||||
|
integrity sha1-5XzzAGXPadKanYIuhf0nNMaGvP0=
|
||||||
|
|
||||||
whatsapp-web.js@^1.8.2:
|
whatsapp-web.js@^1.8.2:
|
||||||
version "1.8.2"
|
version "1.8.2"
|
||||||
resolved "https://registry.yarnpkg.com/whatsapp-web.js/-/whatsapp-web.js-1.8.2.tgz#b9059ca7cb70d6297c3cba954ccf1ce0c004d52e"
|
resolved "https://registry.yarnpkg.com/whatsapp-web.js/-/whatsapp-web.js-1.8.2.tgz#b9059ca7cb70d6297c3cba954ccf1ce0c004d52e"
|
||||||
|
|||||||
@@ -20,10 +20,8 @@ import {
|
|||||||
Button,
|
Button,
|
||||||
Card,
|
Card,
|
||||||
CardActions,
|
CardActions,
|
||||||
CardContent,
|
|
||||||
CardHeader,
|
CardHeader,
|
||||||
IconButton,
|
IconButton,
|
||||||
Typography,
|
|
||||||
} from "@material-ui/core";
|
} from "@material-ui/core";
|
||||||
import { Block, ExpandMore } from "@material-ui/icons";
|
import { Block, ExpandMore } from "@material-ui/icons";
|
||||||
|
|
||||||
@@ -233,8 +231,10 @@ const useStyles = makeStyles(theme => ({
|
|||||||
},
|
},
|
||||||
|
|
||||||
vcard: {
|
vcard: {
|
||||||
// display: "flex",
|
display: "flex",
|
||||||
|
backgroundColor: "inherit",
|
||||||
marginBottom: 10,
|
marginBottom: 10,
|
||||||
|
marginRight: 10,
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -416,50 +416,6 @@ const Ticket = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const parseVcard = vcard => {
|
|
||||||
var Re1 = /^(version|fn|title|org):(.+)$/i;
|
|
||||||
var Re2 = /^([^:;]+);([^:]+):(.+)$/;
|
|
||||||
var ReKey = /item\d{1,2}\./;
|
|
||||||
var fields = {};
|
|
||||||
|
|
||||||
vcard.split(/\r\n|\r|\n/).forEach(function (line) {
|
|
||||||
var results, key;
|
|
||||||
|
|
||||||
if (Re1.test(line)) {
|
|
||||||
results = line.match(Re1);
|
|
||||||
key = results[1].toLowerCase();
|
|
||||||
fields[key] = results[2];
|
|
||||||
} else if (Re2.test(line)) {
|
|
||||||
results = line.match(Re2);
|
|
||||||
key = results[1].replace(ReKey, "").toLowerCase();
|
|
||||||
|
|
||||||
var meta = {};
|
|
||||||
results[2]
|
|
||||||
.split(";")
|
|
||||||
.map(function (p, i) {
|
|
||||||
var match = p.match(/([a-z]+)=(.*)/i);
|
|
||||||
if (match) {
|
|
||||||
return [match[1], match[2]];
|
|
||||||
} else {
|
|
||||||
return ["TYPE" + (i === 0 ? "" : i), p];
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.forEach(function (p) {
|
|
||||||
meta[p[0]] = p[1];
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!fields[key]) fields[key] = [];
|
|
||||||
|
|
||||||
fields[key].push({
|
|
||||||
meta: meta,
|
|
||||||
value: results[3].split(";"),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return fields;
|
|
||||||
};
|
|
||||||
|
|
||||||
const checkMessageMedia = message => {
|
const checkMessageMedia = message => {
|
||||||
if (message.mediaType === "image") {
|
if (message.mediaType === "image") {
|
||||||
return (
|
return (
|
||||||
@@ -490,20 +446,22 @@ const Ticket = () => {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (message.mediaType === "vcard") {
|
if (message.mediaType === "vcard") {
|
||||||
const contactVcard = parseVcard(message.body);
|
|
||||||
|
|
||||||
console.log(contactVcard);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card className={classes.vcard} variant="outlined">
|
<Card className={classes.vcard} variant="outlined">
|
||||||
<CardHeader
|
<CardHeader
|
||||||
avatar={<Avatar aria-label="recipe" />}
|
avatar={
|
||||||
// action={<Button size="small">Enviar Mensagem</Button>}
|
<Avatar
|
||||||
title={contactVcard.fn}
|
aria-label="contact-avatar"
|
||||||
subheader={contactVcard.tel[0].meta.waid}
|
src={message.vcardContact?.profilePicUrl}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
title={message?.vcardContact?.name}
|
||||||
|
subheader={message?.vcardContact?.number}
|
||||||
/>
|
/>
|
||||||
<CardActions>
|
<CardActions>
|
||||||
<Button size="small">Adicionar Contato</Button>
|
<Button size="small" variant="contained">
|
||||||
|
Send Message
|
||||||
|
</Button>
|
||||||
</CardActions>
|
</CardActions>
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user