Automate Emailing Reports

Now that I have created my first report and can generate it on-demand, I need to start thinking in terms of how to automate reporting. I’ve done this successfully in my Access application, and want to reproduce it in Five. I don’t necessarily want to do things the the same way I do in Access, but want to take advantage of the Five architecture and do things the “right” way. Here is what I do in Access to email reports to board of directors:

I already have tables that describe what board positions there are, what members are filling those positions, and what reports each position gets. Using those tables, I generate the reports as PDF files, then send emails to the board members with the report(s) attached. Since several board positions may get the same reports, it is inherently inefficient because board members end up getting several different emails, each with a single report attachment. There is a many-to-many relationships between people and reports, and this generates a LOT of emails.

What I’d rather do, if Five supports it, is to send an email to the particular person with a list of their reports in the body of the email, each report name having a hyperlink so they can click on it and download the file directly to their downloads folder. Theoretically, they wouldn’t even have to log in to Five to do this, if a simple link to the generated report is embedded in their email body.

First question:
Can Five generate a PDF report and supply a hyperlink to that report which will cause the report to be downloaded to their computer downloads folder when the hyperlink is clicked even outside of Five itself?

Second question (if yes to first question):
Can you point me to the documentation which shows how to do this, and/or supply instructions if there is no documentation?

Third question (if yes or no to first question):
How long do the reports “last” on the server before they get deleted? Do I need a process to delete them, or can they “time-out” and be deleted automatically?

There are quite a few more questions, but one step at a time.

Thanks…

I don’t feel it is reasonable to require all recipients to have an account in my application to build a report for themselves. Preferable would be a way to save the report PDF file in a table with a BLOB field (or whatever can hold a PDF file). That could be done somehow in the On Complete event? Can I send a URL to the recipient which, when clicked, would download the saved report to the user’s download folder, OR at least open it in their browser? Is it possible to run code from the clicked url to do the downloading or rendering in their browser?

Simple requirement, right? Right? Thanks…

UPDATE: I’ve been reading the documentation for Generating Reports and Attaching to a Mail Merge, and that seems promising. Can that technique be expanded to create several reports and attach all of them to an email for mail merge?

Great find on Generating Reports and Attaching to a Mail Merge! That approach can be expanded to generate multiple reports and attach them to an email.

Sample below is assigning 2 reports into the SMTPAttachments.

const mailMergeContext = {SMTPToEmail: five.field.EmailAddress, 
SMTPToName: "Staff", 
SMTPAttachments: [reportResult.report, reportResult2.report]};

Thanks for the reply Vin. I will need to study the whole mail merge subject. It is not clear to me whether [reportResult.report, reportResult2.report] objects in that array are actual reports, or url pointers to them, since the example in the referenced article only showed one report being added to the email. It doesn’t explain where the generated reports are “kept” on the server, and how long of a lifetime they have between being generated and being emailed. For example, can I generate 20 different PDF reports, somehow save their URL pointer, then email them all at once? When, after emailing, do they get disposed of?

Mainly, I’m trying to understand the architecture and how I can automate different types of reports.

Currently I have one function in my application that sends out board reports to the board members via email. I select the reports by checking off a list, and they get generated and eventually emailed to the proper recipients. I only need to check them off (select the reports) because I was concerned about the application’s ability to send out many reports to many email addresses. So the requirement to pre-select the reports to be emailed from a list may not be necessary.

I also have another functionality to send Study Group Rosters to either the group leaders, or portfolio registrars, or to group members themselves.

These are 2 different forms/menu items in my application, but they share underlying functionalities. so it seems like I should build my Five application to use common code between them, even if I have 2 different menu items or forms to invoke them.

Above all, I do NOT want to be tied to outdated methodology when designing this in Five. I want to do things the proper way, which I need you folks’ guidance on.

Given that there is a many-to-many relationship between the people receiving the emails and the reports that get attached, would it be reasonable to have a server-side function that sends these emails, and client-side functions to build a context and fill it with lists of items like in your example?

If I have a list of board positions, each getting 1 or more reports emailed to them, would Five require that I build the list of email attachments for each position, then loop through the members assigned to that position, and send each email separately but include the list of documents in the context sent to the server function? Or could you make the SMTPToEmail parameter itself an array of email addresses? If possible, this latter method would work well, because as mentioned it is the board position that has the list of reports to be sent, not the member/email address itself. So if the SMTPToEmail parameter can contain an array, this would be very handy.

Sorry to ramble. If you understand what I am asking, could you suggest some code, even pseudo-code that would accomplish this?

And could you speak to the efficiency of sending many emails at the same time, or somehow segmenting them into separate transactions? Will things “blow up” if I try to send too many emails at the same time?

Thanks so much for reading this long rant…

Sorry to bother.

I’ve attempted to copy the example from the documentation to generate a report and email it to a recipient. I used my Roster report for testing. I added a menu item to email the report.

So in the Reports menu of the running application, clicking Roster will generate the report on-screen. Clicking Generate Reports will open that form and allow you to change parameters, then generate the roster on-screen from the action button. Clicking Email Reports on the menu “should” cause the example code to run and generate an email with the report(s) attached.

I get an email with the designated body text, but the attached content is empty except for Group By Final rqStudyGroupRoster, which is the literal text in the template for that part of the report. But the report itself is not rendering.

So even though I’m closer, the functionality is not working. So here are my questions:

1: I’ve uploaded the FDF to OneDrive. Can you please take a look and see what I may have done wrong?

2: Do you recommend the mail-merge technique as the best way to create and email multiple reports, or is there a better way to accomplish this? There may be several reports, being sent to many recipients.

3: In the context for executing my mail merge, is it possible to send an array of email addresses rather than a single address?

4: If answer 3 is Yes, then could I also send an array for the SMTPToName property as well? Or is it possible to send instead an array of verbose email addresses like “Ron Mittelman (rmittelman@gmail.com)” instead of using both email and name properties?

5: Depending on above answers, would it be more efficient to iterate through the individual email addresses and send one email to each recipient containing all of the reports that recipient gets, or is it better to iterate through the reports and send an email to each person who gets the report, then rinse and repeat? This seems inefficient, since each person will get multiple emails.

6: Not clear how I generate multiple reports and get a reportResult for each. I’m thinking of taking this snippet of the EmailReport function

    const reportResult = five.executeAction('StaffPhoneExtensions', {});
    if (reportResult.isOk() === false)   {
        return five.createError(reportResult);
    }

and just repeating it for every report that is to be printed, with a different name for the reportResult variable? THEN using those variables add them to the attachment names array in the context? Except I’d need to not try adding if there is an error on a particular report, right? so instead of doing a return, maybe create a collection/dictionary/array of the successful ones, so if any are successful, I can email those?

Finally, is it possible to explain what is going on in the example? I was (almost) able to make it work by following the instructions, but don’t really understand what is going on with the mail merge object, using Processes, etc.

As you can see, this is quite a complex requirement. It may take a long time to design this. Any help is MUCH appreciated!

I’ll take a look and get back to you.

I may have found the problem. Email Reports is a process which runs the EmailReports function. This is server-side as it’s triggered by the Do Run event. I changed the function code to only display a message containing five.variable.UserKey, as that is needed for processing, but the showMessage command doesn’t even run.

What I need is some way to run an already existing function which loads the proper filtering tables so the query works. What about changing the event to On Run instead, so I can run code to load the tables properly first? If I do that, can I use the exact same code that was in the example for Do Run?

When I run the report from the Generate Reports form, it causes the GenerateReport client-side function to run the report.

If I use On Run, I can load the proper tables, but not sure if I can then run the server-side process so the mail merge works.

Thanks…

I tried changing things so the process causes my tables to be loaded properly prior to running the report, by using the on selection event. then moved the call to the mail merge back to the Do Run event. Still, not working. All I get is a single group footer text as before.

Also, is it normal for a single report to take 20 seconds or more before I get the message that the process has been completed? This is concerning in case I need to automate a process which emails several reports. Thanks…