Question : Delphi Email Blaster - possibly using Report Builder and PsRBExportDevices

I am using Delphi 2009, Report Builder and PsRBExportDevices PRO.

I want to create an email blaster module in our application with the following features:
a) Program runs a query to return a dataset of customers
b) User is prompted to design their email template / report design (with 1 page per customer)
c) each page of the report is emailed to corresponding customer with report design as the body of the email (NOT AS AN ATTACHMENT)

I am open to ALL ideas / sugestions.

IMPORTANT REQUIREMENTS
* Email needs to support formatting (eg colours / fonts / graphics) - so must be RTF or HTML email format
* Email Blaster needs to be able to send hundreds of emails without getting blocked by the sending mail server anti-spam filter
* This module has to be controlled or at least managed by our Delphi applicaton
* Prefer not to have to export to 3rd party solution (but will consider it)
* For (b) editor can be Report Builder / MS Word / Some HTML Editor
* For (b) if using HTML Editor then what editor? (eg delphi component) AND how to merge data fields from our applications?

So far my best attempt has been to do this:
1) Use Report Builder to produce a separate report per customer (not a big problem)
2) Use PsRBExportDevices to export the report to a PDF file in the Windows Temp dir
3) Set PsRBExportMasterControl.PDF.EmailAfterGenerate:=true
4) Set the PsRBExportMasterControl.PDF.OnEmail event to the attached script below
5) Use INDY tIdSMTP and tIdMessage to send the email

The main problems with my attempt are that:
i) I can't get the content of the report to become the body of the email + I would like graphics in the body of the email as well
ii) I get spam issues for some mail servers (ie the sending server not the receiving server) - these servers don't like me sending lots of emails in a short period.  But how does outlook get away with it (eg when it has been offline with lots of emails ready to send)?

Perhaps I should just give up and use a 3rd party email marketing company such as the following:
* http://www.emailmarketingsoftware.com.au/email-newsletters
* http://www.vision6.com.au/
* http://www.futuremail.com.au/
* http://www.ezymsg.com/
BUT, If we go down this path...
* I must be able to easily export customer lists, details etc (may be different for each email run)
* I would really prefer it to appear as a seamless feature in our software / rather than have teh user manage the export / import
* I really would like to be able to export content like customer statements / invoices into the body of each email per customer

As I said I am open to all ideas / recommendations.  
THANK YOU in advance to all contributors.
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
227:
228:
229:
procedure TPrintBaseForm.PsRBExportMasterControlEMail(
  Sender: TPsRBExportDevice; EMailInfo: TPsRBEMailInfo;
  var Continue: Boolean);
var
  EmailParamFrm: TEmailParamsForm;
  res: TModalResult;
  ExpMstCtrl: TPsRBExportMasterControl;  

  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  function GetAddressString(AText: string): string;
  begin
    Result := Trim(AText);
    Result := StringReplace(Result, CRLF, ';', [rfReplaceAll]);
    if (Result <> '') and (Result[Length(Result)] = ';') then
      System.Delete(Result, Length(Result), 1);
  end;

  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  procedure DoSMTPCreate;
  begin
    if (not ConnectOnceSendMult) or (fIdSMTP=nil) then
    begin
      fIdSMTP:=TIdSMTP.Create(Self);
      //fIdSMTP.OnConnected:=ExpMstCtrl.OnEMailConnected;
      //fIdSMTP.OnDisconnected:=ExpMstCtrl.OnEMailDisConnected;
      //fIdSMTP.OnStatus:=ExpMstCtrl.OnEMailStatus;
      fIdSMTP.Host:=EMailInfo.Host;
      fIdSMTP.UserName:=EMailInfo.UserID;
      fIdSMTP.Password:=EMailInfo.Password;
      fIdSMTP.AuthType:=satNone;
    end;
  end;

  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  procedure DoSMTPConnect;
  begin
    if (not ConnectOnceSendMult) or ((fIdSMTP<>nil) and (not fIdSMTP.Connected)) then
      fIdSMTP.Connect;
  end;

  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  procedure DoSMTPDisconnect;
  begin
    if (not ConnectOnceSendMult) or (IsLastInSendMult and (fIdSMTP<>nil) and fIdSMTP.Connected) then
      fIdSMTP.Disconnect;
  end;

  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  procedure DoSMTPFree;
  begin
    if (not ConnectOnceSendMult) or (IsLastInSendMult and (fIdSMTP<>nil)) then
      FreeAndNil(fIdSMTP);
  end;

  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  procedure SendEmail;
  var
    IdMessage: TIdMessage;
    IdAttachment: TIdAttachmentFile;
    i: integer;
  begin
    ExpMstCtrl:=PsRBExportMasterControl;
    IdMessage:=TIdMessage.Create(Self);
    try
      DoSMTPCreate;

      with IdMessage do
      begin
        for i:=0 to EMailInfo.Attachments.Count-1 do
          IdAttachment:=TIDAttachmentFile.Create(MessageParts,EmailInfo.Attachments[i]);
        Body.Assign(EMailInfo.Body);
        Date:=EMailInfo.Date;
        From.Name:=EMailInfo.FromName;
        From.Address:=EMailInfo.FromAddress;
        ReplyTo.EMailAddresses:=EMailInfo.ReplyTo;
        Subject:=EMailInfo.Subject;
        Recipients.EMailAddresses:=GetAddressString(EMailInfo.RecipientList.Text);
        CCList.EMailAddresses:=GetAddressString(EMailInfo.CCList.Text);
        BCCList.EMailAddresses:=GetAddressString(EMailInfo.BCCList.Text);
      end;

      try
        DoSMTPConnect;
        fIdSMTP.Send(IdMessage);
        //if Assigned(ExpMstCtrl.OnEMailSuccess) then
        //  ExpMstCtrl.OnEMailSuccess(ExpMstCtrl);
        EmailSent:=True;
        DisplayMailProgress('  Email Sent Successfully',True);
      except
        on E: Exception do
        begin
          //if Assigned(ExpMstCtrl.OnEMailError) then
          //  ExpMstCtrl.OnEmailError(Sender,E.Message)
          //else
          DisplayMailProgress('  Error: '+E.Message,True);
    	    MessageDlg(E.Message,mtError,[mbOK],0);
          Continue:=False;
        end;
      end;
    finally
      DoSMTPDisconnect;
      DoSMTPFree;
      IdMessage.Free;
    end;
  end;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  
begin
  if EmailDialogsEnabled then
  begin
    EmailParamFrm:=TEmailParamsForm.Create(Self,nil);
    with EmailParamFrm, EMailInfo, TransPostHelper.EmailTemplatesTable do
    try
      edFromName.Text:=FieldByName('FromName').AsString;
      edFromAddr.Text:=FieldByName('FromAddress').AsString;
      edTo.Text:=EmailRecipients;
      if (EmailCCRecipients<>'') then
        edCc.Text:=EmailCCRecipients
      else
        edCc.Text:=FieldByName('CC').AsString;
      if (EmailBCCRecipients<>'') then
        edBcc.Text:=EmailBCCRecipients
      else
        edBcc.Text:=FieldByName('BCC').AsString;
      if (EmailSubject<>'') then
        edSubject.Text:=EmailSubject
      else
        edSubject.Text:=GetEmailSubject(FieldByName('Subject').AsString);
      if (EmailBody<>'') then
        memoBody.Lines.Text:=EmailBody
      else
        memoBody.Lines.Text:=FieldByName('Body').AsString;
      if EmailAccount<>'' then
        Caption:=Caption+' - '+EmailAccount;

      res:=ShowModal;
      if res=mrYes then
      begin
        Host := FieldByName('Host').AsString;                 //DisplayMailProgress('Host='+Host);
        UserID := FieldByName('UserName').AsString;           //DisplayMailProgress('UserId='+UserID);
        Password := FieldByName('Password').AsString;         //DisplayMailProgress('Password='+Password);
        Body.Text:=memoBody.Lines.Text;                       //DisplayMailProgress('Body='+Body.Text);
        Date := Now;                                          //DisplayMailProgress('Date='+DateToStr(Date));
        FromAddress := edFromAddr.Text;                       //DisplayMailProgress('FromAddress='+FromAddress);
        FromName := edFromName.Text;                          //DisplayMailProgress('FromName='+FromName);
        ReplyTo := FieldByName('ReplyTo').AsString;           //DisplayMailProgress('ReplyTo='+ReplyTo);
        Subject := edSubject.Text;                            //DisplayMailProgress('Subject='+Subject);
        RecipientList.Commatext:=edTo.Text;                   //DisplayMailProgress('Recipient='+RecipientList.Commatext);
        EmailRecipients:=edTo.Text;
        EmailSubject:=edSubject.Text;
        EmailBody:=memoBody.Lines.Text;
        EmailCCRecipients:=edCc.Text;
        EmailBCCRecipients:=edBcc.Text;
        CCList.Add(edCc.Text);
        BCCList.Add(edBcc.Text);
        DeleteFilesAfterEMail:=True;
        if not ReportSettings.IncludeAttachment then
          Attachments.Clear;
      end
      else if res=mrNo then
      begin
        EMailInfo.CancelEMail:=True;
        DisplayMailProgress('Email is NOT sent - user intervention',True);
//        if SMProgForm<>nil then
//          SMProgForm.UpdateProgress('Email is NOT sent - user intervention',True)
//        else if SMProgDetForm<>nil then
//          SMProgDetForm.UpdateProgress('Email is NOT sent - user intervention',True,False);
      end
      else if res=mrAbort then
      begin
        EMailInfo.CancelEMail:=True;
        Continue:=False;
        DisplayMailProgress('Email is NOT sent - user intervention',True);
        DisplayMailProgress('Emailing process is stopped - user intervention',False);
//        if SMProgForm<>nil then
//        begin
//          SMProgForm.UpdateProgress('Email is NOT sent - user intervention',True);
//          SMProgForm.UpdateProgress('Emailing process is stopped - user intervention',False);
//        end
//        else if SMProgDetForm<>nil then
//        begin
//          SMProgDetForm.UpdateProgress('Email is NOT sent - user intervention',True,False);
//          SMProgDetForm.UpdateProgress('Emailing process is stopped - user intervention',False,False);
//        end;
      end;
    finally
      EmailParamFrm.Free;
    end;
  end
  else
  begin
    with EMailInfo, TransPostHelper.EmailTemplatesTable do
    begin
      Host := FieldByName('Host').AsString;
      UserID := FieldByName('UserName').AsString;
      Password := FieldByName('Password').AsString;
      if (EmailBody<>'') then
        Body.Text:=EmailBody
      else
        Body.Text:=FieldByName('Body').AsString;
      Date := Now;
      FromAddress := FieldByName('FromAddress').AsString;
      FromName := FieldByName('FromName').AsString;
      ReplyTo := FieldByName('ReplyTo').AsString;
      if (EmailSubject<>'') then
        Subject:=EmailSubject
      else
        Subject:=GetEmailSubject(FieldByName('Subject').AsString);
      RecipientList.CommaText:=EmailRecipients;
      if (EmailCCRecipients<>'') then
        CCList.CommaText:=EmailCCRecipients
      else
        CCList.CommaText:=FieldByName('CC').AsString;
      if (EmailBCCRecipients<>'') then
        BCCList.CommaText:=EmailBCCRecipients
      else
        BCCList.CommaText:=FieldByName('BCC').AsString;
      DeleteFilesAfterEMail:=True;
      if not ReportSettings.IncludeAttachment then
        Attachments.Clear;
    end;
  end;

  if not EMailInfo.CancelEMail then
  begin
    SendEmail;
    EMailInfo.CancelEMail:=True;  // This is to stop the default email sending happening
  end;
end;

Answer : Delphi Email Blaster - possibly using Report Builder and PsRBExportDevices

Sending email to your server... Well email servers have timers here are some things to think about.
Things email servers do...
1.  Limit the number of connections in a period of time
2.  Limit the number of recipients in a single email
3.  Limit the number of retrys
4.  Limit the number of emails sent in a period of time "think of delaying between each send"
5.  Check your email for "spam" which could be graphics or key phrases.  spam is also rated on how many emails you send that are "identical or with little variation"

Delphi part
sending email using Indy components is pretty easy.  If you need a template based system try using a html form with custom tags like <#FirstName> etc.. then use a page producer to fill in the tags iteratively.

General Tackett
  And some most limit the number of connections in a period of time along with the number of emails sent in a period.  the
Random Solutions  
 
programming4us programming4us