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

feat: Added newsletter functions (close #1365) #1386

Merged
merged 20 commits into from
Oct 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
19cf314
feat: Exported deleteNewsletter function
icleitoncosta Sep 23, 2023
fe24a52
feat: Added WPP.newsletter.destroy function
icleitoncosta Sep 23, 2023
9afa10d
feat: Added Newsletter store
icleitoncosta Sep 23, 2023
43e4380
feat: Exported function msgDataFromMsgModel
icleitoncosta Sep 23, 2023
8ea69fe
feat: Exported updateNewsletterMsgRecord function
icleitoncosta Sep 23, 2023
1dc2e2d
feat: Exported sendNewsletterMessageJob function
icleitoncosta Sep 23, 2023
8a2dc43
feat: Added support for send msg to newsletter
icleitoncosta Sep 23, 2023
900cedf
feat: Exported createNewsletterQuery function
icleitoncosta Sep 25, 2023
5774234
feat: Added WPP.newslleter.create function
icleitoncosta Sep 25, 2023
ffb2cb5
feat: Exported uploadMedia function
icleitoncosta Sep 26, 2023
b71a561
fix: Fixed send ptv message (close #1343)
icleitoncosta Sep 26, 2023
8ecca60
fix: Update minimal version whatsapp to >=2.2321.6-beta
icleitoncosta Sep 26, 2023
4df7c17
chore: Added compatibility for WhatsApp < 2.2326.x
icleitoncosta Sep 26, 2023
eeec327
feat: Exported queryNewsletterMetadataByJid function
icleitoncosta Sep 27, 2023
21c739f
feat: Exported editNewsletterMetadataAction function
icleitoncosta Sep 27, 2023
02e3d03
feat: Added WPP.newsletter.edit function
icleitoncosta Sep 27, 2023
a92c3c8
feat: Exported muteNewsletter function
icleitoncosta Sep 27, 2023
e95f376
feat: Exported unmuteNewsletter function
icleitoncosta Sep 27, 2023
2b45678
feat: Added WPP.newsletter.mute function
icleitoncosta Sep 27, 2023
146cf29
chore: Improved image convertion
edgardmessias Oct 8, 2023
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
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,6 @@
"webpack-cli": "^5.1.4"
},
"engines": {
"whatsapp-web": ">=2.2245.8-beta"
"whatsapp-web": ">=2.2321.6-beta"
}
}
9 changes: 7 additions & 2 deletions src/assert/assertChat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

import { chat as Chat } from '../';
import { WPPError } from '../util';
import { ChatModel, Wid } from '../whatsapp';
import { ChatModel, NewsletterStore, Wid } from '../whatsapp';

export class InvalidChat extends WPPError {
constructor(readonly id: string | { _serialized: string }) {
Expand All @@ -35,7 +35,12 @@ export async function assertFindChat(id: string | Wid): Promise<ChatModel> {
}

export function assertGetChat(id: string | Wid): ChatModel {
const chat = (Chat as any).get(id);
let chat = null;
if (id.toString().includes('newsletter')) {
edgardmessias marked this conversation as resolved.
Show resolved Hide resolved
chat = NewsletterStore.get(id);
} else {
chat = (Chat as any).get(id);
}

if (!chat) {
throw new InvalidChat(id);
Expand Down
10 changes: 7 additions & 3 deletions src/chat/functions/get.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*!
* Copyright 2021 WPPConnect Team
* Copyright 2023 WPPConnect Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -15,7 +15,7 @@
*/

import { assertWid } from '../../assert';
import { ChatModel, ChatStore, Wid } from '../../whatsapp';
import { ChatModel, ChatStore, NewsletterStore, Wid } from '../../whatsapp';

/**
* Find a chat by id
Expand All @@ -24,5 +24,9 @@ import { ChatModel, ChatStore, Wid } from '../../whatsapp';
*/
export function get(chatId: string | Wid): ChatModel | undefined {
const wid = assertWid(chatId);
return ChatStore.get(wid);
if (wid.server === 'newsletter') {
return NewsletterStore.get(wid);
} else {
return ChatStore.get(wid);
}
}
51 changes: 15 additions & 36 deletions src/chat/functions/sendFileMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,8 @@ import { wrapModuleFunction } from '../../whatsapp/exportModule';
import {
generateVideoThumbsAndDuration,
isAnimatedWebp,
processRawAudioVideo,
processRawMedia,
processRawSticker,
uploadMedia,
} from '../../whatsapp/functions';
import {
defaultSendMessageOptions,
Expand Down Expand Up @@ -106,10 +105,6 @@ export interface AudioMessageOptions extends FileMessageOptions {
waveform?: boolean;
}

export interface PushToVideoMessageOptions extends FileMessageOptions {
type: 'ptv';
}

export interface DocumentMessageOptions
extends FileMessageOptions,
MessageButtonsOptions {
Expand All @@ -132,6 +127,7 @@ export interface VideoMessageOptions
MessageButtonsOptions {
type: 'video';
isGif?: boolean;
isPtv?: boolean;
}

/**
Expand Down Expand Up @@ -216,7 +212,8 @@ export interface VideoMessageOptions
* '[number]@c.us',
* 'data:application/msword;base64,<a long base64 file...>',
* {
* type: 'ptv',
* type: 'video',
* isPtv: true,
* }
* );
* ```
Expand All @@ -233,7 +230,6 @@ export async function sendFileMessage(
| ImageMessageOptions
| VideoMessageOptions
| StickerMessageOptions
| PushToVideoMessageOptions
): Promise<SendMessageReturn> {
options = {
...defaultSendMessageOptions,
Expand All @@ -258,7 +254,6 @@ export async function sendFileMessage(
isPtt?: boolean;
asDocument?: boolean;
asGif?: boolean;
isPtv?: boolean;
isAudio?: boolean;
asSticker?: boolean;
precomputedFields?: {
Expand All @@ -279,8 +274,6 @@ export async function sendFileMessage(
isViewOnce = options.isViewOnce;
} else if (options.type === 'video') {
rawMediaOptions.asGif = options.isGif;
} else if (options.type === 'ptv') {
rawMediaOptions.isPtv = true;
} else if (options.type === 'document') {
rawMediaOptions.asDocument = true;
} else if (options.type === 'sticker') {
Expand Down Expand Up @@ -309,6 +302,11 @@ export async function sendFileMessage(
}

await mediaPrep.waitForPrep();
if ((options as any)?.isPtv) {
(mediaPrep as any)._mediaData.type = 'ptv';
(mediaPrep as any)._mediaData.fullHeight = 1128;
(mediaPrep as any)._mediaData.fullWidth = 1128;
}

debug(`sending message (${options.type}) with id ${rawMessage.id}`);
const sendMsgResult = mediaPrep.sendToChat(chat, {
Expand Down Expand Up @@ -432,32 +430,13 @@ webpack.onReady(() => {
return result;
});

wrapModuleFunction(processRawMedia, async (func, ...args) => {
wrapModuleFunction(uploadMedia, async (func, ...args) => {
const [data] = args;

let result = await func(...args);
if ((args as any)[1]?.isPtv) {
result = await (processRawAudioVideo(
data as any,
false,
null,
false,
null,
data.type(),
true
) as any);
}

return result;
});

wrapModuleFunction(processRawAudioVideo, async (func, ...args) => {
const [data] = args;
const result = await func(...args);

if (data.type() === 'video/mp4' && args[6]) {
result.type = 'ptv';
if ((data as any).mediaType == 'ptv') {
(data as any).mediaType = 'video';
return await func(data);
} else {
return await func(...args);
}
return result;
});
});
35 changes: 33 additions & 2 deletions src/chat/functions/sendRawMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,16 @@
import Debug from 'debug';

import { assertFindChat, assertGetChat } from '../../assert';
import { WPPError } from '../../util';
import { MsgModel } from '../../whatsapp';
import { ACK } from '../../whatsapp/enums';
import {
addAndSendMessageEdit,
addAndSendMsgToChat,
addNewsletterMsgsRecords,
msgDataFromMsgModel,
sendNewsletterMessageJob,
updateNewsletterMsgRecord,
} from '../../whatsapp/functions';
import {
defaultSendMessageOptions,
Expand Down Expand Up @@ -60,7 +67,32 @@ export async function sendRawMessage(

debug(`sending message (${rawMessage.type}) with id ${rawMessage.id}`);
let result = null as any;
if (rawMessage.type === 'protocol' && rawMessage.subtype === 'message_edit') {
if (chat?.isNewsletter) {
if (rawMessage.type !== ('chat' || 'image' || 'video'))
throw new WPPError(
'type_not_valid_for_newsletter',
'Please, send a valid type for send message to newsletter. Valdi types: "chat", "image", "video"'
);
const msg = new MsgModel(rawMessage as any);
await addNewsletterMsgsRecords([await msgDataFromMsgModel(msg)]);
const resultNewsletter = await sendNewsletterMessageJob({
msgData: rawMessage,
newsletterJid: chat.id.toString(),
type: rawMessage.type == 'chat' ? 'text' : 'media',
});
chat.msgs.add(msg);

if (resultNewsletter.success) {
msg.t = resultNewsletter.ack.t;
msg.serverId = resultNewsletter.serverId;
}
msg.updateAck(ACK.SENT, true);
await updateNewsletterMsgRecord(msg);
result = [msg, 'OK'];
} else if (
rawMessage.type === 'protocol' &&
rawMessage.subtype === 'message_edit'
) {
const msg = await getMessageById(rawMessage.protocolMessageKey);
await addAndSendMessageEdit(msg, rawMessage);
result = [await getMessageById(rawMessage.protocolMessageKey), null];
Expand All @@ -70,7 +102,6 @@ export async function sendRawMessage(
debug(`message ${rawMessage.id} queued`);

const message = await result[0];

if (options.waitForAck) {
debug(`waiting ack for ${rawMessage.id}`);

Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export * as labels from './labels';
export * as profile from './profile';
export * as status from './status';
export * as util from './util';
export * as newsletter from './newsletter';
export * as whatsapp from './whatsapp';
export * as order from './order';

Expand Down
71 changes: 71 additions & 0 deletions src/newsletter/functions/create.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*!
* Copyright 2023 WPPConnect Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import { blobToBase64, convertToFile, downloadImage } from '../../util';
import { createNewsletterQuery } from '../../whatsapp/functions';

export interface ResultCreateNewsletter {
idJid: string;
inviteCode: string;
inviteLink: string;
name: string;
state: string;
subscribersCount: number;
description: string | null;
timestamp: number;
}

/**
* Create a newsletter
*
* @example
* ```javascript
* // To edit name
* WPP.newsletter.create('Name for your newsletter', {
* description: 'Description for that',
* picture: '<base64_string',
* });
* ```
* @category Newsletter
*/
export async function create(
name: string,
opts: { description?: string; picture?: string }
): Promise<ResultCreateNewsletter> {
let pic = undefined;
if (opts?.picture) {
const file = await convertToFile(opts.picture);
pic = await blobToBase64(file);
({ data: pic } = await downloadImage(pic, 'image/jpeg'));
}
const result = await createNewsletterQuery({
name: name,
description: opts?.description || null,
picture: pic || null,
});

return {
idJid: result?.idJid,
inviteCode: result?.newsletterInviteLinkMetadataMixin.inviteCode,
inviteLink: `https://whatsapp.com/channel/${result?.newsletterInviteLinkMetadataMixin.inviteCode}`,
name: result?.newsletterNameMetadataMixin?.nameElementValue,
state: result?.newsletterStateMetadataMixin?.stateType,
subscribersCount:
result?.newsletterSubscribersMetadataMixin.subscribersCount,
description: opts?.description || null,
timestamp: result?.newsletterCreationTimeMetadataMixin?.creationTimeValue,
};
}
41 changes: 41 additions & 0 deletions src/newsletter/functions/destroy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*!
* Copyright 2023 WPPConnect Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import { WPPError } from '../../util';
import { deleteNewsletter } from '../../whatsapp/functions';

/**
* Delete a newsletter
*
* @example
* ```javascript
* const code = WPP.newsletter.destroy('[newsletter-id]@newsletter');
* ```
*
* @category Newsletter
*/
export async function destroy(id: string): Promise<boolean> {
if (!id || !id.includes('newsletter'))
throw new WPPError(
'send_correctly_newsletter_id',
'Please, send the correct newsletter ID.'
);
try {
return await deleteNewsletter(id);
} catch (error) {
return false;
}
}
Loading