WinBatch Tech Support Home

Database Search

If you can't find the information using the categories below, post a question over in our WinBatch Tech Support Forum.

TechHome

Postie

Can't find the information you are looking for here? Then leave a message over on our WinBatch Tech Support Forum.

kGetMail Get Embedded Images in Raw Email

 Keywords: kGetMail Get Embedded Images Raw Email CID 

You will have to parse the whole email and find all the img tags having the src attribute set to "cid:".


title = "Email Grabber - Get Embedded Images in Raw Email."
AddExtender("WWPST44I.DLL")
;
;host="***"
;fromaddr="***"
;userid="***"
;password="***"

port=""
msgnumber=""
extractfile="msg.txt"
mailbox=""
flags="r"

GoSub UDFS


;Define directory to store email body & attachment files
emaildir = "C:\Temp\mail\"
If !DirExist(emaildir) Then DirMake(emaildir)
DirChange(emaildir)

;Initialize values to be used in kGetMail
kInit(host,fromaddr,userid,password,port)

cntr = 1
While @TRUE
   ;Initialize variables
   header = ""
   body = ""
   ;Get first email only
   ;   Returns header
   header = kGetMail( cntr, emaildir : extractfile, "", mailbox, flags )

   ;Grab the body contents of the email message from output file
   If FileExist( emaildir : extractfile )
      body = FileGet( emaildir : extractfile )
   EndIf

   ;Check if BODY exists
   ;   Break from loop when no body is found
   If body == "" Then Break

   ;Pause( title, "[HEADER]": @CRLF : header : @CRLF : "[BODY]" : @CRLF : body )

   ;Search body for any images
   ptr = StrIndexNC( body, "<img", 1, @FWDSCAN)
   If ptr != 0
       endptr =  StrIndexNC( body, ">", ptr+1, @FWDSCAN)
       htmlimgstr = StrSub( body, ptr, endptr-ptr+1)
       ;Pause('We found an image',htmlimgstr)

       ; Get CID string
       cidptr =  StrIndexNC( htmlimgstr, "cid", 1, @FWDSCAN)
       If cidptr != 0
          cidptr = cidptr+4
          endptr = StrIndexNC( htmlimgstr, '"', cidptr, @FWDSCAN)
          If endptr != 0
             CIDString = StrSub( htmlimgstr, cidptr, endptr-cidptr )
             ;Pause('CidString',CIDString)

             ; Look for Content-ID: <{CIDString}>
             contentcidptr = StrIndexNC( body, "Content-ID: <":CIDString:">", 1, @FWDSCAN )
             If contentcidptr != 0
                 begincontentptr = StrIndexNC( body, "Content-Type:", contentcidptr, @BACKSCAN )
                 If begincontentptr != 0
                    endcontentptr =  StrIndexNC( body, "------=_NextPart", begincontentptr, @FWDSCAN )
                    If endcontentptr != 0
                       contentstr = StrSub( body, begincontentptr, endcontentptr)
                       Pause('We found content',contentstr)

                       ; Get Content-type
                       typeextension = 'UNKNOWN'
                       begincontenttypeptr = StrIndexNC( contentstr, "Content-Type:", 1, @FWDSCAN )
                       If begincontenttypeptr != 0
                          begincontenttypeptr = begincontenttypeptr+StrLen("Content-Type:")
                          endcontenttypeptr = StrIndexNC( contentstr, @CR , begincontenttypeptr, @FWDSCAN )
                          If endcontenttypeptr != 0
                             contenttype = StrTrim(StrSub( contentstr, begincontenttypeptr, endcontenttypeptr-begincontenttypeptr ))
                             Pause('contenttype',contenttype)
                             If contenttype == 'image/jpeg;' Then typeextension = "jpg"
                             If contenttype == 'image/gif;' Then typeextension = "gif"
                             If contenttype == 'image/png;' Then typeextension = "png"
                             If contenttype == 'image/bmp;' Then typeextension = "bmp"
                             If contenttype == 'image/tiff;' Then typeextension = "tif"
                          EndIf
                       EndIf

                       ; Get base64 data only
                       beginbase64ptr = StrIndexNC( contentstr, 'Content-ID: <':CIDString:'>', 1, @FWDSCAN)
                       base64data = StrSub( contentstr, beginbase64ptr+StrLen('Content-ID: <':CIDString:'>'), -1 )
                       ;Pause('base64data',base64data)

                       ; Convert Data to Binary
                       time = StrReplace( TimeYmdHms(), ":", "" )
                       imagename = emaildir: "EmbeddedImg_" :time: ".": typeextension
                       Base64ToBinary(base64data, &phBinary)
                       BinaryWrite( phBinary, imagename )
                       BinaryFree(phBinary)

                       If typeextension != "UNKNOWN" Then RunWait( imagename,"" )


                    EndIf
                 EndIf
             EndIf
          EndIf
       EndIf
   EndIf


   ;Delete output file that contains the BODY
   FileDelete( emaildir : extractfile )

   cntr = cntr+1
EndWhile
Message( title, "Finished Getting Messages" )
Exit

:UDFS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Base64ToBinary - converts base 64 string to binary
;;
;; Parameters: strBase64 - (in) base 64 formatted string
;;             phBinary  - (in/out) pointer to variable
;;                         contains handle to binary buffer
;;                         on success.
;;
;; return: 0 on success otherwise system error number
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
#DefineFunction Base64ToBinary(strBase64, phBinary)
   *phBinary = 0
   CRYPT_STRING_BASE64 = 1
   hCrypt  = DllLoad(DirWindows(1):"Crypt32.dll")
   hByteCount = BinaryAlloc(4)

   ; Get the binary buffer size
   bResult = DllCall(hCrypt, long:"CryptStringToBinaryA",lpstr:strBase64, long:0, long:CRYPT_STRING_BASE64, lpnull, lpbinary:hByteCount, lpnull, lpnull)
   If !bResult
      BinaryFree(hByteCount)
      DllFree(hCrypt)
      Return DllLastError()
   EndIf

   BinaryEodSet( hByteCount, 4 )
   nConvertedBytes = BinaryPeek4(hByteCount, 0)
   hConverted = BinaryAlloc(nConvertedBytes)

   ; Convert the string
   bResult = DllCall(hCrypt, long:"CryptStringToBinaryA",lpstr:strBase64, long:0, long:CRYPT_STRING_BASE64, lpbinary:hConverted, lpbinary:hByteCount, lpnull, lpnull)
   If !bResult Then nReturn = DllLastError()
   Else nReturn = 0

   BinaryFree(hByteCount)
   DllFree(hCrypt)
   BinaryEodSet(hConverted, nConvertedBytes)
   *phBinary = hConverted

   Return nReturn  ; 0 on success otherwise system error
#EndFunction

Return

The raw format of an email containing the embedded image will be something like this

Received: from spooler by *.com (Mercury/32 v4.52); 16 Apr 2013 11:30:34 -0700
X-Envelope-To: <*@*.com>
Return-path: <*@*.com>
Received: from * by *.com (Mercury/32 v4.52) with ESMTP ID MG016B77;
   16 Apr 2013 11:30:25 -0700
Message-ID: <D23A3CD266504782B1304EEB6F791A55@Agave>
Reply-To: "*" <*@*.com>
From: "*" <*@*.com>
To: "*" <*@*.com>
Subject: Embedded Image
Date: Tue, 16 Apr 2013 11:30:34 -0700
Organization: *
MIME-Version: 1.0
Content-Type: multipart/related;
 type="multipart/alternative";
 boundary="----=_NextPart_000_000B_01CE3A95.CFA02480"
X-Priority: 3
X-MSMail-Priority: Normal
Importance: Normal
X-Mailer: Microsoft Windows Live Mail 15.4.3555.308
X-MimeOLE: Produced By Microsoft MimeOLE V15.4.3555.308

This is a multi-part message in MIME format.

------=_NextPart_000_000B_01CE3A95.CFA02480
Content-Type: multipart/alternative;
	boundary="----=_NextPart_001_000C_01CE3A95.CFA02480"


------=_NextPart_001_000C_01CE3A95.CFA02480
Content-Type: text/plain;
	charset="Windows-1252"
Content-Transfer-Encoding: quoted-printable

Embedded image email.


------=_NextPart_001_000C_01CE3A95.CFA02480
Content-Type: text/html;
	charset="Windows-1252"
Content-Transfer-Encoding: quoted-printable

<HTML><HEAD></HEAD>
<BODY dir=3Dltr>
<DIV dir=3Dltr>
<DIV style=3D"FONT-SIZE: 10pt; FONT-FAMILY: 'Calibri'; COLOR: #000000">
<DIV> </DIV>
<DIV><IMG title=3DUntitled=20
style=3D"BORDER-TOP: 0px; BORDER-RIGHT: 0px; BACKGROUND-IMAGE: none; =
BORDER-BOTTOM: 0px; PADDING-TOP: 0px; PADDING-LEFT: 0px; BORDER-LEFT: =
0px; DISPLAY: inline; PADDING-RIGHT: 0px"=20
border=3D0 alt=3DUntitled =
src=3D"cid:F6E4E9719D164B029D6851D91925B5DA@Agave" width=3D644=20
height=3D364></DIV>
<DIV> </DIV>
<DIV style=3D"FONT-SIZE: 10pt; FONT-FAMILY: 'Calibri'; COLOR: #000000">
<BR><BR></DIV></DIV></DIV></BODY></HTML>

------=_NextPart_001_000C_01CE3A95.CFA02480--

------=_NextPart_000_000B_01CE3A95.CFA02480
Content-Type: image/jpeg;
	name="Untitled[1].jpg"
Content-Transfer-Encoding: base64
Content-ID: <F6E4E9719D164B029D6851D91925B5DA@Agave>

/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkI
CQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/2wBDAQMDAwQDBAgEBAgQCwkLEBAQEBAQ
EBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBD/wAARCAFsAoQDASIA
...

------=_NextPart_000_000B_01CE3A95.CFA02480--
... text of the HTML document, which might contain a URI referencing a resource in another body part, for example through a statement such as:
<IMG title=3DUntitled=20
style=3D"BORDER-TOP: 0px; BORDER-RIGHT: 0px; BACKGROUND-IMAGE: none; =
BORDER-BOTTOM: 0px; PADDING-TOP: 0px; PADDING-LEFT: 0px; BORDER-LEFT: =
0px; DISPLAY: inline; PADDING-RIGHT: 0px"=20
border=3D0 alt=3DUntitled =
src=3D"cid:F6E4E9719D164B029D6851D91925B5DA@Agave" width=3D644=20
height=3D364>
If you take a look at the footer, it contains a BASE64 encoded version of your image. You can extract the the BASE64 string, convert it to binary and save it to a file (you can get the file extension based on the Content-Type).
Article ID:   W17591
Filename:   kGetMail Get Embedded Images in Raw Email.txt
File Created: 2017:07:28:12:58:35
Last Updated: 2013:04:16:12:22:23