Last active
March 17, 2023 14:58
A bash script to install whatsmeow2 mdtest into Termux in one line. It'll provide direct integration with Tasker for receiving WhatsApp messages as easy Tasker variables and sending hundreds of messages at once. Check Reddit Tasker for more info - https://www.reddit.com/r/tasker/comments/11a4k49/howto_sendreceive_whatsapp_message_project_v2/
This file contains 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
#!/data/data/com.termux/files/usr/bin/bash | |
echo -ne "\n Checking if Termux has storage permission..." | |
rm -r ~/storage >/dev/null 2>&1 | |
if ! touch /storage/emulated/0/.tmp_check_termux >/dev/null 2>&1 | |
then | |
echo -e "\nGrant Termux storage permission and run the script again\n" | |
termux-setup-storage | |
exit 1 | |
fi | |
rm -rf /storage/emulated/0/.tmp_check_termux >/dev/null 2>&1 | |
termux-setup-storage | |
echo "done" | |
apt update | |
pkg install -y git golang ffmpeg 2>/dev/null | grep -E '(Need to get |Get:|Unpacking |Setting up )' | |
tmpdir="$(mktemp -d)" | |
cd $tmpdir | |
git clone https://github.com/tulir/whatsmeow | |
i="$(grep -m 1 -n 'c := make(chan os.Signal)' whatsmeow/mdtest/main.go | grep -Eo '^[0-9]+')" | |
stop_line="$(wc -l whatsmeow/mdtest/main.go | grep -Eo '^[0-9]+')" | |
while (( $i < $stop_line )) | |
do | |
((i++)) | |
if sed -n "${i}p" whatsmeow/mdtest/main.go | grep -q "}()" | |
then | |
sed -i "${i} a args := os.Args[1:]\nif len(args) > 0 && args[0] != \"null\" {\n if args[0] == \"both\" {\n is_mode = \"both\"\n } else if args[0] == \"receive\" {\n is_mode = \"receive\" \n } else if args[0] == \"send\" {\n is_mode = \"send\"\n } else {\n handleCmd(strings.ToLower(args[0]), args[1:])\n return\n }\n}" whatsmeow/mdtest/main.go | |
break | |
fi | |
done | |
del_start="$(grep -m 1 -n 'case "sendimg":' whatsmeow/mdtest/main.go | grep -Eo '^[0-9]+')" | |
del_stop="$(grep -m 1 -n 'case "setstatus":' whatsmeow/mdtest/main.go | grep -Eo '^[0-9]+')" | |
((del_stop--)) | |
sed -i "$del_start,${del_stop}d" whatsmeow/mdtest/main.go | |
curl -s -O "https://gist.githubusercontent.com/HunterXProgrammer/fe60f4005af16caa6c407af66123558c/raw/3d0807d70677746945d8535d792f5c34cd093e91/extension_media_whatsmeow2_main.go" | |
sed -i -e '/case "setstatus":/{r extension_media_whatsmeow2_main.go' -e 'd}' whatsmeow/mdtest/main.go | |
rm extension_media_whatsmeow2_main.go | |
sed -i '0,/"mime"/s//"os\/exec"\n\t"io"\n\t"encoding\/base64"\n\t"io\/ioutil"/' whatsmeow/mdtest/main.go | |
sed -i "$(($(grep -nm 1 'case "getuser":' whatsmeow/mdtest/main.go | sed 's/:.*//')-1)) a case \"listusers\":\n users, err := cli.Store.Contacts.GetAllContacts()\n if err != nil {\n log.Errorf(\"Failed to get user list: %v\", err)\n } else {\n for number, user := range users {\n log.Infof(\"%v:%+v\", number, user)\n }\n }" whatsmeow/mdtest/main.go | |
sed -i "$(grep -nm 1 'log.Infof("Received message ' whatsmeow/mdtest/main.go | sed 's/:.*//') a if is_mode == \"both\" || is_mode == \"receive\" {\n message := fmt.Sprintf(\"%s\", evt.Message.GetConversation())\n extended_message := fmt.Sprintf(\"%s\", evt.Message.GetExtendedTextMessage())\n sender_pushname := fmt.Sprintf(\"%s\", evt.Info.PushName)\n sender_jid := fmt.Sprintf(\"%s\", evt.Info.Sender)\n receiver_jid := fmt.Sprintf(\"%s\", evt.Info.Chat)\n json_message, _ := json.Marshal(message)\n json_extended_message, _ := json.Marshal(extended_message)\n json_sender_pushname, _ := json.Marshal(sender_pushname)\n var is_from_myself string\n if evt.Info.MessageSource.IsFromMe {\n is_from_myself = \"1\"\n } else {\n is_from_myself = \"0\"\n }\n if evt.Message.GetConversation() != \"\" {\n json_data := fmt.Sprintf(\`{\"type\":\"message\",\"sender_jid\":\"%s\", \"receiver_jid\":\"%s\", \"sender_pushname\":%s, \"is_from_myself\":\"%s\", \"message\":%s}\`, sender_jid, receiver_jid, json_sender_pushname, is_from_myself, json_message)\n log.Infof(\"%s\", json_data)\n args := os.Args[1:]\n if len(args) > 1 {\n if os.Args[2] == \"net.dinglisch.android.taskerm\" {\n intentTaskerm := exec.Command(\"am\", \"broadcast\", \"-a\", \"intent.from.mdtest\", \"-p\", \"net.dinglisch.android.taskerm\", \"--es\", \"json_data\", json_data)\n intentTaskerm.Output()\n } else if os.Args[2] == \"net.dinglisch.android.tasker\" {\n intentTasker := exec.Command(\"am\", \"broadcast\", \"-a\", \"intent.from.mdtest\", \"-p\", \"net.dinglisch.android.tasker\", \"--es\", \"json_data\", json_data)\n intentTasker.Output()\n } else {\n intentTaskerm := exec.Command(\"am\", \"broadcast\", \"-a\", \"intent.from.mdtest\", \"-p\", \"net.dinglisch.android.taskerm\", \"--es\", \"json_data\", json_data)\n intentTaskerm.Output()\n intentTasker := exec.Command(\"am\", \"broadcast\", \"-a\", \"intent.from.mdtest\", \"-p\", \"net.dinglisch.android.tasker\", \"--es\", \"json_data\", json_data)\n intentTasker.Output()\n }\n } else {\n intentTaskerm := exec.Command(\"am\", \"broadcast\", \"-a\", \"intent.from.mdtest\", \"-p\", \"net.dinglisch.android.taskerm\", \"--es\", \"json_data\", json_data)\n intentTaskerm.Output()\n intentTasker := exec.Command(\"am\", \"broadcast\", \"-a\", \"intent.from.mdtest\", \"-p\", \"net.dinglisch.android.tasker\", \"--es\", \"json_data\", json_data)\n intentTasker.Output()\n }\n } else if evt.Message.GetExtendedTextMessage() != nil {\n json_data := fmt.Sprintf(\`{\"type\":\"extended_message\",\"sender_jid\":\"%s\", \"receiver_jid\":\"%s\", \"sender_pushname\":%s, \"is_from_myself\":\"%s\", \"message\":%s}\`, sender_jid, receiver_jid, json_sender_pushname, is_from_myself, json_extended_message)\n log.Infof(\"%s\", json_data)\n args := os.Args[1:]\n if len(args) > 1 {\n if os.Args[2] == \"net.dinglisch.android.taskerm\" {\n intentTaskerm := exec.Command(\"am\", \"broadcast\", \"-a\", \"intent.from.mdtest\", \"-p\", \"net.dinglisch.android.taskerm\", \"--es\", \"json_data\", json_data)\n intentTaskerm.Output()\n } else if os.Args[2] == \"net.dinglisch.android.tasker\" {\n intentTasker := exec.Command(\"am\", \"broadcast\", \"-a\", \"intent.from.mdtest\", \"-p\", \"net.dinglisch.android.tasker\", \"--es\", \"json_data\", json_data)\n intentTasker.Output()\n } else {\n intentTaskerm := exec.Command(\"am\", \"broadcast\", \"-a\", \"intent.from.mdtest\", \"-p\", \"net.dinglisch.android.taskerm\", \"--es\", \"json_data\", json_data)\n intentTaskerm.Output()\n intentTasker := exec.Command(\"am\", \"broadcast\", \"-a\", \"intent.from.mdtest\", \"-p\", \"net.dinglisch.android.tasker\", \"--es\", \"json_data\", json_data)\n intentTasker.Output()\n }\n } else {\n intentTaskerm := exec.Command(\"am\", \"broadcast\", \"-a\", \"intent.from.mdtest\", \"-p\", \"net.dinglisch.android.taskerm\", \"--es\", \"json_data\", json_data)\n intentTaskerm.Output()\n intentTasker := exec.Command(\"am\", \"broadcast\", \"-a\", \"intent.from.mdtest\", \"-p\", \"net.dinglisch.android.tasker\", \"--es\", \"json_data\", json_data)\n intentTasker.Output()\n }\n }\n }" whatsmeow/mdtest/main.go | |
line="$(grep -n 'cli.Disconnect()' whatsmeow/mdtest/main.go | sed 's/:.*//' | sort -r)" | |
for i in $line | |
do | |
sed -i "${i} a if is_mode == \"both\" || is_mode == \"receive\" || is_mode == \"send\" {\n kill_server()\n}" whatsmeow/mdtest/main.go | |
done | |
sed -i "$(grep -nm 1 -E '^\)' whatsmeow/mdtest/main.go | sed 's/:.*//') a var server *http.Server\nvar is_mode string\nvar is_send bool\ntype test_struct struct {\n Data1 string \`json:\"data1\"\`\n Data2 string \`json:\"data2\"\`\n Data3 string \`json:\"data3\"\`\n Data4 string \`json:\"data4\"\`\n Data5 string \`json:\"data5\"\`\n Data6 string \`json:\"data6\"\`\n Data7 string \`json:\"data7\"\`\n Data8 string \`json:\"data8\"\`\n Data9 string \`json:\"data8\"\`\n Data10 string \`json:\"data10\"\`\n}\n\nfunc base64Encode(str string) string {\n return base64.StdEncoding.EncodeToString([]byte(str))\n}\n\nfunc base64Decode(str string) (string, bool) {\n data, err := base64.StdEncoding.DecodeString(str)\n if err != nil {\n return \"\", true\n }\n return string(data), false\n}\n\nfunc mdtest(w http.ResponseWriter, r *http.Request) {\n if r.URL.Path != \"/\" {\n http.Error(w, \"404 not found.\", http.StatusNotFound)\n log.Errorf(\"Invalid request path, 404 not found.\")\n return\n }\n\n switch r.Method {\n case \"GET\":\n log.Infof(\"get request received, mdtest is running\")\n io.WriteString(w, \"mdtest is running\")\n case \"POST\":\n dec := json.NewDecoder(r.Body)\n for {\n var t test_struct\n if err := dec.Decode(&t); err == io.EOF {\n break\n } else if err != nil {\n log.Errorf(\"%s\", err)\n }\n \n if t.Data1 == \"stop\" {\n io.WriteString(w, \"exiting\")\n go func() {\n time.Sleep(1 * time.Second)\n kill_server()\n log.Infof(\"Exit command Received, exiting...\")\n cli.Disconnect()\n os.Exit(0)\n }()\n return\n }\n io.WriteString(w, \"command received\")\n if t.Data1 != \"\" && t.Data2 == \"\" {\n log.Infof(\"no data2\")\n args := []string{t.Data1, \"null\"}\n go handleCmd(strings.ToLower(args[0]), args[1:])\n return\n } else if t.Data1 != \"\" && t.Data2 != \"\" {\n args := []string{t.Data1, t.Data2, t.Data3, t.Data4, t.Data5, t.Data6, t.Data7, t.Data8, t.Data9, t.Data10}\n go handleCmd(strings.ToLower(args[0]), args[1:])\n return\n }\n }\n \n default:\n log.Errorf(\"%s Sorry, only GET and POST methods are supported.\", w)\n }\n}\n\nfunc kill_server() {\n if is_mode == \"receive\" {\n return\n }\n resp, err := http.Get(\"http://localhost:7770\")\n if err == nil {\n body, err := ioutil.ReadAll(resp.Body)\n if err == nil {\n sb := string(body)\n \n if strings.Contains(sb, \"mdtest is running\") {\n server.Close()\n }\n }\n }\n}\n\nfunc MdtestStart() {\n if is_mode == \"receive\" {\n return\n }\n \n resp, err := http.Get(\"http://localhost:7770\")\n if err == nil {\n body, err := ioutil.ReadAll(resp.Body)\n if err == nil {\n sb := string(body)\n \n if !strings.Contains(sb, \"mdtest is running\") {\n http.HandleFunc(\"/\", mdtest)\n log.Infof(\"mdtest started\")\n server = &http.Server{\n Addr: \":7770\",\n Handler: http.DefaultServeMux,\n }\n server.ListenAndServe()\n log.Infof(\"mdtest stopped\")\n }\n } \n } else {\n http.HandleFunc(\"/\", mdtest)\n log.Infof(\"mdtest started\")\n server = &http.Server{\n Addr: \":7770\",\n Handler: http.DefaultServeMux,\n }\n server.ListenAndServe()\n log.Infof(\"mdtest stopped\")\n }\n}" whatsmeow/mdtest/main.go | |
line="$(grep -n 'log.Infof("Marked self as available")' whatsmeow/mdtest/main.go | sed 's/:.*//' | sort -r)" | |
for i in $line | |
do | |
sed -i "${i} a if is_mode == \"both\" {\n log.Infof(\"Receive/Send Mode Enabled\")\n log.Infof(\"Will Now Receive/Send Messages In Tasker\")\n go MdtestStart()\n } else if is_mode == \"receive\" {\n log.Infof(\"Receive Mode Enabled\")\n log.Infof(\"Will Now Receive Messages In Tasker\")\n go MdtestStart()\n } else if is_mode == \"send\" {\n log.Infof(\"Send Mode Enabled\")\n log.Infof(\"Can Now Send Messages From Tasker\")\n go MdtestStart()\n }" whatsmeow/mdtest/main.go | |
done | |
sed -i "$(grep -nm 1 'img := evt.Message.GetImageMessage()' whatsmeow/mdtest/main.go | sed 's/:.*//'),$(($(grep -nm 1 'log.Infof("Saved image in message to %s", path)' whatsmeow/mdtest/main.go | sed 's/:.*//')+1))d" whatsmeow/mdtest/main.go | |
sed -i 's/Os: proto.String("whatsmeow"),/Os: proto.String("whatsmeow2"),/' whatsmeow/store/clientpayload.go | |
value="true"; key="allow-external-apps"; file="/data/data/com.termux/files/home/.termux/termux.properties"; mkdir -p "$(dirname "$file")"; chmod 700 "$(dirname "$file")"; if ! grep -E '^'"$key"'=.*' $file &>/dev/null; then [[ -s "$file" && ! -z "$(tail -c 1 "$file")" ]] && newline=$'\n' || newline=""; echo "$newline$key=$value" >> "$file"; else sed -i'' -E 's/^'"$key"'=.*/'"$key=$value"'/' $file; fi | |
cd whatsmeow/mdtest | |
go mod tidy | |
clear | |
echo -e "\nFinal step, building mdtest binary. Takes about 10s~1min" | |
go build | |
if [ $? -eq 0 ] | |
then | |
mv -f ~/whatsmeow2/mdtest/mdtest.db ${tmpdir}/whatsmeow/mdtest >/dev/null 2>&1 | |
rm -rf ~/whatsmeow2 >/dev/null 2>&1 | |
mv ${tmpdir}/whatsmeow ~/whatsmeow2 >/dev/null 2>&1 | |
echo -e "\nDone, now type \"cd ~/whatsmeow2/mdtest && ./mdtest\"\nto check if WhatsApp qr code is generated properly.\n\nNote:- In case qr code is too big, you can pinch the\nscreen to resize it.\n\nThe code refreshes after some time so quickly take a\npicture of it using a spare phone and\nopen WhatsApp -> ⋮ (menu) -> Linked Devices\nand scan this code in the main device.\n\nGreat, you will now be able to send/receive WhatsApp\nmessages directly as easy Tasker variables.\nYou can integrate this automation apps like Tasker and\neven create WhatsApp chatbots.\n\nCheck Reddit post for more info -\n\nhttps://www.reddit.com/r/tasker/comments/11a4k49/howto_sendreceive_whatsapp_message_project_v2/\n" | |
fi | |
rm -rf $tmpdir >/dev/null 2>&1 | |
cd | |
go clean -cache | |
pkg clean |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment