Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,12 +153,13 @@ To send media
curl -i -X POST \
http://localhost:9876/v15.0/5549988290955/messages \
-H 'Content-Type: application/json' \
-H 'Authorization: 1' \
-d '{
"messaging_product": "whatsapp",
"to": "5549988290955",
"type": "image",
"image": {
"link" : "https://github.githubassets.com/favicons/favicon-dark.png"
"link" : "https://github.githubassets.com/favicons/favicon.png"
}
}'
```
Expand Down
33 changes: 29 additions & 4 deletions src/services/client_baileys.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { GroupMetadata, WAMessage, proto, delay, isJidGroup, jidNormalizedUser, AnyMessageContent } from 'baileys'
import { GroupMetadata, WAMessage, proto, delay, isJidGroup, jidNormalizedUser, AnyMessageContent, Contact as ContactBaileys } from 'baileys'
import fetch, { Response as FetchResponse } from 'node-fetch'
import { Incoming } from './incoming'
import { Listener } from './listener'
Expand Down Expand Up @@ -305,9 +305,22 @@ export class ClientBaileys implements Client {
})
if (!this.config.ignoreHistoryMessages) {
logger.info('Config import history messages %', this.phone)
this.event('messaging-history.set', async ({ messages, isLatest }: { messages: proto.IWebMessageInfo[]; isLatest?: boolean }) => {
logger.info('Importing history messages, is latest %s %s', isLatest, this.phone)
this.listener.process(this.phone, messages, 'history')
this.event('messaging-history.set', async ({ messages, isLatest, contacts }: { messages: proto.IWebMessageInfo[]; contacts: ContactBaileys[]; isLatest?: boolean }) => {
if (contacts) {
const { dataStore } = this.store!
await Promise.all(contacts.map(async (c: Partial<ContactBaileys>) => {
const cId = c.lid || c.id
if (cId && c.imgUrl) {
await dataStore.setImageUrl(cId, c.imgUrl)
}
return dataStore.setContact(c)
})
)
}
if (messages) {
logger.info('Importing history messages, is latest %s %s', isLatest, this.phone)
this.listener.process(this.phone, messages, 'history')
}
})
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
Expand Down Expand Up @@ -625,6 +638,18 @@ export class ClientBaileys implements Client {
remoteJid = key.remoteJid
}
if (remoteJid) {
if (key.fromMe) {
const { dataStore } = this.store!
logger.debug('Loading contact for %s...', remoteJid)
const contact = await dataStore.getContact(remoteJid)
logger.debug('Loaded contact for %s => %s', remoteJid, contact)
if (contact?.name) {
message['contactName'] = contact.name
}
if (contact?.verifiedName) {
message['contactBizName'] = contact?.verifiedName
}
}
const jid = await this.exists(remoteJid)
if (jid) {
try {
Expand Down
4 changes: 3 additions & 1 deletion src/services/data_store.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { GroupMetadata, makeInMemoryStore, WAMessage, WAMessageKey, WASocket } from 'baileys'
import { Contact, GroupMetadata, makeInMemoryStore, WAMessage, WAMessageKey, WASocket } from 'baileys'
import { Config } from './config'

export const dataStores: Map<string, DataStore> = new Map()
Expand Down Expand Up @@ -29,6 +29,8 @@ export type DataStore = ReturnType<typeof makeInMemoryStore> & {
loadImageUrl: (jid: string, sock: Partial<WASocket>) => Promise<string | undefined>
setGroupMetada: (jid: string, data: GroupMetadata) => Promise<void>
getGroupMetada: (jid: string) => Promise<GroupMetadata | undefined>
setContact: (contact: Partial<Contact>) => Promise<void>
getContact: (id: string) => Promise<Contact | undefined>
loadGroupMetada: (jid: string, sock: Partial<WASocket>) => Promise<GroupMetadata | undefined>
loadUnoId: (id: string) => Promise<string | undefined>
setStatus: (id: string, status: MessageStatus) => Promise<void>
Expand Down
22 changes: 21 additions & 1 deletion src/services/data_store_file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,16 +111,36 @@ const dataStoreFile = async (phone: string, config: Config): Promise<DataStore>
logger.debug('contacts.upsert %s', phone, JSON.stringify(contacts))
const { saveProfilePicture } = mediaStore
await Promise.all(contacts.map(async (c) => {
await dataStore.setContact(c)
return saveProfilePicture(c)
})
)
})
ev.on('contacts.update', async (contacts: Partial<Contact>[]) => {
logger.debug('contacts.update %s => %s', phone, JSON.stringify(contacts))
const { saveProfilePicture } = mediaStore
await Promise.all(contacts.map(async (c) => saveProfilePicture(c)))
await Promise.all(contacts.map(async (c: Partial<Contact>) => {
await dataStore.setContact(c)
return saveProfilePicture(c)
})
)
})
}
dataStore.setContact = async (contact: Partial<Contact>) => {
const id = jidToPhoneNumber(contact.id || contact.lid)
const newData: Partial<Contact> = {}
if (contact.name) {
newData.name = contact.name
}
if (contact.verifiedName) {
newData.verifiedName = contact.verifiedName
}
dataStore.contacts[id] = { ...(dataStore.contacts[id] || {}), ...newData }
}
dataStore.getContact = async (id: string) => {
const newId = jidToPhoneNumber(id)
return dataStore.contacts[newId]
}
const loadKey = async (id: string) => {
return keys.get(id)
}
Expand Down
19 changes: 18 additions & 1 deletion src/services/data_store_redis.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { proto, WAMessage, WAMessageKey, GroupMetadata } from 'baileys'
import { proto, WAMessage, WAMessageKey, GroupMetadata, Contact } from 'baileys'
import { DataStore, MessageStatus } from './data_store'
import { jidToPhoneNumber, phoneNumberToJid, isIndividualJid } from './transformer'
import { getDataStore, dataStores } from './data_store'
Expand All @@ -22,6 +22,8 @@ import {
getGroup,
delConfig,
setTemplates,
setContact,
getContact,
} from './redis'
import { Config } from './config'
import logger from './logger'
Expand Down Expand Up @@ -66,6 +68,21 @@ const dataStoreRedis = async (phone: string, config: Config): Promise<DataStore>
}
}
}
store.setContact = async (contact: Partial<Contact>) => {
const id = jidToPhoneNumber(contact.id || contact.lid)
const newData: Partial<Contact> = {}
if (contact.name) {
newData.name = contact.name
}
if (contact.verifiedName) {
newData.verifiedName = contact.verifiedName
}
return setContact(phone, id, newData)
}
store.getContact = async (id: string) => {
const newId = jidToPhoneNumber(id)
return getContact(phone, newId)
}
store.getGroupMetada = async (jid: string) => {
return getGroup(phone, jid)
}
Expand Down
4 changes: 2 additions & 2 deletions src/services/listener_baileys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,9 @@ export class ListenerBaileys implements Listener {
const store = await config.getStore(phone, config)
if (messageType && !['update', 'receipt'].includes(messageType)) {
i = await config.getMessageMetadata(i)
if (i.key && i.key) {
if (i.key && i.key.id) {
const idUno = uuid()
const idBaileys = i.key.id!
const idBaileys = i.key.id
await store?.dataStore.setUnoId(idBaileys, idUno)
await store?.dataStore.setKey(idUno, i.key)
await store?.dataStore.setKey(idBaileys, i.key)
Expand Down
18 changes: 17 additions & 1 deletion src/services/redis.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { createClient } from '@redis/client'
import { REDIS_URL, DATA_JID_TTL, DATA_TTL, SESSION_TTL, DATA_URL_TTL } from '../defaults'
import logger from './logger'
import { GroupMetadata } from 'baileys'
import { Contact, GroupMetadata } from 'baileys'
import { Webhook, configs } from './config'

export const BASE_KEY = 'unoapi-'
Expand Down Expand Up @@ -139,6 +139,10 @@ const connectCountKey = (phone: string, ordinal: number | string) => {
return `${BASE_KEY}connect-count:${phone}:${ordinal}`
}

const contactKey = (phone: string, id: string) => {
return `${BASE_KEY}contact:${phone}:${id}`
}

export const sessionStatusKey = (phone: string) => {
return `${BASE_KEY}status:${phone}`
}
Expand Down Expand Up @@ -222,6 +226,18 @@ export const setSessionStatus = async (phone: string, status: string) => {
await client.set(key, status)
}

export const getContact = async (phone: string, id: string): Promise<Contact | undefined> => {
const key = contactKey(phone, id)
const json = await redisGet(key)
return json ? JSON.parse(json) as Contact : undefined
}

export const setContact = async (phone: string, id: string, contact: Partial<Contact> | undefined ) => {
const key = contactKey(phone, id)
const currentContact = await getContact(phone, id) || {}
await client.set(key, JSON.stringify({ ...currentContact, ...(contact || {} )}))
}

export const getMessageStatus = async (phone: string, id: string) => {
const key = messageStatusKey(phone, id)
return redisGet(key)
Expand Down
2 changes: 1 addition & 1 deletion src/services/transformer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -464,7 +464,7 @@ export const fromBaileysMessageContent = (phone: string, payload: any, config?:
const binMessage = payload.update || payload.receipt || (messageType && payload.message && payload.message[messageType])
let profileName
if (fromMe) {
profileName = senderPhone
profileName = payload.contactBizName || payload.contactName || senderPhone
} else {
profileName = payload.verifiedBizName || payload.pushName || senderPhone
}
Expand Down
Loading