Contact Information

Chris Toohey

Like what you see? Help feed-the-beast by donating to the site and it's humbly thankful author!

My Twitpic Updates
    Site Resources

    RSS Site Content
    Syndicate This Site!
    DG Banner Logo
    Advertisements

    IBM Lotus Notes and Domino 7 now available

    Zephyr v0.1 Quick Tutorial (Flash Demo)

    08/26/2008 01:31:38 PM | Chris Toohey | Bethlehem, PA

    If it sounds like I'm flying through this... I am - first time I recorded I was half-way through before the Jing 5-minute timer cut me off!

    I've gotten a lot of questions since the release of Zephyr v0.1... and I thought the best way to answer them would be to give you a quick (it's like 4:50 minutes in runtime) flash demo and tutorial on just what is Zephyr and how it works.

    Zephyr v0.1 Quick Tutorial (Flash Demo)

    If you like what you see, you can download the totally free mail merge notifications utilty here: Zephyr v0.1 - Configuration-based Rich Text Mail Merge and Emailing Utility

    And - as an aside - if anyone has any suggestions on a (freeware maybe?!) solution that allows me to record this stuff - screencasting, etc. - I'm all ears!


    Like what you see? Help feed-the-beast by donating to the site and it's humbly thankful author!

    Comments

    Rob
    http://ShaverAssociates.net
    08/26/2008 04:14:12 PM

    Wow Chris, way cool.


    I created a Java library six or seven years ago to do something like this, but for text-only emails. And each mailing required me to write a separate agent. (Although many of the emails I send out are done from within a Query Save Agent in response to something a user did like upload a file.)


    QUESTIONS

    1. How did you do search and replace inside a Rich Text field?
    2. What versions of Notes will this work in? Will it work in 7?
    3. Does the user have to fill in the values in the merge fields or are they parced from the body of the template?
    4. How do you set the "From:" address? (I gave up trying many years ago after trying many hacks. It's been a major stumbling block for many of my web applications. I've had to turn down jobs because of it.)


    Thanks for some great stuff here. I'd like to try it out if it'll work on version 7.


    Peace,


    Rob:-]


    Chris Toohey
    http://www.dominoguru.com
    08/26/2008 04:38:05 PM

    Hey Rob!
    Yeah - this'll work with 7. In fact, I have it working with a client running 6.5, and I'm pretty sure that we could get it working with R5!

    As for the rest of your questions...

    1. Check out the mailMergeRT function in the sched/Notifications|Notifications Agent. I'm doing a FindAndReplace inside of a NotesRichTextRange.
    2. Like I said, might even work in R5...
    3. Well, ideally you'd have the job documents populated in a batch process from another application. If this is user-driven, have them fill out a simple UI Form, and that UI form writes the Job Document in the backend. The user doesn't need (and shouldn't get) access to Zephyr really...
    4. Ah. yeah, this was tricky. I'm creating the email at runtime as a new document in the mail.box on whatever server you're currently running. ie., if you're running on Local, it'll write to your local mail.box and await the next time you Send and Receive. Some admins don't like this approach, but it gets the job done ;-)


    John Smart
    http://www.greyduck.com
    09/10/2008 11:29:53 AM

    Great job Chris! I can think of several clients so far where I would have used this if I'd had it!

    Thoughts:

    1. Instead of writing a text "1" into the key field, have you thought about writing a date? Users can compare it against "" to see if it's blank, but otherwise it's a cheap and easy way to be able to tell not only if something was sent, but when.
    2. The code should be a class, with a public "Run" (or more descriptively named) method accepting an email template document (or array, NotesView, NotesDocumentCollection, NotesViewEntryCollection, or NotesViewEntry thereof... the method could have a Select Case TypeName(Context) block in it) as one argument, and some context object as another argument (of type NotesDatabase, NotesView, NotesDocumentCollection, NotesViewEntryCollection, NotesDocument, or NotesViewEntry or array thereof). This way...
      • It's intensely portable/reusable.
      • If people decided not to use your stock agent, they could create their own... i.e. a daily one that iterates through daily templates, and a monthly agent that iterates only through email templates in some 'MonthlyEmailTemplates' view, without duplicating code - they'd both use the same class (in a script library). The only difference between the daily vs monthly agents would be the first argument they pass to the Run method.
      • People can override functionality... for example, if you seprated the source document stamping code
        Call jdoc.ReplaceItemValue(edoc.GetItemValue("keyname")(0), "1")
        Call jdoc.Save(False, False)
        into it's own subroutine then I could extend that class overriding it so that activity is logged in the same field/style where I log other events on the document such as user edits, etc, all without splitting the code stream, making it easier when v0.2 comes around.
      • It will be much easier for you/anyone to, later, add optional fields of "FilePath", and "ViewName" (and "Server"?) to the email template to allow Zephyr to be a centralized app that serves multiple applications.
    3. You should add a FilePath and ViewName fields on the email template form, and then use them, which allows Zephyr to be a centralized app that serves multiple applications. :-)
    4. Why do you do a search an FTSearch in ProcessJobs rather than use a hidden view? I'd expect a hidden view to be faster because the view index rarely ever changes. Am I wrong?
    5. Have you thought about formulaic substitutions? Maybe "This is due in <@ @Text((@Today - DateDue)/86400) @> days!" could be recognized and run through Eval? Again, if this was a class with the various parts stubbed out into their own private methods, this could be left as an excercise for the reader if they wanted to extend the class without creating a headache for themselves if/when there's a new version.


    Chris Toohey
    http://www.dominoguru.com
    09/10/2008 02:15:08 PM

    Good Lord man... excellent comment!

    Trying to keep this in order:

    1. I might very well keep the "1" as a default, but allow you to define your own stamp logic, configured from the email template. I'm thinking that's the best approach and allows for backwards compatibility.
    2. Agreed. This will eventually be re-written, but one of the masters these applications serve is to allow the average developer to rip open the code and play. Most developers are not (sadly) familiar with custom classes, OOP practices, and the more advanced stuff.
    3. Not too sure I follow this one, sorry - could you please elaborate?
    4. Again, trying to keep it simple. I've tried to keep it as copy/paste-able as possible - allowing you to take only the base requirement Domino Design Elements to plug this into any individual application you may need. If you notice, the doclink doesn't really work based on the logic involved with the job documents: why the hell would I want a doclink that takes me to a job document that's being processed by an automated notifications engine? Well, if you put this stuff into an existing Domino App, you can actually get that functionality. Few things in my head to get around that, btw.

      Also, I'm looking to do away with that approach, and the need for a View as well - opting for a slick trick that I've been using lately in my applications that really makes Views and such a thing of the past for this type of functional requirement.
    5. I absolutely have. In fact, I'm adding that into one of the future builds - not only <NotesItem> Mail Merging, but creating a macro-like inline standard to allow this... something like {@If(NotesItem = ""; "foo"; "bar")} could be evaluated quite easily and allow some pretty cool functionality.

    Keep the ideas coming - and I'll keep putting them in the product! And - of course - thanks for the kind words!


    John Smart
    www.greyduck.com
    09/12/2008 02:16:00 PM

    Grr... I had replied via my Treo but I don't see it here.

    Re point 3, what I was trying to say was that this is worthy of a centralized app all by itself, rather than a set of design elements to be cut & pasted ad nauseum. That way, there's less confusion, less version control to worry about. If you release another version, there's no worry about where it came from, etc.

    Therefore, the email template should allow a user to optionally specify a different database and (also optionally) a view to select from.

    Another point I hadn't thought of before... just before memo.save in sendEmail, you should (debug and) add

    'Add hidden field to provide a way to figure out where the email came from.
    Select Case s.NotesBuildVersion
    Case Is < 166 : 'Wow! Who would implement this on an R4 server??
    Case Is < 190 'NotesURL property not available prior to R5
      memo.SourceEmailTemplate = "notes://" + edoc.ParentDatabase.Server + "/" _
    + edoc.ParentDatabase.FilePath + "/0/" + eodc.UniversalID
    Case Else
      memo.SourceEmailTemplate = edoc.NotesURL
    End If



    Add a New Comment


    (Not Published/Public)
    Remember my Information!

    (Enter the text from the image to proceed)

    (Full markup allowed in the comment field below; play nice!)

    Live Comments Preview