Base64 Mime Attachment formatting

This probably already exists, in one or more places, right?

I need Base64 MIME formatted text for emailing - a long string, cut into 72 or 76 or whatever length sections.

I looked in several places.
The RTL has stuff in SOAP, in System.NetEncoding, in some other library.
(I’ve seen some people complaining that Base64 was not encoding properly for them.)

I have attached pdfs to email using Indy before, but this time I want to construct the details of the email.

So … I made my own. ¯\(ツ)

const body_hm1 =
'QkVHSU46VkNBTEVOREFSDQpWRVJTSU9OOjIuMA0KUFJPRElEOi0vL01lZXR1cC8vTWVldHVwIEV2...'

{    72 characters per line
QkVHSU46VkNBTEVOREFSDQpWRVJTSU9OOjIuMA0KUFJPRElEOi0vL01lZXR1cC8vTWVldHVw
IEV2ZW50cyB2MS4wLy9FTg0KQ0FMU0NBTEU6R1JFR09SSUFODQpNRVRIT0Q6UFVCTElTSA0K
WC... }

procedure base64split( t:TStringList; s:string; n:cardinal );
begin
     var i := 0;
     while i < s.Length do begin
         t.Add( s.Substring(i,n) );
         inc(i,n);
     end;
end;

For what it’s worth, I have been bashing my head against some examples until I managed to distill a template that works for Thunderbird and GMail.

I have no idea how it will appear to other software. (It was the “Add to Calendar” feature that I was particularly after).

Thunderbird :

GMail :

1 Like

Here is some code based on what I wrote 20 years ago. (I have updated just updated it to remove any of my dependencies… (but I haven’t tested this updated version). It doesn’t quite answer your question, but I think it does what you want to do. It uses Indy.

uses
  Idemailaddress,
  IDMessage,
  IdBaseComponent,
  IdText,
  idmessageparts,
  idattachment,
  System.Net.Mime;

function SaveMessage(inDocument: string; inName: string; inEmail:string; inSubject: string; inMsg: TIdMessage; imgList2: TStringList): TIdMessage;
var
   addr       : TIDEmailAddressItem;
   htmpart, txtpart: TIdText;
   attach     : TIDMessagePart;
   i          : Integer;
   mimeType   : string;
   kind: TMimeTypes.TKind;
begin
      imgList2.Clear;
      inMsg.Clear;
      inMsg.Body.Text := inDocument;
      inMsg.From.Name := inName;
      inMsg.From.Address := inEmail;
      inMsg.Subject := inSubject;
      inMsg.ContentType := 'multipart/mixed';

      txtpart := TIdText.Create(inMsg.MessageParts);
      txtpart.ContentType := 'text/plain';
      txtpart.Body.Text := '';

      htmpart := TIdText.Create(inMsg.MessageParts, inMsg.Body);
      htmpart.ContentType := 'text/html';

      for i := 0 to imgList2.Count - 1 do
      begin
        attach := inMsg.MessageParts.Add;
        TMimeTypes.Default.GetExtInfo(ExtractFileExt(imgList2.Strings[i]), mimeType, kind);
        attach.ContentType := mimeType;
        attach.Headers.Values['Content-Disposition'] := 'inline';  // or attachment
        attach.ExtraHeaders.Values['Content-ID'] := imgList2.Strings[i];
        attach := nil;
      end;
      {GetFileSize}
  Result := inMsg;
end;

2 Likes

I started off from noticing the emails I got from @SueKing for the committee meetings, then particular emails from Meetup(.)com about meetings, and then from creating a Google Calendar event and emailing a notification to myself.

I also came across :

The .ics info looks something like :

BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Cratic//Cratic Huddle//EN
METHOD:REQUEST
NAME:Cratic Huddle
X-WR-CALNAME:Cratic Huddle
TIMEZONE-ID:Europe/Berlin
X-WR-TIMEZONE:Europe/Berlin
BEGIN:VEVENT
UID:60212c8395841f2cd057864f@cratic.ai
SEQUENCE:0
DTSTAMP:20210208T125937Z
DTSTART:20210219T133059Z
DTEND:20210219T140059Z
SUMMARY:Cratic Huddle
DESCRIPTION:This is the information
ORGANIZER;CN="Izzi":mailto:firstname.lastname@gmail.com
ATTENDEE;ROLE=REQ-PARTICIPANT:MAILTO:firstname.lastname@gmail.com
BEGIN:VALARM
ACTION:DISPLAY
TRIGGER:-PT15M
DESCRIPTION:Cratic Huddle
END:VALARM
BEGIN:VALARM
ACTION:AUDIO
TRIGGER:-PT15M
ATTACH;VALUE=URI:Basso
END:VALARM
URL;VALUE=URI:cratic.ai
END:VEVENT
END:VCALENDAR

I luckily had a notification from the Melbourne Haskell Meetup that came up as I wanted in both Thunderbird and GMail, so I iterated on that … initially by ripping out any TIMEZONE info, that can be a large section all on its own.

In fact, I still haven’t included the TIMEZONE information in my code … so I am now wondering if the alert I sent you for tonight’s Perth meeting would create a correct Google Calendar entry for you in your timezone?

PS: I also don’t know what VALARM does.
PPS: But I did find out apparently you can notify of an event, and then separately send out alterations of that event.

1 Like

VALARM seems to be the alarm component, and it looks like [RFC5545] Section 3.6.6 has details about it

1 Like