Skip to content

Commit

Permalink
Merge pull request #1118 from Juank2001/builderbot
Browse files Browse the repository at this point in the history
fix(meta): property to reply to messages
  • Loading branch information
leifermendez authored Feb 24, 2025
2 parents c023160 + 10c0fd9 commit ca57ff6
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 50 deletions.
4 changes: 2 additions & 2 deletions packages/bot/src/core/coreClass.ts
Original file line number Diff line number Diff line change
Expand Up @@ -684,8 +684,8 @@ class CoreClass<P extends ProviderClass = any, D extends MemoryDB = any> extends
answer !== '__end_flow__'
) {
if (answer !== '__capture_only_intended__') {
await this.provider.sendMessage(numberOrId, answer, ctxMessage)
this.emit('send_message', { ...ctxMessage, from: numberOrId, answer })
const respMessage = await this.provider.sendMessage(numberOrId, answer, ctxMessage)
this.emit('send_message', { ...ctxMessage, from: numberOrId, answer, respMessage })
}
}
await this.database.save({ ...ctxMessage, from: numberOrId })
Expand Down
2 changes: 1 addition & 1 deletion packages/bot/src/core/eventEmitterClass.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { EventEmitter } from 'node:events'
import type { TContext } from '../types'

export type HostEventTypes = {
send_message: [arg1: TContext & { from: string; answer: string | string[] }]
send_message: [arg1: TContext & { from: string; answer: string | string[]; respMessage: any }]
notice: [arg1: { title: string; instructions: string[] }]
}

Expand Down
37 changes: 25 additions & 12 deletions packages/provider-meta/__tests__/provider.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ describe('#MetaProvider', () => {
// Arrange
const fakeRecipient = '1234567890'
const fakeMessage = 'Hello, World!'
metaProvider.sendMessageMeta = jest.fn()
metaProvider.sendMessageMeta = jest.fn() as never

// Act
await metaProvider.sendText(fakeRecipient, fakeMessage)
Expand Down Expand Up @@ -192,7 +192,7 @@ describe('#MetaProvider', () => {
long_number: '123.456',
lat_number: '78.90',
}
metaProvider.sendMessageMeta = jest.fn()
metaProvider.sendMessageMeta = jest.fn() as never

// Act
await metaProvider.sendLocation(fakeRecipient, fakeLocalization)
Expand All @@ -217,7 +217,7 @@ describe('#MetaProvider', () => {
// Arrange
const fakeRecipient = '1234567890'
const fakeText = 'Please share your location'
metaProvider.sendMessageMeta = jest.fn()
metaProvider.sendMessageMeta = jest.fn() as never

// Act
await metaProvider.sendLocationRequest(fakeRecipient, fakeText)
Expand Down Expand Up @@ -250,7 +250,7 @@ describe('#MetaProvider', () => {
emoji: '😄',
}

metaProvider.sendMessageMeta = jest.fn()
metaProvider.sendMessageMeta = jest.fn() as never

// Act
await metaProvider.sendReaction(fakeRecipient, fakeReaction)
Expand All @@ -275,7 +275,7 @@ describe('#MetaProvider', () => {
const fakeRecipient = '1234567890'
const fakePathVideo: any = 'path/to/audio.mp3'

metaProvider.sendMessageMeta = jest.fn()
metaProvider.sendMessageMeta = jest.fn() as never

// Act
await metaProvider.sendAudio(fakeRecipient, fakePathVideo)
Expand Down Expand Up @@ -341,7 +341,7 @@ describe('#MetaProvider', () => {
const fakeMimeType = 'application/pdf'
const fakeNameOriginal = 'file.pdf'

metaProvider.sendMessageMeta = jest.fn()
metaProvider.sendMessageMeta = jest.fn() as never

const formDataMock = {
append: jest.fn(),
Expand Down Expand Up @@ -380,14 +380,18 @@ describe('#MetaProvider', () => {
const fakeRecipient = '1234567890'
const fakeMessage = 'Hello, world!'
const options = {}
const context = undefined
jest.spyOn(metaProvider, 'sendText')
jest.spyOn(metaProvider, 'sendButtons')
jest.spyOn(metaProvider, 'sendMedia')

metaProvider.sendMessageMeta = jest.fn() as never

// Act
await metaProvider.sendMessage(fakeRecipient, fakeMessage, options)
await metaProvider.sendMessage(fakeRecipient, fakeMessage, options, context)

// Assert
expect(metaProvider.sendText).toHaveBeenCalledWith(fakeRecipient, fakeMessage)
expect(metaProvider.sendText).toHaveBeenCalledWith(fakeRecipient, fakeMessage, context)
expect(metaProvider.sendButtons).not.toHaveBeenCalled()
expect(metaProvider.sendMedia).not.toHaveBeenCalled()
})
Expand Down Expand Up @@ -416,17 +420,26 @@ describe('#MetaProvider', () => {
// Arrange
const fakeRecipient = '1234567890'
const fakeMessage = 'Here is a media file'
const fakeMedia = 'path/to/media.jpg'
const fakeMedia = 'https://example.com/video.mp4'
const fakeOptions = { media: fakeMedia }
const context = undefined

const fileDownloaded = 'path/to/downloaded/audio.mp3'
;(utils.generalDownload as jest.MockedFunction<typeof utils.generalDownload>).mockResolvedValue(
fileDownloaded
)
jest.spyOn(mime, 'lookup').mockReturnValue('video/mp4')
jest.spyOn(metaProvider, 'sendButtons')
jest.spyOn(metaProvider, 'sendText')
jest.spyOn(metaProvider, 'sendMedia').mockResolvedValue()
jest.spyOn(metaProvider, 'sendMedia') //.mockResolvedValue()

metaProvider.sendMessageMeta = jest.fn() as never

// Act
await metaProvider.sendMessage(fakeRecipient, fakeMessage, fakeOptions)
await metaProvider.sendMessage(fakeRecipient, fakeMessage, fakeOptions, context)

// Assert
expect(metaProvider.sendMedia).toHaveBeenCalledWith(fakeRecipient, fakeMessage, fakeMedia)
expect(metaProvider.sendMedia).toHaveBeenCalledWith(fakeRecipient, fakeMessage, fakeMedia, context)
expect(metaProvider.sendText).not.toHaveBeenCalled()
expect(metaProvider.sendButtons).not.toHaveBeenCalled()
})
Expand Down
22 changes: 11 additions & 11 deletions packages/provider-meta/src/interface/meta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ import type { TextMessageBody, Reaction, Localization, Message, SaveFileOptions,
export interface MetaInterface {
sendMessageMeta: (body: TextMessageBody) => void
sendMessageToApi: (body: TextMessageBody) => Promise<any>
sendText: (to: string, message: string) => Promise<any>
sendImage: (to: string, mediaInput: string | null, caption: string) => Promise<any>
sendImageUrl: (to: string, url: string, caption: string) => Promise<void>
sendVideo: (to: string, pathVideo: string | null, caption: string) => Promise<any>
sendVideoUrl: (to: string, url: string, caption: string) => Promise<void>
sendMedia: (to: string, text: string, mediaInput: string) => Promise<any>
sendText: (to: string, message: string, context: string | null) => Promise<any>
sendImage: (to: string, mediaInput: string | null, caption: string, context: string | null) => Promise<any>
sendImageUrl: (to: string, url: string, caption: string, context: string | null) => Promise<void>
sendVideo: (to: string, pathVideo: string | null, caption: string, context: string | null) => Promise<any>
sendVideoUrl: (to: string, url: string, caption: string, context: string | null) => Promise<void>
sendMedia: (to: string, text: string, mediaInput: string, context: string | null) => Promise<any>
sendList: (to: string, list: MetaList) => Promise<any>
sendListComplete: (
to: string,
Expand Down Expand Up @@ -42,11 +42,11 @@ export interface MetaInterface {
) => Promise<void>
sendContacts: (to: string, contact: any[]) => Promise<any>
sendCatalog: (number: any, bodyText: any, itemCatalogId: any) => Promise<any>
sendMessage: (number: string, message: string, options?: SendOptions) => Promise<any>
sendMessage: (number: string, message: string, options?: SendOptions, context?: string) => Promise<any>
sendReaction: (number: string, react: Reaction) => Promise<any>
sendLocation: (to: string, localization: Localization) => Promise<any>
sendLocationRequest: (to: string, bodyText: string) => Promise<any>
sendLocation: (to: string, localization: Localization, context: string | null) => Promise<any>
sendLocationRequest: (to: string, bodyText: string, context: string | null) => Promise<any>
saveFile: (ctx: Partial<Message & BotContext>, options?: SaveFileOptions) => Promise<string>
sendFile: (to: string, mediaInput: string | null, caption: string) => Promise<any>
sendAudio: (to: string, fileOpus: string) => void
sendFile: (to: string, mediaInput: string | null, caption: string, context: string | null) => Promise<any>
sendAudio: (to: string, fileOpus: string, context: string | null) => void
}
57 changes: 35 additions & 22 deletions packages/provider-meta/src/meta/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ class MetaProvider extends ProviderClass<MetaInterface> implements MetaInterface
},
]

sendImage = async (to: string, mediaInput = null, caption: string) => {
sendImage = async (to: string, mediaInput = null, caption: string, context = null) => {
to = parseMetaNumber(to)
if (!mediaInput) throw new Error(`MEDIA_INPUT_NULL_: ${mediaInput}`)

Expand Down Expand Up @@ -198,12 +198,13 @@ class MetaProvider extends ProviderClass<MetaInterface> implements MetaInterface
caption,
},
}
if (context) body.context = context
return this.sendMessageMeta(body)
}

sendImageUrl = async (to: string, url: string, caption = '') => {
sendImageUrl = async (to: string, url: string, caption = '', context = null) => {
to = parseMetaNumber(to)
const body = {
const body: TextMessageBody = {
messaging_product: 'whatsapp',
recipient_type: 'individual',
to,
Expand All @@ -213,10 +214,11 @@ class MetaProvider extends ProviderClass<MetaInterface> implements MetaInterface
caption,
},
}
if (context) body.context = context
return this.sendMessageMeta(body)
}

sendVideo = async (to: string, pathVideo = null, caption: string) => {
sendVideo = async (to: string, pathVideo = null, caption: string, context = null) => {
to = parseMetaNumber(to)
if (!pathVideo) throw new Error(`MEDIA_INPUT_NULL_: ${pathVideo}`)

Expand All @@ -239,7 +241,7 @@ class MetaProvider extends ProviderClass<MetaInterface> implements MetaInterface
}
)

const body = {
const body: TextMessageBody = {
messaging_product: 'whatsapp',
to,
type: 'video',
Expand All @@ -248,12 +250,13 @@ class MetaProvider extends ProviderClass<MetaInterface> implements MetaInterface
caption,
},
}
if (context) body.context = context
return this.sendMessageMeta(body)
}

sendVideoUrl = async (to: string, url: string, caption = '') => {
sendVideoUrl = async (to: string, url: string, caption = '', context = null) => {
to = parseMetaNumber(to)
const body = {
const body: TextMessageBody = {
messaging_product: 'whatsapp',
recipient_type: 'individual',
to,
Expand All @@ -263,22 +266,23 @@ class MetaProvider extends ProviderClass<MetaInterface> implements MetaInterface
caption,
},
}
if (context) body.context = context
return this.sendMessageMeta(body)
}

sendMedia = async (to: string, text = '', mediaInput: string) => {
sendMedia = async (to: string, text = '', mediaInput: string, context = null) => {
to = parseMetaNumber(to)
const fileDownloaded = await utils.generalDownload(mediaInput)
const mimeType = mime.lookup(fileDownloaded)
mediaInput = fileDownloaded
if (mimeType.includes('image')) return this.sendImage(to, mediaInput, text)
if (mimeType.includes('video')) return this.sendVideo(to, fileDownloaded, text)
if (mimeType.includes('image')) return this.sendImage(to, mediaInput, text, context)
if (mimeType.includes('video')) return this.sendVideo(to, fileDownloaded, text, context)
if (mimeType.includes('audio')) {
const fileOpus = await utils.convertAudio(mediaInput, 'mp3')
return this.sendAudio(to, fileOpus)
return this.sendAudio(to, fileOpus, context)
}

return this.sendFile(to, mediaInput, text)
return this.sendFile(to, mediaInput, text, context)
}

sendList = async (to: string, list: MetaList) => {
Expand Down Expand Up @@ -522,15 +526,15 @@ class MetaProvider extends ProviderClass<MetaInterface> implements MetaInterface
return this.sendMessageMeta(body)
}

sendMessage = async (to: string, message: string, options?: SendOptions): Promise<any> => {
sendMessage = async (to: string, message: string, options?: SendOptions, context?: string): Promise<any> => {
to = parseMetaNumber(to)
options = { ...options, ...options['options'] }
if (options?.buttons?.length) return this.sendButtons(to, options.buttons, message)
if (options?.media) return this.sendMedia(to, message, options.media)
this.sendText(to, message)
if (options?.media) return this.sendMedia(to, message, options.media, context)
return this.sendText(to, message, context)
}

sendFile = async (to: string, mediaInput = null, caption: string) => {
sendFile = async (to: string, mediaInput = null, caption: string, context = null) => {
to = parseMetaNumber(to)
if (!mediaInput) throw new Error(`MEDIA_INPUT_NULL_: ${mediaInput}`)

Expand All @@ -556,7 +560,7 @@ class MetaProvider extends ProviderClass<MetaInterface> implements MetaInterface
}
)

const body = {
const body: TextMessageBody = {
messaging_product: 'whatsapp',
to: to,
type: 'document',
Expand All @@ -566,10 +570,11 @@ class MetaProvider extends ProviderClass<MetaInterface> implements MetaInterface
caption,
},
}
if (context) body.context = context
return this.sendMessageMeta(body)
}

sendAudio = async (to: string, pathVideo = null) => {
sendAudio = async (to: string, pathVideo = null, context = null) => {
to = parseMetaNumber(to)
if (!pathVideo) throw new Error(`MEDIA_INPUT_NULL_: ${pathVideo}`)

Expand Down Expand Up @@ -601,14 +606,15 @@ class MetaProvider extends ProviderClass<MetaInterface> implements MetaInterface
}
)

const body = {
const body: TextMessageBody = {
messaging_product: 'whatsapp',
to,
type: 'audio',
audio: {
id: mediaId,
},
}
if (context) body.context = context
return this.sendMessageMeta(body)
}

Expand Down Expand Up @@ -684,7 +690,7 @@ class MetaProvider extends ProviderClass<MetaInterface> implements MetaInterface
return this.sendMessageMeta(body)
}

sendText = async (to: string, message: string) => {
sendText = async (to: string, message: string, context = null) => {
to = parseMetaNumber(to)
const body: TextMessageBody = {
messaging_product: 'whatsapp',
Expand All @@ -696,11 +702,17 @@ class MetaProvider extends ProviderClass<MetaInterface> implements MetaInterface
body: message,
},
}
if (context) body.context = context
return this.sendMessageMeta(body)
}

sendMessageMeta = (body: TextMessageBody): void => {
return this.queue.add(() => this.sendMessageToApi(body))
sendMessageMeta = (body: TextMessageBody): Promise<any> => {
return new Promise((resolve) =>
this.queue.add(async () => {
const resp = await this.sendMessageToApi(body)
resolve(resp)
})
)
}

sendMessageToApi = async (body: TextMessageBody): Promise<any> => {
Expand All @@ -713,6 +725,7 @@ class MetaProvider extends ProviderClass<MetaInterface> implements MetaInterface
Authorization: `Bearer ${this.globalVendorArgs.jwtToken}`,
},
})
response.data.payload = body
return response.data
} catch (error) {
console.error(error.message)
Expand Down
18 changes: 16 additions & 2 deletions packages/provider-meta/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,17 @@ interface Video {
link?: string
}

export class File {
mime_type?: string
sha256?: string
id?: string
voice?: boolean
animated?: boolean
filename?: string
caption?: string
link?: string
}

interface TemplateMessage {
name: string
language: {
Expand Down Expand Up @@ -143,10 +154,13 @@ export interface TextMessageBody {
preview_url: boolean
body: string
}
image?: Image
video?: Video
image?: File
video?: File
audio?: File
document?: File
interactive?: any
contacts?: any[]
context?: string
template?: TemplateMessage
}

Expand Down

0 comments on commit ca57ff6

Please sign in to comment.