using System; using System.Threading.Tasks; using System.Net.Http.Headers; using System.Runtime.CompilerServices; using System.Configuration; using Microsoft.Graph.Models; using log4net; using System.Net.Mail; using System.IO; using System.Linq; namespace Epi2Exchange2 { class Program { private static readonly ILog Logger = LogManager.GetLogger(typeof(Program)); private static ConfigLoader Configuration; private static Model.ContactList ContactList; private static O365Connector O365; static async Task Main() { string pathLastRuntime = "LastRun.txt"; DateTime LastRun = DateTime.Parse("01.01.1970 10:00:00"); try { if (File.Exists(pathLastRuntime)) { Logger.Debug("Last run file found. Attempting to parse datetime."); string datetimeFromText = File.ReadAllText(pathLastRuntime); Logger.Debug("Found datetime string: " + datetimeFromText); LastRun = DateTime.Parse(datetimeFromText); Logger.Info("Last run timestamp: " + LastRun.ToString()); } } catch (Exception ex) { Logger.Error("Failed to parse last run timestamp from " + pathLastRuntime + ". Error: " + ex.Message); } Logger.Info("Updating last run timestamp."); updateLastRunTimestamp(); try { Logger.Info("Initializing configuration."); Configuration = ConfigLoader.Instance; Logger.Info("Configuration loaded successfully."); } catch (Exception ex) { Logger.Error("Error loading configuration: " + ex.Message); return; } try { Logger.Info("Initializing O365 connector."); O365 = new O365Connector(Configuration.AzureAd.ClientId, Configuration.AzureAd.ClientSecret, Configuration.AzureAd.TenantId, Configuration.Graph.BaseUrl); Logger.Info("O365 connector initialized."); } catch (Exception ex) { Logger.Error("Error initializing O365 connector: " + ex.Message); return; } try { Logger.Info("Fetching Epirent contacts."); ContactList = new EpiContacts().getContactList(LastRun); } catch (Exception ex) { Logger.Error("Error fetching contacts: " + ex.Message); return; } foreach (Model.Payload Contact in ContactList.Payload) { try { Logger.Debug("Processing contact: " + Contact.Name + " (Primary Key: " + Contact.PrimaryKey + ")"); Model.ContactDetail contactDetail = new EpiContacts().GetContactDetail(Contact.PrimaryKey); var CompanyPhoneNumbers = contactDetail.Payload[0].Communication .Where(c => c.Type == 0) .Select(c => c.PhoneMatchNumber) .ToList(); var CompanyMailAddresses = contactDetail.Payload[0].Communication .Where(c => c.Type == 3) .Select(c => new Microsoft.Graph.Models.EmailAddress { Address = c.Uplink, Name = Contact.Name }) .ToList(); var CompanyMobilePhoneNumber = contactDetail.Payload[0].Communication .FirstOrDefault(c => c.Type == 2)?.PhoneMatchNumber; Contact o365CompanyContact = new Contact { DisplayName = contactDetail.Payload[0].Name, CompanyName = contactDetail.Payload[0].Name, EmailAddresses = CompanyMailAddresses, BusinessPhones = CompanyPhoneNumbers, MobilePhone = CompanyMobilePhoneNumber, NickName = Contact.PrimaryKey.ToString(), }; foreach (string addressBookHolder in Configuration.Graph.Users) { try { O365.SyncContact(o365CompanyContact, addressBookHolder); Logger.Info("Contact synchronized for user: " + addressBookHolder); } catch (Exception ex) { Logger.Error("Error synchronizing contact for " + addressBookHolder + ": " + ex.Message); } } foreach (Model.ContactPerson contactPerson in contactDetail.Payload[0].ContactPerson) { try { Logger.Debug("Processing contact person: " + contactPerson.Name); Model.ContactPersonPayload cperson = new EpiContacts().GetContactPersonDetail(contactPerson.PrimaryKey).Payload[0]; var phoneNumbers = cperson.Communication .Where(c => c.Type == 0) .Select(c => c.PhoneMatchNumber) .ToList(); var mailAddresses = cperson.Communication .Where(c => c.Type == 3) .Select(c => new Microsoft.Graph.Models.EmailAddress { Address = c.Uplink, Name = cperson.Name }) .ToList(); var MobilePhoneNumber = cperson.Communication .FirstOrDefault(c => c.Type == 2)?.PhoneMatchNumber; Contact o365contact = new Contact { GivenName = cperson.FirstName, Surname = cperson.LastName, DisplayName = cperson.Name, CompanyName = contactDetail.Payload[0].Name, Department = cperson.Department, JobTitle = cperson.Position, EmailAddresses = mailAddresses, BusinessPhones = phoneNumbers, MobilePhone = MobilePhoneNumber, NickName = Contact.PrimaryKey + "-" + cperson.PrimaryKey }; foreach (string addressBookHolder in Configuration.Graph.Users) { try { O365.SyncContact(o365contact, addressBookHolder); Logger.Info("Contact person synchronized for user: " + addressBookHolder); } catch (Exception ex) { Logger.Error("Error synchronizing contact person for " + addressBookHolder + ": " + ex.Message); } } } catch (Exception ex) { Logger.Error("Error processing contact person " + contactPerson.Name + ": " + ex.Message); } } } catch (Exception ex) { Logger.Error("Error processing contact " + Contact.Name + ": " + ex.Message); } } } private static void updateLastRunTimestamp() { string fileName = "LastRun.txt"; try { File.WriteAllText(fileName, DateTime.Now.ToString()); Logger.Info("Last run timestamp updated successfully."); } catch (Exception ex) { Logger.Error("Error updating last run timestamp: " + ex.Message); } } } }