Page 1 of 1

Programmatically set retry count/delay amount

Posted: 2019-05-12 16:30
by cblaze22
Is there a way to programmatically set the retry count and delay amount when an emails fails, specifically like a 421 status code where the receiving server has a quota limit and we would like to send those emails on a delay in the future.

Other errors like 452 or 500 can be rejected out right and not tried again. We have retry set to 0 and number of minutes 0 currently, but would like to have a retry on 421 status codes.

I believe we can do this on OnDeliveryFailed.

Re: Programmatically set retry count/delay amount

Posted: 2019-05-12 18:06
by SorenR

Re: Programmatically set retry count/delay amount

Posted: 2019-05-12 20:05
by jimimaseye
... which concludes thus: https://www.hmailserver.com/forum/viewt ... 10&t=30900

However i dont think these do what he is asking for. It seems he requires specific timings and responses dependant on specific return codes.

[Entered by mobile. Excuse my spelling.]

Re: Programmatically set retry count/delay amount

Posted: 2019-05-12 23:48
by mattg
5XX codes from another server are rejected, and hMailserver replies to the author with a daemon message
4XX codes from another server are asking for try again (ie greylisting), these are retried as per the settings in hMailserver in SMTP delivery

Can you set custom retries per message? Sure but you would need to manage that from a database or such, and as part of that make the next retry a long long time away so that it doesn't retry when you don't want it to.

@cblaze22 what EXACTLY are you hoping to do?

Re: Programmatically set retry count/delay amount

Posted: 2019-05-13 01:00
by cblaze22
These email to text carriers have quota limits per hour. We get messages like the one below quite a bit because of how much messaging occurs during weekend tournaments. The example below is for 7077314137@pm.sprint.com.
"Error Type: SMTP[nl] Remote server (52.32.5.167) issued an error.[nl] hMailServer sent: [nl] Remote server replied: 421 spr-ibgw-6002a.stratus.cloudmark.com cmsmtp SMTP server temporarily not available AUP#1260[nl]"
I contacted one of these servers and they concluded it was just that. I want to not retry messages because of log backup with ALL status codes. 500 are sent to a webhook to delete them, while right now all the soft bounces arent retried. However, I would like to retry the 421 since we just went over a limit of messages per hour and try again later.

Re: Programmatically set retry count/delay amount

Posted: 2019-05-13 01:22
by mattg
Looking at the diagnostics that you provided earlier

Code: Select all

SMTP
GENERAL             DELIVERY                  RFC COMPLIANCE            ADVANCED
No. Connections:  0  No Retries:  0 Mins:  0   Plain Text:        False  Bind: 
                     Host: Domain1.com         Empty sender:       True  Batch recipients:    25
Max Msg Size:200480  Relay:-                   Incorrect endings:  True  Use STARTTLS:      True
                     (none entered)            Disc. on invalid:  False  Delivered-To hdr: False
                                                                         Loop limit:           5
                                                                         Recipient hosts:     15
  Routes:
     No routes defined.
Set retries to at least 10, and minutes at at least 10

This may also be a reason that you have so much in your queue.
Every fail, you are trying to reply to the sender saying that the recipient couldn't be reached.

I think the RFCs say that you should retry for 3 days (That's what I do, but I also script a 'trying' notification to the sender after 1 hour and then after each day, so that they know)

Re: Programmatically set retry count/delay amount

Posted: 2019-05-13 01:50
by palinka
cblaze22 wrote:
2019-05-13 01:00
These email to text carriers have quota limits per hour. We get messages like the one below quite a bit because of how much messaging occurs during weekend tournaments. The example below is for 7077314137@pm.sprint.com.
"Error Type: SMTP[nl] Remote server (52.32.5.167) issued an error.[nl] hMailServer sent: [nl] Remote server replied: 421 spr-ibgw-6002a.stratus.cloudmark.com cmsmtp SMTP server temporarily not available AUP#1260[nl]"
I contacted one of these servers and they concluded it was just that. I want to not retry messages because of log backup with ALL status codes. 500 are sent to a webhook to delete them, while right now all the soft bounces arent retried. However, I would like to retry the 421 since we just went over a limit of messages per hour and try again later.
You could resolve those messages to an sms gateway.

Re: Programmatically set retry count/delay amount

Posted: 2019-05-13 03:57
by cblaze22
Not sure what you mean by resolve it with a sms gateway.

Re: Programmatically set retry count/delay amount

Posted: 2019-05-13 04:16
by cblaze22
Oh you mean like Twilio, which we do integrate with but you have to PAY! We ran 163,000+ messages in two days. Thats $1,222+ with Twilio!

Re: Programmatically set retry count/delay amount

Posted: 2019-05-13 11:59
by palinka
Yeah, that's a lot of volume.

I use gammu and a cheap usb modem. I use it mainly for automated messages and reminders for my kids. What i found even with my tiny volume is that email messages to carrier gateways vey easily get caught up in their spam filters. That's why i went with the modem/gammu. I don't think you'd have any better success getting messages through going that route due to your volume.

Soren helped me script a forward-to-gateway called by rule matching regex that looks for a phone number as email address. It works brilliantly. Gammu runs on windows too.

Re: Programmatically set retry count/delay amount

Posted: 2019-05-13 14:49
by cblaze22
Any thoughts on these?

https://www.tecmint.com/best-open-sourc ... -software/

I need this installed on Windows and doesnt look like there are many options. Looks like you have to have a modem connected, which on Azure I dont have the possibility too.

Re: Programmatically set retry count/delay amount

Posted: 2019-05-13 15:23
by palinka
cblaze22 wrote:
2019-05-13 14:49
Any thoughts on these?

https://www.tecmint.com/best-open-sourc ... -software/

I need this installed on Windows and doesnt look like there are many options. Looks like you have to have a modem connected, which on Azure I dont have the possibility too.
Im using gammu. It works. But like i said, unless you're a short code operator with an agreement with the phone carriers, you'll likely get caught in their sms spam filters with that kind of volume.

The hardware issue can be solved by running gammu off a box at your house. Then route messages from azure hmailserver to your house hmailserver, then extrapolate the mobile number and send with gammu.

It might be worth a try if those messages are getting bounced/trapped anyway. I paid $10 for my cheap huwei usb modem on Amazon and added a data line to my tmobile plan for $10/month. If all it costs is $20 to find out if it works when those messages are failing anyway, why not? I believe these cheapie modems are capable of sending 60 messages per second, so the hardware can handle the volume - the only question is whether anyone will actually receive the messages you're sending.

Last thing - kalkun doesn't work with the latest gammu (it was on your link with gammu). Latest gammu handles cheap modem firmware much better than older versions that work with kalkun. You don't need kalkun anyway. It's just a php gui for existing gammu db. It has a couple of cool features but nothing you can't script on your own.

Re: Programmatically set retry count/delay amount

Posted: 2019-05-18 14:53
by cblaze22
Back to the original question. I have failed emails, which call a http request to remove it. However, I set the retry count to 3. This means that failed email will be called 3 times for 500+ errors when its already been removed.

My question is can I set the retry count, loop of the email? If so how can I do this in code? I want it to not retry.

Re: Programmatically set retry count/delay amount

Posted: 2019-05-18 17:23
by cblaze22
Or can you delete the message altogether in Sub OnDeliveryFailed(oMessage, sRecipient, sErrorMessage) so it doesnt retry? Can Result.Value = 2 work in this method?

Re: Programmatically set retry count/delay amount

Posted: 2019-05-19 02:52
by mattg
cblaze22 wrote:
2019-05-18 17:23
Or can you delete the message altogether in Sub OnDeliveryFailed(oMessage, sRecipient, sErrorMessage) so it doesnt retry? Can Result.Value = 2 work in this method?
No, that won't work

cblaze22 wrote:
2019-05-18 14:53
have failed emails, which call a http request to remove it.
That's the point where I would remove the email from the queue

Re: Programmatically set retry count/delay amount

Posted: 2019-05-23 05:19
by cblaze22
Oh yea that makes sense, just remove the email if its not say 421. How do you remove something from the queue though programmatically?

Something like this

Code: Select all

GlobalObjects.DeliveryQueue.Remove(oMessage.ID)
in the DeliveryFail method?

Re: Programmatically set retry count/delay amount

Posted: 2019-05-23 09:56
by mattg
yes, I think that should work

Re: Programmatically set retry count/delay amount

Posted: 2019-05-23 13:45
by cblaze22
Will that syntax work within the normal script methods. I know I had to initialize the DeliveryQueue with the COM API outside of it.

Re: Programmatically set retry count/delay amount

Posted: 2019-05-24 01:07
by mattg
cblaze22 wrote:
2019-05-23 13:45
Will that syntax work within the normal script methods. I know I had to initialize the DeliveryQueue with the COM API outside of it.
Had to, or choose to?

As long as you can get the MessageID it should work. Getting the messageID may be a problem.
When do you check the response code?

Re: Programmatically set retry count/delay amount

Posted: 2019-05-25 05:18
by cblaze22
I am doing this inside the Sub OnDeliveryFailed(oMessage, sRecipient, sErrorMessage) method. I did a test and the syntax doesnt break anything. I did a test to view the queue of the email going through the loop count. However, after the email fails, 550, it doesnt stay in the queue to retry. Is this by design? This is without calling the .Remove on the queue.

Re: Programmatically set retry count/delay amount

Posted: 2019-05-25 06:06
by cblaze22
I think its just a delay in the queue being updated that is throwing me off. I saw some emails pop back up. However the code below seems to be working. If you think there is a better way to refactor it let me know, not a VBScript expert.

Code: Select all

Sub OnDeliveryFailed(oMessage, sRecipient, sErrorMessage)

	Dim regex, matches, match, strResult

	EventLog.Write(sRecipient)
	EventLog.Write(sErrorMessage)

	Set regex = New RegExp
   	regex.IgnoreCase = True
	regex.MultiLine = True
   	regex.Pattern = "^.*Remote server replied: ([0-9]{3}).*$"
 
   	Set matches = regex.Execute(sErrorMessage)

   	If matches.Count >= 1 Then
      		Set match = matches(0)
      		If match.SubMatches.Count >= 1 Then
         		strResult = match.SubMatches(0)
      		Else
         		strResult = ""
			On Error Resume Next
				GlobalObjects.DeliveryQueue.Remove(oMessage.ID)
			On Error Goto 0
         		exit sub
      		End If
   	Else
      		strResult = ""
		On Error Resume Next
			GlobalObjects.DeliveryQueue.Remove(oMessage.ID)
		On Error Goto 0
      		exit sub
   	End If
	EventLog.Write(strResult) 
        EventLog.Write(oMessage.ID)
	If IsNumeric(strResult) And CInt(strResult) >= 500 Then
      		On Error Resume Next
                GlobalObjects.DeliveryQueue.Remove(oMessage.ID)

Re: Programmatically set retry count/delay amount

Posted: 2019-05-25 08:02
by mattg
SMTP 5XX codes should trigger a bounce back to the sender, not a retry

Retries should only happen after 4XX codes

Re: Programmatically set retry count/delay amount

Posted: 2019-05-26 15:58
by cblaze22
Ok I think that makes sense with the 500. But with errors like "Error Description: No mail servers appear to exists for the recipient's address", which has no status code it looks like even when I remove the Message with the Message ID, it creates a new Message ID. So it looks like the code below doesnt accomplish removing messages with no status code, so a retry occurs.

Code: Select all

GlobalObjects.DeliveryQueue.Remove(oMessage.ID)

Re: Programmatically set retry count/delay amount

Posted: 2019-05-26 23:51
by mattg
You can also catch messages with a global rule that looks for 'delivery attempts' and can delete messages with that.

I use that to trigger 'been trying an hour and not delivered yet' type emails to the sender of the message

Re: Programmatically set retry count/delay amount

Posted: 2019-05-27 01:03
by cblaze22
Well I can control delivery attempts through UI but I want to do this only through certain failed messages. Guess I could add a new header to the email like X-Status-Code: 500 and if set to say -1 then delete it with a rule. Does that make sense?

Re: Programmatically set retry count/delay amount

Posted: 2019-05-27 07:05
by mattg
sure, and that will also work

Re: Programmatically set retry count/delay amount

Posted: 2019-05-28 00:38
by cblaze22
I have a weird thing going on here. There is stuff in my queue, and when I send now for something like cherylspink@outlook.con which it should fail, but the log below with SMTP turned on only produces that and leaves it in the Queue when clicking Send now. Any suggestions on this? It should hit my OnDeliveryFailed method but never did.

"DEBUG" 7244 "2019-05-27 18:36:08.504" "PersistentMessage::SetNextTryTime()"
"DEBUG" 7244 "2019-05-27 18:36:08.515" "PersistentMessage::~SetNextTryTime()"
"DEBUG" 4144 "2019-05-27 18:36:08.515" "Adding task DeliveryTask to work queue SMTP delivery queue"
"DEBUG" 4536 "2019-05-27 18:36:08.515" "Executing task DeliveryTask in work queue SMTP delivery queue"
"DEBUG" 4536 "2019-05-27 18:36:08.515" "Delivering message..."
"DEBUG" 4536 "2019-05-27 18:36:08.515" "Applying rules"
"DEBUG" 4536 "2019-05-27 18:36:08.515" "Applying rule Delete No Reply"
"DEBUG" 4536 "2019-05-27 18:36:08.515" "Performing local delivery"
"DEBUG" 4536 "2019-05-27 18:36:08.515" "Local delivery completed"
"DEBUG" 4536 "2019-05-27 18:36:08.515" "Summarizing delivery result"
"DEBUG" 4536 "2019-05-27 18:36:08.515" "Summarized delivery results"
"DEBUG" 4536 "2019-05-27 18:36:08.515" "SD::RescheduleDelivery_"
"DEBUG" 4536 "2019-05-27 18:36:08.515" "Retrieving retry options."
"DEBUG" 4536 "2019-05-27 18:36:08.515" "Starting rescheduling."
"DEBUG" 4536 "2019-05-27 18:36:08.515" "PersistentMessage::SetNextTryTime()"
"DEBUG" 4536 "2019-05-27 18:36:08.530" "PersistentMessage::~SetNextTryTime()"
"DEBUG" 4536 "2019-05-27 18:36:08.530" "Message rescheduled for later delivery."
The only time it hits the OnDeliveryFailed is when it has no more retries.
"DEBUG" 5228 "2019-05-27 18:49:29.148" "PersistentMessage::SetNextTryTime()"
"DEBUG" 5228 "2019-05-27 18:49:29.163" "PersistentMessage::~SetNextTryTime()"
"DEBUG" 4144 "2019-05-27 18:49:29.163" "Adding task DeliveryTask to work queue SMTP delivery queue"
"DEBUG" 4260 "2019-05-27 18:49:29.163" "Executing task DeliveryTask in work queue SMTP delivery queue"
"DEBUG" 4260 "2019-05-27 18:49:29.163" "Delivering message..."
"DEBUG" 4260 "2019-05-27 18:49:29.179" "Applying rules"
"DEBUG" 4260 "2019-05-27 18:49:29.179" "Applying rule Delete No Reply"
"DEBUG" 4260 "2019-05-27 18:49:29.179" "Performing local delivery"
"DEBUG" 4260 "2019-05-27 18:49:29.179" "Local delivery completed"
"DEBUG" 4260 "2019-05-27 18:49:29.366" "Summarizing delivery result"
"DEBUG" 4260 "2019-05-27 18:49:29.366" "Summarized delivery results"
"DEBUG" 4260 "2019-05-27 18:49:29.366" "SD::RescheduleDelivery_"
"DEBUG" 4260 "2019-05-27 18:49:29.366" "Retrieving retry options."
"DEBUG" 4260 "2019-05-27 18:49:29.366" "Aborting delivery."
"DEBUG" 4260 "2019-05-27 18:49:29.366" "Executing event OnDeliveryFailed"
"DEBUG" 4260 "2019-05-27 18:49:30.203" "Event completed"
"DEBUG" 4260 "2019-05-27 18:49:30.203" "Message not rescheduled for later delivery."
"DEBUG" 4260 "2019-05-27 18:49:30.203" "SD::SubmitErrorLog_"
"DEBUG" 4260 "2019-05-27 18:49:30.203" "Saving message: {ABA5E2C6-8E50-42F4-8259-B2F4EC4E3BC6}.eml"
"DEBUG" 4260 "2019-05-27 18:49:30.219" "SD::~SubmitErrorLog_"
"DEBUG" 4260 "2019-05-27 18:49:30.219" "Deleting message"
"DEBUG" 4260 "2019-05-27 18:49:30.234" "Deleting message file."

Re: Programmatically set retry count/delay amount

Posted: 2019-05-28 00:58
by mattg
cblaze22 wrote:
2019-05-28 00:38
The only time it hits the OnDeliveryFailed is when it has no more retries.
That's logically correct (and also why I didn't know that OnDeliveryFailed triggered for outgoing messages. I normally don't let messages get that far. I send delayed one hour, delayed 1 day, delayed 2 days messages first, and probably manually remove the offending message)

In your case the message has not been delivered YET until the final delivery attempt, then it is a FAILED DELIVERY message.

Just because a server can't be found now for outlook.con doesn't mean that one won't exist in the near future, it just may be a DNS propagation issue momentarily.

Re: Programmatically set retry count/delay amount

Posted: 2019-05-28 02:36
by cblaze22
Well yea but I didnt know it didnt call it on every call but it does make sense but I am back at square one. Well when can I add the X-Failure header then lol. Does it hit any other methods that you know of on a failure/retry setup?

Re: Programmatically set retry count/delay amount

Posted: 2019-05-29 18:52
by cblaze22
So is there no way to add something to an email header in the queue that failed on the first try?

Re: Programmatically set retry count/delay amount

Posted: 2019-06-10 05:05
by cblaze22
Well I really cant think of anything else I can do in this regard. I thought there maybe a way since we figured out the X-Priority and Unsubscribe based on status code features we needed.

Re: Programmatically set retry count/delay amount

Posted: 2019-06-10 07:01
by mattg
How about you add a non-descript header to ALL messages using OnDeliverMessage

And then look for messages with that header in the queue using your scheduled task

messages without that header won't have been attempted