C
C#2mo ago
João Paulo

How can i detect a new e-mail arrival using GraphClientServer

I'm using Microsoft's outlook service through their graph library Microsoft.Graph. I make a login request in an API and they send a security code to my company's email I got stuck in the part of fetching my mailbox trying to find the security code e-mail. Is there a common way of doing it? I was thinking about requesting the mail count in the inbox and loop wait until something happens. I looked through the docs and didn't find anything about an event-like thing
using (var timeout = Task.Delay(TimeSpan.FromMinutes(TIMEOUT_MAIL_WAIT_m)))
{
while (timeout.IsCompleted is false)
{
string filter = $"receivedDateTime ge {DateTime.UtcNow:yyyy-MM-ddTHH:mm:ssZ} and from/emailAddress/address eq '{emailAddress}'";
var messages = await graphClient.Users[config.UserMailAddress].MailFolders.Inbox.Messages.Request().Filter(filter).GetAsync();

foreach (var message in messages)
{
Console.WriteLine($"From: {message.From.EmailAddress.Address}, Subject: {message.Subject}");
}

if (Task.WhenAny(Task.Delay(TimeSpan.FromMinutes(1)), timeout) == timeout)
{
throw new TimeoutException("damn");
}

}
}
using (var timeout = Task.Delay(TimeSpan.FromMinutes(TIMEOUT_MAIL_WAIT_m)))
{
while (timeout.IsCompleted is false)
{
string filter = $"receivedDateTime ge {DateTime.UtcNow:yyyy-MM-ddTHH:mm:ssZ} and from/emailAddress/address eq '{emailAddress}'";
var messages = await graphClient.Users[config.UserMailAddress].MailFolders.Inbox.Messages.Request().Filter(filter).GetAsync();

foreach (var message in messages)
{
Console.WriteLine($"From: {message.From.EmailAddress.Address}, Subject: {message.Subject}");
}

if (Task.WhenAny(Task.Delay(TimeSpan.FromMinutes(1)), timeout) == timeout)
{
throw new TimeoutException("damn");
}

}
}
3 Replies
João Paulo
João Paulo2mo ago
the security code e-mail generally takes 1 minute to arrive
SpReeD
SpReeD2mo ago
I don't know about Microsoft.Graph, but every mail has an unique id; you could crossechck by this id.
João Paulo
João Paulo2mo ago
current working solution is as follows
const int TIMEOUT_MAIL_WAIT_m = 8;
const int ANTIDDOS_LAG_ms = 2900;

using var timeout_cts = new CancellationTokenSource();
using var timeout = Task.Delay(TimeSpan.FromMinutes(TIMEOUT_MAIL_WAIT_m), timeout_cts.Token);

string query = $"ReceivedDateTime gt {DateTime.UtcNow:yyyy-MM-ddTHH:mm:ssZ} and from/emailAddress/address eq '{emailAddress}'";
var messageRepository = graphClient.Users[config.UserMailAddress].MailFolders.Inbox.Messages;

while (timeout.IsCompleted is false)
{
var msg = await messageRepository.Request().Filter(query).GetAsync();
if (msg.Count is not 0)
{
Console.WriteLine("Message detected");
// TODO: write logic to the captured message right here

timeout_cts.Cancel();
break;
}

if (Task.WhenAny(Task.Delay(TimeSpan.FromMinutes(1)), timeout) == timeout) break;
Thread.Sleep(ANTIDDOS_LAG_ms);
}

if (timeout.IsCompleted && timeout.IsCanceled is false)
{
// TODO: better exception message, mail not received whitin time limit frame
throw new TimeoutException("damn");
}
const int TIMEOUT_MAIL_WAIT_m = 8;
const int ANTIDDOS_LAG_ms = 2900;

using var timeout_cts = new CancellationTokenSource();
using var timeout = Task.Delay(TimeSpan.FromMinutes(TIMEOUT_MAIL_WAIT_m), timeout_cts.Token);

string query = $"ReceivedDateTime gt {DateTime.UtcNow:yyyy-MM-ddTHH:mm:ssZ} and from/emailAddress/address eq '{emailAddress}'";
var messageRepository = graphClient.Users[config.UserMailAddress].MailFolders.Inbox.Messages;

while (timeout.IsCompleted is false)
{
var msg = await messageRepository.Request().Filter(query).GetAsync();
if (msg.Count is not 0)
{
Console.WriteLine("Message detected");
// TODO: write logic to the captured message right here

timeout_cts.Cancel();
break;
}

if (Task.WhenAny(Task.Delay(TimeSpan.FromMinutes(1)), timeout) == timeout) break;
Thread.Sleep(ANTIDDOS_LAG_ms);
}

if (timeout.IsCompleted && timeout.IsCanceled is false)
{
// TODO: better exception message, mail not received whitin time limit frame
throw new TimeoutException("damn");
}