Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

WhatsAPP and VFP9 SP2

Steve-vfp9user

Programmer
Feb 5, 2013
336
GB
Hello all

Haven't posted for a long time and hoping someone can suggest a link or other assistance.

This forum has multiple posts for WhatsAPP messages via VFP but having tried them, none appear to be working, well at least not for me.

I have the WhatsAPP Windows 10 App installed from the Microsoft Store which actually opens when I run the code below and shows the thread of the recipient I am trying to send a message to but the actual message is not being sent.

I asked chatGPT to come up with this but it's not working. No error meesages are shown.

Code:
DECLARE INTEGER ShellExecute IN SHELL32.DLL ;
    INTEGER hWnd, STRING lpOperation, STRING lpFile, ;
    STRING lpParameters, STRING lpDirectory, INTEGER nShowCmd

* Define the recipient phone number (without spaces or symbols)
lcPhoneNumber = "447539677744"  && Replace with actual number

* Define the message to send
lcMessage = "Hello, this is an automated message from Visual FoxPro!"

* Open WhatsApp chat
lcWhatsAppURL = "whatsapp://send?phone=" + lcPhoneNumber
ShellExecute(0, "open", lcWhatsAppURL, "", "", 1)

* Wait for WhatsApp to open
SLEEP(6000)  && Adjust delay if needed

* Type the message using NirCmd
lcNirCmdPath = "C:\nircmd\nircmd.exe"  && Adjust path if needed

* Simulate typing the message
lcCmd = '"' + lcNirCmdPath + '" sendkeypress "' + lcMessage + '"'
RUN /N &lcCmd

* Simulate pressing "Enter" to send the message
RUN /N C:\nircmd\nircmd.exe sendkeypress 0x0D
 
I have no familiarity with this, I just happened to read it and was curious enough to reply.

There are no error messages because for one, the generated code doesn't do any error checking - it is written making a lot of assumptions, the main one being that everything will work fine, no checking return values/statuses etc.

One thing you didn't make clear is whether the message gets "typed" by the part that simulates typing the message, you just said the message doesn't send. I will assume it is NOT being "typed" as that is probably the main problem and why no message is sent, the whole thing relies on a lot that is outside of your absolute control.

My interpretation of the main part of the code and the potential flaws, follows

The "* Open WhatsApp chat" section, you are Shell-Executing a string that begins "whatsapp://send" so your machine (and every other machine this might run on) needs to be told what to do here. Windows probably doesn't natively know what to do with a string that being "whatsapp://send" but this isn't a part that fails, it's just something to note. Your description is that you've installed a WhatsApp application from the MS Store and this section is working for you so presumably this part is mostly fine because installing the app is what allows Windows to know how to handle that string.

The "* Wait for WhatsApp to open" section, this is just a pause to wait for the app to load presumably but SLEEP is not a native VFP command. It is a WinAPI call which your code doesn't show you've declared it but presumably you have at some other point in your dev session otherwise that line would throw an error like "Unrecognised command verb" or similar.

What is also interesting with these kinds of solutions is that just having an arbitrary call to Sleep for an arbitrary value does make it look like a bodge, getting the code to wait for non-concrete amount of time to wait for something external to do something. 6 seconds on one machine isn't equal to 6 seconds on a different machine with different performance, it's an inexact aspect.

Because this solution is using a third-party application in this manner you are always at the mercy of that third-party app changing in some way. You might get this working eventually but what if the app auto-updates a week later and then the current solution no longer works because the app does something subtly different to before. It's always a risk.

The "* Type the message using NirCmd" and "* Simulate typing the message" sections are where the solution is likely failing. I'm not familiar with NirCmd but briefly looking at it, it does appear to be a cmd-like app for doing things mostly invisibly so I can understand what it is trying to do. This part looks like it is 100% reliant on your caret (focus) being in the correct place as it is effectively just taking the message from earlier in the program and almost "playing it" as if it is being typed live BUT if when the WhatsApp application launched and showed you the correct thread, the caret isn't in the correct place, then simulating the message being "typed" may not put the message anywhere, it might just go into the ether.

I suppose this is similar to if you scripted something to try to automatically type in all the entries in a form you didn't have control of, with tabs etc to move from one field to another and then the form changed, even subtly, so the wrong values were being typed into the wrong fields. In that scenario you'd have to update your script accordingly.

Perhaps for you, this program assumes that the caret (focus) is in the correct place in the WhatsApp app and it simply isn't.

The "* Simulate pressing "Enter" to send the message" section is similar to above. It is probably 100% reliant on the caret or focus being in the correct place and it is not. Perhaps simulating pressing Enter does not send the message either because the app disables the "Send" facility when there is no message (and the earlier section not typing the message is why there is no message) or just the focus being in the wrong place is why simulating pressing Enter doesn't do anything.

In summary the code you've got works on assumptions:

1. It assumes that the Windows shell will know how to handle the "whatsapp://send" string - it does for you, you get that by installing the application
2. It waits for a non-concrete amount of time for the app to launch, select the correct recipient and make itself ready - on one machine this could be fine being 6 seconds, on a slower machine might it need 10 seconds or even 20 seconds.
3. It assumes that the caret will be in the correct place, ready to received a "simulated" typed message. If the caret never gets to the correct input box or if it's just not there because the SLEEP was too short - this is possibly the breaking point.
4. Same as #3 it assumes that simulating pressing enter will tell the control that currently has the focus to send the message but if the wrong control has the focus, plus if #3 fails, then #4 is likely to fail also

I don't necessarily have a solution, that's just my analysis of the code and where the problem(s) could lie.
 
There's at least another two assumptions that the code makes that I didn't mention in the initial reply. The code doesn't double-check it just assumes that nircmd.exe exists, and it exists in the path you've specified.

In the "simulate typing" part the run command is built up using the lcNirCmdPath variable but the code doesn't actually pre-emptively check that the exe does exist at that path. If it didn't exist then the RUN command would fail and you'd get a visible error at runtime so since you say you are not getting an error we can presume that you do have it installed in that location and that adds extra credence to the theory that the reason this whole thing is failing is because when nircmd.exe runs and simulates typing the message, the caret (focus) just isn't in the correct place.

Further, even though in the "simulate typing" part the run command is built up using the lcNirCmdPath variable, the "simulate pressing enter" part has the run command totally ignore the lcNirCmdPath variable. So you've got the full path to the exe specified on two different lines. Not a problem if you can always guarantee that the exe lives at that specific path and especially if you do some checking before but as the code stands right now, if you put the exe in a slightly different place, you'd have two different lines of code to update, which isn't great coding, something to be avoided if you can. If something can be variable, put it in one place and with something like a path to a file you can write the code to check if the file exists and make that an IF surrounding all the parts that rely on the file being there, perhaps even putting a MESSAGEBOX in the ELSE to inform you if it doesn't exist - at least temporarily in dev while you test the whole proof of concept (POC).

It's always a good idea if you are trying a new POC to write plenty of error checking, evaluation of return values, even outputting things to the "console" using ? if you are really struggling to figure out what is going on. Then when you've got it working remove any unnecessary debugging output, but it is still always useful to check return values etc, especially on things like ShellExecute.
 

Part and Inventory Search

Sponsor

Back
Top