Skip to content

Instantly share code, notes, and snippets.

@HunterXProgrammer
Last active March 17, 2023 14:58
Show Gist options
  • Save HunterXProgrammer/a1894f4a80d807d63b8467b3e053f094 to your computer and use it in GitHub Desktop.
Save HunterXProgrammer/a1894f4a80d807d63b8467b3e053f094 to your computer and use it in GitHub Desktop.
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/
#!/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