Skip to content

Conversation

cleitonme
Copy link

@cleitonme cleitonme commented Jul 15, 2025

Summary by Sourcery

Enable voice/video call initiation and termination via the socket API, and add full support for interactive message formats (buttons, templates, and lists) across content generation, sending logic, and type definitions, with a related Proto enum mapping correction.

New Features:

  • Introduce offerCall and terminateCall methods in the message-receive socket for initiating and ending voice/video calls
  • Add support for interactive messages (buttons, template buttons, and list messages) in content generation and sending APIs

Bug Fixes:

  • Fix WAProto listMessage listType mapping so SINGLE_SELECT maps correctly

Enhancements:

  • Extend TypeScript message types with Buttonable, Templatable, and Listable interfaces
  • Expose getButtonArgs helper in the message send socket

fmedeiros95 and others added 20 commits October 7, 2024 10:54
This commit adds two new functions, offerCall and terminateCall, to the messages-recv.ts file. The offerCall function is used to initiate a call with the option to include video, while the terminateCall function is used to end an ongoing call. These functions provide additional functionality for handling calls in the application.
Copy link

sourcery-ai bot commented Jul 15, 2025

Reviewer's Guide

This PR augments the messaging layer by adding call signaling methods in the receive socket, implements support for interactive message types (buttons, template buttons, lists) across content generation and sending, extends message type definitions accordingly, and fixes the protobuf mapping for single‐select lists.

Class diagram for new call signaling methods in makeMessagesRecvSocket

classDiagram
    class makeMessagesRecvSocket {
        +offerCall(toJid: string, isVideo: boolean)
        +terminateCall(callId: string, toJid: string)
        +rejectCall(callId: string, callFrom: string)
    }
Loading

Class diagram for extended message content types (Buttonable, Templatable, Listable)

classDiagram
    class Buttonable {
        +buttons: proto.Message.ButtonsMessage.IButton[]
    }
    class Templatable {
        +templateButtons: proto.IHydratedTemplateButton[]
        +footer: string
    }
    class Listable {
        +sections: proto.Message.ListMessage.ISection[]
        +title: string
        +buttonText: string
    }
    class AnyRegularMessageContent {
    }
    AnyRegularMessageContent <|-- Buttonable
    AnyRegularMessageContent <|-- Templatable
    AnyRegularMessageContent <|-- Listable
Loading

Class diagram for message sending with interactive types

classDiagram
    class makeMessagesSocket {
        +getButtonType(message: proto.IMessage)
        +getButtonArgs(message: proto.IMessage): BinaryNode['attrs']
    }
Loading

File-Level Changes

Change Details Files
Added call signaling functionality to the receive socket
  • Imported generateMessageIDV2, jidEncode, createParticipantNodes and getUSyncDevices
  • Implemented offerCall and terminateCall methods
  • Updated rejectCall to use generateMessageIDV2 for stanza IDs
  • Exposed offerCall and terminateCall in the socket API
src/Socket/messages-recv.ts
Extended generateWAMessageContent to handle interactive message types
  • Added ButtonType constant
  • Built buttonsMessage when message.buttons is present
  • Constructed templateMessage for templateButtons
  • Created listMessage for sections-based lists
src/Utils/messages.ts
Injected business () nodes for outgoing interactive messages
  • Imported ListType
  • Added getButtonType and getButtonArgs helpers
  • Appended node with correct tag and attrs for buttons and lists
  • Exported getButtonArgs via the socket API
src/Socket/messages-send.ts
Augmented message type definitions to include interactive fields
  • Defined Buttonable, Templatable and Listable interfaces
  • Extended AnyMediaMessageContent and AnyRegularMessageContent to include these interfaces
src/Types/Message.ts
Fixed protobuf mapping for single-select list types
  • Changed listType mapping for SINGLE_SELECT from 1 to 2
WAProto/index.js

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @cleitonme - I've reviewed your changes - here's some feedback:

  • Consider extracting the buttons and list node construction logic into shared helper functions to avoid duplication between generateWAMessageContent and makeMessagesSocket.
  • Extract the common call stanza creation bits into a reusable helper to reduce duplication and improve readability between offerCall and terminateCall.
  • Please clarify the rationale for changing SINGLE_SELECT listType from 1 to 2 in WAProto/index.js and include compatibility tests to guard against regressions.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- Consider extracting the buttons and list node construction logic into shared helper functions to avoid duplication between generateWAMessageContent and makeMessagesSocket.
- Extract the common call stanza creation bits into a reusable helper to reduce duplication and improve readability between offerCall and terminateCall.
- Please clarify the rationale for changing SINGLE_SELECT listType from 1 to 2 in WAProto/index.js and include compatibility tests to guard against regressions.

## Individual Comments

### Comment 1
<location> `src/Socket/messages-send.ts:571` </location>
<code_context>
 					logger.debug({ jid }, 'adding device identity')
 				}

+				const buttonType = getButtonType(message)
+				if(buttonType) {
+					(stanza.content as BinaryNode[]).push({
+						tag: 'biz',
+						attrs: { },
+						content: [
+							{
+								tag: buttonType,
+								attrs: getButtonArgs(message),
+							}
+						]
+					})
+
+					logger.debug({ jid }, 'adding business node')
+				}
+
</code_context>

<issue_to_address>
Business node injection for button types may not be compatible with all message types.

Limit 'biz' node injection to supported message types or add validation to avoid malformed stanzas.

Suggested implementation:

```typescript
				const buttonType = getButtonType(message)
				const supportedBizTypes = ['template', 'button', 'list'] // add or adjust supported types as needed
				const messageType = message.type // adjust if message type is accessed differently

				if(buttonType && supportedBizTypes.includes(messageType)) {
					(stanza.content as BinaryNode[]).push({
						tag: 'biz',
						attrs: { },
						content: [
							{
								tag: buttonType,
								attrs: getButtonArgs(message),
							}
						]
					})

					logger.debug({ jid }, 'adding business node')
				}

```

- Ensure that `message.type` correctly reflects the type of the message. If the message type is determined differently in your codebase, adjust the `messageType` assignment accordingly.
- Update the `supportedBizTypes` array to include all and only the message types that should support business node injection.
</issue_to_address>

### Comment 2
<location> `src/Types/Message.ts:84` </location>
<code_context>
+    /** Title of a List Message only */
+    title?: string
+
+    /** Text of the bnutton on the list (required) */
+    buttonText?: string
+}
</code_context>

<issue_to_address>
Typo in comment: 'bnutton' should be 'button'.

Fixing the typo enhances readability and professionalism.
</issue_to_address>

<suggested_fix>
<<<<<<< SEARCH
    /** Text of the bnutton on the list (required) */
    buttonText?: string
=======
    /** Text of the button on the list (required) */
    buttonText?: string
>>>>>>> REPLACE

</suggested_fix>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +571 to +580
const buttonType = getButtonType(message)
if(buttonType) {
(stanza.content as BinaryNode[]).push({
tag: 'biz',
attrs: { },
content: [
{
tag: buttonType,
attrs: getButtonArgs(message),
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (bug_risk): Business node injection for button types may not be compatible with all message types.

Limit 'biz' node injection to supported message types or add validation to avoid malformed stanzas.

Suggested implementation:

				const buttonType = getButtonType(message)
				const supportedBizTypes = ['template', 'button', 'list'] // add or adjust supported types as needed
				const messageType = message.type // adjust if message type is accessed differently

				if(buttonType && supportedBizTypes.includes(messageType)) {
					(stanza.content as BinaryNode[]).push({
						tag: 'biz',
						attrs: { },
						content: [
							{
								tag: buttonType,
								attrs: getButtonArgs(message),
							}
						]
					})

					logger.debug({ jid }, 'adding business node')
				}
  • Ensure that message.type correctly reflects the type of the message. If the message type is determined differently in your codebase, adjust the messageType assignment accordingly.
  • Update the supportedBizTypes array to include all and only the message types that should support business node injection.

Comment on lines +84 to +85
/** Text of the bnutton on the list (required) */
buttonText?: string
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick (typo): Typo in comment: 'bnutton' should be 'button'.

Fixing the typo enhances readability and professionalism.

Suggested change
/** Text of the bnutton on the list (required) */
buttonText?: string
/** Text of the button on the list (required) */
buttonText?: string

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants