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 sizbut 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 2

Status
Not open for further replies.

Steve-vfp9user

Programmer
Feb 5, 2013
337
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.
 
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.
Paul

You mentioned, "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 apologies, the message doesn't get typed, it just opens the list of recipients on my Whatsapp list after I execute the code but no message is ever sent or typed.
 
OK, that was the assumption that I was going on so thanks for confirming it.

You said, in your original message:
... which actually opens when I run the code below and shows the thread of the recipient I am trying to send a message to...
so the assumption I'm making from that part, is that the ShellExecute bit of the code is working absolutely fine, the correct app is loading and within the app it's going to the correct recipient. However, what happens next is probably outside your control, it is entirely within the control of the WhatsApp application, not you.

My whole theory as to why the code is not doing what you want is that after the WhatsApp application opens and navigates to the correct recipient, the caret is not sitting in the correct place for a message to be "typed", this means when you leverage the nircmd.exe to simulate typing a message, it is doing that but with the caret not in the correct place, that simulation is just "typing keys" into the ether.

At each point there are potentials for failure, at the point where I believe it is not working for you, the assumption the code is making is that the WhatsApp application has the caret/focus in the correct place so when nircmd.exe simulates typing the message, it is the WhatsApp application that has the caret in the correct place, happy to receive the simulated key-presses. It could be that there is no way of 100% ascertaining that the application loads and puts the focus at the correct place.

As I intimated in my first reply, that code may have been written by someone a while back, when the behaviour of the WhatsApp application was such that the caret/focus did end up in the correct place but now the application might be on a different version, with different behaviour which means it is not. Heck, they might have deliberately changed the WhatsApp application to stop people automating it in the manner that you are attempting to. That's what you could be up against with this program.

One thing you can potentially try is just comment out everything AFTER the call to SLEEP, then run the whole code, sit back, wait the 6 (or so) seconds and then look at the WhatsApp application, just observe it. Where is the caret? Is the caret blinking away anywhere? If you can't see it, can you press tab and see if you can make a caret or focus move about the screen? That's the type of analysis that you may have to do, to try to figure out where the focus is.

If the focus is not in the correct place then, with the application launching the way you are, can you, with JUST the keyboard, press keys, particularly the tab key or any hotkeys or shortcuts, to get the focus/caret in the correct place? If you can't do it manually with your keyboard then you might not be able to tell nircmd.exe how to do it.

I don't have any desire to install the WhatsApp application on any of my machines so I am trying to help, a little blind. One thing you could potentially do is, run the program while everything after the sleep is commented out, wait the 6 (or so) seconds and then take a screenshot. Paste the screenshot into your favourite image editing application, blur anything that you don't want us to see (people's mobile numbers etc) and then attach that image to a reply on this thread and perhaps someone here can see more of what you are describing and we'll have a bit more information to go on.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top