Skip to content

Commit

Permalink
feat: Added send buttons for text message
Browse files Browse the repository at this point in the history
  • Loading branch information
edgardmessias committed Sep 17, 2021
1 parent 01b9eeb commit 332a8fe
Show file tree
Hide file tree
Showing 7 changed files with 117 additions and 32 deletions.
91 changes: 72 additions & 19 deletions src/chat/Chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,13 @@ import Emittery from 'emittery';
import { assertFindChat, assertGetChat, assertWid } from '../assert';
import * as webpack from '../webpack';
import {
ButtonCollection,
ChatModel,
ChatStore,
ClockSkew,
Constants,
MsgKey,
ReplyButtonModel,
UserPrefs,
Wid,
} from '../whatsapp';
Expand All @@ -33,13 +35,18 @@ import {
findChat,
randomMessageId,
} from '../whatsapp/functions';
import { ChatRawMessage } from '.';
import { ChatEventTypes, ChatSendMessageOptions } from './types';
import { MessageButtonsOptions, RawMessage, TextMessageOptions } from '.';
import { ChatEventTypes, SendMessageOptions } from './types';

const debugChat = Debug('WPP:chat');
const debugMessage = Debug('WPP:message');

export class Chat extends Emittery<ChatEventTypes> {
public defaultSendMessageOptions: SendMessageOptions = {
createChat: false,
waitForAck: true,
};

constructor() {
super();
webpack.onInjected(() => this.initialize());
Expand All @@ -63,28 +70,72 @@ export class Chat extends Emittery<ChatEventTypes> {
return ChatStore.get(wid);
}

prepareMessageButtons(
message: RawMessage,
options: MessageButtonsOptions
): RawMessage {
if (!options.buttons) {
return message;
}

if (!Array.isArray(options.buttons)) {
throw 'Buttons options is not a array';
}

if (options.buttons.length === 0 || options.buttons.length > 3) {
throw 'Buttons options must have between 1 and 3 options';
}

if (message.type === 'chat') {
message.contentText = message.body;
} else {
message.contentText = message.caption;
}

message.title = options.title;
message.footer = options.footer;
message.isDynamicReplyButtonsMsg = true;

message.dynamicReplyButtons = options.buttons.map((b) => ({
buttonId: b.id,
buttonText: { displayText: b.text },
type: 1,
}));

// For UI only
message.replyButtons = new ButtonCollection();
message.replyButtons.add(
message.dynamicReplyButtons.map(
(b) =>
new ReplyButtonModel({
id: b.buttonId,
displayText: b.buttonText?.displayText || undefined,
})
)
);

return message;
}

async sendRawMessage(
chatId: any,
message: ChatRawMessage,
options: ChatSendMessageOptions = {}
message: RawMessage,
options: SendMessageOptions = this.defaultSendMessageOptions
): Promise<any> {
const chat = options.createChat
? await assertFindChat(chatId)
: assertGetChat(chatId);

message = Object.assign(
{},
{
t: ClockSkew.globalUnixTime(),
from: UserPrefs.getMaybeMeUser(),
to: chat.id,
self: 'out',
isNewMsg: true,
local: true,
ack: Constants.ACK.CLOCK,
},
message
);
message = {
t: ClockSkew.globalUnixTime(),
from: UserPrefs.getMaybeMeUser(),
to: chat.id,
self: 'out',
isNewMsg: true,
local: true,
ack: Constants.ACK.CLOCK,
...message,
};

if (!message.id) {
message.id = new MsgKey({
Expand Down Expand Up @@ -120,16 +171,18 @@ export class Chat extends Emittery<ChatEventTypes> {
async sendTextMessage(
chatId: any,
content: any,
options: ChatSendMessageOptions = {}
options: TextMessageOptions = this.defaultSendMessageOptions
): Promise<any> {
const message: ChatRawMessage = {
let message: RawMessage = {
body: content,
type: 'chat',
subtype: null,
urlText: null,
urlNumber: null,
};

message = this.prepareMessageButtons(message, options);

const result = await this.sendRawMessage(chatId, message, options);

return result;
Expand Down
17 changes: 15 additions & 2 deletions src/chat/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,22 @@ export interface ChatEventTypes {
idle: undefined;
}

export interface ChatSendMessageOptions {
export interface SendMessageOptions {
waitForAck?: boolean;
createChat?: boolean;
}

export type ChatRawMessage = ModelPropertiesContructor<MsgModel>;
export interface MessageButtonsOptions {
buttons?: Array<{
id: string;
text: string;
}>;
title?: string;
footer?: string;
}

export type TextMessageOptions = SendMessageOptions & MessageButtonsOptions;

export type AllMessageOptions = SendMessageOptions & MessageButtonsOptions;

export type RawMessage = ModelPropertiesContructor<MsgModel>;
5 changes: 3 additions & 2 deletions src/whatsapp/collections/ButtonCollection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,13 @@

import { exportModule } from '../exportModule';
import { ReplyButtonModel } from '../models';
import { Collection } from './Collection';
import { CollectionCache } from './CollectionCache';

/**
* @whatsapp 2.2126.14:67549
* @whatsapp 2.2136.9:84142
*/
export declare class ButtonCollection extends Collection<ReplyButtonModel> {
export declare class ButtonCollection extends CollectionCache<ReplyButtonModel> {
static model: ReplyButtonModel;
static comparator(): any;
}
Expand Down
7 changes: 6 additions & 1 deletion src/whatsapp/collections/Collection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ interface Option {
remove: boolean;
}

/**
* @whatsapp 2.2126.14:64770
* @whatsapp 2.2136.9:85392
*/
export declare interface Collection<M>
extends EventEmitter,
Pick<
Expand All @@ -40,14 +44,15 @@ export declare interface Collection<M>

/**
* @whatsapp 2.2126.14:64770
* @whatsapp 2.2136.9:85392
*/
export declare class Collection<M, A = M | M[]> extends EventEmitter {
static model: any;
static comparator: (a: any, b: any) => number;

modelClass: M;

constructor(e: any, t?: { parent: any });
constructor(e?: any, t?: { parent: any });

add(value: A, options?: Option): A;

Expand Down
1 change: 1 addition & 0 deletions src/whatsapp/collections/CollectionCache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { Collection } from './Collection';

/**
* @whatsapp 2.2126.14:53125
* @whatsapp 2.2136.9:36513
*/
export declare class CollectionCache<C, A = C | C[]> extends Collection<C> {
static cachePolicy: {
Expand Down
19 changes: 13 additions & 6 deletions src/whatsapp/models/MsgModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@

/**
* @whatsapp 2.2126.14:94490
* @whatsapp 2.2136.9:92954
*/
import { MsgCollection } from '../collections';
import { ButtonCollection, MsgCollection } from '../collections';
import { exportProxyModel } from '../exportModule';
import { MsgKey, Wid } from '../misc';
import {
Expand Down Expand Up @@ -47,7 +48,7 @@ interface Props {
isNewMsg: boolean;
star?: any;
recvFresh?: any;
caption?: any;
caption?: string;
interactiveAnnotations?: any;
clientUrl?: any;
loc?: any;
Expand Down Expand Up @@ -105,7 +106,7 @@ interface Props {
thumbnailHQ?: any;
richPreviewType?: any;
doNotPlayInline?: any;
title?: any;
title?: string;
description?: any;
businessOwnerJid?: any;
productId?: any;
Expand Down Expand Up @@ -191,10 +192,16 @@ interface Props {
productListItemCount?: any;
productHeaderImageRejected?: any;
isDynamicReplyButtonsMsg: boolean;
dynamicReplyButtons?: any;
replyButtons?: any;
dynamicReplyButtons?: Array<{
buttonId: string;
buttonText: {
displayText: string;
};
type: number;
}>;
replyButtons?: ButtonCollection;
buttonsResponse?: any;
selectedButtonId?: any;
selectedButtonId?: string;
interactiveMessage?: any;
isMdHistoryMsg: boolean;
}
Expand Down
9 changes: 7 additions & 2 deletions src/whatsapp/models/ReplyButtonModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,16 @@ import {

/**
* @whatsapp 2.2126.14:83065
* @whatsapp 2.2136.9:46420
*/
interface Props {
id?: any;
displayText?: any;
id?: string;
displayText?: string;
}

/**
* @whatsapp 2.2126.14:83065
* @whatsapp 2.2136.9:46420
*/
interface Session {
stale?: any;
Expand All @@ -40,17 +42,20 @@ interface Session {

/**
* @whatsapp 2.2126.14:83065
* @whatsapp 2.2136.9:46420
*/
interface Derived {}

/**
* @whatsapp 2.2126.14:83065
* @whatsapp 2.2136.9:46420
*/
export declare interface ReplyButtonModel
extends ModelProxy<Props, Session, Derived> {}

/**
* @whatsapp 2.2126.14:83065
* @whatsapp 2.2136.9:46420
*/
export declare class ReplyButtonModel extends Model {
constructor(
Expand Down

0 comments on commit 332a8fe

Please sign in to comment.