diff --git a/privet/ailabs/README.md b/privet/ailabs/README.md index 773dacc..e9d96bc 100644 --- a/privet/ailabs/README.md +++ b/privet/ailabs/README.md @@ -1,4 +1,4 @@ -# AI Labs v 1.0.3 RC +# AI Labs v 1.0.4 RC ##### [Changelog](#changelog_link) Incorporate AI into your phpBB board and get ready for an exciting experience. @@ -41,7 +41,7 @@ Go to `ACP` > `Customise` > `Manage extensions` and enable the `AI Labs` extensi Finally go to `ACP` > `Extensions` > `AI Labs` > `Settings` and add desired AI configurations: ![Attachment settings](../privet/ailabs/docs/ailabs_settings.png) -## ChatGPT basic setup +## ChatGPT setup * You will need OpenAI account, sign up at https://platform.openai.com/. To obtain API key go to https://platform.openai.com/account/api-keys, click on `Create new secret key`, copy and save in a safe place generated API key. @@ -50,14 +50,14 @@ Finally go to `ACP` > `Extensions` > `AI Labs` > `Settings` and add desired AI c * Create new board user who will act as AI bot, for our example we will use user `ChatGPT`. Make sure this user account is activated and fully functional. -* Got to `ACP` > `Extensions` > `AI Labs` > `Settings` and add new configuration, select `chatgpt` from AI dropdown: +* Got to `ACP` > `Extensions` > `AI Labs` > `Settings` and add new configuration, select `chatgpt` from AI dropdown: ![Attachment settings](../privet/ailabs/docs/chatgpt_setup.png) - Use `Load default configuration/template` to get defaults. Replace Configuration JSON `api-key` with your Open AI key. - Select forums where you want `ChatGPT` AI user to reply to new posts and/or to quoted and [@mention](https://www.phpbb.com/customise/db/extension/simple_mentions) (if you are using Simple mentions extension) posts. -* Save changes, navigate to forum configured above and create new post (if you configured `Reply on a post`) or quote/[@mention]() `ChatGPT` user: +* Save changes, navigate to forum configured above and create new post (if you configured `Reply on a post`) or quote/[@mention]() `ChatGPT` user: ![Attachment settings](../privet/ailabs/docs/chatgpt_example.png) * Fine-tuning can be done by adjusting following OpenAI API chat parameters https://platform.openai.com/docs/api-reference/chat @@ -99,18 +99,35 @@ Refer to https://platform.openai.com/docs/api-reference/images/create to learn m * You will need Stability AI account, follow official instructions https://platform.stability.ai/docs/getting-started/authentication to create account and obtain API key. -* Create new board user, let's say `Stable Diffusion` and create configuration: +* Create new board user, let's say `Stable Diffusion` and create configuration: ![Attachment settings](../privet/ailabs/docs/stablediffusion_setup.png) [Examples](https://privet.fun/viewtopic.php?t=2801) * Refer to https://api.stability.ai/docs#tag/v1generation/operation/textToImage to learn more about configuration JSON parameters. +## Troubleshooting +AI Labs extension maintains internal logs, you should have admin or moderator rights to see log icon: +![Attachment settings](../privet/ailabs/docs/debugging_post_icon.png) + +You can see entire AI communication history in the log: +![Attachment settings](../privet/ailabs/docs/debugging_log.png) +If Log entry is empty it ususally means that `/ailabs/*` routes blocked by one of phpBB extensions (eg Login Required) and you will need to add `/ailabs/*` to extension whitelist. +You can examine Log `response` (JSON) to see details for AI response. +Please feel free to post your quesions or concerns at https://github.com/privet-fun/phpbb_ailabs/issues. ## Support and suggestions This extension is currently being actively developed. For communication, please use https://github.com/privet-fun/phpbb_ailabs/issues. ## Changelog +* 1.0.4 June 4, 2023 + - Troubleshooting section added + - Added cofiguration for reply in topics + - Fixed links generation for cases where cookies disabled + - AI Labs internal controlles (`/ailabs/*`) will attempt to establish session to deal with phpBB extensions like Login Required + - Better descriptions added to help with setup + - Minor bugfixes + * 1.0.3 June 1, 2023 - bumped php requirements to >= 7.4 - Comma removed, reported by [Vlad__](https://www.phpbbguru.net/community/viewtopic.php?p=561224#p561224) diff --git a/privet/ailabs/adm/style/acp_ailabs_body.html b/privet/ailabs/adm/style/acp_ailabs_body.html index c480f72..862c537 100644 --- a/privet/ailabs/adm/style/acp_ailabs_body.html +++ b/privet/ailabs/adm/style/acp_ailabs_body.html @@ -6,15 +6,23 @@ -

{{ lang('ACP_AILABS_TITLE') }}

+
+

{{ lang('ACP_AILABS_TITLE') }}

+
v. {{ U_AILABS_VERSION }} +

- {{ lang('LBL_AILABS_SETTINGS_DESC') }} + {{ lang('LBL_AILABS_SETTINGS_DESC') }} {% if U_AILABS_VEIW %} {{ lang('ACP_AILABS_ADD') }}

+ + {% if U_IP_CHECK %} + {{ U_IP_CHECK }} + {% endif %} + {% endif %} {% if U_AILABS_ADD_EDIT %} @@ -120,13 +128,15 @@ function doReset() { setTimeout(function () { resetValue('ailabs_forums_post', {{ ailabs_forums_post }}); - resetValue('ailabs_forums_mention', {{ ailabs_forums_mention }}); + resetValue('ailabs_forums_reply', {{ ailabs_forums_reply }}); + resetValue('ailabs_forums_mention', {{ ailabs_forums_mention }}); }, 500); } window.addEventListener("DOMContentLoaded", function () { $(".chosen-select").chosen(); setupSelect('ailabs_forums_post', {{ ailabs_forums_post }}); + setupSelect('ailabs_forums_reply', {{ ailabs_forums_reply }}); setupSelect('ailabs_forums_mention', {{ ailabs_forums_mention }}); }); @@ -151,7 +161,7 @@

-
+
[ {L_FIND_USERNAME} ] @@ -195,10 +205,10 @@
- {{ lang('LBL_AILABS_REPLY_POST_FORUMS') }} - {{ lang('LBL_AILABS_REPLY_POST_FORUMS_EXPLAIN') }} - {% for key,value in AILABS_FORUMS_LIST %} {% endfor %} @@ -206,10 +216,21 @@
- {{ lang('LBL_AILABS_REPLY_QUOTE_FORUMS') }} - {{ lang('LBL_AILABS_REPLY_QUOTE_FORUMS_EXPLAIN') }} - + {% for key,value in AILABS_FORUMS_LIST %} + + {% endfor %} + +
+ +
+ {{ lang('LBL_AILABS_QUOTE_FORUMS') }} + {{ lang('LBL_AILABS_QUOTE_FORUMS_EXPLAIN') }} + + @@ -235,11 +257,17 @@ + + + + + - - + + + @@ -247,9 +275,10 @@ {% for user in U_AILABS_USERS %} - + + diff --git a/privet/ailabs/composer.json b/privet/ailabs/composer.json index 5b613bd..c2d6d9e 100644 --- a/privet/ailabs/composer.json +++ b/privet/ailabs/composer.json @@ -3,8 +3,8 @@ "type": "phpbb-extension", "description": "AI Labs", "homepage": "https://privet.fun", - "version": "1.0.3", - "time": "2023-06-01", + "version": "1.0.4", + "time": "2023-06-04", "keywords": [ "phpbb", "extension", diff --git a/privet/ailabs/config/services.yml b/privet/ailabs/config/services.yml index b5745b4..57240b1 100644 --- a/privet/ailabs/config/services.yml +++ b/privet/ailabs/config/services.yml @@ -15,6 +15,7 @@ services: - '@template' - '@user' - '%core.root_path%' + - '%core.php_ext%' - '%privet.ailabs.tables.users%' privet.ailabs.listener: diff --git a/privet/ailabs/controller/acp_controller.php b/privet/ailabs/controller/acp_controller.php index 981bd4a..e653c57 100644 --- a/privet/ailabs/controller/acp_controller.php +++ b/privet/ailabs/controller/acp_controller.php @@ -23,6 +23,7 @@ class acp_controller //implements acp_interface protected $template; protected $user; protected $root_path; + protected $php_ext; protected $ailabs_users_table; protected $id; @@ -51,6 +52,7 @@ class acp_controller //implements acp_interface \phpbb\template\template $template, \phpbb\user $user, $root_path, + $php_ext, $ailabs_users_table ) { $this->config = $config; @@ -63,6 +65,7 @@ class acp_controller //implements acp_interface $this->template = $template; $this->user = $user; $this->root_path = $root_path; + $this->php_ext = $php_ext; $this->ailabs_users_table = $ailabs_users_table; } @@ -93,6 +96,7 @@ class acp_controller //implements acp_interface 'config' => $this->request->variable('ailabs_config', '', true), 'template' => $this->request->variable('ailabs_template', '', true), 'forums_post' => $this->request->variable('ailabs_forums_post', ''), + 'forums_reply' => $this->request->variable('ailabs_forums_reply', ''), 'forums_mention' => $this->request->variable('ailabs_forums_mention', ''), 'enabled' => $this->request->variable('ailabs_enabled', true), ]; @@ -111,8 +115,8 @@ class acp_controller //implements acp_interface trigger_error($this->language->lang('AILABS_USER_ALREADY_CONFIGURED', $username) . adm_back_link($this->u_action), E_USER_WARNING); } - if (empty($data['forums_post']) && empty($data['forums_mention'])) { - trigger_error($this->language->lang('AILABS_SPECIFY_POST_OR_MENTION') . adm_back_link($this->u_action), E_USER_WARNING); + if (empty($data['forums_post']) && empty($data['forums_reply']) && empty($data['forums_mention'])) { + trigger_error($this->language->lang('AILABS_SPECIFY_FORUM') . adm_back_link($this->u_action), E_USER_WARNING); } if (!isset($error)) { @@ -122,6 +126,7 @@ class acp_controller //implements acp_interface 'config' => (string) html_entity_decode($data['config']), 'template' => (string) html_entity_decode($data['template']), 'forums_post' => (string) html_entity_decode($data['forums_post']), + 'forums_reply' => (string) html_entity_decode($data['forums_reply']), 'forums_mention' => (string) html_entity_decode($data['forums_mention']), 'enabled' => (bool) $data['enabled'] ]; @@ -159,6 +164,7 @@ class acp_controller //implements acp_interface 'ailabs_config' => (string) $row['config'], 'ailabs_template' => (string) $row['template'], 'ailabs_forums_post' => (string) $row['forums_post'], + 'ailabs_forums_reply' => (string) $row['forums_reply'], 'ailabs_forums_mention' => (string) $row['forums_mention'], 'ailabs_enabled' => (bool) $row['enabled'] ]; @@ -177,8 +183,6 @@ class acp_controller //implements acp_interface ]); } - global $phpbb_root_path, $phpEx; - $this->template->assign_vars( array_merge( $edit, @@ -187,8 +191,9 @@ class acp_controller //implements acp_interface 'U_AILABS_ADD_EDIT' => true, 'U_ACTION' => $this->action == 'add' ? $this->u_action . '&action=add' : $this->u_action . '&action=edit&user_id=' . $this->user_id, 'U_BACK' => $this->u_action, - 'U_FIND_USERNAME' => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=searchuser&form=ailabs_configuration&field=ailabs_username&select_single=true'), + 'U_FIND_USERNAME' => generate_board_url() . '/' . append_sid("memberlist.$this->php_ext", 'mode=searchuser&form=ailabs_configuration&field=ailabs_username&select_single=true', true, $this->user->session_id), 'AILABS_FORUMS_LIST' => $this->build_forums_list(), + 'U_AILABS_VERSION' => $this->config['privet_ailabs_version'], ] ) ); @@ -229,7 +234,9 @@ class acp_controller //implements acp_interface $controller = explode("/", $row['controller']); $row['controller'] = end($controller); + $row['username_url'] = generate_board_url() . '/' . append_sid("memberlist.$this->php_ext", 'mode=viewprofile&u=' . $row['user_id'], true, $this->user->session_id); $row['forums_post_names'] = $this->get_forums_names($row['forums_post'], $forums); + $row['forums_reply_names'] = $this->get_forums_names($row['forums_reply'], $forums); $row['forums_mention_names'] = $this->get_forums_names($row['forums_mention'], $forums); $row['U_EDIT'] = $this->u_action . '&action=edit&user_id=' . $row['user_id'] . '&hash=' . generate_link_hash('acp_ailabs'); $row['U_DELETE'] = $this->u_action . '&action=delete&user_id=' . $row['user_id'] . '&username=' . $row['username'] . '&hash=' . generate_link_hash('acp_ailabs'); @@ -243,12 +250,23 @@ class acp_controller //implements acp_interface 'U_AILABS_USERS' => $ailabs_users, 'U_ADD' => $this->u_action . '&action=add', 'U_ACTION' => $this->u_action, - 'U_AILABS_VEIW' => true + 'U_AILABS_VEIW' => true, + 'U_AILABS_VERSION' => $this->config['privet_ailabs_version'], + 'U_IP_CHECK' => $this->warn_ip_check() ]; return $this->template->assign_vars($template_vars); } + protected function warn_ip_check() + { + if ($this->config['ip_check'] != 0) { + $url = generate_board_url() . '/' . append_sid("adm/index.$this->php_ext", ['i' => 'acp_board', 'mode' => 'security'], true, $this->user->session_id); + return $this->language->lang('LBL_AILABS_IP_VALIDATION', $url); + } + return null; + } + protected function find_user_id($username) { $user_id = null; @@ -306,19 +324,18 @@ class acp_controller //implements acp_interface return $return; } - protected function get_forums_names($str, $forums) { + protected function get_forums_names($str, $forums) + { $result = []; - if(!empty($str)) { + if (!empty($str)) { $arr = json_decode($str); - if(!empty($arr) && is_array($arr)) { - foreach($arr as $id) - { - $name = empty($forums[$id]) ? $id : $forums[$id]; - array_push($result, $name); + if (!empty($arr) && is_array($arr)) { + foreach ($arr as $id) { + $name = empty($forums[$id]) ? $id : $forums[$id]; + array_push($result, $name); } } } return join(', ', $result); } - } diff --git a/privet/ailabs/controller/chatgpt.php b/privet/ailabs/controller/chatgpt.php index 78ffb62..1362060 100644 --- a/privet/ailabs/controller/chatgpt.php +++ b/privet/ailabs/controller/chatgpt.php @@ -92,72 +92,71 @@ class chatgpt extends AIController $post_first_discarded = null; $mode = $this->job['post_mode']; - if ($mode == 'reply' || $mode == 'quote') { - $history = ['post_text' => $this->job['post_text']]; + $history = ['post_text' => $this->job['post_text']]; - $pattern = '/job['ailabs_username'] . '"\spost_id="(.*)"\stime="(.*)"\suser_id="' . $this->job['ailabs_user_id'] . '">/'; + $pattern = '/job['ailabs_username'] . '"\spost_id="(.*)"\stime="(.*)"\suser_id="' . $this->job['ailabs_user_id'] . '">/'; - $this->log['history.pattern'] = $pattern; - $this->log_flush(); + $this->log['history.pattern'] = $pattern; + $this->log_flush(); - $history_tokens = 0; - $round = -1; - do { - $round++; - $matches = null; - preg_match_all( - $pattern, - $history['post_text'], - $matches - ); + // Attempt to unwind history using quoted posts + $history_tokens = 0; + $round = -1; + do { + $round++; + $matches = null; + preg_match_all( + $pattern, + $history['post_text'], + $matches + ); - $history = null; + $history = null; - if ($matches != null && !empty($matches) && !empty($matches[1][0])) { - $postid = (int) $matches[1][0]; + if ($matches != null && !empty($matches) && !empty($matches[1][0])) { + $postid = (int) $matches[1][0]; - $sql = 'SELECT j.job_id, j.post_id, j.response_post_id, j.request, j.response, p.post_text, j.request_tokens, j.response_tokens ' . - 'FROM ' . $this->jobs_table . ' j ' . - 'JOIN ' . POSTS_TABLE . ' p ON p.post_id = j.post_id ' . - 'WHERE ' . $this->db->sql_build_array('SELECT', ['response_post_id' => $postid]); - $result = $this->db->sql_query($sql); - $history = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); + $sql = 'SELECT j.job_id, j.post_id, j.response_post_id, j.request, j.response, p.post_text, j.request_tokens, j.response_tokens ' . + 'FROM ' . $this->jobs_table . ' j ' . + 'JOIN ' . POSTS_TABLE . ' p ON p.post_id = j.post_id ' . + 'WHERE ' . $this->db->sql_build_array('SELECT', ['response_post_id' => $postid]); + $result = $this->db->sql_query($sql); + $history = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); - if (!empty($history)) { - $count_tokens = $history['request_tokens'] + $history['response_tokens']; + if (!empty($history)) { + $count_tokens = $history['request_tokens'] + $history['response_tokens']; - $discard = $this->max_tokens < ($this->message_tokens + $history_tokens + $count_tokens); + $discard = $this->max_tokens < ($this->message_tokens + $history_tokens + $count_tokens); - $posts[] = [ - 'postid' => $postid, - 'request_tokens' => $history['request_tokens'], - 'response_tokens' => $history['response_tokens'], - 'runnig_total_tokens' => $history_tokens + $count_tokens, - 'discard' => $discard - ]; + $posts[] = [ + 'postid' => $postid, + 'request_tokens' => $history['request_tokens'], + 'response_tokens' => $history['response_tokens'], + 'runnig_total_tokens' => $history_tokens + $count_tokens, + 'discard' => $discard + ]; - if ($discard) { - $post_first_discarded = $postid; - break; - } - - $post_first_taken = $postid; - $history_tokens += $count_tokens; - - array_unshift( - $messages, - ['role' => 'user', 'content' => trim($history['request'])], - ['role' => 'assistant', 'content' => trim($history['response'])] - ); + if ($discard) { + $post_first_discarded = $postid; + break; } - } - } while (!empty($history)); - if (!empty($posts)) { - $this->log['history.posts'] = $posts; - $this->log_flush(); + $post_first_taken = $postid; + $history_tokens += $count_tokens; + + array_unshift( + $messages, + ['role' => 'user', 'content' => trim($history['request'])], + ['role' => 'assistant', 'content' => trim($history['response'])] + ); + } } + } while (!empty($history)); + + if (!empty($posts)) { + $this->log['history.posts'] = $posts; + $this->log_flush(); } if (!empty($this->cfg->prefix)) { @@ -237,14 +236,16 @@ class chatgpt extends AIController $this->log['finish'] = date('Y-m-d H:i:s'); if (!empty($posts)) { + $viewtopic = "{$this->root_path}viewtopic.{$this->php_ext}"; $discarded = ''; if ($post_first_discarded != null) { - $discarded = $this->language->lang('AILABS_POSTS_DISCARDED', $post_first_discarded); + $discarded = $this->language->lang('AILABS_POSTS_DISCARDED', $viewtopic, $post_first_discarded); } $total_posts_count = count($posts) * 2 + 2; $total_tokens_used_count = $request_tokens + $response_tokens; $info = $this->language->lang( 'AILABS_DISCARDED_INFO', + $viewtopic, $post_first_taken, $total_posts_count, $discarded, diff --git a/privet/ailabs/controller/log.php b/privet/ailabs/controller/log.php index c0a765b..06202f7 100644 --- a/privet/ailabs/controller/log.php +++ b/privet/ailabs/controller/log.php @@ -33,10 +33,10 @@ class log extends AIController if (!empty($data)) { foreach ($data as &$row) { - $row['poster_user_url'] = generate_board_url() . '/' . append_sid("memberlist.$this->php_ext", 'mode=viewprofile&u=' . $row['poster_id'], true, ''); - $row['ailabs_user_url'] = generate_board_url() . '/' . append_sid("memberlist.$this->php_ext", 'mode=viewprofile&u=' . $row['ailabs_user_id'], true, ''); + $row['poster_user_url'] = generate_board_url() . '/' . append_sid("memberlist.$this->php_ext", 'mode=viewprofile&u=' . $row['poster_id'], true, $this->user->session_id); + $row['ailabs_user_url'] = generate_board_url() . '/' . append_sid("memberlist.$this->php_ext", 'mode=viewprofile&u=' . $row['ailabs_user_id'], true, $this->user->session_id); if (!empty($row['response_post_id'])) { - $row['response_url'] = generate_board_url() . '/' . append_sid('viewtopic.php?p=' . $row['response_post_id'] . '#p' . $row['response_post_id'], true, ''); + $row['response_url'] = generate_board_url() . '/' . append_sid("viewtopic.$this->php_ext", 'p=' . $row['response_post_id'] . '#p' . $row['response_post_id'], true, $this->user->session_id); } } diff --git a/privet/ailabs/docs/ailabs_settings.png b/privet/ailabs/docs/ailabs_settings.png index bd3bcd0..0ad2608 100644 Binary files a/privet/ailabs/docs/ailabs_settings.png and b/privet/ailabs/docs/ailabs_settings.png differ diff --git a/privet/ailabs/docs/chatgpt_bender_example.png b/privet/ailabs/docs/chatgpt_bender_example.png index a29b748..7697540 100644 Binary files a/privet/ailabs/docs/chatgpt_bender_example.png and b/privet/ailabs/docs/chatgpt_bender_example.png differ diff --git a/privet/ailabs/docs/chatgpt_setup.png b/privet/ailabs/docs/chatgpt_setup.png index d0bab3b..d23fdc9 100644 Binary files a/privet/ailabs/docs/chatgpt_setup.png and b/privet/ailabs/docs/chatgpt_setup.png differ diff --git a/privet/ailabs/docs/dalle_setup.png b/privet/ailabs/docs/dalle_setup.png index 5823cd9..5b87c2e 100644 Binary files a/privet/ailabs/docs/dalle_setup.png and b/privet/ailabs/docs/dalle_setup.png differ diff --git a/privet/ailabs/docs/debugging_log.png b/privet/ailabs/docs/debugging_log.png new file mode 100644 index 0000000..451e860 Binary files /dev/null and b/privet/ailabs/docs/debugging_log.png differ diff --git a/privet/ailabs/docs/debugging_post_icon.png b/privet/ailabs/docs/debugging_post_icon.png new file mode 100644 index 0000000..f338cfd Binary files /dev/null and b/privet/ailabs/docs/debugging_post_icon.png differ diff --git a/privet/ailabs/docs/stablediffusion_setup.png b/privet/ailabs/docs/stablediffusion_setup.png index 69f3f17..c472140 100644 Binary files a/privet/ailabs/docs/stablediffusion_setup.png and b/privet/ailabs/docs/stablediffusion_setup.png differ diff --git a/privet/ailabs/event/listener.php b/privet/ailabs/event/listener.php index a76a8b4..955074c 100644 --- a/privet/ailabs/event/listener.php +++ b/privet/ailabs/event/listener.php @@ -115,8 +115,12 @@ class listener implements EventSubscriberInterface if ($mode == 'post' && $user['post'] == 1) { array_push($ailabs_users, $user); } else { - if ($user['mention'] == 1 && in_array($user['user_id'], $ailabs_users_notified)) + if ($mode == 'reply' && $user['reply'] == 1) { array_push($ailabs_users, $user); + } else { + if ($user['mention'] == 1 && in_array($user['user_id'], $ailabs_users_notified)) + array_push($ailabs_users, $user); + } } } @@ -154,6 +158,39 @@ class listener implements EventSubscriberInterface $request = utf8_encode_ucr($request); } + global $config; + + $cookie_name = $config['cookie_name']; + $headers = []; + + $copy_headers = ['X-Forwarded-For', 'User-Agent']; + foreach ($copy_headers as $header_name) { + if (!empty($this->request->header($header_name))) { + array_push($headers, "$header_name: " . $this->request->header($header_name)); + } + } + + $cookies = []; + if ($this->request->is_set($cookie_name . '_sid', \phpbb\request\request_interface::COOKIE) || $this->request->is_set($cookie_name . '_u', \phpbb\request\request_interface::COOKIE)) { + array_push($cookies, $cookie_name . '_u=' . $this->request->variable($cookie_name . '_u', 0, false, \phpbb\request\request_interface::COOKIE)); + array_push($cookies, $cookie_name . '_k=' . $this->request->variable($cookie_name . '_k', '', false, \phpbb\request\request_interface::COOKIE)); + array_push($cookies, $cookie_name . '_sid=' . $this->request->variable($cookie_name . '_sid', '', false, \phpbb\request\request_interface::COOKIE)); + + array_push($headers, "Cookie: " . implode('; ', $cookies)); + } + + $context = null; + if (!empty($headers)) { + $context = stream_context_create( + array( + 'http' => array( + 'method' => "HEAD", + 'header' => implode("\r\n", $headers) + ) + ) + ); + } + // https://area51.phpbb.com/docs/dev/master/db/dbal.html foreach ($ailabs_users as $user) { $data = [ @@ -174,8 +211,11 @@ class listener implements EventSubscriberInterface $this->update_post($data); - $url = generate_board_url() . $user['controller'] . '?job_id=' . $data['job_id']; - get_headers($url); + $url = append_sid(generate_board_url() . $user['controller'], ['job_id' => $data['job_id']], true, $this->user->session_id); + + // Provide same cookies, session id and browser name so phpBB can authenticate user. + // Verify that Server Configuration > Security Settings > Session IP validation set to none + get_headers($url, false, $context); unset($data); } } @@ -211,6 +251,7 @@ class listener implements EventSubscriberInterface $return = array(); $sql = 'SELECT c.user_id, ' . 'c.forums_post LIKE \'%"' . $id . '"%\' as post, ' . + 'c.forums_reply LIKE \'%"' . $id . '"%\' as reply, ' . 'c.forums_mention LIKE \'%"' . $id . '"%\' as mention, ' . 'c.controller, ' . 'u.username ' . @@ -223,6 +264,7 @@ class listener implements EventSubscriberInterface 'user_id' => $row['user_id'], 'username' => $row['username'], 'post' => $row['post'], + 'reply' => $row['reply'], 'mention' => $row['mention'], 'controller' => $row['controller'] )); @@ -312,9 +354,9 @@ class listener implements EventSubscriberInterface $ailabs = array(); foreach ($jobs as $key => $value) { - $value->user_url = generate_board_url() . '/' . append_sid("memberlist.$this->php_ext", 'mode=viewprofile&u=' . $value->ailabs_user_id, true, ''); + $value->user_url = generate_board_url() . '/' . append_sid("memberlist.$this->php_ext", 'mode=viewprofile&u=' . $value->ailabs_user_id, true, $this->user->session_id); if (!empty($value->response_post_id)) { - $value->response_url = generate_board_url() . '/' . append_sid('viewtopic.php?p=' . $value->response_post_id . '#p' . $value->response_post_id, true, ''); + $value->response_url = generate_board_url() . '/' . append_sid("viewtopic.$this->php_ext", "p=$value->response_post_id#p$value->response_post_id", true, $this->user->session_id); } $value->status = $this->get_status(empty($value->status) ? null : $value->status); array_push($ailabs, $value); diff --git a/privet/ailabs/includes/AIController.php b/privet/ailabs/includes/AIController.php index c5f4d21..31ada15 100644 --- a/privet/ailabs/includes/AIController.php +++ b/privet/ailabs/includes/AIController.php @@ -240,8 +240,14 @@ class AIController { // Prep posting $poll = $uid = $bitfield = $options = ''; - $allow_bbcode = $allow_urls = $allow_smilies = true; - generate_text_for_storage($response, $uid, $bitfield, $options, $allow_bbcode, $allow_urls, $allow_smilies); + generate_text_for_storage($response, $uid, $bitfield, $options, true, true, true); + + // For some reason uid is not calculated by generate_text_for_storage + if (empty($uid)) { + $message_parser = new \parse_message($response); + $message_parser->parse(true, true, true); + $uid = $message_parser->bbcode_uid; + } $data = array( 'poster_id' => $job['ailabs_user_id'], diff --git a/privet/ailabs/language/en/common.php b/privet/ailabs/language/en/common.php index 7a475b4..f28b6d4 100644 --- a/privet/ailabs/language/en/common.php +++ b/privet/ailabs/language/en/common.php @@ -19,8 +19,8 @@ if (empty($lang) || !is_array($lang)) { $lang = array_merge($lang, [ 'AILABS_ERROR_CHECK_LOGS' => '[color=#FF0000]Error. Pelase check logs.[/color]', - 'AILABS_POSTS_DISCARDED' => ', posts starting from [url=/viewtopic.php?p=%1$d#p%1$d]this post[/url] were discarded', - 'AILABS_DISCARDED_INFO' => '[size=75][url=/viewtopic.php?p=%1$d#p%1$d]Beginning[/url] of a conversation containing %2$d posts%3$s (%4$d tokens of %5$d were used)[/size]', + 'AILABS_POSTS_DISCARDED' => ', posts starting from [url=%1$s?p=%2$d#p%2$d]this post[/url] were discarded', + 'AILABS_DISCARDED_INFO' => '[size=75][url=%1$s?p=%2$d#p%2$d]Beginning[/url] of a conversation containing %3$d posts%4$s (%5$d tokens of %6$d were used)[/size]', 'AILABS_THINKING' => 'thinking', 'AILABS_REPLYING' => 'replying…', 'AILABS_REPLIED' => 'replied ↓', diff --git a/privet/ailabs/language/en/info_acp_ailabs.php b/privet/ailabs/language/en/info_acp_ailabs.php index 40637b4..4e6c07d 100644 --- a/privet/ailabs/language/en/info_acp_ailabs.php +++ b/privet/ailabs/language/en/info_acp_ailabs.php @@ -29,7 +29,7 @@ $lang = array_merge($lang, [ 'AILABS_USER_EMPTY' => 'Please select user', 'AILABS_USER_NOT_FOUND' => 'Unable to locate user %1$s', 'AILABS_USER_ALREADY_CONFIGURED' => 'User %1$s already configured, only one configuration per user supported', - 'AILABS_SPECIFY_POST_OR_MENTION' => 'Both Reply on a post and Reply when quoted can\'t be empty, please specify at least one', + 'AILABS_SPECIFY_FORUM' => 'Please select at least one forum', 'LOG_ACP_AILABS_ADDED' => 'AI Labs configuration added', 'LOG_ACP_AILABS_EDITED' => 'AI Labs configuration updated', @@ -39,20 +39,31 @@ $lang = array_merge($lang, [ 'ACP_AILABS_UPDATED' => 'Configuration successfully updated', 'ACP_AILABS_DELETED_CONFIRM' => 'Are you sure that you wish to delete the configuration associated with user %1$s?', - 'LBL_AILABS_SETTINGS_DESC' => 'Please visit 👉 https://github.com/privet-fun/phpbb_ailabs for detailed configuration instructions and examples', - 'LBL_AILABS_USERNAME' => 'User Name', + 'LBL_AILABS_SETTINGS_DESC' => 'Please visit 👉 https://github.com/privet-fun/phpbb_ailabs for detailed configuration instructions, troubleshooting and examples.', + 'LBL_AILABS_USERNAME' => 'AI bot', 'LBL_AILABS_CONTROLLER' => 'AI', 'LBL_AILABS_CONFIG' => 'Configuration JSON', 'LBL_AILABS_TEMPLATE' => 'Template', - 'LBL_AILABS_REPLY_POST_FORUMS' => 'Reply on a post', - 'LBL_AILABS_REPLY_QUOTE_FORUMS' => 'Reply when quoted', + + 'LBL_AILABS_REPLY_TO' => 'Forums where AI bot reply to', + 'LBL_AILABS_POST_FORUMS' => 'New topic', + 'LBL_AILABS_REPLY_FORUMS' => 'Reply in a topic', + 'LBL_AILABS_QUOTE_FORUMS' => 'Quote or mention', 'LBL_AILABS_ENABLED' => 'Enabled', 'LBL_AILABS_SELECT_FORUMS' => 'Select forums...', 'LBL_AILABS_CONFIG_EXPLAIN' => 'Must be valid JSON, please refer to documnetation for details', 'LBL_AILABS_TEMPLATE_EXPLAIN' => 'Valid variables: {post_id}, {request}, {info}, {response}, {images}, {attachments}, {poster_id}, {poster_name}, {ailabs_username}', - 'LBL_AILABS_REPLY_POST_FORUMS_EXPLAIN' => 'Specify forums where AI will reply to new posts', - 'LBL_AILABS_REPLY_QUOTE_FORUMS_EXPLAIN' => 'Specify forums where AI will reply to quoted posts', + 'LBL_AILABS_POST_FORUMS_EXPLAIN' => 'Specify forums where AI will reply to new topic', + 'LBL_AILABS_REPLY_FORUMS_EXPLAIN' => 'Specify forums where AI will reply to reply in the topic', + 'LBL_AILABS_QUOTE_FORUMS_EXPLAIN' => 'Specify forums where AI will reply when quoted or mentioned', + 'LBL_AILABS_IP_VALIDATION' => '⚠️ Warning: Your ACP > General > Server Configuration > Security Settings > ' . + 'Session IP validation setting NOT set to None, ' . + 'this may prevent AI Labs to reply if you are using phpBB extensions which force user to be logged in ' . + '(eg Login Required). ' . + 'Set Session IP validation to None or add "/ailabs/*" to extension whitelist. ' . + 'Please refer to troubleshooting section for more details.', + 'LBL_AILABS_CONFIG_DEFAULT' => 'Load default configuration', 'LBL_AILABS_TEMPLATE_DEFAULT' => 'Load default template', ]); diff --git a/privet/ailabs/language/ru/common.php b/privet/ailabs/language/ru/common.php index b28c6c9..f8bc8f6 100644 --- a/privet/ailabs/language/ru/common.php +++ b/privet/ailabs/language/ru/common.php @@ -19,8 +19,8 @@ if (empty($lang) || !is_array($lang)) { $lang = array_merge($lang, [ 'AILABS_ERROR_CHECK_LOGS' => '[color=#FF0000]Ошибка. Лог содержит детальную информацию.[/color]', - 'AILABS_POSTS_DISCARDED' => ', сообщения начиная с [url=/viewtopic.php?p=%1$d#p%1$d]этого[/url] не включены', - 'AILABS_DISCARDED_INFO' => '[size=75][url=/viewtopic.php?p=%1$d#p%1$d]Начало[/url] беседы из %2$d сообщений%3$s (%4$d токенов из %5$d использовано)[/size]', + 'AILABS_POSTS_DISCARDED' => ', сообщения начиная с [url=%1$s?p=%2$d#p%2$d]этого[/url] не включены', + 'AILABS_DISCARDED_INFO' => '[size=75][url=%1$s?p=%2$d#p%2$d]Начало[/url] беседы из %3$d сообщений%4$s (%5$d токенов из %6$d использовано)[/size]', 'AILABS_THINKING' => 'думает', 'AILABS_REPLYING' => 'отвечает…', 'AILABS_REPLIED' => 'ответил ↓', diff --git a/privet/ailabs/language/ru/info_acp_ailabs.php b/privet/ailabs/language/ru/info_acp_ailabs.php index 27fe095..b56beff 100644 --- a/privet/ailabs/language/ru/info_acp_ailabs.php +++ b/privet/ailabs/language/ru/info_acp_ailabs.php @@ -29,7 +29,7 @@ $lang = array_merge($lang, [ 'AILABS_USER_EMPTY' => 'Пожалуйста, выберите пользователя', 'AILABS_USER_NOT_FOUND' => 'Не удалось найти пользователя %1$s', 'AILABS_USER_ALREADY_CONFIGURED' => 'Пользователь %1$s уже настроен, поддерживается только одна конфигурация на пользователя', - 'AILABS_SPECIFY_POST_OR_MENTION' => 'Нельзя оставлять пустыми и "Ответ на сообщение" и "Ответ при цитировании", пожалуйста, укажите хотя бы одно значение', + 'AILABS_SPECIFY_FORUM' => 'Укажите хотя бы один форум', 'LOG_ACP_AILABS_ADDED' => 'Конфигурация AI Labs добавлена', 'LOG_ACP_AILABS_EDITED' => 'Конфигурация AI Labs изменена', @@ -39,20 +39,33 @@ $lang = array_merge($lang, [ 'ACP_AILABS_UPDATED' => 'Конфигурация успешно обновлена', 'ACP_AILABS_DELETED_CONFIRM' => 'Вы уверены, что хотите удалить конфигурацию, связанную с пользователем %1$s?', - 'LBL_AILABS_SETTINGS_DESC' => 'Пожалуйста, посетите 👉 https://github.com/privet-fun/phpbb_ailabs для получения подробных инструкций по настройке и примеров', - 'LBL_AILABS_USERNAME' => 'Имя пользователя', + 'LBL_AILABS_SETTINGS_DESC' => 'Пожалуйста, посетите 👉 https://github.com/privet-fun/phpbb_ailabs для получения подробных инструкций по настройке и примеров.', + 'LBL_AILABS_USERNAME' => 'AI бот', 'LBL_AILABS_CONTROLLER' => 'AI', 'LBL_AILABS_CONFIG' => 'Конфигурация в формате JSON', 'LBL_AILABS_TEMPLATE' => 'Шаблон', - 'LBL_AILABS_REPLY_POST_FORUMS' => 'Ответ на сообщение', - 'LBL_AILABS_REPLY_QUOTE_FORUMS' => 'Ответ при цитировании', + + 'LBL_AILABS_REPLY_TO' => 'Форумы где AI бот отвечает на', + 'LBL_AILABS_POST_FORUMS' => 'Новую тему', + 'LBL_AILABS_REPLY_FORUMS' => 'Ответ в теме', + 'LBL_AILABS_QUOTE_FORUMS' => 'Цитирование или упоминание', 'LBL_AILABS_ENABLED' => 'Включено', 'LBL_AILABS_SELECT_FORUMS' => 'Выберите форумы...', 'LBL_AILABS_CONFIG_EXPLAIN' => 'Пожалуйста, обратитесь к документации для получения подробных инструкций по настройке и примеров', 'LBL_AILABS_TEMPLATE_EXPLAIN' => 'Допустимые переменные: {post_id}, {request}, {info}, {response}, {images}, {attachments}, {poster_id}, {poster_name}, {ailabs_username}', - 'LBL_AILABS_REPLY_POST_FORUMS_EXPLAIN' => 'Укажите форумы, на которых AI будет отвечать на новые сообщения', - 'LBL_AILABS_REPLY_QUOTE_FORUMS_EXPLAIN' => 'Укажите форумы, на которых AI будет отвечать на цитируемые сообщения', + 'LBL_AILABS_POST_FORUMS_EXPLAIN' => 'Укажите форумы, на которых AI будет отвечать на новые темы', + 'LBL_AILABS_REPLY_FORUMS_EXPLAIN' => 'Укажите форумы, на которых AI будет отвечать на ответы', + 'LBL_AILABS_QUOTE_FORUMS_EXPLAIN' => 'Укажите форумы, на которых AI будет отвечать на цитируемые сообщения или упоминания', + 'LBL_AILABS_IP_VALIDATION' => '⚠️ Предупреждение: Администрировать > Общие > Конфигурация сервера > Безопасность > ' . + 'Проверка IP-адреса сессии НЕ установлена в значение «Нет». ' . + 'Это может препятствовать работе AI Labs в случае если вы используете расширения phpBB, ' . + 'требующие авторизацию пользователя ' . + '(например Login Required). ' . + 'Установите проверку IP-адреса сессии в значение "Нет" или добавьте "/ailabs/*" в белый список расширений. ' . + 'Пожалуйста, обратитесь к разделу по ' . + 'устранению неполадок для получения дополнительной информации.', + 'LBL_AILABS_CONFIG_DEFAULT' => 'Загрузить конфигурацию по умолчанию', 'LBL_AILABS_TEMPLATE_DEFAULT' => 'Загрузить шаблон по умолчанию', ]); diff --git a/privet/ailabs/migrations/v1x/release_1_0_4_schema.php b/privet/ailabs/migrations/v1x/release_1_0_4_schema.php new file mode 100644 index 0000000..9096792 --- /dev/null +++ b/privet/ailabs/migrations/v1x/release_1_0_4_schema.php @@ -0,0 +1,51 @@ +config['privet_ailabs_version']) && version_compare($this->config['privet_ailabs_version'], '1.0.4', '>='); + } + + public function update_data() + { + return array( + array('config.add', array('privet_ailabs_version', '1.0.4')), + ); + } + + public function revert_data() + { + return array( + array('config.remove', array('privet_ailabs_version')), + ); + } + + public function update_schema() + { + return [ + 'add_columns' => [ + $this->table_prefix . 'ailabs_users' => [ + 'forums_reply' => ['VCHAR', ''], // eg ["forum_id1","forum_id2"] + ], + ], + ]; + } + +}
{{ lang('LBL_AILABS_REPLY_TO') }}
{{ lang('LBL_AILABS_USERNAME') }} {{ lang('LBL_AILABS_CONTROLLER') }}{{ lang('LBL_AILABS_REPLY_POST_FORUMS') }}{{ lang('LBL_AILABS_REPLY_QUOTE_FORUMS') }}{{ lang('LBL_AILABS_POST_FORUMS') }}{{ lang('LBL_AILABS_REPLY_FORUMS') }}{{ lang('LBL_AILABS_QUOTE_FORUMS') }} {{ lang('LBL_AILABS_ENABLED') }}
{{ user.username }}{{ user.username }} {{ user.controller }} {{ user.forums_post_names }}{{ user.forums_reply_names }} {{ user.forums_mention_names }}