mirror of
https://github.com/cheveguerra/whatsapp-web.js.git
synced 2026-04-20 20:49:14 +00:00
feat: Send contacts (#395)
Introduces the ability to send contact cards. You can send Contacts directly or send a vCard string and it will be automatically parsed. If you'd like to disable this autoparse functionality, you can set `parseVCards: false` as an option while sending a message. close #293
This commit is contained in:
@@ -49,7 +49,7 @@ Take a look at [example.js](https://github.com/pedroslopez/whatsapp-web.js/blob/
|
|||||||
| Send media (video) | ✅ [(requires google chrome)](https://github.com/pedroslopez/whatsapp-web.js/issues/78#issuecomment-592723583) |
|
| Send media (video) | ✅ [(requires google chrome)](https://github.com/pedroslopez/whatsapp-web.js/issues/78#issuecomment-592723583) |
|
||||||
| Send stickers | _pending_ |
|
| Send stickers | _pending_ |
|
||||||
| Receive media (images/audio/video/documents) | ✅ |
|
| Receive media (images/audio/video/documents) | ✅ |
|
||||||
| Send contact cards | _pending_ |
|
| Send contact cards | ✅ |
|
||||||
| Send location | ✅ |
|
| Send location | ✅ |
|
||||||
| Receive location | ✅ |
|
| Receive location | ✅ |
|
||||||
| Message replies | ✅ |
|
| Message replies | ✅ |
|
||||||
|
|||||||
4
index.d.ts
vendored
4
index.d.ts
vendored
@@ -517,6 +517,8 @@ declare namespace WAWebJS {
|
|||||||
linkPreview?: boolean
|
linkPreview?: boolean
|
||||||
/** Send audio as voice message */
|
/** Send audio as voice message */
|
||||||
sendAudioAsVoice?: boolean
|
sendAudioAsVoice?: boolean
|
||||||
|
/** Automatically parse vCards and send them as contacts */
|
||||||
|
parseVCards?: boolean
|
||||||
/** Image or videos caption */
|
/** Image or videos caption */
|
||||||
caption?: string
|
caption?: string
|
||||||
/** Id of the message that is being quoted (or replied to) */
|
/** Id of the message that is being quoted (or replied to) */
|
||||||
@@ -549,7 +551,7 @@ declare namespace WAWebJS {
|
|||||||
static fromFilePath: (filePath: string) => MessageMedia
|
static fromFilePath: (filePath: string) => MessageMedia
|
||||||
}
|
}
|
||||||
|
|
||||||
export type MessageContent = string | MessageMedia | Location
|
export type MessageContent = string | MessageMedia | Location | Contact | Contact[]
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a Contact on WhatsApp
|
* Represents a Contact on WhatsApp
|
||||||
|
|||||||
@@ -420,6 +420,7 @@ class Client extends EventEmitter {
|
|||||||
* @typedef {Object} MessageSendOptions
|
* @typedef {Object} MessageSendOptions
|
||||||
* @property {boolean} [linkPreview=true] - Show links preview
|
* @property {boolean} [linkPreview=true] - Show links preview
|
||||||
* @property {boolean} [sendAudioAsVoice=false] - Send audio as voice message
|
* @property {boolean} [sendAudioAsVoice=false] - Send audio as voice message
|
||||||
|
* @property {boolean} [parseVCards=true] - Automatically parse vCards and send them as contacts
|
||||||
* @property {string} [caption] - Image or video caption
|
* @property {string} [caption] - Image or video caption
|
||||||
* @property {string} [quotedMessageId] - Id of the message that is being quoted (or replied to)
|
* @property {string} [quotedMessageId] - Id of the message that is being quoted (or replied to)
|
||||||
* @property {Contact[]} [mentions] - Contacts that are being mentioned in the message
|
* @property {Contact[]} [mentions] - Contacts that are being mentioned in the message
|
||||||
@@ -430,7 +431,7 @@ class Client extends EventEmitter {
|
|||||||
/**
|
/**
|
||||||
* Send a message to a specific chatId
|
* Send a message to a specific chatId
|
||||||
* @param {string} chatId
|
* @param {string} chatId
|
||||||
* @param {string|MessageMedia|Location} content
|
* @param {string|MessageMedia|Location|Contact|Array<Contact>} content
|
||||||
* @param {MessageSendOptions} [options] - Options used when sending the message
|
* @param {MessageSendOptions} [options] - Options used when sending the message
|
||||||
*
|
*
|
||||||
* @returns {Promise<Message>} Message that was just sent
|
* @returns {Promise<Message>} Message that was just sent
|
||||||
@@ -441,6 +442,7 @@ class Client extends EventEmitter {
|
|||||||
sendAudioAsVoice: options.sendAudioAsVoice,
|
sendAudioAsVoice: options.sendAudioAsVoice,
|
||||||
caption: options.caption,
|
caption: options.caption,
|
||||||
quotedMessageId: options.quotedMessageId,
|
quotedMessageId: options.quotedMessageId,
|
||||||
|
parseVCards: options.parseVCards === false ? false : true,
|
||||||
mentionedJidList: Array.isArray(options.mentions) ? options.mentions.map(contact => contact.id._serialized) : []
|
mentionedJidList: Array.isArray(options.mentions) ? options.mentions.map(contact => contact.id._serialized) : []
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -456,6 +458,12 @@ class Client extends EventEmitter {
|
|||||||
} else if (content instanceof Location) {
|
} else if (content instanceof Location) {
|
||||||
internalOptions.location = content;
|
internalOptions.location = content;
|
||||||
content = '';
|
content = '';
|
||||||
|
} else if(content instanceof Contact) {
|
||||||
|
internalOptions.contactCard = content.id._serialized;
|
||||||
|
content = '';
|
||||||
|
} else if(Array.isArray(content) && content.length > 0 && content[0] instanceof Contact) {
|
||||||
|
internalOptions.contactCardList = content.map(contact => contact.id._serialized);
|
||||||
|
content = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
const newMessage = await this.pupPage.evaluate(async (chatId, message, options, sendSeen) => {
|
const newMessage = await this.pupPage.evaluate(async (chatId, message, options, sendSeen) => {
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ exports.ExposeStore = (moduleRaidStr) => {
|
|||||||
window.Store.MediaUpload = window.mR.findModule('uploadMedia')[0];
|
window.Store.MediaUpload = window.mR.findModule('uploadMedia')[0];
|
||||||
window.Store.Cmd = window.mR.findModule('Cmd')[0].default;
|
window.Store.Cmd = window.mR.findModule('Cmd')[0].default;
|
||||||
window.Store.MediaTypes = window.mR.findModule('msgToMediaType')[0];
|
window.Store.MediaTypes = window.mR.findModule('msgToMediaType')[0];
|
||||||
|
window.Store.VCard = window.mR.findModule('vcardFromContactModel')[0];
|
||||||
window.Store.UserConstructor = window.mR.findModule((module) => (module.default && module.default.prototype && module.default.prototype.isServer && module.default.prototype.isUser) ? module.default : null)[0].default;
|
window.Store.UserConstructor = window.mR.findModule((module) => (module.default && module.default.prototype && module.default.prototype.isServer && module.default.prototype.isUser) ? module.default : null)[0].default;
|
||||||
window.Store.Validators = window.mR.findModule('findLinks')[0];
|
window.Store.Validators = window.mR.findModule('findLinks')[0];
|
||||||
window.Store.WidFactory = window.mR.findModule('createWid')[0];
|
window.Store.WidFactory = window.mR.findModule('createWid')[0];
|
||||||
@@ -78,6 +79,39 @@ exports.LoadUtils = () => {
|
|||||||
delete options.location;
|
delete options.location;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let vcardOptions = {};
|
||||||
|
if (options.contactCard) {
|
||||||
|
let contact = window.Store.Contact.get(options.contactCard);
|
||||||
|
vcardOptions = {
|
||||||
|
body: window.Store.VCard.vcardFromContactModel(contact).vcard,
|
||||||
|
type: 'vcard',
|
||||||
|
vcardFormattedName: contact.formattedName
|
||||||
|
};
|
||||||
|
delete options.contactCard;
|
||||||
|
} else if(options.contactCardList) {
|
||||||
|
let contacts = options.contactCardList.map(c => window.Store.Contact.get(c));
|
||||||
|
let vcards = contacts.map(c => window.Store.VCard.vcardFromContactModel(c));
|
||||||
|
vcardOptions = {
|
||||||
|
type: 'multi_vcard',
|
||||||
|
vcardList: vcards,
|
||||||
|
body: undefined
|
||||||
|
};
|
||||||
|
delete options.contactCardList;
|
||||||
|
} else if(options.parseVCards && typeof(content) === 'string' && content.startsWith('BEGIN:VCARD')) {
|
||||||
|
delete options.parseVCards;
|
||||||
|
try {
|
||||||
|
const parsed = window.Store.VCard.parseVcard(content);
|
||||||
|
if(parsed) {
|
||||||
|
vcardOptions = {
|
||||||
|
type: 'vcard',
|
||||||
|
vcardFormattedName: window.Store.VCard.vcardGetNameFromParsed(parsed)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} catch(_) {
|
||||||
|
// not a vcard
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (options.linkPreview) {
|
if (options.linkPreview) {
|
||||||
delete options.linkPreview;
|
delete options.linkPreview;
|
||||||
const link = window.Store.Validators.findLink(content);
|
const link = window.Store.Validators.findLink(content);
|
||||||
@@ -109,7 +143,8 @@ exports.LoadUtils = () => {
|
|||||||
type: 'chat',
|
type: 'chat',
|
||||||
...locationOptions,
|
...locationOptions,
|
||||||
...attOptions,
|
...attOptions,
|
||||||
...quotedMsgOptions
|
...quotedMsgOptions,
|
||||||
|
...vcardOptions
|
||||||
};
|
};
|
||||||
|
|
||||||
await window.Store.SendMessage.addAndSendMsgToChat(chat, message);
|
await window.Store.SendMessage.addAndSendMsgToChat(chat, message);
|
||||||
|
|||||||
Reference in New Issue
Block a user