Skip to content
This repository has been archived by the owner on Jun 30, 2022. It is now read-only.

[Email Skill]Adaptive Card update with Graph API #1029

Merged
merged 24 commits into from
Apr 2, 2019
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
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
4 changes: 2 additions & 2 deletions docs/virtual-assistant/gettingstarted.md
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ The [Add Authentication to your bot](https://docs.microsoft.com/en-us/azure/bot-
- `Notes.ReadWrite`
- `People.Read`
- `Tasks.ReadWrite`
- `User.Read`
- `User.ReadBasic.All`
- Click Add Permissions at the bottom to apply the changes.

Next you need to create the Authentication Connection for your Bot. Ensure you use the same combination of Scopes that you provided in the above command. The first command shown below will retrieve the appId (ApplicationId) and appPassword (Client Secret) that you need to complete this step.
Expand All @@ -210,7 +210,7 @@ The commands shown below assume you have used the deployment process and your re
```shell
msbot get production --secret YOUR_SECRET

az bot authsetting create --resource-group YOUR_BOT_NAME --name YOUR_BOT_NAME --setting-name "YOUR_AUTH_CONNECTION_DISPLAY_NAME" --client-id "YOUR_APPLICATION_ID" --client-secret "YOUR_APPLICATION_PASSWORD" --service Aadv2 --parameters clientId="YOUR_APPLICATION_ID" clientSecret="YOUR_APPLICATION_PASSWORD" tenantId=common --provider-scope-string "Calendars.ReadWrite Mail.ReadWrite Mail.Send Tasks.ReadWrite Notes.ReadWrite People.Read User.Read Contacts.Read"
az bot authsetting create --resource-group YOUR_BOT_NAME --name YOUR_BOT_NAME --setting-name "YOUR_AUTH_CONNECTION_DISPLAY_NAME" --client-id "YOUR_APPLICATION_ID" --client-secret "YOUR_APPLICATION_PASSWORD" --service Aadv2 --parameters clientId="YOUR_APPLICATION_ID" clientSecret="YOUR_APPLICATION_PASSWORD" tenantId=common --provider-scope-string "Calendars.ReadWrite Mail.ReadWrite Mail.Send Tasks.ReadWrite Notes.ReadWrite People.Read User.ReadBasic.All Contacts.Read"
```

> NOTE: Take special care when running the `authsetting` commands to correctly escape special characters in your client secret key (or parameters that contain special characters).
Expand Down
50 changes: 48 additions & 2 deletions lib/microsoft.bot.builder.solutions/Responses/ResponseManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,46 @@ public Activity GetCardResponse(
return MessageFactory.Carousel(attachments, response.Text, response.Speak, response.InputHint) as Activity;
}

public Activity GetCardResponse(
string templateId,
Card card,
StringDictionary tokens = null,
string containerName = null,
IEnumerable<Card> containerItems = null)
{
var locale = CultureInfo.CurrentUICulture.Name;
var assembly = Assembly.GetCallingAssembly();
var json = LoadCardJson(card.Name, locale, assembly);

var emailOverviewCard = BuildCard(json, card.Data);
if (!string.IsNullOrEmpty(containerName))
{
var itemsContainer = emailOverviewCard.Body.Find(item => item.Id == containerName);
if ((itemsContainer != null) && itemsContainer is AdaptiveContainer)
{
foreach (var cardItem in containerItems)
{
var itemJson = LoadCardJson(cardItem.Name, locale, assembly);
var itemCard = BuildCard(itemJson, cardItem.Data);
var itemContainer = itemCard.Body[0] as AdaptiveContainer;

(itemsContainer as AdaptiveContainer).Items.Add(itemContainer);
}
}
}

var cardObj = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(emailOverviewCard));
var attachment = new Attachment(AdaptiveCard.ContentType, content: cardObj);

if (templateId != null)
{
var response = GetResponse(templateId, tokens);
return MessageFactory.Attachment(attachment, response.Text, response.Speak, response.InputHint) as Activity;
}

return MessageFactory.Attachment(attachment, null, null, null) as Activity;
}

public ResponseTemplate GetResponseTemplate(string templateId, string locale = null)
{
locale = locale ?? CultureInfo.CurrentUICulture.Name;
Expand Down Expand Up @@ -350,6 +390,13 @@ private string LoadCardJson(string cardName, string locale, Assembly assembly)
}

private Attachment BuildCardAttachment(string json, ICardData data = null)
{
var card = BuildCard(json, data);
var cardObj = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(card));
return new Attachment(AdaptiveCard.ContentType, content: cardObj);
}

private AdaptiveCard BuildCard(string json, ICardData data = null)
{
// If cardData was provided
if (data != null)
Expand All @@ -376,8 +423,7 @@ private Attachment BuildCardAttachment(string json, ICardData data = null)

// Deserialize/Serialize logic is needed to prevent JSON exception in prompts
var card = AdaptiveCard.FromJson(json).Card;
var cardObj = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(card));
return new Attachment(AdaptiveCard.ContentType, content: cardObj);
return card;
}
}
}
6 changes: 6 additions & 0 deletions solutions/Virtual-Assistant/src/csharp/VirtualAssistant.sln
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RestaurantBooking", "experi
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NewsSkill", "experimental\skills\newsskill\NewsSkill.csproj", "{A7FB024B-A18F-4B0D-865D-313DD941E581}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Bot.Builder.Solutions", "..\..\..\..\lib\microsoft.bot.builder.solutions\Microsoft.Bot.Builder.Solutions.csproj", "{2EEA7099-45A1-4BFA-A2E3-EDB51F025B5C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -117,6 +119,10 @@ Global
{A7FB024B-A18F-4B0D-865D-313DD941E581}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A7FB024B-A18F-4B0D-865D-313DD941E581}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A7FB024B-A18F-4B0D-865D-313DD941E581}.Release|Any CPU.Build.0 = Release|Any CPU
{2EEA7099-45A1-4BFA-A2E3-EDB51F025B5C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2EEA7099-45A1-4BFA-A2E3-EDB51F025B5C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2EEA7099-45A1-4BFA-A2E3-EDB51F025B5C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2EEA7099-45A1-4BFA-A2E3-EDB51F025B5C}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Threading;
Expand All @@ -9,10 +10,12 @@
using EmailSkill.Dialogs.Shared.Resources;
using EmailSkill.Dialogs.Shared.Resources.Cards;
using EmailSkill.Dialogs.Shared.Resources.Strings;
using EmailSkill.Extensions;
using EmailSkill.ServiceClients;
using EmailSkill.Util;
using Microsoft.Bot.Builder;
using Microsoft.Bot.Builder.Dialogs;
using Microsoft.Bot.Builder.Solutions.Resources;
using Microsoft.Bot.Builder.Solutions.Responses;
using Microsoft.Bot.Builder.Solutions.Skills;
using Microsoft.Bot.Builder.Solutions.Util;
Expand Down Expand Up @@ -71,27 +74,38 @@ public DeleteEmailDialog(
var state = await EmailStateAccessor.GetAsync(sc.Context);
var skillOptions = (EmailSkillDialogOptions)sc.Options;

var focusedMessage = state.Message?.FirstOrDefault();
if (focusedMessage != null)
var message = state.Message?.FirstOrDefault();
if (message != null)
{
var nameListString = DisplayHelper.ToDisplayRecipientsString_Summay(focusedMessage.ToRecipients);
var nameListString = DisplayHelper.ToDisplayRecipientsString_Summay(message.ToRecipients);
var senderIcon = await GetUserPhotoUrlAsync(sc.Context, message.Sender.EmailAddress);
var emailCard = new EmailCardData
{
Subject = string.Format(EmailCommonStrings.SubjectFormat, focusedMessage.Subject),
NameList = string.Format(EmailCommonStrings.ToFormat, nameListString),
EmailContent = string.Format(EmailCommonStrings.ContentFormat, focusedMessage.BodyPreview),
Subject = message.Subject,
EmailContent = message.BodyPreview,
Sender = message.Sender.EmailAddress.Name,
EmailLink = message.WebLink,
ReceivedDateTime = message?.ReceivedDateTime == null
? CommonStrings.NotAvailable
: message.ReceivedDateTime.Value.UtcDateTime.ToDetailRelativeString(state.GetUserTimeZone()),
Speak = SpeakHelper.ToSpeechEmailDetailOverallString(message, state.GetUserTimeZone()),
SenderIcon = senderIcon
};
emailCard = await ProcessRecipientPhotoUrl(sc.Context, emailCard, message.ToRecipients);

var speech = SpeakHelper.ToSpeechEmailSendDetailString(focusedMessage.Subject, nameListString, focusedMessage.BodyPreview);
var speech = SpeakHelper.ToSpeechEmailSendDetailString(message.Subject, nameListString, message.BodyPreview);
var tokens = new StringDictionary
{
{ "EmailDetails", speech },
};

var recipientCard = message.ToRecipients.Count() > 5 ? "DetailCard_RecipientMoreThanFive" : "DetailCard_RecipientLessThanFive";
var prompt = ResponseManager.GetCardResponse(
DeleteEmailResponses.DeleteConfirm,
new Card("EmailWithOutButtonCard", emailCard),
tokens);
new Card("EmailDetailCard", emailCard),
tokens,
"items",
new List<Card>().Append(new Card(recipientCard, emailCard)));

var retry = ResponseManager.GetResponse(EmailSharedResponses.ConfirmSendFailed);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Threading;
Expand Down Expand Up @@ -94,24 +95,25 @@ public ForwardEmailDialog(
var content = state.Content.Equals(EmailCommonStrings.EmptyContent) ? string.Empty : state.Content;
await service.ForwardMessageAsync(id, content, recipients);

var nameListString = DisplayHelper.ToDisplayRecipientsString_Summay(state.Recipients);

var emailCard = new EmailCardData
{
Subject = state.Subject.Equals(EmailCommonStrings.EmptySubject) ? null : string.Format(EmailCommonStrings.SubjectFormat, state.Subject),
NameList = string.Format(EmailCommonStrings.ToFormat, nameListString),
EmailContent = state.Content.Equals(EmailCommonStrings.EmptyContent) ? null : string.Format(EmailCommonStrings.ContentFormat, state.Content),
Subject = state.Subject.Equals(EmailCommonStrings.EmptySubject) ? null : state.Subject,
EmailContent = state.Content.Equals(EmailCommonStrings.EmptyContent) ? null : state.Content,
};
emailCard = await ProcessRecipientPhotoUrl(sc.Context, emailCard, state.Recipients);

var stringToken = new StringDictionary
{
{ "Subject", state.Subject },
};

var recipientCard = state.Recipients.Count() > 5 ? "ConfirmCard_RecipientMoreThanFive" : "ConfirmCard_RecipientLessThanFive";
var reply = ResponseManager.GetCardResponse(
EmailSharedResponses.SentSuccessfully,
new Card("EmailWithOutButtonCard", emailCard),
stringToken);
stringToken,
"items",
new List<Card>().Append(new Card(recipientCard, emailCard)));

await sc.Context.SendActivityAsync(reply);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Threading;
Expand Down Expand Up @@ -85,24 +86,25 @@ public ReplyEmailDialog(
await service.ReplyToMessageAsync(message.Id, content);
}

var nameListString = DisplayHelper.ToDisplayRecipientsString_Summay(message?.ToRecipients);

var emailCard = new EmailCardData
{
Subject = state.Subject.Equals(EmailCommonStrings.EmptySubject) ? null : string.Format(EmailCommonStrings.SubjectFormat, state.Subject),
NameList = string.Format(EmailCommonStrings.ToFormat, nameListString),
EmailContent = state.Content.Equals(EmailCommonStrings.EmptyContent) ? null : string.Format(EmailCommonStrings.ContentFormat, state.Content),
Subject = state.Subject.Equals(EmailCommonStrings.EmptySubject) ? null : state.Subject,
EmailContent = state.Content.Equals(EmailCommonStrings.EmptyContent) ? null : state.Content,
};
emailCard = await ProcessRecipientPhotoUrl(sc.Context, emailCard, state.Recipients);

var stringToken = new StringDictionary
{
{ "Subject", state.Subject },
};

var recipientCard = state.Recipients.Count() > 5 ? "ConfirmCard_RecipientMoreThanFive" : "ConfirmCard_RecipientLessThanFive";
var reply = ResponseManager.GetCardResponse(
EmailSharedResponses.SentSuccessfully,
new Card("EmailWithOutButtonCard", emailCard),
stringToken);
stringToken,
"items",
new List<Card>().Append(new Card(recipientCard, emailCard)));

await sc.Context.SendActivityAsync(reply);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using EmailSkill.Dialogs.FindContact;
Expand Down Expand Up @@ -308,7 +310,8 @@ public SendEmailDialog(

var emailCard = new EmailCardData
{
EmailContent = string.Format(EmailCommonStrings.ContentFormat, state.Content),
Subject = EmailCommonStrings.MessageConfirm,
EmailContent = state.Content,
};

var stringToken = new StringDictionary
Expand Down Expand Up @@ -385,23 +388,25 @@ public SendEmailDialog(
var content = state.Content.Equals(EmailCommonStrings.EmptyContent) ? string.Empty : state.Content;
await service.SendMessageAsync(content, subject, state.Recipients);

var nameListString = DisplayHelper.ToDisplayRecipientsString_Summay(state.Recipients);

var emailCard = new EmailCardData
{
Subject = state.Subject.Equals(EmailCommonStrings.EmptySubject) ? null : string.Format(EmailCommonStrings.SubjectFormat, state.Subject),
NameList = string.Format(EmailCommonStrings.ToFormat, nameListString),
EmailContent = state.Content.Equals(EmailCommonStrings.EmptyContent) ? null : string.Format(EmailCommonStrings.ContentFormat, state.Content),
};
emailCard = await ProcessRecipientPhotoUrl(sc.Context, emailCard, state.Recipients);

var stringToken = new StringDictionary
{
{ "Subject", state.Subject },
};

var recipientCard = state.Recipients.Count() > 5 ? "ConfirmCard_RecipientMoreThanFive" : "ConfirmCard_RecipientLessThanFive";
var replyMessage = ResponseManager.GetCardResponse(
EmailSharedResponses.SentSuccessfully,
new Card("EmailWithOutButtonCard", emailCard),
stringToken);
stringToken,
"items",
new List<Card>().Append(new Card(recipientCard, emailCard)));

await sc.Context.SendActivityAsync(replyMessage);
}
Expand Down
Loading