Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(meta): property to reply to messages #1118

Open
wants to merge 1 commit into
base: builderbot
Choose a base branch
from
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
4 changes: 2 additions & 2 deletions packages/bot/src/core/coreClass.ts
Original file line number Diff line number Diff line change
Expand Up @@ -683,8 +683,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