Merge pull request #732 from wrongecho/email-parse-domains

Email parsing for all domains registered under a client
This commit is contained in:
Johnny 2023-10-08 19:50:44 -04:00 committed by GitHub
commit d1a627c209
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 86 additions and 83 deletions

View File

@ -72,6 +72,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
$domain_webhost = intval($row['domain_webhost']); $domain_webhost = intval($row['domain_webhost']);
$domain_expire = nullable_htmlentities($row['domain_expire']); $domain_expire = nullable_htmlentities($row['domain_expire']);
$domain_registrar_name = nullable_htmlentities($row['vendor_name']); $domain_registrar_name = nullable_htmlentities($row['vendor_name']);
$domain_created_at = nullable_htmlentities($row['domain_created_at']);
if (empty($domain_registrar_name)) { if (empty($domain_registrar_name)) {
$domain_registrar_name = "-"; $domain_registrar_name = "-";
} }
@ -82,7 +83,6 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
if ($row) { if ($row) {
$domain_webhost_name = nullable_htmlentities($row['vendor_name']); $domain_webhost_name = nullable_htmlentities($row['vendor_name']);
} }
$domain_created_at = nullable_htmlentities($row['domain_created_at']);
?> ?>
<tr> <tr>

View File

@ -94,9 +94,9 @@ function addTicket($contact_id, $contact_name, $contact_email, $client_id, $date
// Prep ticket details // Prep ticket details
$message = nl2br($message); $message = nl2br($message);
$message = mysqli_real_escape_string($mysqli, "<i>Email from: $contact_email at $date:-</i> <br><br>$message"); $message_escaped = mysqli_real_escape_string($mysqli, "<i>Email from: $contact_email at $date:-</i> <br><br>$message");
mysqli_query($mysqli, "INSERT INTO tickets SET ticket_prefix = '$config_ticket_prefix', ticket_number = $ticket_number, ticket_subject = '$subject', ticket_details = '$message', ticket_priority = 'Low', ticket_status = 'Pending-Assignment', ticket_created_by = 0, ticket_contact_id = $contact_id, ticket_client_id = $client_id"); mysqli_query($mysqli, "INSERT INTO tickets SET ticket_prefix = '$config_ticket_prefix', ticket_number = $ticket_number, ticket_subject = '$subject', ticket_details = '$message_escaped', ticket_priority = 'Low', ticket_status = 'Pending-Assignment', ticket_created_by = 0, ticket_contact_id = $contact_id, ticket_client_id = $client_id");
$id = mysqli_insert_id($mysqli); $id = mysqli_insert_id($mysqli);
// Logging // Logging
@ -141,27 +141,16 @@ function addTicket($contact_id, $contact_name, $contact_email, $client_id, $date
// E-mail client notification that ticket has been created // E-mail client notification that ticket has been created
if ($config_ticket_client_general_notifications == 1) { if ($config_ticket_client_general_notifications == 1) {
$email_subject = "Ticket created - [$config_ticket_prefix$ticket_number] - $subject"; // Insert email into queue (first, escape vars)
$email_body = "<i style='color: #808080'>##- Please type your reply above this line -##</i><br><br>Hello, $contact_name<br><br>Thank you for your email. A ticket regarding \"$subject\" has been automatically created for you.<br><br>Ticket: $config_ticket_prefix$ticket_number<br>Subject: $subject<br>Status: Open<br>https://$config_base_url/portal/ticket.php?id=$id<br><br>~<br>$company_name<br>Support Department<br>$config_ticket_from_email<br>$company_phone"; $contact_email_escaped = sanitizeInput($contact_email);
$contact_name_escaped = sanitizeInput($contact_name);
$config_ticket_from_email_escaped = sanitizeInput($config_ticket_from_email);
$config_ticket_from_name_escaped = sanitizeInput($config_ticket_from_name);
$mail = sendSingleEmail( $subject_escaped = mysqli_escape_string($mysqli, "Ticket created - [$config_ticket_prefix$ticket_number] - $subject");
$config_smtp_host, $body_escaped = mysqli_escape_string($mysqli, "<i style='color: #808080'>##- Please type your reply above this line -##</i><br><br>Hello, $contact_name<br><br>Thank you for your email. A ticket regarding \"$subject\" has been automatically created for you.<br><br>Ticket: $config_ticket_prefix$ticket_number<br>Subject: $subject<br>Status: Open<br>https://$config_base_url/portal/ticket.php?id=$id<br><br>~<br>$company_name<br>Support Department<br>$config_ticket_from_email<br>$company_phone");
$config_smtp_username,
$config_smtp_password,
$config_smtp_encryption,
$config_smtp_port,
$config_ticket_from_email,
$config_ticket_from_name,
$contact_email,
$contact_name,
$email_subject,
$email_body
);
if ($mail !== true) { mysqli_query($mysqli, "INSERT INTO email_queue SET email_recipient = '$contact_email_escaped', email_recipient_name = '$contact_name_escaped', email_from = '$config_ticket_from_email_escaped', email_from_name = '$config_ticket_from_name_escaped', email_subject = '$subject_escaped', email_content = '$body_escaped'");
mysqli_query($mysqli, "INSERT INTO notifications SET notification_type = 'Mail', notification = 'Failed to send email to $contact_email'");
mysqli_query($mysqli, "INSERT INTO logs SET log_type = 'Mail', log_action = 'Error', log_description = 'Failed to send email to $contact_email regarding $subject. $mail'");
}
} }
@ -173,8 +162,10 @@ function addTicket($contact_id, $contact_name, $contact_email, $client_id, $date
$client_row = mysqli_fetch_array($client_sql); $client_row = mysqli_fetch_array($client_sql);
$client_name = sanitizeInput($client_row['client_name']); $client_name = sanitizeInput($client_row['client_name']);
$details = removeEmoji($message); // TODO: Fix Emojis and HTML opening tags sometimes breaking this "forwarding"
$email_subject = "ITFlow - New Ticket - $client_name: $subject"; $details = removeEmoji($message_escaped);
$email_subject = mysqli_escape_string($mysqli, "ITFlow - New Ticket - $client_name: $subject");
$email_body = "Hello, <br><br>This is a notification that a new ticket has been raised in ITFlow. <br>Client: $client_name<br>Priority: Low (email parsed)<br>Link: https://$config_base_url/ticket.php?ticket_id=$id <br><br>--------------------------------<br><br><b>$subject</b><br>$details"; $email_body = "Hello, <br><br>This is a notification that a new ticket has been raised in ITFlow. <br>Client: $client_name<br>Priority: Low (email parsed)<br>Link: https://$config_base_url/ticket.php?ticket_id=$id <br><br>--------------------------------<br><br><b>$subject</b><br>$details";
mysqli_query($mysqli, "INSERT INTO email_queue SET email_recipient = '$config_ticket_new_ticket_notification_email', email_recipient_name = 'ITFlow Agents', email_from = '$config_ticket_from_email', email_from_name = '$config_ticket_from_name', email_subject = '$email_subject', email_content = '$email_body'"); mysqli_query($mysqli, "INSERT INTO email_queue SET email_recipient = '$config_ticket_new_ticket_notification_email', email_recipient_name = 'ITFlow Agents', email_from = '$config_ticket_from_email', email_from_name = '$config_ticket_from_name', email_subject = '$email_subject', email_content = '$email_body'");
@ -366,9 +357,17 @@ if ($emails) {
$date = trim(mysqli_real_escape_string($mysqli, nullable_htmlentities(strip_tags($parser->getHeader('date'))))); $date = trim(mysqli_real_escape_string($mysqli, nullable_htmlentities(strip_tags($parser->getHeader('date')))));
$attachments = $parser->getAttachments(); $attachments = $parser->getAttachments();
// Get the message content
// (first try HTML parsing, but switch to plain text if the email is empty/plain-text only)
// $message = $parser->getMessageBody('htmlEmbedded');
// if (empty($message)) {
// echo "DEBUG: Switching to plain text parsing for this message ($subject)";
// $message = $parser->getMessageBody('text');
// }
// TODO: Default to getting HTML and fallback to plaintext, but HTML emails seem to break the forward/agent notifications
$message = $parser->getMessageBody('text'); $message = $parser->getMessageBody('text');
// If below is enabled and up above is enabled text based emails get cut out
//$message = $parser->getMessageBody('htmlEmbedded');
// Check if we can identify a ticket number (in square brackets) // Check if we can identify a ticket number (in square brackets)
if (preg_match("/\[$config_ticket_prefix\d+\]/", $subject, $ticket_number)) { if (preg_match("/\[$config_ticket_prefix\d+\]/", $subject, $ticket_number)) {
@ -407,14 +406,14 @@ if ($emails) {
// Couldn't match this email to an existing ticket or an existing client contact // Couldn't match this email to an existing ticket or an existing client contact
// Checking to see if the sender domain matches a client website // Checking to see if the sender domain matches a client website
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT * FROM clients WHERE client_website = '$from_domain' LIMIT 1")); $row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT * FROM domains WHERE domain_name = '$from_domain' LIMIT 1"));
if ($row && $from_domain == $row['client_website']) { if ($row && $from_domain == $row['domain_name']) {
// We found a match - create a contact under this client and raise a ticket for them // We found a match - create a contact under this client and raise a ticket for them
// Client details // Client details
$client_id = intval($row['client_id']); $client_id = intval($row['domain_client_id']);
// Contact details // Contact details
$password = password_hash(randomString(), PASSWORD_DEFAULT); $password = password_hash(randomString(), PASSWORD_DEFAULT);

View File

@ -516,7 +516,7 @@ function sendSingleEmail($config_smtp_host, $config_smtp_username, $config_smtp_
$smtp_auth = true; $smtp_auth = true;
} }
try{ try {
// Mail Server Settings // Mail Server Settings
$mail->CharSet = "UTF-8"; // Specify UTF-8 charset to ensure symbols ($/£) load correctly $mail->CharSet = "UTF-8"; // Specify UTF-8 charset to ensure symbols ($/£) load correctly
$mail->SMTPDebug = 0; // No Debugging $mail->SMTPDebug = 0; // No Debugging
@ -712,13 +712,13 @@ function shortenClient($client) {
// Break into words. // Break into words.
$words = explode(' ', trim($cleaned)); $words = explode(' ', trim($cleaned));
$shortened = ''; $shortened = '';
// If there's only one word. // If there's only one word.
if (count($words) == 1) { if (count($words) == 1) {
$word = $words[0]; $word = $words[0];
if (strlen($word) <= 3) { if (strlen($word) <= 3) {
return strtoupper($word); return strtoupper($word);
} }
@ -753,22 +753,22 @@ function roundToNearest15($time) {
// Extract hours, minutes, and seconds from the matched time string // Extract hours, minutes, and seconds from the matched time string
list(, $hours, $minutes, $seconds) = $matches; list(, $hours, $minutes, $seconds) = $matches;
// Convert everything to seconds for easier calculation // Convert everything to seconds for easier calculation
$totalSeconds = ($hours * 3600) + ($minutes * 60) + $seconds; $totalSeconds = ($hours * 3600) + ($minutes * 60) + $seconds;
// Calculate the remainder when divided by 900 seconds (15 minutes) // Calculate the remainder when divided by 900 seconds (15 minutes)
$remainder = $totalSeconds % 900; $remainder = $totalSeconds % 900;
if ($remainder > 450) { // If remainder is more than 7.5 minutes (450 seconds), round up if ($remainder > 450) { // If remainder is more than 7.5 minutes (450 seconds), round up
$totalSeconds += (900 - $remainder); $totalSeconds += (900 - $remainder);
} else { // Else round down } else { // Else round down
$totalSeconds -= $remainder; $totalSeconds -= $remainder;
} }
// Convert total seconds to decimal hours // Convert total seconds to decimal hours
$decimalHours = $totalSeconds / 3600; $decimalHours = $totalSeconds / 3600;
// Return the decimal hours // Return the decimal hours
return number_format($decimalHours, 2); return number_format($decimalHours, 2);
} }

View File

@ -327,15 +327,15 @@ if (isset($_GET['ticket_id'])) {
</div> </div>
<?php if(!empty($contact_email)){ ?> <?php if(!empty($contact_email)){ ?>
<div class="col-md-2"> <div class="col-md-2">
<div class="form-group"> <div class="form-group">
<div class="custom-control custom-checkbox"> <div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="ticket_reply_type_checkbox" name="public_reply_type" value="1" checked> <input type="checkbox" class="custom-control-input" id="ticket_reply_type_checkbox" name="public_reply_type" value="1" checked>
<label class="custom-control-label" for="ticket_reply_type_checkbox">Email contact<br><small class="text-secondary">(Public Update)</small></label> <label class="custom-control-label" for="ticket_reply_type_checkbox">Email contact<br><small class="text-secondary">(Public Update)</small></label>
</div>
</div> </div>
</div> </div>
</div>
<?php } ?> <?php } ?>
@ -483,13 +483,13 @@ if (isset($_GET['ticket_id'])) {
<!-- Contact card --> <!-- Contact card -->
<div class="card card-body card-outline card-dark mb-3"> <div class="card card-body card-outline card-dark mb-3">
<h4 class="text-secondary">Contact</h4> <h4 class="text-secondary">Contact</h4>
<?php if (!empty($contact_id)) { ?> <?php if (!empty($contact_id)) { ?>
<div> <div>
<i class="fa fa-fw fa-user text-secondary ml-1 mr-2"></i><a href="#" data-toggle="modal" data-target="#editTicketContactModal<?php echo $ticket_id; ?>"><strong><?php echo $contact_name; ?></strong> <i class="fa fa-fw fa-user text-secondary ml-1 mr-2"></i><a href="#" data-toggle="modal" data-target="#editTicketContactModal<?php echo $ticket_id; ?>"><strong><?php echo $contact_name; ?></strong>
</a> </a>
</div> </div>
<?php <?php
@ -517,32 +517,36 @@ if (isset($_GET['ticket_id'])) {
</div> </div>
<?php } ?> <?php } ?>
<hr>
<?php <?php
// Previous tickets
$prev_ticket_id = $prev_ticket_subject = $prev_ticket_status = ''; // Default blank
$sql_prev_ticket = "SELECT ticket_id, ticket_created_at, ticket_subject, ticket_status, ticket_assigned_to FROM tickets WHERE ticket_contact_id = $contact_id AND ticket_id <> $ticket_id ORDER BY ticket_id DESC LIMIT 1"; $sql_prev_ticket = "SELECT ticket_id, ticket_created_at, ticket_subject, ticket_status, ticket_assigned_to FROM tickets WHERE ticket_contact_id = $contact_id AND ticket_id <> $ticket_id ORDER BY ticket_id DESC LIMIT 1";
$row = mysqli_fetch_assoc(mysqli_query($mysqli, $sql_prev_ticket)); $prev_ticket_row = mysqli_fetch_assoc(mysqli_query($mysqli, $sql_prev_ticket));
$prev_ticket_id = intval($row['ticket_id']); if ($prev_ticket_row) {
$prev_ticket_subject = nullable_htmlentities($row['ticket_subject']); $prev_ticket_id = intval($prev_ticket_row['ticket_id']);
$prev_ticket_status = nullable_htmlentities($row['ticket_status']); $prev_ticket_subject = nullable_htmlentities($prev_ticket_row['ticket_subject']);
?> $prev_ticket_status = nullable_htmlentities($prev_ticket_row['ticket_status']);
?>
<div> <hr>
<i class="fa fa-fw fa-history text-secondary ml-1 mr-2"></i><b>Previous ticket:</b> <div>
<a href="ticket.php?ticket_id=<?php echo $prev_ticket_id; ?>"><?php echo $prev_ticket_subject; ?></a> <i class="fa fa-fw fa-history text-secondary ml-1 mr-2"></i><b>Previous ticket:</b>
</div> <a href="ticket.php?ticket_id=<?php echo $prev_ticket_id; ?>"><?php echo $prev_ticket_subject; ?></a>
<div class="mt-1"> </div>
<?php if ($prev_ticket_status == 'Open') { ?> <div class="mt-1">
<i class="fa fa-fw fa-hourglass-start text-secondary ml-1 mr-2"></i><strong>Status:</strong> <i class="fa fa-fw fa-hourglass-start text-secondary ml-1 mr-2"></i><strong>Status:</strong>
<span class="text-danger"><?php echo $prev_ticket_status; ?></span> <?php if ($prev_ticket_status == 'Open') { ?>
<?php } else { ?> <span class="text-danger"><?php echo $prev_ticket_status; ?></span>
<i class="fa fa-fw fa-hourglass-start text-secondary ml-1 mr-2"></i><strong>Status:</strong> <?php } else { ?>
<span class="text-success"><?php echo $prev_ticket_status; ?></span> <span class="text-success"><?php echo $prev_ticket_status; ?></span>
<?php } ?> <?php } ?>
</div> </div>
<?php } ?> <!-- End previous ticket IF statement -->
<?php } else { ?> <?php } else { ?>
<div> <div>
<a href="#" data-toggle="modal" data-target="#editTicketContactModal<?php echo $ticket_id; ?>"><i class="fa fa-fw fa-plus mr-2"></i>Add a Contact</a> <a href="#" data-toggle="modal" data-target="#editTicketContactModal<?php echo $ticket_id; ?>"><i class="fa fa-fw fa-plus mr-2"></i>Add a Contact</a>
@ -565,12 +569,12 @@ if (isset($_GET['ticket_id'])) {
$sql_ticket_watchers = mysqli_query($mysqli, "SELECT * FROM ticket_watchers WHERE watcher_ticket_id = $ticket_id ORDER BY watcher_email DESC"); $sql_ticket_watchers = mysqli_query($mysqli, "SELECT * FROM ticket_watchers WHERE watcher_ticket_id = $ticket_id ORDER BY watcher_email DESC");
while ($ticket_watcher_row = mysqli_fetch_array($sql_ticket_watchers)) { while ($ticket_watcher_row = mysqli_fetch_array($sql_ticket_watchers)) {
$ticket_watcher_email = nullable_htmlentities($ticket_watcher_row['watcher_email']); $ticket_watcher_email = nullable_htmlentities($ticket_watcher_row['watcher_email']);
?> ?>
<div class='mt-1'> <div class='mt-1'>
<i class="fa fa-fw fa-eye text-secondary ml-1 mr-2"></i><?php echo $ticket_watcher_email; ?> <i class="fa fa-fw fa-eye text-secondary ml-1 mr-2"></i><?php echo $ticket_watcher_email; ?>
</div> </div>
<?php } ?> <?php } ?>
</div> </div>
<!-- End Ticket watchers card --> <!-- End Ticket watchers card -->
@ -586,14 +590,14 @@ if (isset($_GET['ticket_id'])) {
<div class="mt-2"> <div class="mt-2">
<i class="fa fa-fw fa-history text-secondary ml-1 mr-2"></i>Updated: <strong><?php echo $ticket_updated_at; ?></strong> <i class="fa fa-fw fa-history text-secondary ml-1 mr-2"></i>Updated: <strong><?php echo $ticket_updated_at; ?></strong>
</div> </div>
<?php <?php
if ($ticket_status == "Closed") { if ($ticket_status == "Closed") {
$sql_closed_by = mysqli_query($mysqli, "SELECT * FROM tickets, users WHERE ticket_closed_by = user_id"); $sql_closed_by = mysqli_query($mysqli, "SELECT * FROM tickets, users WHERE ticket_closed_by = user_id");
$row = mysqli_fetch_array($sql_closed_by); $row = mysqli_fetch_array($sql_closed_by);
$ticket_closed_by_display = nullable_htmlentities($row['user_name']); $ticket_closed_by_display = nullable_htmlentities($row['user_name']);
?> ?>
<div class="mt-1"> <div class="mt-1">
<i class="fa fa-fw fa-user text-secondary ml-1 mr-2"></i>Closed by: <?php echo ucwords($ticket_closed_by_display); ?> <i class="fa fa-fw fa-user text-secondary ml-1 mr-2"></i>Closed by: <?php echo ucwords($ticket_closed_by_display); ?>
</div> </div>
@ -601,7 +605,7 @@ if (isset($_GET['ticket_id'])) {
<i class="fa fa-fw fa-comment-dots text-secondary ml-1 mr-2"></i>Feedback: <?php echo $ticket_feedback; ?> <i class="fa fa-fw fa-comment-dots text-secondary ml-1 mr-2"></i>Feedback: <?php echo $ticket_feedback; ?>
</div> </div>
<?php } ?> <?php } ?>
<?php if (!empty($ticket_total_reply_time)) { ?> <?php if (!empty($ticket_total_reply_time)) { ?>
<div class="mt-1"> <div class="mt-1">
<i class="far fa-fw fa-clock text-secondary ml-1 mr-2"></i>Total time worked: <?php echo $ticket_total_reply_time; ?> <i class="far fa-fw fa-clock text-secondary ml-1 mr-2"></i>Total time worked: <?php echo $ticket_total_reply_time; ?>
@ -613,13 +617,13 @@ if (isset($_GET['ticket_id'])) {
<!-- Asset card --> <!-- Asset card -->
<div class="card card-body card-outline card-dark mb-3"> <div class="card card-body card-outline card-dark mb-3">
<h4 class="text-secondary">Asset</h4> <h4 class="text-secondary">Asset</h4>
<?php if ($asset_id == 0) { ?> <?php if ($asset_id == 0) { ?>
<div> <div>
<a href="#" data-toggle="modal" data-target="#editTicketAssetModal<?php echo $ticket_id; ?>"><i class="fa fa-fw fa-plus mr-2"></i>Add an Asset</a> <a href="#" data-toggle="modal" data-target="#editTicketAssetModal<?php echo $ticket_id; ?>"><i class="fa fa-fw fa-plus mr-2"></i>Add an Asset</a>
</div> </div>
<?php } else { ?> <?php } else { ?>
<div> <div>
@ -686,7 +690,7 @@ if (isset($_GET['ticket_id'])) {
<i class="fas fa-fw fa-ticket-alt"></i> <i class="fas fa-fw fa-ticket-alt"></i>
Ticket: <a href="ticket.php?ticket_id=<?php echo $service_ticket_id; ?>"><?php echo "$service_ticket_prefix$service_ticket_number" ?></a> <?php echo "on $service_ticket_created_at - <b>$service_ticket_subject</b> ($service_ticket_status)"; ?> Ticket: <a href="ticket.php?ticket_id=<?php echo $service_ticket_id; ?>"><?php echo "$service_ticket_prefix$service_ticket_number" ?></a> <?php echo "on $service_ticket_created_at - <b>$service_ticket_subject</b> ($service_ticket_status)"; ?>
</p> </p>
<?php <?php
} }
?> ?>
</div> </div>
@ -699,13 +703,13 @@ if (isset($_GET['ticket_id'])) {
</div> </div>
<?php } // End Ticket asset Count ?> <?php } // End Ticket asset Count ?>
<?php } // End if asset_id == 0 else ?> <?php } // End if asset_id == 0 else ?>
</div> </div>
<!-- End Asset card --> <!-- End Asset card -->
<!-- Vendor card --> <!-- Vendor card -->
<div class="card card-body card-outline card-dark mb-3"> <div class="card card-body card-outline card-dark mb-3">
<h4 class="text-secondary">Vendor</h4> <h4 class="text-secondary">Vendor</h4>
<?php if (empty($vendor_id)) { ?> <?php if (empty($vendor_id)) { ?>
@ -784,14 +788,14 @@ if (isset($_GET['ticket_id'])) {
<i class="fas fa-fw fa-file-invoice mr-2"></i>Invoice Ticket <i class="fas fa-fw fa-file-invoice mr-2"></i>Invoice Ticket
</a> </a>
<?php } <?php }
if ($ticket_status !== "Closed") { ?> if ($ticket_status !== "Closed") { ?>
<a href="post.php?close_ticket=<?php echo $ticket_id; ?>" class="btn btn-secondary btn-block confirm-link"> <a href="post.php?close_ticket=<?php echo $ticket_id; ?>" class="btn btn-secondary btn-block confirm-link">
<i class="fas fa-fw fa-gavel mr-2"></i>Close Ticket <i class="fas fa-fw fa-gavel mr-2"></i>Close Ticket
</a> </a>
<?php } ?> <?php } ?>
</div> </div>
</div> </div>
</div> </div>