Skip to main content
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.

Send a Gmail messagePascalC++
// 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;
// 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.
void __fastcall TForm1::SendStatusReport()
{
  TTMSFNCCloudGoogleGmailMessage *Msg = new TTMSFNCCloudGoogleGmailMessage();
  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);
}

void __fastcall TForm1::GmailMessageSent(TObject *Sender,
  TTMSFNCCloudGoogleGmailMessage *AMessage,
  TTMSFNCCloudBaseRequestResult *ARequestResult)
{
  if (ARequestResult->Success)
    ShowMessage("Message sent as " + AMessage->ID);
  else
    ShowMessage("Send failed: " + ARequestResult->ResultString);

  delete AMessage; // safe to free now: the async send has completed.
}

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.

Add and remove Gmail message labelsPascalC++
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;
void __fastcall TForm1::StarThenUnstarMessage(const System::UnicodeString AMessageID)
{
  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");
}

void __fastcall TForm1::GmailLabelsUpdated(TObject *Sender, const System::UnicodeString AMessageID,
  TTMSFNCCloudBaseRequestResult *ARequestResult)
{
  if (ARequestResult->Success)
    TMSFNCCloudGoogleGmail1->RemoveMessageLabels(AMessageID, "STARRED");
}

void __fastcall TForm1::GmailLabelsRemoved(TObject *Sender, const System::UnicodeString AMessageID,
  TTMSFNCCloudBaseRequestResult *ARequestResult)
{
  if (ARequestResult->Success)
    Memo1->Lines->Add("Unstarred " + AMessageID);
}

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.

Delete a Gmail messagePascalC++
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;
void __fastcall TForm1::DeleteMessageByID(const System::UnicodeString AMessageID)
{
  TMSFNCCloudGoogleGmail1->OnDeleteMessage = GmailMessageDeleted;
  TMSFNCCloudGoogleGmail1->DeleteMessage(AMessageID);
}

void __fastcall TForm1::GmailMessageDeleted(TObject *Sender, const System::UnicodeString AMessageID,
  TTMSFNCCloudBaseRequestResult *ARequestResult)
{
  if (ARequestResult->Success)
    Memo1->Lines->Add("Deleted message " + AMessageID);
}

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:

Send a message, then label it as importantPascalC++
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;
void __fastcall TForm1::SendAndFlagImportant()
{
  TTMSFNCCloudGoogleGmailMessage *Msg = new TTMSFNCCloudGoogleGmailMessage();
  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);
}

void __fastcall TForm1::GmailSentThenLabeled(TObject *Sender,
  TTMSFNCCloudGoogleGmailMessage *AMessage,
  TTMSFNCCloudBaseRequestResult *ARequestResult)
{
  if (ARequestResult->Success)
    TMSFNCCloudGoogleGmail1->UpdateMessageLabels(AMessage->ID, "IMPORTANT");

  delete AMessage; // safe to free now: the async send has completed.
}

void __fastcall TForm1::GmailLabelsUpdated(TObject *Sender, const System::UnicodeString AMessageID,
  TTMSFNCCloudBaseRequestResult *ARequestResult)
{
  if (ARequestResult->Success)
    Memo1->Lines->Add("Flagged " + AMessageID + " as important");
}

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.
  • TTMSFNCCloudGoogleGmail — SendMessage, SendMailMessage, UpdateMessageLabels, RemoveMessageLabels, DeleteMessage, OnSendMessage, OnUpdateMessageLabels, OnRemoveMessageLabels, OnDeleteMessage

See also