Is sending iMessages/SMS/MMS by scripting the Messages program completely unreliable?

This is my code:

on run ()
set theMsg to "Hello world"
set contacts to {{contact:"mailaddress", hex:"x9B"}, {contact:"mailaddress", hex:"x9C"}, {contact:"phonenumber", hex:"xA7"}, {contact:"phonenumber", hex:"xA8"}}
	repeat with adressee in contacts
		try
			set theHex to hex of adressee
			set theContact to contact of adressee
			set theMsg to msg & theHex
			tell application "Messages"
				send theMsg to participant theContact
			end tell
			set myDelay to (random number from 3 to 6)
			delay myDelay
		on error errMsg
			log "error: " & errMsg
		end try
	end repeat
end run

But the recipient list is some 400 recipients, a mix of phone numbers and e-mail addresses. Some phone numbers/e-mail addresses are connected with an Apple account and can receive iMessages, while others aren’t and therefore receives SMS/MMS (MMS might sometimes be delivered by e-mail).

Furthermore, the message sent is pretty long, about 850 characters so it might be sent as either 6 linked SMS or an MMS.

This is not spam, everyone has opted in. It is for society with very high level of engagement. That is, I don’t think anyone will report this as spam or something like that.

This is what happens:

  1. The first few messages are sent, but then it gets stuck on a message. There is progress bar in the upper part of the window, either green or blue (I guess it indicates whether it is an SMS or iMessage in that particular chat):


Note that the To:-field is empty.

I have left it like this for an hour, with no progress.

  1. When I click a chat that is stuck like this in the list of chats to the left, the recipient just disappears!?

ezgif-15d989e0d05bb

(The blue flash indicates a click)

  1. I run this script from Script Editor. If I click Stop in the middle of the execution you would expect the script to stop immediately, but it doesn’t instead it “rushes” through the loop, ignoring any delay I have specified, “sending” maybe another hundred messages. I am not sure if those messages are actually sent, or tried to be sent - they all (?) end up like I describe in (1) and (2) above.

It might be that I actually have to click Stop twice to actually stop the script. That, the first time I click Stop it starts to rush through the loop and the second time I click Stop it actually stops.

  1. Manually sending messages, both SMS and iMessages, and both long and short messages, seems to work fine.

  2. I just noticed that messages/recipients that I thought had failed have received multiple message. That is, I tried to send a message to A an hour ago but (2) happened and when I restarted Messages A had disappeared from the list of chats. Later on I try to send a new message to A and this time it is successful, but when I look at the entry for A there are two messages, one timestamped an hour ago and one timestamped a few seconds ago.

Is the Messages program unreliable? Especially when scripting? Has anyone tried what I try to do? That is, send a message to a couple of hundred recipients using different protocols? Did it work for you?

I’m afraid I have no specific knowledge of this area that might help, however, if it was me, I would build some debug logging. make a count that increments at a point that indicates, say, the (apparent) successful completion of a message. Provide an output message or log entry with the specifics of the data being handled.
Maybe control ‘debug mode’ with an interactive option on start up “do you need full debugging info Y/N” or similiar. Add a limit ‘How many records to process’. and ‘What record number to start from’ - all that sort of thing.
Also some metrics at the completion or interruption “126 addresses used, 63 were SMS”. - that sort of thing.
I would not expect it to be unreliable, but I might expect that it can be upset by unexpected data. See if you can locate a specific record where it locks. Obtain permission from the owner, and test with just that record (again, condition your script to run the loop to that point, and not send the previous entries.