Skip to content
This repository was archived by the owner on Jun 30, 2022. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1312,10 +1312,12 @@ protected async Task HandleDialogExceptions(WaterfallStepContext sc, SkillExcept

private IDictionary<string, string> AssembleTelemetryData(WaterfallStepContext sc)
{
var telemetryData = new Dictionary<string, string>();
telemetryData.Add("activityId", sc.Context.Activity.Id);
telemetryData.Add("userId", sc.Context.Activity.From.Id);
telemetryData.Add("activeDialog", sc.ActiveDialog.ToString());
var telemetryData = new Dictionary<string, string>
{
{ "activityId", sc.Context.Activity.Id },
{ "userId", sc.Context.Activity.From.Id },
{ "activeDialog", sc.ActiveDialog.ToString() }
};

return telemetryData;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
using Google.Apis.Auth.OAuth2.Responses;
using Google.Apis.Gmail.v1;
using Google.Apis.Gmail.v1.Data;
using Google.Apis.Requests;
using Google.Apis.Services;
using Google.Apis.Util.Store;
using Microsoft.Bot.Solutions.Data;
Expand All @@ -31,7 +32,7 @@ namespace EmailSkill
public class GMailService : IMailService
{
private static GmailService service;
private int pageSize;
private readonly int pageSize;
private string pageToken = string.Empty;

/// <summary>
Expand Down Expand Up @@ -75,6 +76,49 @@ public static GmailService GetServiceClient(GoogleClient config, string token)
return service;
}

public static string Base64UrlEncode(string text)
{
var textBytes = Encoding.UTF8.GetBytes(text);

var result = System.Convert.ToBase64String(textBytes);
result = result.Split('=')[0]; // Remove any trailing '='s
result = result.Replace('+', '-'); // 62nd char of encoding
result = result.Replace('/', '_'); // 63rd char of encoding
return result;
}

// decode from base64url to utf-8 bytes
public static byte[] Base64UrlDecode(string text)
{
string result = text;
result = result.Replace('-', '+'); // 62nd char of encoding
result = result.Replace('_', '/'); // 63rd char of encoding

// Pad with trailing '='s
switch (result.Length % 4)
{
case 0: break; // No pad chars in this case
case 2: result += "=="; break; // Two pad chars
case 3: result += "="; break; // One pad char
default:
throw new System.Exception(
"Illegal base64url string!");
}

byte[] textBytes = Convert.FromBase64String(result);
return textBytes;
}

// decode to mimeMessage
public static MimeMessage DecodeToMessage(string text)
{
byte[] msg = Base64UrlDecode(text);
MemoryStream mm = new MemoryStream(msg);
MimeKit.MimeMessage mime = MimeKit.MimeMessage.Load(mm);
return mime;
}

/// <inheritdoc/>
public async Task ForwardMessageAsync(string id, string content, List<Recipient> recipients)
{
try
Expand Down Expand Up @@ -131,28 +175,33 @@ public async Task ForwardMessageAsync(string id, string content, List<Recipient>
content = quoted.ToString();
}

await service.Users.Messages.Send(
var sendRequest = service.Users.Messages.Send(
new GmailMessage()
{
Raw = Base64UrlEncode(forward.ToString() + content),
ThreadId = threadId,
}, "me").ExecuteAsync();
}, "me");
await ((IClientServiceRequest<GmailMessage>)sendRequest).ExecuteAsync();
}
catch (GoogleApiException ex)
{
throw GoogleClient.HandleGoogleAPIException(ex);
}
}
}

public async Task SendMessageAsync(string content, string subject, List<Recipient> recipients)
public async Task SendMessageAsync(string content, string subject, List<Recipient> recipients)
{
try
{
// get from address
var user = service.Users.GetProfile("me").Execute();
var mess = new MailMessage();
mess.Subject = subject;
mess.From = new MailAddress(user.EmailAddress);
var profileRequest = service.Users.GetProfile("me");
var user = ((IClientServiceRequest<Profile>)profileRequest).Execute();
var mess = new MailMessage
{
Subject = subject,
From = new MailAddress(user.EmailAddress)
};

foreach (var re in recipients)
{
mess.To.Add(new MailAddress(re.EmailAddress.Address));
Expand All @@ -164,11 +213,12 @@ public async Task SendMessageAsync(string content, string subject, List<Recipien
mess.AlternateViews.Add(adds);

var mime = MimeMessage.CreateFromMailMessage(mess);
await service.Users.Messages.Send(
var sendRequest = service.Users.Messages.Send(
new GmailMessage()
{
Raw = Base64UrlEncode(mime.ToString()),
}, "me").ExecuteAsync();
{
Raw = Base64UrlEncode(mime.ToString()),
}, "me");
await ((IClientServiceRequest<GmailMessage>)sendRequest).ExecuteAsync();
}
catch (GoogleApiException ex)
{
Expand Down Expand Up @@ -238,12 +288,13 @@ public async Task<List<MSMessage>> ReplyToMessageAsync(string id, string content
content = quoted.ToString();
}

await service.Users.Messages.Send(
new GmailMessage()
var sendRequest = service.Users.Messages.Send(
new GmailMessage()
{
Raw = Base64UrlEncode(reply.ToString() + content),
ThreadId = threadId,
}, "me").ExecuteAsync();
}, "me");
await ((IClientServiceRequest<GmailMessage>)sendRequest).ExecuteAsync();
return null;
}
catch (GoogleApiException ex)
Expand All @@ -256,7 +307,8 @@ public async Task<List<MSMessage>> GetMyMessagesAsync(DateTime fromTime, DateTim
{
try
{
var user = service.Users.GetProfile("me").Execute();
var profileRequest = service.Users.GetProfile("me");
var user = ((IClientServiceRequest<Profile>)profileRequest).Execute();
var userAddress = user.EmailAddress;

string searchOperation = string.Empty;
Expand Down Expand Up @@ -302,7 +354,7 @@ public async Task<List<MSMessage>> GetMyMessagesAsync(DateTime fromTime, DateTim
var tempReq = service.Users.Messages.List("me");
tempReq.MaxResults = skip;
tempReq.Q = searchOperation;
var tempRes = tempReq.Execute();
var tempRes = ((IClientServiceRequest<ListMessagesResponse>)tempReq).Execute();
if (tempRes.NextPageToken != null && tempRes.NextPageToken != string.Empty)
{
this.pageToken = tempRes.NextPageToken;
Expand All @@ -316,8 +368,8 @@ public async Task<List<MSMessage>> GetMyMessagesAsync(DateTime fromTime, DateTim
request.PageToken = this.pageToken;
}

ListMessagesResponse response = await request.ExecuteAsync();
List<MSMessage> result = new List<MSMessage>();
var response = await ((IClientServiceRequest<ListMessagesResponse>)request).ExecuteAsync();
var result = new List<MSMessage>();

// response.Messages only have id and threadID
if (response.Messages != null)
Expand All @@ -326,7 +378,7 @@ public async Task<List<MSMessage>> GetMyMessagesAsync(DateTime fromTime, DateTim
{
var req = service.Users.Messages.Get("me", temp.Id);
req.Format = UsersResource.MessagesResource.GetRequest.FormatEnum.Raw;
return req.ExecuteAsync();
return ((IClientServiceRequest<GmailMessage>)req).ExecuteAsync();
}));
if (messages != null && messages.Length > 0)
{
Expand Down Expand Up @@ -379,46 +431,21 @@ public string AppendFilterString(string old, string filterString)
return result;
}

private static string Base64UrlEncode(string text)
{
var textBytes = Encoding.UTF8.GetBytes(text);
return System.Convert.ToBase64String(textBytes)
.Replace('+', '-')
.Replace('/', '_')
.Replace("=", string.Empty);
}

// decode from base64url to utf-8 bytes
private static byte[] Base64UrlDecode(string text)
{
var temp = text.Replace('-', '+')
.Replace('_', '/');
byte[] textBytes = Convert.FromBase64String(temp);
return textBytes; // Encoding.UTF8.GetString(textBytes);
}

// decode to mimeMessage
private static MimeMessage DecodeToMessage(string text)
{
byte[] msg = Base64UrlDecode(text);
MemoryStream mm = new MemoryStream(msg);
MimeKit.MimeMessage mime = MimeKit.MimeMessage.Load(mm);
return mime;
}

private async Task<(MimeMessage, string)> GetMessageById(string id)
{
var request = service.Users.Messages.Get("me", id);
request.Format = UsersResource.MessagesResource.GetRequest.FormatEnum.Raw;
var response = await request.ExecuteAsync();
var response = await ((IClientServiceRequest<GmailMessage>)request).ExecuteAsync();
var mime = DecodeToMessage(response.Raw);
return (mime, response.ThreadId);
}

private MSMessage MapMimeMessageToMSMessage(MimeMessage mime)
{
MSMessage message = new MSMessage();
message.ReceivedDateTime = mime.Date;
MSMessage message = new MSMessage
{
ReceivedDateTime = mime.Date
};
if (mime.To != null)
{
var to = new List<Recipient>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using Google.Apis.Auth.OAuth2.Responses;
using Google.Apis.People.v1;
using Google.Apis.People.v1.Data;
using Google.Apis.Requests;
using Google.Apis.Services;
using Google.Apis.Util.Store;
using Microsoft.Graph;
Expand Down Expand Up @@ -78,8 +79,8 @@ public async Task<List<MsPerson>> GetPeopleAsync(string name)
PeopleResource.ConnectionsResource.ListRequest peopleRequest = service.People.Connections.List("people/me");
peopleRequest.RequestMaskIncludeField = "person.emailAddresses,person.names";

ListConnectionsResponse connectionsResponse = await peopleRequest.ExecuteAsync();
IList<GooglePerson> connections = connectionsResponse.Connections;
ListConnectionsResponse connectionsResponse = await ((IClientServiceRequest<ListConnectionsResponse>)peopleRequest).ExecuteAsync();
IList<GooglePerson> connections = connectionsResponse.Connections;

var result = new List<MsPerson>();
if (connections != null && connections.Count > 0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,13 @@ public interface IMailService
/// </summary>
/// <param name="startDateTime">Start date time.</param>
/// <param name="endDateTime">End date time.</param>
/// <param name="isRead">If been read.</param>
/// <param name="getUnRead">If been read.</param>
/// <param name="isImportant">If important.</param>
/// <param name="directlyToMe">If directly to user.</param>
/// <param name="mailAddress">Message coming from address.</param>
/// <param name="skip">Skip message count.</param>
/// <returns>A <see cref="Task{TResult}"/> representing the result of the asynchronous operation.</returns>
Task<List<Message>> GetMyMessagesAsync(DateTime startDateTime, DateTime endDateTime, bool isRead, bool isImportant, bool directlyToMe, string mailAddress, int skip);
Task<List<Message>> GetMyMessagesAsync(DateTime startDateTime, DateTime endDateTime, bool getUnRead, bool isImportant, bool directlyToMe, string mailAddress, int skip);

/// <summary>
/// Delete email.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
using System.Collections.Generic;
using System.Net.Mail;
using System.Text;
using EmailSkill;
using MimeKit;
using GmailMessage = Google.Apis.Gmail.v1.Data.Message;

namespace EmailSkillTest.API.Fakes
{
public class GmailUtil
{
public static IList<GmailMessage> GetFakeGmailMessageList(int size = 5)
{
var messages = new List<GmailMessage>();

for (int i = 0; i < size; i++)
{
var message = GetFakeGmailMessage(to: "test@test.com" + i);
messages.Add(message);
}

return messages;
}

public static GmailMessage GetFakeGmailMessage(
string from = "test@test.com",
string to = "test@test.com",
string subject = "test subject",
string content = "test content")
{
var mess = new MailMessage
{
Subject = subject,
From = new MailAddress(from)
};
mess.To.Add(new MailAddress(to));

var adds = AlternateView.CreateAlternateViewFromString(content, new System.Net.Mime.ContentType("text/plain"));
adds.ContentType.CharSet = Encoding.UTF8.WebName;
mess.AlternateViews.Add(adds);

var mime = MimeMessage.CreateFromMailMessage(mess);
var gmailMessage = new GmailMessage()
{
Raw = GMailService.Base64UrlEncode(mime.ToString()),
ThreadId = "1"
};

return gmailMessage;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
using Google.Apis.Gmail.v1;
using Moq;
using static Google.Apis.Gmail.v1.UsersResource;
using GmailMessage = Google.Apis.Gmail.v1.Data.Message;

namespace EmailSkillTest.API.Fakes
{
public class MockGoogleServiceClient
{
private readonly Mock<GmailService> mockMailService;
private readonly Mock<MessagesResource> mockMessagesResource;
private readonly Mock<UsersResource> mockUsersResource;

public MockGoogleServiceClient()
{
this.mockMailService = new Mock<GmailService>();
this.mockMessagesResource = new Mock<MessagesResource>(mockMailService.Object);
this.mockUsersResource = new Mock<UsersResource>(mockMailService.Object);

this.mockUsersResource.SetupGet(users => users.Messages).Returns(mockMessagesResource.Object);

this.mockUsersResource.Setup(users => users.GetProfile(It.IsAny<string>())).Returns((string userId) =>
{
MockUsersResource.MockGetProfileRequest mockGetProfileRequest = new MockUsersResource.MockGetProfileRequest(this.mockMailService.Object, userId);
return mockGetProfileRequest;
});

this.mockMailService.SetupGet(service => service.Users).Returns(mockUsersResource.Object);

this.mockMessagesResource.Setup(messages => messages.Send(It.IsAny<GmailMessage>(), It.IsAny<string>())).Returns((GmailMessage body, string userId) =>
{
MockMessagesResource.MockSendRequest mockSendRequest = new MockMessagesResource.MockSendRequest(this.mockMailService.Object, body, userId);
return mockSendRequest;
});

this.mockMessagesResource.Setup(messages => messages.Get(It.IsAny<string>(), It.IsAny<string>())).Returns((string userId, string id) =>
{
MockMessagesResource.MockGetRequest mockGetRequest = new MockMessagesResource.MockGetRequest(this.mockMailService.Object, userId, id);

return mockGetRequest;
});

this.mockMessagesResource.Setup(messages => messages.List(It.IsAny<string>())).Returns((string userId) =>
{
MockMessagesResource.MockListRequest mockListRequest = new MockMessagesResource.MockListRequest(this.mockMailService.Object, userId);

return mockListRequest;
});
}

public Mock<GmailService> GetMockGraphServiceClient()
{
return this.mockMailService;
}
}
}
Loading