Can Panorama (6 or X) include images in email?

I could not find this topic by searching, but I apologize if it has already been addressed. I generally send personalized emails, via Panorama 6, using a procedure that has “sendoneemail” in a loop that increments through the records. I would like to include a picture in those personalized emails, but I can’t find a way to do that. If it isn’t possible to include images in the personalized emails sent via procedure, is it possible to do so in non-personalized bulk emails? How about with Panorama X? Thank you!

1 Like

Either version can do it, but it does take some work on your part. I have procedures in Panorama that embed images, include attachments and all HTML and CSS formatting. The “trick” is that I have Panorama creating then running Python scripts.

James, could you share the portion of the code that adds an image, stored in a field, added to a personalized (procedure-run) email or an image stored on disc added to a bulk email … for Panorama 6? Or is that an over-simplification of the task? I use a Mac if that makes a difference. I know nothing about Python scripts, but I am a retired engineer, so perhaps I can figure it out enough to adapt for my use. :slight_smile:

I’d suggest that you start by taking a look at some Python scripts for sending email. The basics aren’t too bad. There are a lot of canned scripts to include images and attachments.

Then you get one set up to work as you want. Get it set up so that Panorama can send it for you- without modifications. Once that much is working, you can start inserting Panorama variables to replace the parts that you want to have change with each message.

It is some work to do it, but I had never touched Python before I decided to pursue it. I learned through trial and error to modify the canned scripts. Now I have some fairly elaborate procedures reliably sending out one or sometimes hundreds of indiviualized emails at a time.

Mine have reached the point of using so many variables that it would be more work to explain what they represent than is reasonable. But - at the end of this message is my basic Python test script. The defining of the variables is omitted in the example, but must be accomplished before having Panorama run it. Most should be clear enough. If not, ask me. You could just as easily load data from fields in their place.

I send authenticated email, as do most of my clients, so it does require the same settings as Apple Mail and such. Here’s are how I set several of them up as preferences:

Here’s an example of an email sent from a Panorama database with a deliberately large photograph embedded:

Local lvResult, lvName, lvToEmail, lvFromEmail, lvReplyEmail, lvSubject, lvMessage, lvUser, lvPassword, lvAuthentication, lvSMTP, lvPort, lvSSL, lvTLS
python |||
import os
from email.MIMEText import MIMEText
import smtplib
strTo = $«lvToEmail»$
strFrom = $«lvFromEmail»$
strCC = ""
strError = ""
msg = MIMEText($«lvMessage»$)
msg['Subject'] = $«lvSubject»$
msg['From'] = $«lvFromEmail»$
msg['Reply-to'] = $«lvReplyEmail»$
msg['To'] = $«lvToEmail»$
try:
    smtp = smtplib.SMTP|||
    +?(lvSSL ≠ "","_SSL","")+|||($«lvSMTP»$, $«lvPort»$) 
    smtp.ehlo() |||+?(lvTLS="","","
    smtp.starttls()")+?(lvAuthentication="None","","
    smtp.login($«lvUser»$, $«lvPassword»$)")+|||
    smtp.sendmail(strFrom, strTo, msg.as_string())
    smtp.quit()
except smtplib.SMTPException,error:
    print str(error)
|||,lvResult

James, thank you very much. Most helpful! I will take your advice and “play” with Python. Your sample email shows that it is possible to do exactly what I want. One last question (not smart enough yet to ask more), would a photo, as your winter example, be imbedded in the message (1vMessage?) or … would the text be split into two pieces (one before/above the picture, and one after) with the picture inserted between? That is, can 1vMessage contain both text and image?

Once you have it all set up for attachments, etc, you’re actually sending two emails in one. In essence, one is plain text, the other is HTML. Just as you can with a web page, the image sits within the HTML email wherever you place it. You can have numerous images of varying sizes sprinkled around a full-fledged layout. Of course, it all comes down to your skills with HTML at that point.

Here’s that sample email as it was sent by Panorama to Python with chunks of text relaced with … for brevity and personal info xxxx’d out. You’ll see (with some effort) that it loops to process however many photos are embedded, and that my single photo is in the middle of the HTML.

#!/usr/bin/python
# -*- coding: utf-8 -*-
import os, sys
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
from email.MIMEImage import MIMEImage
try:
    strFrom = '''James Cook <xxxxx>'''
    strTo = '''James Cook < xxxxx >'''
    strCC = ''''''
    strSend = ['xxxxx']
    strError = ""
    # Create the root message and fill in the from, to, and subject headers
    msgRoot = MIMEMultipart('related')
    msgRoot['Subject'] = '''Winter Scenes'''
    msgRoot['From'] = strFrom
    msgRoot['Reply-to'] = strFrom
    msgRoot['To'] = strTo
    msgRoot['Cc'] = strCC
    msgRoot.preamble = 'This is a multi-part message in MIME format.'
    # Encapsulate the plain and HTML versions of the message body in an
    # 'alternative' part, so email agents can decide which they want to display.
    msgAlternative = MIMEMultipart('alternative')
    msgRoot.attach(msgAlternative)
    msgText = MIMEText('''
Hi Rich,
I\'d suggest that ....ding out one or sometimes hundreds of indiviualized emails at a time.
Winter in Saugatuck Dunes State Park
Mine ha...fields in their place.
As always, our best, 
Jim and Kat Cook
If you wish you can s...ents.
 ''')
    msgAlternative.attach(msgText)
    msgText = MIMEText('''<p><font color="#0000FF"><font face="Verdana"><blockquote><div style="text-align: center;"><br /></div></p><p>Hi Rich,</p><p><blockquote><br />I\'d suggest that ...sage.</p><p>It is...a time.</p><p><div align="center"><br /><img src="cid:image1"><br /><font face="Helvetica">Winter in Saugatuck Dunes State Park</font><br /></div></p><p>Mine hav....ce.</p></blockquote><br />As always, our best,&nbsp;<br />Jim and Kat Cook</p><p><font size="-1">If you wish you can...ur list of recipients.</font></font></p><p></blockquote><br />&nbsp;</font></font></p>''', 'html')
    msgAlternative.attach(msgText)
    # ATTACH MULTIPLE IMAGES
    if '''/myhd/correspondence/graphics/DSC03221.jpg''' != "":
        images = '''/myhd/correspondence/graphics/DSC03221.jpg'''.splitlines()
        i=1
        for image in images:
            # print 'Image',i,': ',image,'\n'
            fp = open(image, 'rb')
            msgImage = MIMEImage(fp.read())
            fp.close()
            # Define the image's ID as referenced above
            msgImage.add_header('Content-ID', '<image'+str(i)+'>')
            msgRoot.attach(msgImage)
            i+=1
    
    # Send the email
    import smtplib
    smtp = smtplib.SMTP_SSL('''xxx''', xxx) 
    try:
        smtp.ehlo() 
        smtp.starttls() 
        smtp.ehlo()
    except:
        pass
    smtp.login('''xxxxxx''', '''xxxxx''')
    smtp.sendmail(strFrom, strSend, msgRoot.as_string())
    smtp.quit()
except: print("Sending Error : "+strTo)

One more time, thank you James. You have been very helpful (and patient). I’m “fairly good” with html (host my own genealogy site); I’m sure I will be able to figure it out from here. :slight_smile: