(07-16-2024, 11:38 AM)Justin Case Wrote: IdSMTPServer1MsgReceive(ASender: TIdSMTPServerContext; AMsg: TStream; var VAction: TIdDataReply);
EEeeeek!
Yeah, Indy 9 gave you a choice of 3 different events to receive emails: OnReceiveRaw, OnReceiveMessage, and OnReceiveMessageParsed. In Indy 10, there is only a single event, OnMsgReceive (effectively the same as OnReceiveRaw). TIdSMTPServer no longer makes any assumptions about what the data represents or what to do with the data, it lets you handle all of that in your own code.
(07-16-2024, 11:38 AM)Justin Case Wrote: So, I've done:
Msg := TIdMessage.Create;
Msg.LoadFromStream(AMsg);
But now I am stuck with a new problem... who is it TO?
ASender.RCPTList.EMailAddresses (and similar under ASender.RCPTList) !!!
Yes, ASender.RCPTList contains the actual recipients that the client specified in its RCTO TO commands. These are the actual recipients you must deliver to. The TStream in the OnMsgReceive event is the raw data that the client wants delivered to each recipient. It can be any arbitrary data, but it is usually an RFC 822/2822 formatted email. Its To: and Cc: headers (if present) are not required to match the ASender.RCPTList and should not be considered for delivery purposes. The ASender.RCPTList is the source of truth. In fact, this is how BCC (Blind Carbon Copy) is implemented - BCC recipients are only available in the ASender.RCPTList and not in the TStream data. This is how clients can send emails to hidden recipients without letting all recipients know who the email is being sent to.
(07-16-2024, 11:38 AM)Justin Case Wrote: But there could be many there.. how do I know which one I approved earlier in RcptTo? - I could use a variable somewhere but I kinda thought it would be made available in the parameters!
It is, actually. If you reject a recipient in the OnRcptTo event, it will not be added to the ASender.RCPTList. Only approved recipients are stored in that list. This was the same in Indy 9, too.
In Indy 10, the email data will not be accepted unless at least 1 recipient is approved (Indy 9 would accept an email with no approved recipients). The client will be told which recipients are rejected. If you reach the OnMsgReceive event, it means the client is ok with the rejected recipients and has decided to continue on with delivery to the remaining recipients who were approved.
(07-16-2024, 11:38 AM)Justin Case Wrote: It looks like I need to loop through the items and process every single address all over again to determine if it's ok or a fail.
You need to process the ASender.RCPTList to know who has been accepted to deliver the data to, yes. But you should have already validated each recipient in the OnRcptTo event. You don't need to do it again. By the time you reach the OnMsgReceive event, the client has been told you are accepting the email for delivery and thus you are now required to deliver the provided data to approved recipients.
(07-16-2024, 11:38 AM)Justin Case Wrote: Is that correct or am I missing something? Should I just call the RcptTo event on each address?
No.
(07-16-2024, 11:38 AM)Justin Case Wrote: Obviously if it's an outgoing mail I guess that's straight forward but if it's incoming for a local user and there's lots of addresses in there that is gonna require more cpu cycles right?
Each entry in the ASender.RCPTList is an individual recipient. If you read the ASender.RCPTList.EMailAddresses property, it will consolidate the entries into a single string. You don't need to do that (unless you want to store that string somewhere, of course).

