* [PATCH RFC] send-mail: add support for Microsoft Graph API
@ 2025-05-25 11:06 Aditya Garg
2025-05-25 11:22 ` Aditya Garg
2025-05-25 20:24 ` brian m. carlson
0 siblings, 2 replies; 5+ messages in thread
From: Aditya Garg @ 2025-05-25 11:06 UTC (permalink / raw)
To: Junio C Hamano, git@vger.kernel.org
Cc: Eric Sunshine, sandals@crustytoothpaste.net, Julian Swagemakers,
Jeff King, Zi Yao, Rens Oliemans, Drew DeVault
Apart from SMTP, Microsoft also provides a REST API, branded as
Microsoft Graph for sending mails. Upon testing a bit, I have
found a few benefits over SMTP. Firstly, SMTP servers of Microsoft
are kinda slow. On an average, initialising the SMTP server even
on a fast internet connection takes around 8-10 seconds with
send-email. Once initialised, subsequent messages sometimes also
face delays, taking around 3-5 seconds per message, and other
times they are sent almost instantaneously. Secondly, their SMTP
server does not respect the Message-ID specified by the user and
replaces it with their own generated string.
Microsoft Graph API solves both these problems. It is extremely
fast, taking around 1 second to send a series of 5 patches, and
also respects the Message-ID specified by the user.
After this patch, users can use the graph API by having their
config as:
[sendemail]
useMSGraph = true
MSGraphUser = yourname@outlook.com
The API requires an OAuth2.0 access token for authentication, and
users can either generate them manually, or use a credential helper
TODO:
I still need to write the documentation for this feature, but I wanted to
get the code reviewed first.
PS: This patch is sent using MS Graph. Note the fixed Message-ID ;)
Signed-off-by: Aditya Garg <gargaditya08@live.com>
---
git-send-email.perl | 71 ++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 67 insertions(+), 4 deletions(-)
diff --git a/git-send-email.perl b/git-send-email.perl
index b09251c4fc..edb96c7e1a 100755
--- a/git-send-email.perl
+++ b/git-send-email.perl
@@ -73,7 +73,10 @@ sub usage {
--no-smtp-auth * Disable SMTP authentication. Shorthand for
`--smtp-auth=none`
--smtp-debug <0|1> * Disable, enable Net::SMTP debug.
-
+ --[no-]use-msgraph <str> * Use Microsoft Graph API instead of SMTP.
+ --msgraph-user <str> * Username in case an email API is used.
+ If not specified, the from address is used.
+ --msgraph-token <str> * OAuth2.0 access token for the email API.
--batch-size <int> * send max <int> message per connection.
--relogin-delay <int> * delay <int> seconds between two successive login.
This option can only be used with --batch-size
@@ -201,7 +204,7 @@ sub format_2822_time {
# Variables we fill in automatically, or via prompting:
my (@to,@cc,@xh,$envelope_sender,
$initial_in_reply_to,$reply_to,$initial_subject,@files,
- $author,$sender,$smtp_authpass,$annotate,$compose,$time);
+ $author,$sender,$smtp_authpass,$annotate,$compose,$time,$msgraph_token);
# Things we either get from config, *or* are overridden on the
# command-line.
my ($no_cc, $no_to, $no_bcc, $no_identity, $no_header_cmd);
@@ -283,6 +286,7 @@ sub do_edit {
my ($compose_encoding);
my ($sendmail_cmd);
my ($mailmap_file, $mailmap_blob);
+my ($msgraph_user);
# Variables with corresponding config settings & hardcoded defaults
my ($debug_net_smtp) = 0; # Net::SMTP, see send_message()
my $thread = 1;
@@ -293,6 +297,7 @@ sub do_edit {
my $target_xfer_encoding = 'auto';
my $forbid_sendmail_variables = 1;
my $outlook_id_fix = 'auto';
+my $use_msgraph = 0;
my %config_bool_settings = (
"thread" => \$thread,
@@ -309,6 +314,7 @@ sub do_edit {
"forbidsendmailvariables" => \$forbid_sendmail_variables,
"mailmap" => \$mailmap,
"outlookidfix" => \$outlook_id_fix,
+ "usemsgraph" => \$use_msgraph,
);
my %config_settings = (
@@ -337,6 +343,8 @@ sub do_edit {
"composeencoding" => \$compose_encoding,
"transferencoding" => \$target_xfer_encoding,
"sendmailcmd" => \$sendmail_cmd,
+ "msgraphuser" => \$msgraph_user,
+ "msgraphtoken" => \$msgraph_token,
);
my %config_path_settings = (
@@ -556,6 +564,9 @@ sub config_regexp {
"git-completion-helper" => \$git_completion_helper,
"v=s" => \$reroll_count,
"outlook-id-fix!" => \$outlook_id_fix,
+ "use-msgraph!" => \$use_msgraph,
+ "msgraph-user=s" => \$msgraph_user,
+ "msgraph-token:s" => \$msgraph_token,
);
$rc = GetOptions(%options);
@@ -1095,7 +1106,7 @@ sub expand_one_alias {
$reply_to = sanitize_address($reply_to);
}
-if (!defined $sendmail_cmd && !defined $smtp_server) {
+if (!defined $sendmail_cmd && !defined $smtp_server && !$use_msgraph) {
my @sendmail_paths = qw( /usr/sbin/sendmail /usr/lib/sendmail );
push @sendmail_paths, map {"$_/sendmail"} split /:/, $ENV{PATH};
foreach (@sendmail_paths) {
@@ -1603,6 +1614,7 @@ sub is_outlook {
sub send_message {
my ($recipients_ref, $to, $date, $gitversion, $cc, $ccline, $header) = gen_header();
my @recipients = @$recipients_ref;
+ my $msgraph_response_code;
my @sendmail_parameters = ('-i', @recipients);
my $raw_from = $sender;
@@ -1680,6 +1692,52 @@ sub send_message {
}
print $sm "$header\n$message";
close $sm or die $!;
+ } elsif ($use_msgraph) {
+ # Use Microsoft Graph API
+ # https://learn.microsoft.com/en-us/graph/api/user-sendmail
+ my $auth_api;
+ if (!defined $msgraph_user) {
+ $msgraph_user = (defined $smtp_authuser
+ ? $smtp_authuser
+ : $raw_from
+ );
+ }
+ require MIME::Base64;
+ require HTTP::Tiny;
+ $auth_api = Git::credential({
+ 'protocol' => 'https',
+ 'host' => 'graph.microsoft.com',
+ 'username' => $msgraph_user,
+ 'password' => $msgraph_token,
+ }, sub {
+ my $cred = shift;
+ $msgraph_token = $cred->{'password'};
+ });
+ my $email_url = "https://graph.microsoft.com/v1.0/users/$msgraph_user/sendMail";
+ my $real_message = "$header\n$message\n";
+ # Convert LF to CRLF
+ unless ($real_message =~ /\r\n/) {
+ $real_message =~ s/\r?\n/\r\n/g;
+ }
+ # The API requires the message to be base64 encoded if sending in MIME format.
+ my $encoded_message = MIME::Base64::encode_base64($real_message, "");
+ my $http = HTTP::Tiny->new(
+ default_headers => {
+ 'Authorization' => "Bearer $msgraph_token",
+ 'Content-Type' => 'text/plain',
+ },
+ );
+ my $response = $http->post($email_url, {
+ content => $encoded_message,
+ });
+
+
+ if (!$response->{success}) {
+ die sprintf(__("Failed to send email: %s\nResponse: %s"),
+ $response->{status}, $response->{content});
+ } else {
+ $msgraph_response_code = $response->{status};
+ }
} else {
if (!defined $smtp_server) {
@@ -1790,12 +1848,15 @@ sub send_message {
} else {
print($dry_run ? __("Dry-OK. Log says:") : __("OK. Log says:"));
print "\n";
- if (!defined $sendmail_cmd && !file_name_is_absolute($smtp_server)) {
+ if (!defined $sendmail_cmd && !file_name_is_absolute($smtp_server)
+ && !$use_msgraph) {
print "Server: $smtp_server\n";
print "MAIL FROM:<$raw_from>\n";
foreach my $entry (@recipients) {
print "RCPT TO:<$entry>\n";
}
+ } elsif ($use_msgraph) {
+ print "Email API: Microsoft Graph API\n";
} else {
my $sm;
if (defined $sendmail_cmd) {
@@ -1810,6 +1871,8 @@ sub send_message {
if ($smtp) {
print __("Result: "), $smtp->code, ' ',
($smtp->message =~ /\n([^\n]+\n)$/s);
+ } elsif (defined $msgraph_response_code) {
+ print __("Result: "), $msgraph_response_code;
} else {
print __("Result: OK");
}
--
2.49.0
^ permalink raw reply related [flat|nested] 5+ messages in thread* Re: [PATCH RFC] send-mail: add support for Microsoft Graph API
2025-05-25 11:06 [PATCH RFC] send-mail: add support for Microsoft Graph API Aditya Garg
@ 2025-05-25 11:22 ` Aditya Garg
2025-05-25 20:24 ` brian m. carlson
1 sibling, 0 replies; 5+ messages in thread
From: Aditya Garg @ 2025-05-25 11:22 UTC (permalink / raw)
To: Junio C Hamano, git
Cc: Eric Sunshine, sandals, Julian Swagemakers, Jeff King, Zi Yao,
Rens Oliemans, Drew DeVault
On 25/05/25 4:34 pm, Aditya Garg wrote:
> Apart from SMTP, Microsoft also provides a REST API, branded as
> Microsoft Graph for sending mails. Upon testing a bit, I have
> found a few benefits over SMTP. Firstly, SMTP servers of Microsoft
> are kinda slow. On an average, initialising the SMTP server even
> on a fast internet connection takes around 8-10 seconds with
> send-email. Once initialised, subsequent messages sometimes also
> face delays, taking around 3-5 seconds per message, and other
> times they are sent almost instantaneously. Secondly, their SMTP
> server does not respect the Message-ID specified by the user and
> replaces it with their own generated string.
>
> Microsoft Graph API solves both these problems. It is extremely
> fast, taking around 1 second to send a series of 5 patches, and
> also respects the Message-ID specified by the user.
>
> After this patch, users can use the graph API by having their
> config as:
>
> [sendemail]
> useMSGraph = true
> MSGraphUser = yourname@outlook.com
>
> The API requires an OAuth2.0 access token for authentication, and
> users can either generate them manually, or use a credential helper
Also, if someone is interested in testing, you can use a small credentialhelper for msgraph here:
https://github.com/AdityaGarg8/git-credential-email/tree/msgraph
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH RFC] send-mail: add support for Microsoft Graph API
2025-05-25 11:06 [PATCH RFC] send-mail: add support for Microsoft Graph API Aditya Garg
2025-05-25 11:22 ` Aditya Garg
@ 2025-05-25 20:24 ` brian m. carlson
2025-05-26 1:36 ` Drew DeVault
2025-05-26 3:38 ` Aditya Garg
1 sibling, 2 replies; 5+ messages in thread
From: brian m. carlson @ 2025-05-25 20:24 UTC (permalink / raw)
To: Aditya Garg
Cc: Junio C Hamano, git@vger.kernel.org, Eric Sunshine,
Julian Swagemakers, Jeff King, Zi Yao, Rens Oliemans,
Drew DeVault
[-- Attachment #1: Type: text/plain, Size: 2379 bytes --]
On 2025-05-25 at 11:06:32, Aditya Garg wrote:
> Apart from SMTP, Microsoft also provides a REST API, branded as
> Microsoft Graph for sending mails. Upon testing a bit, I have
> found a few benefits over SMTP. Firstly, SMTP servers of Microsoft
> are kinda slow. On an average, initialising the SMTP server even
> on a fast internet connection takes around 8-10 seconds with
> send-email. Once initialised, subsequent messages sometimes also
> face delays, taking around 3-5 seconds per message, and other
> times they are sent almost instantaneously. Secondly, their SMTP
> server does not respect the Message-ID specified by the user and
> replaces it with their own generated string.
>
> Microsoft Graph API solves both these problems. It is extremely
> fast, taking around 1 second to send a series of 5 patches, and
> also respects the Message-ID specified by the user.
I don't think we should be adding support for proprietary methods of
sending mail. There are two standard methods, which are SMTP and the
sendmail binary, that are well known, well understood, and widely
deployed.
It is well known that Microsoft has invented a lot of proprietary
Outlook-specific formats for messages, such as TNEF and MAPI, which we
should also not support because they are poorly defined and not
specified in an open standard. I would also be opposed to sending mail
in formats or using methods that are proprietary to Google, Amazon, or
any other provider, since we already have clear specifications on how
mail is to be sent that precede this project's existence by some time.
I understand that the Outlook servers may be slow and inefficient as
well as modify the Message-ID, but that's ultimately a problem you need
to address with them and get them to fix. I should note that I don't
have that problem: I run my own Postfix and Dovecot servers which are
very speedy, and I feel confident any other provider could do so as
well. I also have never had that problem sending mail through Google's
SMTP server at work.
If this REST API approach is well defined by an RFC or some other open
specification process that the public can participate in and deployed
among a large number of providers, including several open source
implementations, then we might consider adopting it.
--
brian m. carlson (they/them)
Toronto, Ontario, CA
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 325 bytes --]
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH RFC] send-mail: add support for Microsoft Graph API
2025-05-25 20:24 ` brian m. carlson
@ 2025-05-26 1:36 ` Drew DeVault
2025-05-26 3:38 ` Aditya Garg
1 sibling, 0 replies; 5+ messages in thread
From: Drew DeVault @ 2025-05-26 1:36 UTC (permalink / raw)
To: brian m. carlson, Aditya Garg
Cc: Junio C Hamano, git@vger.kernel.org, Eric Sunshine,
Julian Swagemakers, Jeff King, Zi Yao, Rens Oliemans
[-- Attachment #1.1.1: Type: text/plain, Size: 313 bytes --]
I'm inclined to agree that it would be less than ideal to add
first-class support for proprietary protocols to git send-email. Some
kind of local SMTP => Graph API bridge is probably a better solution,
assuming Microsoft won't listen to reason (nor your boss, when you ask
them to switch away from Outlook).
[-- Attachment #1.2: 42F3F1862E3CC4B8.asc --]
[-- Type: application/pgp-keys, Size: 644 bytes --]
-----BEGIN PGP PUBLIC KEY BLOCK-----
mDMEZ7Y9kxYJKwYBBAHaRw8BAQdA/pPy6X+nNL5T2QaJKEM08xN/Kz7wFTAZoH5Y
riV9x1m0IERyZXcgRGVWYXVsdCA8ZHJld0BkZGV2YXVsdC5vcmc+iJMEExYKADsC
GwMFCwkIBwICIgIGFQoJCAsCBBYCAwECHgcCF4AWIQSftec33CWynY7sRpFC8/GG
LjzEuAUCZ7Y9wwAKCRBC8/GGLjzEuMEEAP9DH+1LgvTqZDLZ8babB5Cdp5y0ZW+Q
Tx78mh1L8jJd6gEAssmgsImcrZv4adP2UW5RU5BHCe9KUdx0DyV83QwlFAS4OARn
tj2TEgorBgEEAZdVAQUBAQdAGAH9dlaCONoXpmQgHoQgYI2tS+VM3mzU8I2PyVYQ
1GUDAQgHiHgEGBYKACACGwwWIQSftec33CWynY7sRpFC8/GGLjzEuAUCZ7Y91gAK
CRBC8/GGLjzEuHcnAP4yjOiM0yqkST6yXzDUWze7B9Im24F8HVx+wNqcDaDtcAD/
fKQhz0SCPiblO6lc7MFUvlaOz2v87UpUYRhzPdgQqwk=
=emrb
-----END PGP PUBLIC KEY BLOCK-----
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH RFC] send-mail: add support for Microsoft Graph API
2025-05-25 20:24 ` brian m. carlson
2025-05-26 1:36 ` Drew DeVault
@ 2025-05-26 3:38 ` Aditya Garg
1 sibling, 0 replies; 5+ messages in thread
From: Aditya Garg @ 2025-05-26 3:38 UTC (permalink / raw)
To: brian m. carlson
Cc: Junio C Hamano, git@vger.kernel.org, Eric Sunshine,
Julian Swagemakers, Jeff King, Zi Yao, Rens Oliemans,
Drew DeVault
> On 26 May 2025, at 1:55 AM, brian m. carlson <sandals@crustytoothpaste.net> wrote:
>
> On 2025-05-25 at 11:06:32, Aditya Garg wrote:
>> Apart from SMTP, Microsoft also provides a REST API, branded as
>> Microsoft Graph for sending mails. Upon testing a bit, I have
>> found a few benefits over SMTP. Firstly, SMTP servers of Microsoft
>> are kinda slow. On an average, initialising the SMTP server even
>> on a fast internet connection takes around 8-10 seconds with
>> send-email. Once initialised, subsequent messages sometimes also
>> face delays, taking around 3-5 seconds per message, and other
>> times they are sent almost instantaneously. Secondly, their SMTP
>> server does not respect the Message-ID specified by the user and
>> replaces it with their own generated string.
>>
>> Microsoft Graph API solves both these problems. It is extremely
>> fast, taking around 1 second to send a series of 5 patches, and
>> also respects the Message-ID specified by the user.
>
> I don't think we should be adding support for proprietary methods of
> sending mail. There are two standard methods, which are SMTP and the
> sendmail binary, that are well known, well understood, and widely
> deployed.
>
> It is well known that Microsoft has invented a lot of proprietary
> Outlook-specific formats for messages, such as TNEF and MAPI, which we
> should also not support because they are poorly defined and not
> specified in an open standard. I would also be opposed to sending mail
> in formats or using methods that are proprietary to Google, Amazon, or
> any other provider, since we already have clear specifications on how
> mail is to be sent that precede this project's existence by some time.
>
> I understand that the Outlook servers may be slow and inefficient as
> well as modify the Message-ID, but that's ultimately a problem you need
> to address with them and get them to fix. I should note that I don't
> have that problem: I run my own Postfix and Dovecot servers which are
> very speedy, and I feel confident any other provider could do so as
> well. I also have never had that problem sending mail through Google's
> SMTP server at work.
>
> If this REST API approach is well defined by an RFC or some other open
> specification process that the public can participate in and deployed
> among a large number of providers, including several open source
> implementations, then we might consider adopting it.
Fair, I was thinking proprietary protocols might not be accepted upstream.
I think its best to use an SMTP bridge, or use the sendmail-cmd like
capabilities of send-email.
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2025-05-26 3:38 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-05-25 11:06 [PATCH RFC] send-mail: add support for Microsoft Graph API Aditya Garg
2025-05-25 11:22 ` Aditya Garg
2025-05-25 20:24 ` brian m. carlson
2025-05-26 1:36 ` Drew DeVault
2025-05-26 3:38 ` Aditya Garg
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox