Last active
August 3, 2024 17:45
-
-
Save HunterXProgrammer/0278cc5508e04a3cc88a1ee1fc84893f to your computer and use it in GitHub Desktop.
Adds support for sending videos/pdf/documents and voice messages via whatsmeow mdtest command in Termux/Tasker. Check this for info - https://www.reddit.com/r/tasker/comments/10wiahq/howto_send_imagesvideospdfdocuments_in_whatsapp/
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
case "senddoc": | |
if len(args) < 3 { | |
log.Errorf("Usage: senddoc <jid> <document path> <title> [mime-type]") | |
return | |
} | |
recipient, ok := parseJID(args[0]) | |
if !ok { | |
return | |
} | |
data, err := os.ReadFile(args[1]) | |
if err != nil { | |
log.Errorf("Failed to read %s: %v", args[0], err) | |
return | |
} | |
uploaded, err := cli.Upload(context.Background(), data, whatsmeow.MediaDocument) | |
if err != nil { | |
log.Errorf("Failed to upload file: %v", err) | |
return | |
} | |
if len(args) < 4 { | |
msg := &waProto.Message{DocumentMessage: &waProto.DocumentMessage{ | |
Title: proto.String(args[2]), | |
Url: proto.String(uploaded.URL), | |
DirectPath: proto.String(uploaded.DirectPath), | |
MediaKey: uploaded.MediaKey, | |
Mimetype: proto.String(http.DetectContentType(data)), | |
FileEncSha256: uploaded.FileEncSHA256, | |
FileSha256: uploaded.FileSHA256, | |
FileLength: proto.Uint64(uint64(len(data))), | |
}} | |
resp, err := cli.SendMessage(context.Background(), recipient, msg) | |
if err != nil { | |
log.Errorf("Error sending document message: %v", err) | |
} else { | |
log.Infof("Document message sent (server timestamp: %s)", resp.Timestamp) | |
} | |
} else { | |
msg := &waProto.Message{DocumentMessage: &waProto.DocumentMessage{ | |
Title: proto.String(args[2]), | |
Url: proto.String(uploaded.URL), | |
DirectPath: proto.String(uploaded.DirectPath), | |
MediaKey: uploaded.MediaKey, | |
Mimetype: proto.String(args[3]), | |
FileEncSha256: uploaded.FileEncSHA256, | |
FileSha256: uploaded.FileSHA256, | |
FileLength: proto.Uint64(uint64(len(data))), | |
}} | |
resp, err := cli.SendMessage(context.Background(), recipient, msg) | |
if err != nil { | |
log.Errorf("Error sending document message: %v", err) | |
} else { | |
log.Infof("Document message sent (server timestamp: %s)", resp.Timestamp) | |
} | |
} | |
case "sendvid": | |
if len(args) < 2 { | |
log.Errorf("Usage: sendvid <jid> <video path>") | |
return | |
} | |
recipient, ok := parseJID(args[0]) | |
if !ok { | |
return | |
} | |
data, err := os.ReadFile(args[1]) | |
if err != nil { | |
log.Errorf("Failed to read %s: %v", args[0], err) | |
return | |
} | |
uploaded, err := cli.Upload(context.Background(), data, whatsmeow.MediaVideo) | |
if err != nil { | |
log.Errorf("Failed to upload file: %v", err) | |
return | |
} | |
jpegImageFile, jpegErr := os.Open("/storage/emulated/0/Tasker/convert_video/thumbnail.jpg") | |
if jpegErr != nil{ | |
log.Errorf("Failed to find preview thumbnail file generated by Tasker") | |
log.Infof("The video message will still be sent, but preview won't be available") | |
msg := &waProto.Message{VideoMessage: &waProto.VideoMessage{ | |
Url: proto.String(uploaded.URL), | |
DirectPath: proto.String(uploaded.DirectPath), | |
MediaKey: uploaded.MediaKey, | |
Mimetype: proto.String(http.DetectContentType(data)), | |
FileEncSha256: uploaded.FileEncSHA256, | |
FileSha256: uploaded.FileSHA256, | |
FileLength: proto.Uint64(uint64(len(data))), | |
}} | |
resp, err := cli.SendMessage(context.Background(), recipient, msg) | |
if err != nil { | |
log.Errorf("Error sending video message: %v", err) | |
} else { | |
log.Infof("Video message sent (server timestamp: %s)", resp.Timestamp) | |
} | |
} else { | |
defer jpegImageFile.Close() | |
jpegFileinfo, _ := jpegImageFile.Stat() | |
var jpegSize int64 = jpegFileinfo.Size() | |
jpegBytes := make([]byte, jpegSize) | |
jpegBuffer := bufio.NewReader(jpegImageFile) | |
_, jpegErr = jpegBuffer.Read(jpegBytes) | |
thumbnailResp, err := cli.Upload(context.Background(), jpegBytes, whatsmeow.MediaImage) | |
if err != nil { | |
log.Errorf("Failed to upload preview thumbnail file: %v", err) | |
return | |
} | |
msg := &waProto.Message{VideoMessage: &waProto.VideoMessage{ | |
Url: proto.String(uploaded.URL), | |
DirectPath: proto.String(uploaded.DirectPath), | |
ThumbnailDirectPath: &thumbnailResp.DirectPath, | |
ThumbnailSha256: thumbnailResp.FileSHA256, | |
ThumbnailEncSha256: thumbnailResp.FileEncSHA256, | |
JpegThumbnail: jpegBytes, | |
MediaKey: uploaded.MediaKey, | |
Mimetype: proto.String(http.DetectContentType(data)), | |
FileEncSha256: uploaded.FileEncSHA256, | |
FileSha256: uploaded.FileSHA256, | |
FileLength: proto.Uint64(uint64(len(data))), | |
}} | |
resp, err := cli.SendMessage(context.Background(), recipient, msg) | |
if err != nil { | |
log.Errorf("Error sending video message: %v", err) | |
} else { | |
log.Infof("Video message sent (server timestamp: %s)", resp.Timestamp) | |
} | |
} | |
case "sendaudio": | |
if len(args) < 2 { | |
log.Errorf("Usage: sendaudio <jid> <audio path>") | |
return | |
} | |
recipient, ok := parseJID(args[0]) | |
if !ok { | |
return | |
} | |
data, err := os.ReadFile(args[1]) | |
if err != nil { | |
log.Errorf("Failed to read %s: %v", args[0], err) | |
return | |
} | |
uploaded, err := cli.Upload(context.Background(), data, whatsmeow.MediaAudio) | |
if err != nil { | |
log.Errorf("Failed to upload file: %v", err) | |
return | |
} | |
msg := &waProto.Message{AudioMessage: &waProto.AudioMessage{ | |
Url: proto.String(uploaded.URL), | |
DirectPath: proto.String(uploaded.DirectPath), | |
MediaKey: uploaded.MediaKey, | |
Mimetype: proto.String("audio/ogg; codecs=opus"), | |
FileEncSha256: uploaded.FileEncSHA256, | |
FileSha256: uploaded.FileSHA256, | |
FileLength: proto.Uint64(uint64(len(data))), | |
}} | |
resp, err := cli.SendMessage(context.Background(), recipient, msg) | |
if err != nil { | |
log.Errorf("Error sending audio message: %v", err) | |
} else { | |
log.Infof("Audio message sent (server timestamp: %s)", resp.Timestamp) | |
} | |
case "sendimg": | |
if len(args) < 2 { | |
log.Errorf("Usage: sendimg <jid> <image path> [caption]") | |
return | |
} | |
recipient, ok := parseJID(args[0]) | |
if !ok { | |
return | |
} | |
data, err := os.ReadFile(args[1]) | |
if err != nil { | |
log.Errorf("Failed to read %s: %v", args[0], err) | |
return | |
} | |
uploaded, err := cli.Upload(context.Background(), data, whatsmeow.MediaImage) | |
if err != nil { | |
log.Errorf("Failed to upload file: %v", err) | |
return | |
} | |
jpegImageFile, jpegErr := os.Open("/storage/emulated/0/Tasker/convert_image/thumbnail.jpg") | |
if jpegErr != nil{ | |
log.Errorf("Failed to find preview thumbnail file generated by Tasker") | |
log.Infof("The image message will still be sent, but preview won't be available") | |
msg := &waProto.Message{ImageMessage: &waProto.ImageMessage{ | |
Caption: proto.String(strings.Join(args[2:], " ")), | |
Url: proto.String(uploaded.URL), | |
DirectPath: proto.String(uploaded.DirectPath), | |
MediaKey: uploaded.MediaKey, | |
Mimetype: proto.String(http.DetectContentType(data)), | |
FileEncSha256: uploaded.FileEncSHA256, | |
FileSha256: uploaded.FileSHA256, | |
FileLength: proto.Uint64(uint64(len(data))), | |
}} | |
resp, err := cli.SendMessage(context.Background(), recipient, msg) | |
if err != nil { | |
log.Errorf("Error sending image message: %v", err) | |
} else { | |
log.Infof("Image message sent (server timestamp: %s)", resp.Timestamp) | |
} | |
} else { | |
defer jpegImageFile.Close() | |
jpegFileinfo, _ := jpegImageFile.Stat() | |
var jpegSize int64 = jpegFileinfo.Size() | |
jpegBytes := make([]byte, jpegSize) | |
jpegBuffer := bufio.NewReader(jpegImageFile) | |
_, jpegErr = jpegBuffer.Read(jpegBytes) | |
thumbnailResp, err := cli.Upload(context.Background(), jpegBytes, whatsmeow.MediaImage) | |
if err != nil { | |
log.Errorf("Failed to upload preview thumbnail file: %v", err) | |
return | |
} | |
msg := &waProto.Message{ImageMessage: &waProto.ImageMessage{ | |
Caption: proto.String(strings.Join(args[2:], " ")), | |
Url: proto.String(uploaded.URL), | |
DirectPath: proto.String(uploaded.DirectPath), | |
ThumbnailDirectPath: &thumbnailResp.DirectPath, | |
ThumbnailSha256: thumbnailResp.FileSHA256, | |
ThumbnailEncSha256: thumbnailResp.FileEncSHA256, | |
JpegThumbnail: jpegBytes, | |
MediaKey: uploaded.MediaKey, | |
Mimetype: proto.String(http.DetectContentType(data)), | |
FileEncSha256: uploaded.FileEncSHA256, | |
FileSha256: uploaded.FileSHA256, | |
FileLength: proto.Uint64(uint64(len(data))), | |
}} | |
resp, err := cli.SendMessage(context.Background(), recipient, msg) | |
if err != nil { | |
log.Errorf("Error sending image message: %v", err) | |
} else { | |
log.Infof("Image message sent (server timestamp: %s)", resp.Timestamp) | |
} | |
} | |
case "setstatus": |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Here is a full list of commands that whatsmeow mdtest handles. Extension functionality added to list as well:-
Usage: appstate <types...>
Usage: request-appstate-key <ids...>
Usage: checkuser <phone numbers...>
Usage: subscribepresence <jid>
Usage: presence <available/unavailable>
Usage: chatpresence <jid> <composing/paused> [audio]
Usage: getuser <jids...>
Usage: getavatar <jid> [existing ID] [--preview] [--community]
Usage: getgroup <jid>
Usage: subgroups <jid>
Usage: communityparticipants <jid>
Usage: getinvitelink <jid> [--reset]
Usage: queryinvitelink <link>
Usage: querybusinesslink <link>
Usage: acceptinvitelink <link>
Usage: setdisappeartimer <jid> <days>
Usage: send <jid> <text>
Usage: sendpoll <jid> <max answers> <question> -- <option 1> / <option 2> / ...
Usage: multisend <jids...> -- <text> (the -- is required)
Usage: react <jid> <message ID> <reaction>
Usage: revoke <jid> <message ID>
Usage: senddoc <jid> <document path> <title>
Usage: sendvid <jid> <video path>
Usage: sendaudio <jid> <audio path>
Usage: sendimg <jid> <image path> [caption
]Usage: setstatus <message>