<?php

/*
 * ==========================================================
 * POST.PHP
 * ==========================================================
 *
 * Messenger response listener. This file receive the Facebook Messenger messages of the agents forwarded by board.support. This file requires the Messenger App.
 * © 2017-2025 board.support. All rights reserved.
 *
 */

if (isset($_GET['hub_mode']) && $_GET['hub_mode'] == 'subscribe') {
    require('../../include/functions.php');
    sb_cloud_load_by_url();
    if ($_GET['hub_verify_token'] == sb_get_multi_setting('messenger', 'messenger-key')) {
        echo $_GET['hub_challenge'];
    }
    die();
}
$raw = file_get_contents('php://input');
flush();
if (function_exists('fastcgi_finish_request')) {
    fastcgi_finish_request();
}
if ($raw) {
    require('../../include/functions.php');
    $response = json_decode($raw, true);
    $message = false;
    $sender_id = false;
    $page_id = false;
    $attachments = [];
    $response_messaging = false;
    if (isset($response['messaging'])) {
        $response_messaging = $response['messaging'];
    } else if (isset($response['object'])) {
        if (isset($response['entry'][0]['messaging'])) {
            $response_messaging = $response['entry'][0]['messaging'];
        } else if (isset($response['entry'][0]['standby'])) {
            $response_messaging = $response['entry'][0]['standby'];
        }
    }
    $response_message = [];
    if ($response_messaging) {
        $response_message = isset($response_messaging[0]['message']) ? $response_messaging[0]['message'] : (isset($response_messaging[0]['postback']) ? ['text' => sb_isset($response_messaging[0]['postback'], 'title', [])] : '');
    }
    $is_echo = isset($response_message['is_echo']);
    $postback = sb_isset($response_messaging, 'postback');
    $is_instagram = sb_isset($response, 'object') == 'instagram';
    $comment_data = false;
    $comment_post_id = false;
    $comment_id = false;
    $platform_code = $is_instagram ? 'ig' : 'fb';
    $user = false;
    $is_deleted = $response_message && !empty($response_message['is_deleted']);
    if ($response_message) {
        $sender_id = $response_messaging[0]['sender']['id'];
        $message = sb_isset($response_message, 'text');
        $attachments = sb_isset($response_message, 'attachments', []);
    } else if (isset($response['sender'])) {
        $sender_id = $response['sender']['id'];
        $message = sb_isset($response['message'], 'text');
        $attachments = sb_isset($response['attachments'], 'attachments', []);
    } else if ($postback) {
        $sender_id = $response_messaging[0]['sender']['id'];
        $message = sb_isset($postback, 'title', '');
    } else {
        $comment_data = sb_isset($response, ['entry', 0, 'changes', 0]);
        if ($comment_data) {
            $field = sb_isset($comment_data, 'field');
            $comment_data = $comment_data['value'];
            $sender_id = $comment_data['from']['id'];
            switch ($field) {
                case 'comments':
                    $message = $comment_data['text'];
                    $comment_post_id = $comment_data['media']['id'];
                    $comment_id = $comment_data['id'];
                    break;
                case 'feed':
                    $message = $comment_data['message'];
                    $comment_post_id = $comment_data['post_id'];
                    $comment_id = $comment_data['comment_id'];
                    break;
            }
        }
    }
    if ($sender_id && ($message || $attachments || $is_deleted)) {
        $GLOBALS['SB_FORCE_ADMIN'] = true;
        if (sb_is_cloud()) {
            sb_cloud_load_by_url();
            sb_cloud_membership_validation(true);
        }

        // Page ID
        $sender_id_admin = false;
        if (isset($response['object']) && isset($response['entry'])) {
            $page_id = $response['entry'][0]['id'];
        } else if (isset($response['recipient'])) {
            $page_id = $response['recipient']['id'];
        } else if ($response_messaging) {
            $page_id = $response_messaging[0]['recipient']['id'];
        }
        if ($page_id == $sender_id) {
            $page_id = $sender_id;
            $sender_id_admin = sb_db_get('SELECT id FROM sb_users WHERE user_type = "agent" OR user_type = "admin" ORDER BY user_type, creation_time LIMIT 1')['id'];
            if ($comment_data) {
                $sender_id = false;
                $parent_comment_id = sb_isset($comment_data, 'parent_id');
                $is_echo = true;
                if ($parent_comment_id) {
                    $sender_id = sb_isset(sb_db_get('SELECT value FROM sb_users_data WHERE slug = "facebook-id" AND user_id = (SELECT user_id FROM sb_messages WHERE payload LIKE \'%"cid":"' . sb_db_escape($parent_comment_id) . '"%\' LIMIT 1) LIMIT 1'), 'value');
                }
            } else {
                $sender_id = $response_messaging[0]['recipient']['id'];
            }
        }
        if (!$sender_id) {
            die();
        }
        if (sb_isset($comment_data, 'verb') == 'edited') {
            $message_id = sb_isset(sb_db_get('SELECT id FROM sb_messages WHERE payload LIKE \'%"cid":"' . sb_db_escape($comment_id) . '"%\' LIMIT 1'), 'id');
            if ($message_id) {
                sb_update_message($message_id, $message);
                die();
            }
        }
        $sender_id = sb_db_escape($sender_id);
        $page_id = sb_db_escape($page_id);
        $page_settings = sb_messenger_get_page($page_id);

        // User
        $user = sb_db_get('SELECT A.id, A.first_name, A.last_name, A.profile_image, A.email, A.user_type FROM sb_users A, sb_users_data B WHERE A.user_type <> "agent" AND A.user_type <> "admin" AND A.id = B.user_id AND B.slug = "facebook-id" AND B.value = "' . sb_db_escape($sender_id) . '" LIMIT 1');
        if (!$user) {
            $user_id = sb_messenger_add_user($sender_id, $page_id, 'lead', $is_instagram, $message);
            $user = sb_get_user($user_id);
        } else {
            $user_id = $user['id'];
        }
        if ($user_id) {

            // Get user and conversation information
            $GLOBALS['SB_LOGIN'] = $user;
            $conversation = sb_db_get('SELECT id, status_code FROM sb_conversations WHERE source = "' . $platform_code . '" AND user_id = ' . $user_id . ($comment_data ? ' AND extra_2 = "' . $comment_post_id . '"' : ' AND (extra_2 = "" OR extra_2 IS NULL)') . ' LIMIT 1');
            $conversation_id = sb_isset($conversation, 'id');
            $department = sb_isset($page_settings, 'messenger-page-department', -1); // Deprecated. Replace with: sb_isset($page_settings, messenger-page-department', 0])
            $department = is_array($department) ? $department[0] : $department; // Deprecated

            // [FIX] Deduplication: Check if message already exists (Double Webhook Delivery Prevention)
            $dedup_id = sb_isset($response_message, 'mid', $comment_data ? $comment_id : false);
            $dedup_key = $comment_data ? 'cid' : 'mid';
            if ($dedup_id && $conversation_id) {
                if (sb_db_get('SELECT id FROM sb_messages WHERE conversation_id = ' . $conversation_id . ' AND payload LIKE \'%"' . $dedup_key . '":"' . sb_db_escape($dedup_id) . '"%\' LIMIT 1')) {
                    die();
                }
            }
            $count_attachments = count($attachments);

            // Message deleted
            if ($conversation_id && $is_deleted) {
                $message_id = sb_db_get('SELECT id FROM sb_messages WHERE conversation_id = ' . $conversation_id . ' AND payload LIKE "%' . sb_db_escape($response_message['mid']) . '%"');
                return $message_id ? sb_delete_message($message_id['id']) : false;
            }
            $is_routing = sb_routing_is_active();
            if (!$conversation_id) {
                $extra_3 = '';
                $title = '';
                if ($comment_post_id) {
                    $post = sb_messenger_get_post($comment_post_id, $page_id, $is_instagram);
                    if ($is_instagram) {
                        $caption = sb_isset($post, 'caption');
                        if (mb_strlen($caption) > 50) {
                            $caption = mb_substr($caption, 0, 50) . '...';
                        }
                        $title = sb_download_file(sb_isset($post, 'thumbnail_url', sb_isset($post, 'media_url')), $comment_post_id) . ($caption ? '?t=' . $caption : '');
                        $extra_3 = json_encode([str_replace('https://www.instagram.com/', '', sb_isset($post, 'permalink')), sb_isset($post, 'media_type')]);
                    } else {
                        $title = sb_isset($post, 'message');
                        if (mb_strlen($title) > 50) {
                            $title = mb_substr($title, 0, 50) . '...';
                        }
                        $picture = sb_download_file(sb_isset($post, ['attachments', 'data', 0, 'media', 'image', 'src']), $comment_post_id . '.jpg');
                        if ($picture) {
                            $title = $title ? $picture . '?t=' . $title : $picture;
                        }
                        $extra_3 = $comment_post_id;
                    }
                }
                $conversation_id = sb_isset(sb_new_conversation($user_id, 2, $title, $department, $is_routing ? sb_routing_find_best_agent($department) : -1, $platform_code, $page_id, $comment_post_id, $extra_3, sb_isset($page_settings, 'messenger-page-tags')), 'details', [])['id'];
                if ($comment_data) {
                    $dms = sb_get_setting('messenger-dm-comment', []);
                    foreach ($dms as $dm) {
                        $dm_message = $dm['messenger-dm-comment-message'];
                        if ((empty($dm['messenger-dm-comment-post-id']) || $dm['messenger-dm-comment-post-id'] == $comment_post_id) && !empty($dm_message)) {
                            $response = sb_messenger_send_dm($page_id, $comment_id, $dm_message, $is_instagram);
                            if (!sb_is_error($response)) {
                                $conversation_id_chat = sb_isset(sb_db_get('SELECT id FROM sb_conversations WHERE source = "' . $platform_code . '" AND user_id = ' . $user_id . ' AND extra_2 = "" LIMIT 1'), 'id');
                                $dm_status_code = -1;
                                if (!$conversation_id_chat) {
                                    $dm_status_code = 3;
                                    $conversation_id_chat = sb_isset(sb_new_conversation($user_id, 3, '', $department, -1, $platform_code, $page_id, '', '', sb_isset($page_settings, 'messenger-page-tags')), ['details', 'id']);
                                }
                                sb_send_message(sb_get_bot_ID(), $conversation_id_chat, $dm_message, [], $dm_status_code);
                            }
                        }
                    }
                }
            } else {
                if ($is_echo && $sender_id_admin) {
                    if ($parent_comment_id) {
                        if (!empty('SELECT id FROM sb_messages WHERE conversation_id = ' . $conversation_id . ' AND payload LIKE \'%"cid":"' . sb_db_escape($parent_comment_id) . '"%\' LIMIT 1')) {
                            $GLOBALS['SB_FORCE_ADMIN'] = false;
                            return false;
                        }
                    } else if ($response_message) {
                        if (empty($message) || (isset($response_message['metadata']) && !empty(sb_db_get('SELECT id FROM sb_messages WHERE id = ' . explode('|', $response_message['metadata'])[0])))) {
                            $GLOBALS['SB_FORCE_ADMIN'] = false;
                            return false;
                        }
                        $messages_previous = sb_db_get('SELECT message, attachments, creation_time FROM sb_messages WHERE conversation_id = ' . $conversation_id . ' ORDER BY id DESC LIMIT 3', false);
                        foreach ($messages_previous as $message_previous) {
                            $message_previous_text = html_entity_decode(trim(sb_messaging_platforms_text_formatting(sb_isset($message_previous, 'message'))));
                            $message_previous_count = count(json_decode(sb_isset($message_previous, 'attachments', '[]'), true));
                            $rich_message = html_entity_decode(trim(sb_isset(sb_messenger_rich_messages($message), 0)));
                            $message_previous_rich_message = html_entity_decode(trim(sb_isset(sb_messenger_rich_messages($message_previous_text), 0)));
                            if ($is_instagram) {
                                $message_previous_text = sb_clear_text_formatting($message);
                            }
                            if ($message_previous && (preg_replace("/\r\n|\r|\n/", '', $message_previous_text) == preg_replace("/\r\n|\r|\n/", '', $message) || $rich_message == $message_previous_text || preg_replace("/\r\n|\r|\n/", '', $message_previous_rich_message) == preg_replace("/\r\n|\r|\n/", '', $rich_message) || ($count_attachments && ($count_attachments == $message_previous_count || $message_previous_count > 1) && strtotime($message_previous['creation_time']) < sb_gmt_now(60, true)))) {
                                $GLOBALS['SB_FORCE_ADMIN'] = false;
                                return false;
                            }
                        }
                    }
                }
                if ($is_routing && sb_isset(sb_db_get('SELECT status_code FROM sb_conversations WHERE id = ' . $conversation_id), 'status_code') == 3) {
                    sb_update_conversation_agent($conversation_id, sb_routing_find_best_agent($department));
                }
            }

            // Attachments
            $attachments_2 = [];
            for ($i = 0; $i < $count_attachments; $i++) {
                $type = $attachments[$i]['type'];
                if ($type == 'image' && sb_isset($attachments[$i]['payload'], 'sticker_id') == '369239263222822' && !$message) {
                    $message = "👍";
                } else {
                    $url = sb_isset($attachments[$i]['payload'], 'url');
                    if ($url) {
                        $file_name = urldecode(basename(strpos($url, '?') ? substr($url, 0, strpos($url, '?')) : $url));
                        $mime = !strpos($file_name, '.');
                        if ($mime && $type == 'audio') {
                            $file_name .= '.mp3';
                            $mime = false;
                        }
                        $file_name = rand(99999, 999999999) . '_' . (strpos($url, 'audio_clip') || strpos($url, 'audioclip') || $type == 'audio' ? 'voice_message_' : '') . strtolower($file_name);
                        $url = sb_download_file($url, $file_name, $mime, [], 0);
                        array_push($attachments_2, [basename($url), $url]);
                    } else if ($type == 'fallback') {
                        $message_id = sb_isset($response, 'id', $response['entry'][0]['id']);
                        $message .= sb_('Attachment unavailable.') . ($message_id ? ' ' . sb_('View it on Messenger.') . PHP_EOL . 'https://www.facebook.com/messages/t/' . $message_id : '');
                    }
                }
            }

            // Send message
            $response = sb_send_message($sender_id_admin ? $sender_id_admin : $user_id, $conversation_id, $message, $attachments_2, false, $comment_data ? ['cid' => $comment_id] : ['mid' => sb_db_escape(sb_isset($response_message, 'mid'))]);

            // Dialogflow and bot messages
            if (!$is_echo) {
                sb_messaging_platforms_functions($conversation_id, $message, $attachments_2, $user, ['source' => $platform_code, 'platform_value' => $sender_id, 'page_id' => $page_id, 'conversation_id' => $conversation_id, 'message_id' => $response['id'], 'stop_unknow_answer' => $comment_data ? true : false, 'is_comment' => !empty($comment_data)]);
            }

            // Queue
            sb_queue_check_and_run($conversation_id, $department, $is_instagram ? 'ig' : 'fb');

            // Online status
            if (!$sender_id_admin) {
                sb_update_users_last_activity($user_id);
            }
        }
    }
    $GLOBALS['SB_FORCE_ADMIN'] = false;
    return $response;
}
die();

?>