Messages
Once your Whinself app is properly connected to the network and authenticated, whatsapp websocket connection will receive all messages from the network.
Receiving Messages
Whinself app won't save this messages events and will http post them, in raw format, to the endpoint you indicated in your initial settings (config.json, key: nrurl). You can change your incoming messages webhook in runtime through the front end app at anytime.
Example of an incoming message payload (click to expand)
{
"event": {
"Info": {
"Chat": "[REDACTED]@s.whatsapp.net",
"Sender": "[REDACTED]@s.whatsapp.net",
"IsFromMe": false,
"IsGroup": false,
"BroadcastListOwner": "",
"ID": "3A0B435DF237870E775C",
"ServerID": 0,
"Type": "text",
"PushName": "JimmyJazz",
"Timestamp": "2025-03-28T00:58:58+01:00",
"Category": "",
"Multicast": false,
"MediaType": "",
"Edit": "",
"MsgBotInfo": {
"EditType": "",
"EditTargetID": "",
"EditSenderTimestampMS": "0001-01-01T00:00:00Z"
},
"MsgMetaInfo": {
"TargetID": "",
"TargetSender": ""
},
"VerifiedName": null,
"DeviceSentMeta": null
},
"Message": {
"conversation": "Hello there ✌️",
"messageContextInfo": {
"deviceListMetadata": {
"senderKeyHash": "4jjdP/o07epKtg==",
"senderTimestamp": 1742938147,
"recipientKeyHash": "TndGCtT9bDklLA==",
"recipientTimestamp": 1742760376
},
"deviceListMetadataVersion": 2,
"messageSecret": "P9V9fZnTlhT+9kaydOiCXoiiF6BMcRn2fnqV58gvXSY="
}
},
"IsEphemeral": false,
"IsViewOnce": false,
"IsViewOnceV2": false,
"IsViewOnceV2Extension": false,
"IsDocumentWithCaption": false,
"IsLottieSticker": false,
"IsEdit": false,
"SourceWebMsg": null,
"UnavailableRequestID": "",
"RetryCount": 0,
"NewsletterMeta": null,
"RawMessage": {
"conversation": "Hello there ✌️",
"messageContextInfo": {
"deviceListMetadata": {
"senderKeyHash": "4jjdP/o07epKtg==",
"senderTimestamp": 1742938147,
"recipientKeyHash": "TndGCtT9bDklNA==",
"recipientTimestamp": 1742760376
},
"deviceListMetadataVersion": 2,
"messageSecret": "P9V9fZnTlhT+9kaydOiCXoiiF6BMcRn2fnqV58gvmSY="
}
}
},
"phone": "[REDACTED]",
"slotid": "slotid"
}
Key Components of an Incoming Message
The webhook payload contains these important fields:
- event.Info.Chat: The chat identifier (individual or group)
- event.Info.Sender: The sender's identifier
- event.Info.Type: Message type (text, image, etc.)
- event.Info.PushName: Sender's display name
- event.Message.conversation: The text content (for text messages)
- phone: Your WhatsApp phone number
- slotid: Your Whinself instance identifier
Sending Messages with WHinself API
This guide will help you understand how to send different types of messages using the WhatsApp API.
Basic Message Sending
The way to send a message is using the /wspout
endpoint.
Example Request
curl -X POST http://localhost:8888/wspout \
-H "Content-Type: application/json" \
-d '{
"text": "Hello from the API!",
"jid": "[email protected]"
}'
Example Response
{
"status": "Message sent successfully"
}
Sending Media Messages
The /wspout
endpoint supports various types of media messages including images, videos, documents, and audio files.
Sending an Image
curl -X POST http://localhost:8888/wspout \
-H "Content-Type: application/json" \
-d '{
"image": {
"url": "https://upload.wikimedia.org/wikipedia/en/a/a9/Example.jpg"
},
"caption": "Check out this image!",
"jid": "[email protected]"
}'
Sending a Video
curl -X POST http://localhost:8888/wspout \
-H "Content-Type: application/json" \
-d '{
"video": {
"url": "https://filesamples.com/samples/video/mp4/sample_960x400_ocean_with_audio.mp4"
},
"caption": "Watch this video!",
"jid": "[email protected]"
}'
Sending a Document
curl -X POST http://localhost:8888/wspout \
-H "Content-Type: application/json" \
-d '{
"document": {
"url": "https://filesamples.com/samples/document/pdf/sample2.pdf",
"filename": "zanzibar-itinerary.pdf"
},
"caption": "Here is the document",
"jid": "[email protected]"
}'
Sending an Audio Message
curl -X POST http://localhost:8888/wspout \
-H "Content-Type: application/json" \
-d '{
"audio": {
"url": "https://filesamples.com/samples/audio/mp3/sample3.mp3"
},
"jid": "[email protected]"
}'
Sending a Voice Message (PTT/push-to-talk)
curl -X POST \
http://localhost:30000/wspout \
-H "Content-Type: application/json" \
-d '{
"jid": "[email protected]",
"audio": {
"url": "https://github.com/inUtil-Labs/inutil-labs.github.io/raw/refs/heads/master/assets/whinself.opus",
"isPTT": true,
"seconds":37
}
}'
Important considerations:
- WhatsApp is somewhat picky with the voice format. It requires a mimeType audio/ogg; codecs=opus format. 1-channel (mono) 24k
- You may want to implement your tool to calculate the seconds if unknown.
Sending Base64 Encoded Media
You can also send media files using base64 encoded strings instead of URLs.
Example with Base64 Image
curl -X POST http://localhost:8888/wspout \
-H "Content-Type: application/json" \
-d '{
"image": {
"b64": "base64_encoded_image_string"
},
"caption": "Image from base64",
"jid": "[email protected]"
}'
Other Messages Types
Sending a Contact/Vcard
Be mindful abour VCard standard to produce a proper and acceptable payload.
curl -X POST http://localhost:8888/wspout \
-H "Content-Type: application/json" \
-d '{
"jid": "[email protected]",
"contact": {
"displayName": "John Doe",
"vcard": "BEGIN:VCARD\nVERSION:3.0\nN:Doe;John;;;\nFN:John Doe\nTEL;type=CELL;waid=1234567890:+1 (234) 567-890\nEND:VCARD"
}
}'
Sending a Location
curl -X POST http://localhost:8888/wspout \
-H "Content-Type: application/json" \
-d '{
"jid": "[email protected]",
"location": {
"latitude": 37.7749,
"longitude": -122.4194,
"name": "San Francisco",
"address": "California, USA"
}
}'
Best Practices
-
JID Format
- Always use the complete JID format:
[email protected]
- Include the country code in the phone number
- Example:
[email protected]
- Always use the complete JID format:
-
Media Content
- Keep media file sizes reasonable
- Use appropriate formats (JPEG/PNG for images, MP4 for videos, etc.)
- Consider using URLs for large files instead of base64 encoding
-
Rate Limiting
- Be mindful of API rate limits
- Implement appropriate delays between messages
- Consider using bulk messaging for large audiences
-
Error Handling
- Always check the response status
- Implement retry logic for temporary failures
- Log errors for debugging purposes
Code Examples
Python Example (click to expand)
import requests
import json
def send_message(jid, text):
url = "http://localhost:8888/wspout"
payload = {
"text": text,
"jid": jid
}
try:
response = requests.post(url, json=payload)
response.raise_for_status()
return response.text
except requests.exceptions.RequestException as e:
print(f"Error sending message: {e}")
return None
# Example usage
result = send_message("[email protected]", "Hello from Python!")
if result:
print("Message sent successfully!")
JavaScript Example (click to expand)
async function sendMessage(jid, text) {
const url = "http://localhost:8888/wspout";
const payload = {
text: text,
jid: jid,
};
try {
const response = await fetch(url, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const result = await response.text();
return result;
} catch (error) {
console.error("Error sending message:", error);
return null;
}
}
// Example usage
sendMessage("[email protected]", "Hello from JavaScript!").then(
(result) => {
if (result) {
console.log("Message sent successfully!");
}
}
);
Go Example (click to expand)
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
type Message struct {
Text string `json:"text"`
JID string `json:"jid"`
}
func sendMessage(jid, text string) error {
url := "http://localhost:8888/wspout"
payload := Message{
Text: text,
JID: jid,
}
jsonData, err := json.Marshal(payload)
if err != nil {
return fmt.Errorf("error marshaling JSON: %v", err)
}
resp, err := http.Post(url, "application/json", bytes.NewBuffer(jsonData))
if err != nil {
return fmt.Errorf("error sending request: %v", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("unexpected status code: %d", resp.StatusCode)
}
return nil
}
func main() {
err := sendMessage("[email protected]", "Hello from Go!")
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
fmt.Println("Message sent successfully!")
}
Important: Whinself is an unofficial third-party tool that allows you to send and receive messages through your personal WhatsApp account. It is not an official WhatsApp API and is not affiliated with, authorized, or endorsed by WhatsApp or Meta Platforms, Inc. Users are responsible for ensuring their usage complies with WhatsApp's Terms of Service.