diff --git a/App.config b/App.config new file mode 100644 index 0000000..2d6c111 --- /dev/null +++ b/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/OutlookCaseHelper.sln b/OutlookCaseHelper.sln new file mode 100644 index 0000000..ff5fccc --- /dev/null +++ b/OutlookCaseHelper.sln @@ -0,0 +1,35 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.14.37027.9 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OutlookCaseHelper", "OutlookCaseHelper\OutlookCaseHelper.csproj", "{6541931B-814B-42A0-8FD3-3F10FF401964}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{8EC462FD-D22E-90A8-E5CE-7E832BA40C5D}" + ProjectSection(SolutionItems) = preProject + App.config = App.config + OutlookHelper.cs = OutlookHelper.cs + EndProjectSection +EndProject +Project("{54435603-DBB4-11D2-8724-00A0C9A8B90C}") = "OutlookCaseHelperSetup", "OutlookCaseHelperSetup\OutlookCaseHelperSetup.vdproj", "{45984EC3-3682-760C-C1F0-4987692FB84A}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {6541931B-814B-42A0-8FD3-3F10FF401964}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6541931B-814B-42A0-8FD3-3F10FF401964}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6541931B-814B-42A0-8FD3-3F10FF401964}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6541931B-814B-42A0-8FD3-3F10FF401964}.Release|Any CPU.Build.0 = Release|Any CPU + {45984EC3-3682-760C-C1F0-4987692FB84A}.Debug|Any CPU.ActiveCfg = Debug + {45984EC3-3682-760C-C1F0-4987692FB84A}.Release|Any CPU.ActiveCfg = Release + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {718AF298-6A90-49DD-A9D9-3CA11B97679B} + EndGlobalSection +EndGlobal diff --git a/OutlookCaseHelper/Form1.Designer.cs b/OutlookCaseHelper/Form1.Designer.cs new file mode 100644 index 0000000..27477a8 --- /dev/null +++ b/OutlookCaseHelper/Form1.Designer.cs @@ -0,0 +1,39 @@ +namespace OutlookCaseHelper +{ + partial class Form1 + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(800, 450); + this.Text = "Form1"; + } + + #endregion + } +} diff --git a/OutlookCaseHelper/Form1.cs b/OutlookCaseHelper/Form1.cs new file mode 100644 index 0000000..ee4851e --- /dev/null +++ b/OutlookCaseHelper/Form1.cs @@ -0,0 +1,155 @@ +using System; +using System.Drawing; +using System.Windows.Forms; + +namespace OutlookCaseHelper +{ + public partial class Form1 : Form + { + private NotifyIcon trayIcon; + private ContextMenuStrip trayMenu; + private OutlookHelper outlookHelper; + + public Form1() + { + InitializeComponent(); + this.WindowState = FormWindowState.Minimized; + this.ShowInTaskbar = false; + InitializeTray(); + outlookHelper = new OutlookHelper(); + } + + private void InitializeTray() + { + trayMenu = new ContextMenuStrip(); + trayMenu.Items.Add("Process Selected Email", null, ProcessEmail_Click); + trayMenu.Items.Add("Remove Rule", null, RemoveRule_Click); + trayMenu.Items.Add("-"); + trayMenu.Items.Add("Exit", null, Exit_Click); + + trayIcon = new NotifyIcon(); + trayIcon.Icon = SystemIcons.Application; + trayIcon.ContextMenuStrip = trayMenu; + trayIcon.Text = "Outlook Case Manager"; + trayIcon.Visible = true; + trayIcon.MouseDoubleClick += TrayIcon_MouseDoubleClick; + } + + private void ProcessEmail_Click(object? sender, EventArgs e) + { + try + { + var trackingId = outlookHelper.GetSelectedEmailTrackingId(); + if (string.IsNullOrEmpty(trackingId)) + { + MessageBox.Show( + "No email selected or ID not found in subject.\n\nExpected format: Title - TrackingID1111111111111111", + "Warning", + MessageBoxButtons.OK, + MessageBoxIcon.Warning); + return; + } + + bool success = outlookHelper.CreateFolderAndMoveEmails(trackingId); + if (success) + { + MessageBox.Show( + $"Folder created/updated and emails moved successfully!\n\nTrackingID: {trackingId}", + "Success", + MessageBoxButtons.OK, + MessageBoxIcon.Information); + } + else + { + MessageBox.Show( + "Error processing email. Make sure Outlook is open.", + "Error", + MessageBoxButtons.OK, + MessageBoxIcon.Error); + } + } + catch (Exception ex) + { + MessageBox.Show($"Error: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + + private void RemoveRule_Click(object? sender, EventArgs e) + { + try + { + var form = new InputForm("Enter TrackingID to remove:", "Remove Rule"); + if (form.ShowDialog() == DialogResult.OK && !string.IsNullOrEmpty(form.TrackingId)) + { + bool success = outlookHelper.RemoveRuleAndMoveToClosed(form.TrackingId); + if (success) + { + MessageBox.Show( + "Rule removed successfully!\n\nFolder moved to: Inbox > Cases > Closed", + "Success", + MessageBoxButtons.OK, + MessageBoxIcon.Information); + } + else + { + MessageBox.Show( + "Error removing rule. Check if folder exists.", + "Error", + MessageBoxButtons.OK, + MessageBoxIcon.Error); + } + } + } + catch (Exception ex) + { + MessageBox.Show($"Error: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + + private void TrayIcon_MouseDoubleClick(object? sender, MouseEventArgs e) + { + ProcessEmail_Click(null, EventArgs.Empty); + } + + private void Exit_Click(object? sender, EventArgs e) + { + trayIcon.Visible = false; + Application.Exit(); + } + + // Simple input dialog + private class InputForm : Form + { + private TextBox txtInput; + public string TrackingId { get; private set; } = ""; + + public InputForm(string prompt, string title) + { + this.Text = title; + this.Width = 400; + this.Height = 150; + this.StartPosition = FormStartPosition.CenterScreen; + + var label = new Label { Text = prompt, Left = 20, Top = 20, Width = 360, Height = 30 }; + txtInput = new TextBox { Left = 20, Top = 60, Width = 340, Height = 30 }; + + var btnOk = new Button { Text = "OK", Left = 200, Top = 100, Width = 80, DialogResult = DialogResult.OK }; + var btnCancel = new Button { Text = "Cancel", Left = 290, Top = 100, Width = 80, DialogResult = DialogResult.Cancel }; + + this.Controls.Add(label); + this.Controls.Add(txtInput); + this.Controls.Add(btnOk); + this.Controls.Add(btnCancel); + + this.AcceptButton = btnOk; + this.CancelButton = btnCancel; + } + + protected override void OnFormClosing(FormClosingEventArgs e) + { + TrackingId = txtInput.Text; + base.OnFormClosing(e); + } + } + } +} \ No newline at end of file diff --git a/OutlookCaseHelper/Form1.resx b/OutlookCaseHelper/Form1.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/OutlookCaseHelper/Form1.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/OutlookCaseHelper/OutlookCaseHelper.csproj b/OutlookCaseHelper/OutlookCaseHelper.csproj new file mode 100644 index 0000000..510afd2 --- /dev/null +++ b/OutlookCaseHelper/OutlookCaseHelper.csproj @@ -0,0 +1,41 @@ + + + + WinExe + net8.0-windows + enable + true + enable + + + + + tlbimp + 6 + 9 + 00062fff-0000-0000-c000-000000000046 + 0 + false + true + + + tlbimp + 8 + 2 + 2df8d04c-5bfa-101b-bde5-00aa0044de52 + 0 + false + true + + + tlbimp + 2 + 1 + 0006f062-0000-0000-c000-000000000046 + 0 + false + true + + + + \ No newline at end of file diff --git a/OutlookCaseHelper/OutlookHelper.cs b/OutlookCaseHelper/OutlookHelper.cs new file mode 100644 index 0000000..ffec2e7 --- /dev/null +++ b/OutlookCaseHelper/OutlookHelper.cs @@ -0,0 +1,127 @@ +using System; +using System.Collections.Generic; +using System.Text.RegularExpressions; +using Outlook = Microsoft.Office.Interop.Outlook; + +namespace OutlookCaseHelper +{ + public class OutlookHelper + { + private Outlook.Application outlookApp; + private Outlook.NameSpace outlookNamespace; + + public OutlookHelper() + { + outlookApp = new Outlook.Application(); + outlookNamespace = outlookApp.GetNamespace("MAPI"); + } + + public string? GetSelectedEmailTrackingId() + { + try + { + Outlook.Explorer activeExplorer = outlookApp.ActiveExplorer(); + if (activeExplorer == null) return null; + + Outlook.Selection selection = activeExplorer.Selection; + if (selection.Count == 0) return null; + + Outlook.MailItem? email = selection[1] as Outlook.MailItem; + if (email == null) return null; + + // Aceita "TrackingID#1234567890" com qualquer número + Match match = Regex.Match(email.Subject, @"TrackingID#(\d+)"); + if (match.Success) + return match.Groups[1].Value; + + return null; + } + catch { return null; } + } + + public bool CreateFolderAndMoveEmails(string trackingId) + { + try + { + Outlook.Folder? inboxFolder = + outlookNamespace.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox) as Outlook.Folder; + if (inboxFolder == null) return false; + + Outlook.Folder casesFolder = GetOrCreateFolder(inboxFolder, "Cases"); + Outlook.Folder activeFolder = GetOrCreateFolder(casesFolder, "Active"); + Outlook.Folder trackingFolder = GetOrCreateFolder(activeFolder, trackingId); + + MoveEmailsWithTrackingId(inboxFolder, trackingId, trackingFolder); + + Outlook.Folder? sentFolder = + outlookNamespace.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderSentMail) as Outlook.Folder; + if (sentFolder != null) + MoveEmailsWithTrackingId(sentFolder, trackingId, trackingFolder); + + return true; + } + catch { return false; } + } + + public bool RemoveRuleAndMoveToClosed(string trackingId) + { + try + { + Outlook.Folder? inboxFolder = + outlookNamespace.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox) as Outlook.Folder; + if (inboxFolder == null) return false; + + Outlook.Folder? casesFolder = GetFolder(inboxFolder, "Cases"); + if (casesFolder == null) return false; + + Outlook.Folder? activeFolder = GetFolder(casesFolder, "Active"); + if (activeFolder == null) return false; + + Outlook.Folder? trackingFolder = GetFolder(activeFolder, trackingId); + if (trackingFolder == null) return false; + + Outlook.Folder closedFolder = GetOrCreateFolder(casesFolder, "Closed"); + trackingFolder.MoveTo(closedFolder); + + return true; + } + catch { return false; } + } + + private Outlook.Folder GetOrCreateFolder(Outlook.Folder parent, string name) + { + foreach (Outlook.Folder folder in parent.Folders) + { + if (folder.Name == name) + return folder; + } + return (Outlook.Folder)parent.Folders.Add(name); + } + + private Outlook.Folder? GetFolder(Outlook.Folder parent, string name) + { + foreach (Outlook.Folder folder in parent.Folders) + { + if (folder.Name == name) + return folder; + } + return null; + } + + private void MoveEmailsWithTrackingId(Outlook.Folder source, string trackingId, Outlook.Folder dest) + { + var toMove = new List(); + + foreach (object item in source.Items) + { + Outlook.MailItem? mail = item as Outlook.MailItem; + // Procura "TrackingID#" + os números no subject + if (mail != null && mail.Subject != null && mail.Subject.Contains($"TrackingID#{trackingId}")) + toMove.Add(mail); + } + + foreach (var mail in toMove) + mail.Move(dest); + } + } +} \ No newline at end of file diff --git a/OutlookCaseHelper/Program.cs b/OutlookCaseHelper/Program.cs new file mode 100644 index 0000000..1d57e52 --- /dev/null +++ b/OutlookCaseHelper/Program.cs @@ -0,0 +1,16 @@ +using System; +using System.Windows.Forms; + +namespace OutlookCaseHelper +{ + internal static class Program + { + [STAThread] + static void Main() + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Application.Run(new Form1()); + } + } +} diff --git a/OutlookCaseHelperSetup/OutlookCaseHelperSetup.vdproj b/OutlookCaseHelperSetup/OutlookCaseHelperSetup.vdproj new file mode 100644 index 0000000..a800251 --- /dev/null +++ b/OutlookCaseHelperSetup/OutlookCaseHelperSetup.vdproj @@ -0,0 +1,863 @@ +"DeployProject" +{ +"VSVersion" = "3:800" +"ProjectType" = "8:{978C614F-708E-4E1A-B201-565925725DBA}" +"IsWebType" = "8:FALSE" +"ProjectName" = "8:OutlookCaseHelperSetup" +"LanguageId" = "3:1033" +"CodePage" = "3:1252" +"UILanguageId" = "3:1033" +"SccProjectName" = "8:" +"SccLocalPath" = "8:" +"SccAuxPath" = "8:" +"SccProvider" = "8:" + "Hierarchy" + { + "Entry" + { + "MsmKey" = "8:_3B183E44CB644AC2B8CFD4CE7E8493D5" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_5B02FA9AA2644553AA7EE8D7F202F0B4" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_684A16145DD24AC28E88938986685418" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_868FC254C3604138BDFCB4BF85E6CED6" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_FA25D952CE8540949268CBFE3D45EC23" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_UNDEFINED" + "OwnerKey" = "8:_684A16145DD24AC28E88938986685418" + "MsmSig" = "8:_UNDEFINED" + } + } + "Configurations" + { + "Debug" + { + "DisplayName" = "8:Debug" + "IsDebugOnly" = "11:TRUE" + "IsReleaseOnly" = "11:FALSE" + "OutputFilename" = "8:Debug\\OutlookCaseHelperSetup.msi" + "PackageFilesAs" = "3:2" + "PackageFileSize" = "3:-2147483648" + "CabType" = "3:1" + "Compression" = "3:2" + "SignOutput" = "11:FALSE" + "CertificateFile" = "8:" + "PrivateKeyFile" = "8:" + "TimeStampServer" = "8:" + "InstallerBootstrapper" = "3:2" + "BootstrapperCfg:{63ACBE69-63AA-4F98-B2B6-99F9E24495F2}" + { + "Enabled" = "11:TRUE" + "PromptEnabled" = "11:TRUE" + "PrerequisitesLocation" = "2:1" + "Url" = "8:" + "ComponentsUrl" = "8:" + "Items" + { + "{EDC2488A-8267-493A-A98E-7D9C3B36CDF3}:.NETFramework,Version=v4.7.2" + { + "Name" = "8:Microsoft .NET Framework 4.7.2 (x86 and x64)" + "ProductCode" = "8:.NETFramework,Version=v4.7.2" + } + } + } + } + "Release" + { + "DisplayName" = "8:Release" + "IsDebugOnly" = "11:FALSE" + "IsReleaseOnly" = "11:TRUE" + "OutputFilename" = "8:Release\\OutlookCaseHelperSetup.msi" + "PackageFilesAs" = "3:2" + "PackageFileSize" = "3:-2147483648" + "CabType" = "3:1" + "Compression" = "3:2" + "SignOutput" = "11:FALSE" + "CertificateFile" = "8:" + "PrivateKeyFile" = "8:" + "TimeStampServer" = "8:" + "InstallerBootstrapper" = "3:2" + "BootstrapperCfg:{63ACBE69-63AA-4F98-B2B6-99F9E24495F2}" + { + "Enabled" = "11:TRUE" + "PromptEnabled" = "11:TRUE" + "PrerequisitesLocation" = "2:1" + "Url" = "8:" + "ComponentsUrl" = "8:" + } + } + } + "Deployable" + { + "CustomAction" + { + } + "DefaultFeature" + { + "Name" = "8:DefaultFeature" + "Title" = "8:" + "Description" = "8:" + } + "ExternalPersistence" + { + "LaunchCondition" + { + "{A06ECF26-33A3-4562-8140-9B0E340D4F24}:_BFEDFA5E85F94C47BB88C71FBEEFAA6F" + { + "Name" = "8:.NET Core" + "Message" = "8:[VSDNETCOREMSG]" + "AllowLaterVersions" = "11:FALSE" + "InstallUrl" = "8:https://dotnet.microsoft.com/download/dotnet-core/[NetCoreVerMajorDotMinor]" + "IsNETCore" = "11:TRUE" + "Architecture" = "2:0" + "Runtime" = "2:0" + } + "{A06ECF26-33A3-4562-8140-9B0E340D4F24}:_D3F0CDFC80C349B1963A549FD2F583C0" + { + "Name" = "8:.NET Framework" + "Message" = "8:[VSDNETMSG]" + "FrameworkVersion" = "8:.NETFramework,Version=v4.7.2" + "AllowLaterVersions" = "11:FALSE" + "InstallUrl" = "8:http://go.microsoft.com/fwlink/?LinkId=863262" + } + } + } + "File" + { + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_3B183E44CB644AC2B8CFD4CE7E8493D5" + { + "SourcePath" = "8:..\\OutlookCaseHelper\\bin\\Release\\net8.0-windows\\publish\\OutlookCaseHelper.pdb" + "TargetName" = "8:OutlookCaseHelper.pdb" + "Tag" = "8:" + "Folder" = "8:_AC75D4F5EDF14629A9F064045458FC4F" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_5B02FA9AA2644553AA7EE8D7F202F0B4" + { + "SourcePath" = "8:..\\OutlookCaseHelper\\bin\\Release\\net8.0-windows\\publish\\OutlookCaseHelper.deps.json" + "TargetName" = "8:OutlookCaseHelper.deps.json" + "Tag" = "8:" + "Folder" = "8:_AC75D4F5EDF14629A9F064045458FC4F" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_684A16145DD24AC28E88938986685418" + { + "AssemblyRegister" = "3:1" + "AssemblyIsInGAC" = "11:FALSE" + "AssemblyAsmDisplayName" = "8:OutlookCaseHelper, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL" + "ScatterAssemblies" + { + "_684A16145DD24AC28E88938986685418" + { + "Name" = "8:OutlookCaseHelper.dll" + "Attributes" = "3:512" + } + } + "SourcePath" = "8:..\\OutlookCaseHelper\\bin\\Release\\net8.0-windows\\publish\\OutlookCaseHelper.dll" + "TargetName" = "8:" + "Tag" = "8:" + "Folder" = "8:_AC75D4F5EDF14629A9F064045458FC4F" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_868FC254C3604138BDFCB4BF85E6CED6" + { + "SourcePath" = "8:..\\OutlookCaseHelper\\bin\\Release\\net8.0-windows\\publish\\OutlookCaseHelper.exe" + "TargetName" = "8:OutlookCaseHelper.exe" + "Tag" = "8:" + "Folder" = "8:_AC75D4F5EDF14629A9F064045458FC4F" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_FA25D952CE8540949268CBFE3D45EC23" + { + "SourcePath" = "8:..\\OutlookCaseHelper\\bin\\Release\\net8.0-windows\\publish\\OutlookCaseHelper.runtimeconfig.json" + "TargetName" = "8:OutlookCaseHelper.runtimeconfig.json" + "Tag" = "8:" + "Folder" = "8:_AC75D4F5EDF14629A9F064045458FC4F" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } + } + "FileType" + { + } + "Folder" + { + "{1525181F-901A-416C-8A58-119130FE478E}:_653E840325B24D5BADCD87AB7B5EF5C6" + { + "Name" = "8:#1919" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:ProgramMenuFolder" + "Folders" + { + "{9EF0B969-E518-4E46-987F-47570745A589}:_F66DBC3EB3F247C29BAF8010BFB5C784" + { + "Name" = "8:Outlook Case Helper" + "AlwaysCreate" = "11:TRUE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_9F0EC822D32E404ABC1DEC9D2AB2A8D0" + "Folders" + { + } + } + } + } + "{3C67513D-01DD-4637-8A68-80971EB9504F}:_AC75D4F5EDF14629A9F064045458FC4F" + { + "DefaultLocation" = "8:[ProgramFiles64Folder][Manufacturer]\\[ProductName]" + "Name" = "8:#1925" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:TARGETDIR" + "Folders" + { + } + } + "{1525181F-901A-416C-8A58-119130FE478E}:_FE08DF4F570842E384F31ADA1A4AC90E" + { + "Name" = "8:#1916" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:DesktopFolder" + "Folders" + { + } + } + } + "LaunchCondition" + { + } + "Locator" + { + } + "MsiBootstrapper" + { + "LangId" = "3:1033" + "RequiresElevation" = "11:FALSE" + } + "Product" + { + "Name" = "8:Microsoft Visual Studio" + "ProductName" = "8:CaseEmailHandler" + "ProductCode" = "8:{DC06A175-18E5-4D5E-8F04-6245F0C6B696}" + "PackageCode" = "8:{EB395FB1-1C30-4195-B77B-07AF0FD08B31}" + "UpgradeCode" = "8:{AAF43788-D89F-4285-AC74-CA5E1413DADC}" + "AspNetVersion" = "8:2.0.50727.0" + "RestartWWWService" = "11:FALSE" + "RemovePreviousVersions" = "11:FALSE" + "DetectNewerInstalledVersion" = "11:TRUE" + "InstallAllUsers" = "11:FALSE" + "ProductVersion" = "8:1.0.0" + "Manufacturer" = "8:Well" + "ARPHELPTELEPHONE" = "8:" + "ARPHELPLINK" = "8:" + "Title" = "8:OutlookCaseHelperSetup" + "Subject" = "8:" + "ARPCONTACT" = "8:Microsoft Corp." + "Keywords" = "8:" + "ARPCOMMENTS" = "8:" + "ARPURLINFOABOUT" = "8:" + "ARPPRODUCTICON" = "8:" + "ARPIconIndex" = "3:0" + "SearchPath" = "8:" + "UseSystemSearchPath" = "11:TRUE" + "TargetPlatform" = "3:1" + "PreBuildEvent" = "8:" + "PostBuildEvent" = "8:" + "RunPostBuildEvent" = "3:0" + } + "Registry" + { + "HKLM" + { + "Keys" + { + "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_C038C37B617547EEB359E2E4076CCE51" + { + "Name" = "8:Software" + "Condition" = "8:" + "AlwaysCreate" = "11:FALSE" + "DeleteAtUninstall" = "11:FALSE" + "Transitive" = "11:FALSE" + "Keys" + { + "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_BF2DF809390A4F68ADDF14C33E2AED46" + { + "Name" = "8:[Manufacturer]" + "Condition" = "8:" + "AlwaysCreate" = "11:FALSE" + "DeleteAtUninstall" = "11:FALSE" + "Transitive" = "11:FALSE" + "Keys" + { + } + "Values" + { + } + } + } + "Values" + { + } + } + } + } + "HKCU" + { + "Keys" + { + "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_807F2CEDD3C14C61AD6E968A58A19D98" + { + "Name" = "8:Software" + "Condition" = "8:" + "AlwaysCreate" = "11:FALSE" + "DeleteAtUninstall" = "11:FALSE" + "Transitive" = "11:FALSE" + "Keys" + { + "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_3C91D391EBE2401F919257ACA05BCA79" + { + "Name" = "8:[Manufacturer]" + "Condition" = "8:" + "AlwaysCreate" = "11:FALSE" + "DeleteAtUninstall" = "11:FALSE" + "Transitive" = "11:FALSE" + "Keys" + { + } + "Values" + { + } + } + } + "Values" + { + } + } + } + } + "HKCR" + { + "Keys" + { + } + } + "HKU" + { + "Keys" + { + } + } + "HKPU" + { + "Keys" + { + } + } + } + "Sequences" + { + } + "Shortcut" + { + "{970C0BB2-C7D0-45D7-ABFA-7EC378858BC0}:_408AF6BD4D5C4E58B4F99B8856B2BF5E" + { + "Name" = "8:OutlookCaseHelper.exe" + "Arguments" = "8:" + "Description" = "8:" + "ShowCmd" = "3:1" + "IconIndex" = "3:0" + "Transitive" = "11:FALSE" + "Target" = "8:_868FC254C3604138BDFCB4BF85E6CED6" + "Folder" = "8:_F66DBC3EB3F247C29BAF8010BFB5C784" + "WorkingFolder" = "8:_AC75D4F5EDF14629A9F064045458FC4F" + "Icon" = "8:" + "Feature" = "8:" + } + } + "UserInterface" + { + "{2479F3F5-0309-486D-8047-8187E2CE5BA0}:_0447E5F67B5C413D8D200514C7B147A0" + { + "UseDynamicProperties" = "11:FALSE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdBasicDialogs.wim" + } + "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_15E645296E2943EB8AAF2C1D24EC33FC" + { + "Name" = "8:#1900" + "Sequence" = "3:2" + "Attributes" = "3:1" + "Dialogs" + { + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_02411CF26D6A4448B09DA24D681BE57E" + { + "Sequence" = "3:300" + "DisplayName" = "8:Confirm Installation" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdAdminConfirmDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_162D4EC79F814815A5418D6D3E338C0A" + { + "Sequence" = "3:100" + "DisplayName" = "8:Welcome" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdAdminWelcomeDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "CopyrightWarning" + { + "Name" = "8:CopyrightWarning" + "DisplayName" = "8:#1002" + "Description" = "8:#1102" + "Type" = "3:3" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:1" + "Value" = "8:#1202" + "DefaultValue" = "8:#1202" + "UsePlugInResources" = "11:TRUE" + } + "Welcome" + { + "Name" = "8:Welcome" + "DisplayName" = "8:#1003" + "Description" = "8:#1103" + "Type" = "3:3" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:1" + "Value" = "8:#1203" + "DefaultValue" = "8:#1203" + "UsePlugInResources" = "11:TRUE" + } + } + } + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_F234C933281D47F09F1D6E50FA857C19" + { + "Sequence" = "3:200" + "DisplayName" = "8:Installation Folder" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdAdminFolderDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_8D94EFE568E146EB93681A08320793DE" + { + "Name" = "8:#1902" + "Sequence" = "3:1" + "Attributes" = "3:3" + "Dialogs" + { + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_D05C04B694174938AEDD7F9734EE1C73" + { + "Sequence" = "3:100" + "DisplayName" = "8:Finished" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdFinishedDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "UpdateText" + { + "Name" = "8:UpdateText" + "DisplayName" = "8:#1058" + "Description" = "8:#1158" + "Type" = "3:15" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:1" + "Value" = "8:#1258" + "DefaultValue" = "8:#1258" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_8F673FA183BB47F0B35769332753560A" + { + "Name" = "8:#1900" + "Sequence" = "3:1" + "Attributes" = "3:1" + "Dialogs" + { + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_5574C5608E90421A9F9854445231C412" + { + "Sequence" = "3:200" + "DisplayName" = "8:Installation Folder" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdFolderDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "InstallAllUsersVisible" + { + "Name" = "8:InstallAllUsersVisible" + "DisplayName" = "8:#1059" + "Description" = "8:#1159" + "Type" = "3:5" + "ContextData" = "8:1;True=1;False=0" + "Attributes" = "3:0" + "Setting" = "3:0" + "Value" = "3:1" + "DefaultValue" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_8D58EEEC23E14DBC9F4D9DB32472B784" + { + "Sequence" = "3:300" + "DisplayName" = "8:Confirm Installation" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdConfirmDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_AF042E632A674F9A9F665FCD3BDBCE34" + { + "Sequence" = "3:100" + "DisplayName" = "8:Welcome" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdWelcomeDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "CopyrightWarning" + { + "Name" = "8:CopyrightWarning" + "DisplayName" = "8:#1002" + "Description" = "8:#1102" + "Type" = "3:3" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:1" + "Value" = "8:#1202" + "DefaultValue" = "8:#1202" + "UsePlugInResources" = "11:TRUE" + } + "Welcome" + { + "Name" = "8:Welcome" + "DisplayName" = "8:#1003" + "Description" = "8:#1103" + "Type" = "3:3" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:1" + "Value" = "8:#1203" + "DefaultValue" = "8:#1203" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_911F202758834A03A51744282016DC88" + { + "Name" = "8:#1902" + "Sequence" = "3:2" + "Attributes" = "3:3" + "Dialogs" + { + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_CCCF34546F7041C5B356FA4D6B626272" + { + "Sequence" = "3:100" + "DisplayName" = "8:Finished" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdAdminFinishedDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{2479F3F5-0309-486D-8047-8187E2CE5BA0}:_9DBD0A9301F847CFA4DE7BD74FB0B0F3" + { + "UseDynamicProperties" = "11:FALSE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdUserInterface.wim" + } + "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_C7437F22E55F4B3F911E3BB9D2257E83" + { + "Name" = "8:#1901" + "Sequence" = "3:1" + "Attributes" = "3:2" + "Dialogs" + { + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_D113748183E148829EBB4F33D175754C" + { + "Sequence" = "3:100" + "DisplayName" = "8:Progress" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdProgressDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "ShowProgress" + { + "Name" = "8:ShowProgress" + "DisplayName" = "8:#1009" + "Description" = "8:#1109" + "Type" = "3:5" + "ContextData" = "8:1;True=1;False=0" + "Attributes" = "3:0" + "Setting" = "3:0" + "Value" = "3:1" + "DefaultValue" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_C8EE6042DC604144A58F91C2E49409D2" + { + "Name" = "8:#1901" + "Sequence" = "3:2" + "Attributes" = "3:2" + "Dialogs" + { + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_37287037C531482495EB88FEA7F44C44" + { + "Sequence" = "3:100" + "DisplayName" = "8:Progress" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdAdminProgressDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "ShowProgress" + { + "Name" = "8:ShowProgress" + "DisplayName" = "8:#1009" + "Description" = "8:#1109" + "Type" = "3:5" + "ContextData" = "8:1;True=1;False=0" + "Attributes" = "3:0" + "Setting" = "3:0" + "Value" = "3:1" + "DefaultValue" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + } + "MergeModule" + { + } + "ProjectOutput" + { + } + } +} diff --git a/OutlookHelper.cs b/OutlookHelper.cs new file mode 100644 index 0000000..59dda1e --- /dev/null +++ b/OutlookHelper.cs @@ -0,0 +1,163 @@ +using System; +using System.Collections.Generic; +using System.Text.RegularExpressions; +using Outlook = Microsoft.Office.Interop.Outlook; + +namespace OutlookCaseHelper +{ + public class OutlookHelper + { + private Outlook.Application outlookApp; + private Outlook.NameSpace outlookNamespace; + + public OutlookHelper() + { + outlookApp = new Outlook.Application(); + outlookNamespace = outlookApp.GetNamespace("MAPI"); + } + + // Get Tracking ID from selected email subject + public string? GetSelectedEmailTrackingId() + { + try + { + Outlook.Explorer activeExplorer = outlookApp.ActiveExplorer(); + if (activeExplorer == null) + return null; + + Outlook.Selection selection = activeExplorer.Selection; + if (selection.Count == 0) + return null; + + Outlook.MailItem email = selection[1] as Outlook.MailItem; + if (email == null) + return null; + + // Subject pattern: "Something - TrackingID1234567890123456" + string pattern = @"TrackingID(\d+)"; + Match match = Regex.Match(email.Subject, pattern); + + if (match.Success) + return match.Groups[1].Value; + + return null; + } + catch + { + return null; + } + } + + // Create folder and move all emails with this tracking id + public bool CreateFolderAndMoveEmails(string trackingId) + { + try + { + Outlook.Folder inboxFolder = + outlookNamespace.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox) as Outlook.Folder; + + Outlook.Folder casesFolder = GetOrCreateFolder(inboxFolder, "Cases"); + Outlook.Folder activeFolder = GetOrCreateFolder(casesFolder, "Active"); + Outlook.Folder trackingFolder = GetOrCreateFolder(activeFolder, trackingId); + + MoveEmailsWithTrackingId(inboxFolder, trackingId, trackingFolder); + + Outlook.Folder sentFolder = + outlookNamespace.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderSentMail) as Outlook.Folder; + if (sentFolder != null) + MoveEmailsWithTrackingId(sentFolder, trackingId, trackingFolder); + + return true; + } + catch + { + return false; + } + } + + // Remove rule: move folder from Active to Closed + public bool RemoveRuleAndMoveToClosed(string trackingId) + { + try + { + Outlook.Folder inboxFolder = + outlookNamespace.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox) as Outlook.Folder; + + Outlook.Folder casesFolder = GetFolder(inboxFolder, "Cases"); + if (casesFolder == null) return false; + + Outlook.Folder activeFolder = GetFolder(casesFolder, "Active"); + if (activeFolder == null) return false; + + Outlook.Folder trackingFolder = GetFolder(activeFolder, trackingId); + if (trackingFolder == null) return false; + + Outlook.Folder closedFolder = GetOrCreateFolder(casesFolder, "Closed"); + MoveAllItemsFromFolder(trackingFolder, closedFolder); + + try + { + activeFolder.Folders.Remove(trackingId); + } + catch { } + + return true; + } + catch + { + return false; + } + } + + private Outlook.Folder GetOrCreateFolder(Outlook.Folder parent, string name) + { + foreach (Outlook.Folder folder in parent.Folders) + { + if (folder.Name == name) + return folder; + } + + return parent.Folders.Add(name) as Outlook.Folder; + } + + private Outlook.Folder? GetFolder(Outlook.Folder parent, string name) + { + foreach (Outlook.Folder folder in parent.Folders) + { + if (folder.Name == name) + return folder; + } + return null; + } + + private void MoveEmailsWithTrackingId(Outlook.Folder source, string trackingId, Outlook.Folder dest) + { + var toMove = new List(); + + foreach (object item in source.Items) + { + Outlook.MailItem mail = item as Outlook.MailItem; + if (mail != null && mail.Subject.Contains($"TrackingID{trackingId}")) + toMove.Add(mail); + } + + foreach (var mail in toMove) + mail.Move(dest); + } + + private void MoveAllItemsFromFolder(Outlook.Folder source, Outlook.Folder dest) + { + var toMove = new List(); + + foreach (object item in source.Items) + { + Outlook.MailItem mail = item as Outlook.MailItem; + if (mail != null) + toMove.Add(mail); + } + + foreach (var mail in toMove) + mail.Move(dest); + } + } +}