diff --git a/README.md b/README.md index c045db1..9278ebe 100644 --- a/README.md +++ b/README.md @@ -84,7 +84,6 @@ Almost there! You need to do three simple steps manually in the [Azure portal](h - Update the backend App Service application settings - Open the web app resource created for backend application and navigate to the Environment variables blade. - Update values for `AcsPhoneNumber` and `EmailSender` with the phone number and sender email address obtained in previous steps. - - Update the value for `EmailRecipient` with your email address where you would like to receive emails sent out by the sample applications. - Remember to save settings. ## Setup Instructions – Local environment diff --git a/app/backend/Models/EmailSummaryRequest.cs b/app/backend/Models/EmailSummaryRequest.cs index 9a3b2d2..ddce196 100644 --- a/app/backend/Models/EmailSummaryRequest.cs +++ b/app/backend/Models/EmailSummaryRequest.cs @@ -5,7 +5,8 @@ namespace CustomerSupportServiceSample.Models { public class SummaryRequest { - [JsonPropertyName("body")] + public string? Address { get; set; } + public string? Body { get; set; } } } \ No newline at end of file diff --git a/app/backend/Services/SummaryService.cs b/app/backend/Services/SummaryService.cs index 6e880cf..dab7abd 100644 --- a/app/backend/Services/SummaryService.cs +++ b/app/backend/Services/SummaryService.cs @@ -11,7 +11,6 @@ public class SummaryService : ISummaryService private readonly ILogger logger; private readonly string acsConnectionString; private readonly string sender; - private readonly string recipient; public SummaryService( IChatService chatService, @@ -25,7 +24,6 @@ public SummaryService( this.configuration = configuration; acsConnectionString = this.configuration["AcsConnectionString"] ?? ""; sender = this.configuration["EmailSender"] ?? ""; - recipient = this.configuration["EmailRecipient"] ?? ""; ArgumentException.ThrowIfNullOrEmpty(acsConnectionString); } @@ -52,17 +50,15 @@ public async Task SendSummaryEmail(SummaryRequest summary) var htmlContent = summary.Body; try { - logger.LogInformation("Sending email: to={}, from={}, body={}", recipient, sender, htmlContent); + logger.LogInformation("Sending email: to={}, from={}, body={}", summary.Address, sender, htmlContent); ArgumentException.ThrowIfNullOrEmpty(sender); - ArgumentException.ThrowIfNullOrEmpty(recipient); - // Note: - // This quickstart sample uses receiver email address from app configuration for simplicity - // In production scenario customer would provide their preferred email address + ArgumentException.ThrowIfNullOrEmpty(summary.Address); + EmailClient emailClient = new(this.acsConnectionString); EmailSendOperation emailSendOperation = await emailClient.SendAsync( WaitUntil.Completed, sender, - recipient, + summary.Address, "Follow up on support conversation", htmlContent); return emailSendOperation.Value.Status.ToString(); diff --git a/app/backend/backend.sln b/app/backend/backend.sln new file mode 100644 index 0000000..78f7661 --- /dev/null +++ b/app/backend/backend.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.5.002.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CustomerSupportServiceSample", "CustomerSupportServiceSample.csproj", "{8E16C0A1-74F6-4A8A-A19F-48137D38DEAA}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {8E16C0A1-74F6-4A8A-A19F-48137D38DEAA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8E16C0A1-74F6-4A8A-A19F-48137D38DEAA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8E16C0A1-74F6-4A8A-A19F-48137D38DEAA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8E16C0A1-74F6-4A8A-A19F-48137D38DEAA}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {A187B7FF-4E2B-4E67-A1C4-8CEA462F2D4B} + EndGlobalSection +EndGlobal diff --git a/app/frontend/src/components/Agent/SummaryWindow.tsx b/app/frontend/src/components/Agent/SummaryWindow.tsx index 4ca8d1c..307b2aa 100644 --- a/app/frontend/src/components/Agent/SummaryWindow.tsx +++ b/app/frontend/src/components/Agent/SummaryWindow.tsx @@ -30,6 +30,8 @@ const SummaryWindow: React.FC = () => { const [isLoading, setIsLoading] = useState(false); const [summaryDetails, setSummaryDetails] = useState(); const [summaryConversation, setSummaryConversation] = useState(); + const [customerEmailAddress, setCustomerEmailAddress] = useState(''); + const chatThreadId = localStorage.getItem('chatThreadId'); useEffect(() => { if (isModalOpen) { @@ -57,6 +59,7 @@ const SummaryWindow: React.FC = () => { const handleSendSummary = async () => { const emailBodyTemplate = await getEmailTemplate(summaryConversation?.result); const email: SummaryEmailData = { + address: customerEmailAddress, body: emailBodyTemplate }; @@ -66,6 +69,12 @@ const SummaryWindow: React.FC = () => { } else { console.log('Email sent succesfully!'); } + + setIsModalOpen(false); + }; + + const handleEmailUpdate = (event: React.ChangeEvent) => { + setCustomerEmailAddress(event.target.value); }; return ( @@ -88,6 +97,10 @@ const SummaryWindow: React.FC = () => {

Summary

{summaryDetails?.summaryItems[0].description}

+
+

Customer email address

+ +

Tasks

    diff --git a/app/frontend/src/styles/SummaryWindow.css b/app/frontend/src/styles/SummaryWindow.css index ff9215d..fc0ce80 100644 --- a/app/frontend/src/styles/SummaryWindow.css +++ b/app/frontend/src/styles/SummaryWindow.css @@ -4,10 +4,10 @@ Licensed under the MIT License.*/ .dialog { font-family: Arial, sans-serif; width: 950px; - height: 590px; + /* height: 590px; */ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); background-color: #fff; - overflow: hidden; + /* overflow: hidden; */ border-radius: 8px; } @@ -20,11 +20,16 @@ Licensed under the MIT License.*/ .summary-section, .tasks-section, +.email-address-section, .communication-section { padding: 4px; padding-left: 16px; } +.email-address-input { + width: 300px; +} + .bordered-content { border: 2px solid lightgray; border-radius: 5px; @@ -42,7 +47,7 @@ Licensed under the MIT License.*/ margin-top: 8px; width: 900px; white-space: pre-line; - height: 190px; + height: 100px; overflow-y: scroll; } @@ -87,9 +92,9 @@ Licensed under the MIT License.*/ text-align: right; } - .send-summary-button:hover { - background-color: #00894F; - } +.send-summary-button:hover { + background-color: #00894F; +} .button-group { display: flex; diff --git a/app/frontend/src/utils/SendSummaryDetails.tsx b/app/frontend/src/utils/SendSummaryDetails.tsx index 4f90e97..325dd6c 100644 --- a/app/frontend/src/utils/SendSummaryDetails.tsx +++ b/app/frontend/src/utils/SendSummaryDetails.tsx @@ -5,6 +5,7 @@ import config from '../appsettings.json'; const BASE_URL = config.baseUrl; export interface SummaryEmailData { + address: string; body: string; }