Skip to content

Commit

Permalink
feat: Added WPP.chat.setChatList function (#2498)
Browse files Browse the repository at this point in the history
  • Loading branch information
icleitoncosta authored Nov 18, 2024
1 parent b277004 commit 4969c66
Show file tree
Hide file tree
Showing 6 changed files with 210 additions and 5 deletions.
1 change: 1 addition & 0 deletions src/chat/functions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ export {
sendVCardContactMessage,
VCardContact,
} from './sendVCardContactMessage';
export { setChatList } from './setChatList';
export { setInputText } from './setInputText';
export { setNotes } from './setNotes';
export { starMessage, StarMessageReturn } from './starMessage';
Expand Down
163 changes: 163 additions & 0 deletions src/chat/functions/setChatList.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
/*!
* 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 * as webpack from '../../webpack';
import { Cmd } from '../../whatsapp';
import { wrapModuleFunction } from '../../whatsapp/exportModule';
import {
getShouldAppearInList,
isFilterExcludedFromSearchTreatmentInInboxFlow,
} from '../../whatsapp/functions';

/**
* Set custom Chat list in panel of whatsapp
* * @example
* ```javascript
* // Your custom list
* WPP.chat.setChatList('custom', ['[email protected]', '[email protected]']);
*
* // List only with unread chats
* WPP.chat.setChatList('unread');
*
* // List only with favorites chats
* WPP.chat.setChatList('favorites');
*
* // List only with groups chats
* WPP.chat.setChatList('group');
*
* // List only labels chat
* WPP.chat.setChatList('labels', '454545_labelId');
* ```
* @category Chat
*/
let allowList: string[] = [];
let filterType: string = 'all';

export enum FilterChatListTypes {
ALL = 'all',
CUSTOM = 'custom',
UNREAD = 'unread',
PERSONAL = 'personal',
NON_CONTACT = 'non_contact',
GROUP = 'group',
FAVORITES = 'favorites',
CONTACT = 'contact',
BUSINESS = 'business',
BROADCAST = 'broadcast',
LABELS = 'labels',
ASSIGNED_TO_YOU = 'assigned_to_you',
}
export async function setChatList(
type: FilterChatListTypes,
ids?: string | string[]
): Promise<{ type: FilterChatListTypes; list?: string[] }> {
filterType = type;
if (!type) {
throw new WPPError('send_type_filter', `Please send a valid type filter`);
} else if (type == FilterChatListTypes.LABELS && !ids) {
throw new WPPError('send_labelId', `Please send a valid label id`);
} else if (type == FilterChatListTypes.CUSTOM && !ids) {
throw new WPPError('send_ids', `Please send a valid ids`);
}
if (typeof ids == 'string') ids = [ids];
if (type == FilterChatListTypes.CUSTOM && ids) {
allowList = ids;
Cmd.trigger('set_active_filter', 'unread');
Cmd.trigger('set_active_filter');
return {
type: type as any,
list: allowList,
};
} else if (type == FilterChatListTypes.ALL) {
Cmd.trigger('set_active_filter');
return {
type: type as any,
};
} else if (type == FilterChatListTypes.LABELS) {
Cmd.trigger('set_active_filter', FilterChatListTypes.LABELS, ids![0]);
return {
type: type as any,
};
} else {
Cmd.trigger('set_active_filter', 'unread');
Cmd.trigger('set_active_filter', type);
return {
type: type as any,
};
}
}

webpack.onFullReady(applyPatch, 1000);

function applyPatch() {
wrapModuleFunction(getShouldAppearInList, (func, ...args) => {
const [chat] = args;

if (filterType === FilterChatListTypes.CUSTOM) {
if (allowList.includes(chat.id?.toString())) {
return true;
}
return false;
}
return func(...args);
});
/**
* If a custom list is set and the user clicks on 'favorites' or 'unread,'
* show the correct list, not just the allowed contacts.
*/
wrapModuleFunction(
isFilterExcludedFromSearchTreatmentInInboxFlow,
async (func, ...args) => {
const [type] = args;

if (type === FilterChatListTypes.LABELS) return func(...args);

if (filterType == FilterChatListTypes.CUSTOM) {
filterType = FilterChatListTypes.ALL;
Cmd.trigger('set_active_filter', 'default');
Cmd.trigger('set_active_filter', type);
}

filterType = FilterChatListTypes.ALL;
Cmd.trigger('set_active_filter', type);
return func(...args);
}
);
}

/**
* Custom Wrap function with the callback
*
* This is not the best way to fix the wrapper for this function;
* I need to improve it soon. However, the idea is to make it work.
* Due to the lack of time and the urgency in the WhatsApp groups,
* I'm committing it this way to provide a quick solution.
*/
export function wrapShouldAppearFunction<TFunc extends (...args: any[]) => any>(
func: TFunc,
callback: (func: TFunc, ...args: Parameters<TFunc>) => ReturnType<TFunc>
): TFunc {
const wrappedFunc: any = (...args: Parameters<TFunc>) => {
return callback(func, ...args);
};
Object.defineProperties(
wrappedFunc,
Object.getOwnPropertyDescriptors(getShouldAppearInList)
);

return wrappedFunc as TFunc;
}
17 changes: 12 additions & 5 deletions src/whatsapp/exportModule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

import Debug from 'debug';

import { wrapShouldAppearFunction } from '../chat/functions/setChatList';
import { trackException } from '../gtag';
import { InferArgs, InferReturn, wrapFunction } from '../util';
import * as webpack from '../webpack';
Expand Down Expand Up @@ -267,11 +268,17 @@ export function wrapModuleFunction<TFunc extends (...args: any[]) => any>(
}

const baseModule = parts.reduce((a, b) => a?.[b], module);

baseModule[functionName] = wrapFunction(
func.bind(baseModule) as TFunc,
callback
);
if (functionName == 'getShouldAppearInList') {
baseModule[functionName] = wrapShouldAppearFunction(
func.bind(baseModule) as TFunc,
callback
);
} else {
baseModule[functionName] = wrapFunction(
func.bind(baseModule) as TFunc,
callback
);
}

moduleIdMap.set(baseModule[functionName], moduleId);
functionPathMap.set(baseModule[functionName], functionPath);
Expand Down
1 change: 1 addition & 0 deletions src/whatsapp/functions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ export * from './handleSingleMsg';
export * from './initializeAltDeviceLinking';
export * from './isAnimatedWebp';
export * from './isAuthenticated';
export * from './isFilterExcludedFromSearchTreatmentInInboxFlow';
export * from './isRegistered';
export * from './isUnreadTypeMsg';
export * from './isWid';
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*!
* Copyright 2024 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 { exportModule } from '../exportModule';

export declare function isFilterExcludedFromSearchTreatmentInInboxFlow(
type?: string
): void;

exportModule(
exports,
{
isFilterExcludedFromSearchTreatmentInInboxFlow:
'isFilterExcludedFromSearchTreatmentInInboxFlow',
},
(m) => m.isFilterExcludedFromSearchTreatmentInInboxFlow
);
3 changes: 3 additions & 0 deletions src/whatsapp/misc/Cmd.ts
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,9 @@ export declare class CmdClass extends EventEmitter {
showMerchantDetailsEntityTypePopup(e?: any, t?: any): void;
showCountrySelector(e?: any, t?: any, r?: any): void;
toggleStickerMaker(): void;
setActiveFilter(
type?: 'unread' | 'favorites' | 'personal' | 'assigned_to_you' | 'labels'
): Promise<void>;
}

/** @whatsapp 88102
Expand Down

0 comments on commit 4969c66

Please sign in to comment.