GPAL.Mail starts with server settings: a server name and optional port for SMTP going out, and IMAP or POP3 coming in. You configure whichever direction the workflow needs and add credentials once. Credentials do not have to be in the source. WithCredentials takes an ICredentials built once from a vault, so a workflow can be checked in without its password, and the same credential works for a browser or a REST call. The settings can also live in a file: SaveSettings writes them to GPALMail.yaml beside the exe, and a new GPAL.Mail loads that file automatically. Anything the code sets explicitly runs after the load and therefore wins. Only one incoming server is kept, so naming an IMAP server forgets a POP server and the other way round.
// the mail object first, then the server settings and the envelope on it
IGPALMail mail = GPAL
// Built once from a vault, and the same one works for a browser or a REST call
ICredentials mailLogin = GPAL
IGPALMail mail = mail
// Keep them for next time, beside the exe
mail
// What it ended up using, whether that came from code or from the file
GPAL
Composing is a short fluent chain: from, to, cc, and bcc addresses, a subject, a body, and any attachments. WithName follows an address to give it a display name, so the same call names the sender or any recipient. A path works for an attachment, which is how a run mails its own log: the logger reports where it actually wrote through LogFullPath, and that goes straight to WithAttachment. Send throws when it cannot deliver, so there is no quiet failure to check for.
mail
Receive reads from the configured incoming server. WithUnreadOnly and WithMaxMessages decide how much it is allowed to bring back, which matters because the default is the whole mailbox. The overload with an out parameter hands the messages over in the same call, each one carrying its subject, from address, body, when it was sent, and the filename of every attachment. Attachments are more than names, so SaveTo writes them to disk: on the mail object it saves the attachments of every message received, and on a single ReceivedEmail it saves just that one and hands back a GPALFile for each file written, ready for the next step of the workflow. Then the message has to be taken out of the way, or the next run does all of it again: MarkAsRead and Delete do that for one message, MarkAllAsRead and DeleteAll for the batch. That is the whole shape of an inbox-watching automation: fetch what is new, look at what came, save what matters, mark it handled, and carry on with the files. Clear resets the envelope between messages while keeping the server settings.
// Only the new mail, and only as much of it as this run will finish
mail
foreach (ReceivedEmail email in received)
{
if (false == email
List<GPALFile> saved = email
foreach (GPALFile invoice in saved)
GPAL
email
}
Showing off some plain text in these paragraphs eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo veniam mollitia excepturi animi eum illum non libero sapiente provident assumenda, delectus voluptatum nobis sed dolorem adipisci laudantium incidunt. Error, ratione?
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo veniam mollitia excepturi animi eum illum non libero sapiente provident assumenda, delectus voluptatum nobis sed dolorem adipisci laudantium incidunt. Error, ratione?
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo veniam mollitia excepturi animi eum illum non libero sapiente provident assumenda, delectus voluptatum nobis sed dolorem adipisci laudantium incidunt. Error, ratione?
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo veniam mollitia excepturi animi eum illum non libero sapiente provident assumenda, delectus voluptatum nobis sed dolorem adipisci laudantium incidunt. Error, ratione?
Here you can find different accents and emphasis sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
This is a link and how it could look like bestlinkinthebeautifulworld. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Here's just some classic bold text adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam notBoldSecondbestlinkinthebeautifulworld illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Obcaecati, iste distinctio veritatis eligendi laboriosam adipisicing elit illo nostrum corporis at adipisicing elit libero vel voluptas? Expedita, adipisicing facere dolores voluptatem ad ab rem assumenda soluta!
Other cuple of colors in case we want to emphasize several ways adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam adipisicing elit illo nostrum corporis at voluptatem libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta! Lorem ipsum dolor, sit amet consectetur adipisicing elit. Quod veniam, quam ad expedita laborum sed at voluptates culpa ipsam ut vel. Ullam temporibus a mollitia quod aliquam ratione exercitationem nesciunt.
Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta! Lorem ipsum dolor, sit amet consectetur adipisicing elit. Quod veniam, quam ad expedita laborum sed at voluptates culpa ipsam ut vel. Ullam temporibus a mollitia quod aliquam ratione exercitationem nesciunt.
Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Lorem ipsum dolor sit amet consectetur adipisicing elit. Repudiandae quas consequuntur illo numquam assumenda autem exercitationem distinctio perspiciatis in natus. Eius dicta similique ipsam ipsa minima, nemo quae enim tempore.
GPAL
.CallIfNotFound(GenericCallIfNotFound)
.WithPublishToConsole();
//System.Drawing.Rectangle windowSize = new System.Drawing.Rectangle(10, 10, 1500, 1024);
// NOTE: we have to set browser = before we execute any steps
// this is due to the 'GenericCallIfNotFound' which might throw an exception, and BankScraper will not have the browser set when it calls scraper.Close()
// until the complete fluent line gets executed (meaning every step, meaning browser is not set until everything else succeeds)
browser = GPAL.Browser
.WithBrowserType(Enums.BrowserType.Chrome)
.WithProfileDataDirectory(ChromeProfileLocation)
.WithUseAutomationEngine(AutomationEngine.Selenium)
.WithWindowSize(new System.Drawing.Rectangle(0,0,1920,1080))
.ToGPALObject();