Table of Contents

Sending, labeling and deleting

TTMSFNCCloudGoogleGmail composes and sends messages, applies or removes labels on an existing message, and deletes messages. This chapter covers sending a fully-populated message, managing labels by name, and deleting a message.

Sending a message

SendMessage sends a fully-populated TTMSFNCCloudGoogleGmailMessage — build the message on Files (for outgoing attachments or inline images) and call SendMessage with it. SendMailMessage is an alias for SendMessage with the same signature — use whichever name reads better in your code. Both raise OnSendMessage when the send completes.

// The component keeps a reference to the message object until the send
// completes (it stamps the new message ID onto it in OnSendMessage), so it
// must not be freed right after calling SendMessage - free it in the
// completion event instead.
procedure TForm1.SendStatusReport;
var
  Msg: TTMSFNCCloudGoogleGmailMessage;
begin
  Msg := TTMSFNCCloudGoogleGmailMessage.Create;
  Msg.Subject := 'Status report';
  Msg.Body := 'Everything is running fine.';
  Msg.MessageType := mtPlainText;
  Msg.ToRecipients.Add('recipient@example.com');

  TMSFNCCloudGoogleGmail1.OnSendMessage := GmailMessageSent;
  TMSFNCCloudGoogleGmail1.SendMessage(Msg);
end;

procedure TForm1.GmailMessageSent(Sender: TObject;
  const AMessage: TTMSFNCCloudGoogleGmailMessage;
  const ARequestResult: TTMSFNCCloudBaseRequestResult);
begin
  if ARequestResult.Success then
    ShowMessage('Message sent as ' + AMessage.ID)
  else
    ShowMessage('Send failed: ' + ARequestResult.ResultString);

  AMessage.Free; // safe to free now: the async send has completed.
end;

Managing message labels

UpdateMessageLabels and RemoveMessageLabels add or remove one or more labels from a message, given a comma-separated list of label names (for example 'STARRED' or a user-created label's display name) and the message's ID. Both raise OnUpdateMessageLabels / OnRemoveMessageLabels when the change completes.

procedure TForm1.StarThenUnstarMessage(const AMessageID: string);
begin
  TMSFNCCloudGoogleGmail1.OnUpdateMessageLabels := GmailLabelsUpdated;
  TMSFNCCloudGoogleGmail1.OnRemoveMessageLabels := GmailLabelsRemoved;

  // Labels must already be loaded once (see the warning in the guide) -
  // call GetLabels and wait for OnGetLabels before the first label update.
  TMSFNCCloudGoogleGmail1.UpdateMessageLabels(AMessageID, 'STARRED');
end;

procedure TForm1.GmailLabelsUpdated(Sender: TObject; const AMessageID: string;
  const ARequestResult: TTMSFNCCloudBaseRequestResult);
begin
  if ARequestResult.Success then
    TMSFNCCloudGoogleGmail1.RemoveMessageLabels(AMessageID, 'STARRED');
end;

procedure TForm1.GmailLabelsRemoved(Sender: TObject; const AMessageID: string;
  const ARequestResult: TTMSFNCCloudBaseRequestResult);
begin
  if ARequestResult.Success then
    Memo1.Lines.Add('Unstarred ' + AMessageID);
end;
Warning

Both methods resolve each name against the Labels collection, calling GetLabels automatically only when that collection is still empty — but that call is itself asynchronous, so a label update issued immediately after still runs against an empty collection and silently applies no labels. Call GetLabels yourself and wait for OnGetLabels at least once before the first label update in a session.

Deleting a message

DeleteMessage removes a message, either by passing the retrieved message object or its identifier, raising OnDeleteMessage when the deletion completes.

procedure TForm1.DeleteMessageByID(const AMessageID: string);
begin
  TMSFNCCloudGoogleGmail1.OnDeleteMessage := GmailMessageDeleted;
  TMSFNCCloudGoogleGmail1.DeleteMessage(AMessageID);
end;

procedure TForm1.GmailMessageDeleted(Sender: TObject; const AMessageID: string;
  const ARequestResult: TTMSFNCCloudBaseRequestResult);
begin
  if ARequestResult.Success then
    Memo1.Lines.Add('Deleted message ' + AMessageID);
end;

Combining a send with adding a label

Applying a label to a message right after sending it — for example marking a sent confirmation as IMPORTANT — chains naturally through the completion events:

procedure TForm1.SendAndFlagImportant;
var
  Msg: TTMSFNCCloudGoogleGmailMessage;
begin
  Msg := TTMSFNCCloudGoogleGmailMessage.Create;
  Msg.Subject := 'Escalation';
  Msg.Body := 'This needs immediate attention.';
  Msg.MessageType := mtPlainText;
  Msg.ToRecipients.Add('oncall@example.com');

  TMSFNCCloudGoogleGmail1.OnSendMessage := GmailSentThenLabeled;
  TMSFNCCloudGoogleGmail1.OnUpdateMessageLabels := GmailLabelsUpdated;
  TMSFNCCloudGoogleGmail1.SendMessage(Msg);
end;

procedure TForm1.GmailSentThenLabeled(Sender: TObject;
  const AMessage: TTMSFNCCloudGoogleGmailMessage;
  const ARequestResult: TTMSFNCCloudBaseRequestResult);
begin
  if ARequestResult.Success then
    TMSFNCCloudGoogleGmail1.UpdateMessageLabels(AMessage.ID, 'IMPORTANT');

  AMessage.Free; // safe to free now: the async send has completed.
end;

procedure TForm1.GmailLabelsUpdated(Sender: TObject; const AMessageID: string;
  const ARequestResult: TTMSFNCCloudBaseRequestResult);
begin
  if ARequestResult.Success then
    Memo1.Lines.Add('Flagged ' + AMessageID + ' as important');
end;

Common mistakes

  • Passing a label ID instead of its name. UpdateMessageLabels and RemoveMessageLabels look labels up by Name, not ID, even though the parameter is documented as an identifier list — pass Gmail's well-known system names (INBOX, STARRED, IMPORTANT, UNREAD) or a user label's display name.
  • Updating labels before Labels has ever loaded. See the warning above.
  • Deleting by a stale identifier. Delete the message (or ID) from a current listing; an ID from a much older listing may already point at a removed message.
  • TTMSFNCCloudGoogleGmailSendMessage, SendMailMessage, UpdateMessageLabels, RemoveMessageLabels, DeleteMessage, OnSendMessage, OnUpdateMessageLabels, OnRemoveMessageLabels, OnDeleteMessage

See also