Răsfoiți Sursa

Ticket #4603 - Antispam: Integrate Lasso Moderation API.

AntonLV 2 ani în urmă
părinte
comite
b6404e7a41

+ 1 - 1
modules/boonex/antispam/classes/BxAntispamAlertsResponse.php

@@ -42,7 +42,7 @@ class BxAntispamAlertsResponse extends BxDolAlertsResponse
                     BxDolService::call('bx_antispam', 'check_form_for_toxicity', array(&$oAlert->aExtras['object']));
                     break;
                 case 'form_submitted':
-                    BxDolService::call('bx_antispam', 'on_form_submitted', array($oAlert->aExtras['module'], $oAlert->aExtras['entry_id']));
+                    BxDolService::call('bx_antispam', 'on_form_submitted', array($oAlert->aExtras['module'], $oAlert->aExtras['entry_id'], $oAlert->aExtras['action'], &$oAlert->aExtras['form_object']));
                     break;
             }
         } elseif ('comment' == $oAlert->sUnit && BxDolService::call('bx_antispam', 'is_last_form_submitted_toxic', array())) {

+ 9 - 0
modules/boonex/antispam/classes/BxAntispamConfig.php

@@ -28,6 +28,11 @@ class BxAntispamConfig extends BxDolModuleConfig
         'toxicity_enable' => 'bx_antispam_toxicity_filter_enable',
         'toxicity_action' => 'bx_antispam_toxicity_filter_action',
         'toxicity_report' => 'bx_antispam_toxicity_filter_report',
+        'lm_enable' => 'bx_antispam_lasso_moderation_enable',
+        'lm_api_key' => 'bx_antispam_lasso_moderation_api_key',
+        'lm_webhook_secret' => 'lasso_moderation_webhook_secret',
+        'lm_action' => 'bx_antispam_lasso_moderation_action',
+        'lm_report' => 'bx_antispam_lasso_moderation_report',
     );
     /**
      * default local options, it is filled in with real system options in class contructor, @see restoreAntispamOptions
@@ -44,6 +49,10 @@ class BxAntispamConfig extends BxDolModuleConfig
         'toxicity_enable' => '',
         'toxicity_action' => '',
         'toxicity_report' => '',
+        'lm_enable' => '',
+        'lm_api_key' => '',
+        'lm_action' => '',
+        'lm_report' => ''
     );
 
     public function __construct($aModule)

+ 162 - 0
modules/boonex/antispam/classes/BxAntispamLassoModeration.php

@@ -0,0 +1,162 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Antispam Antispam
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+class BxAntispamLassoModeration extends BxDol
+{
+    protected $_sModule;
+    protected $_oModule;
+
+    protected $_sApiKey;
+    protected $_sWebhookSecret;
+    protected $_sEndpoint;
+
+    public function __construct()
+    {
+        parent::__construct();
+
+        $this->_sModule = 'bx_antispam';
+        $this->_oModule = BxDolModule::getInstance($this->_sModule);
+
+        $this->_sApiKey = $this->_oModule->_oConfig->getAntispamOption('lm_api_key');
+        $this->_sWebhookSecret = $this->_oModule->_oConfig->getAntispamOption('lm_webhook_secret');
+
+        $this->_sEndpoint = 'https://api.lassomoderation.com/api/v1';
+    }
+
+    public function processEvent()
+    {
+        $sInput = @file_get_contents("php://input");
+        
+        $sInputHmac = hash_hmac('sha256', $sInput, $this->_sWebhookSecret, true);
+        $sInputHmac = 'sha256=' . base64_encode($sInputHmac);
+        
+        if($sInputHmac !== '')
+            return 404;
+        
+        $aEvent = json_decode($sInput, true);
+        if(empty($aEvent) || !is_array($aEvent)) 
+            return 404;
+
+        //TODO: Do something here.
+
+        //$this->_onHarmfulContentFound();
+
+        return 200;
+    }
+
+    public function addContent($sModule, $iId, $aData = [])
+    {
+        $aModule = BxDolModuleQuery::getInstance()->getModuleByName($sModule);
+        if(empty($aModule) || !is_array($aModule))
+            return false;
+
+        $iAuthorId = !empty($aData['author_id']) ? $aData['author_id'] : bx_srv($sModule, 'get_author', [$iId]);
+        $sAuthorName = !empty($aData['author_name']) ? $aData['author_name'] : BxDolProfile::getInstanceMagic($iAuthorId)->getDisplayName();
+
+        $iDataAdded = !empty($aData['date_added']) ? $aData['date_added'] : bx_srv($sModule, 'get_date_added', [$iId]);
+
+        $sText = !empty($aData['text']) ? $aData['text'] : bx_srv($sModule, 'get_text', [$iId]);
+
+        $aParams = [
+            'project' => [
+                'id' => md5(BX_DOL_URL_ROOT),
+                'name' => getParam('site_title'),
+            ],
+            'topic' => [
+                'id' => 'mod_' . $aModule['id'],
+                'name' => $aModule['title'],
+            ],
+            'user' => [
+                'id' => 'prof_' . $iAuthorId,
+                'name' => $sAuthorName
+            ],
+            'content_id' => $sModule . '_' . $iId,
+            'created_at' => bx_time_utc($iDataAdded ? $iDataAdded : time()),
+            'text' => $sText,
+            'image_urls' => isset($aData['images']) ? $aData['images'] : [],
+            'video_urls' => isset($aData['videos']) ? $aData['videos'] : []
+        ];
+
+        return $this->_call('/content', $aParams);
+    }
+
+    public function log($mixedContents, $sTitle = '')
+    {
+        $this->_oModule->log($mixedContents, 'Lasso Moderation', $sTitle);
+    }
+
+    /**
+     * Internal methods.
+     */
+    protected function _call($sRequest, $aParams, $sMethod = 'post-json', $aHeaders = [])
+    {
+        $aHeaders[] = 'Authorization: Bearer ' . $this->_sApiKey;           
+
+        $sResult = bx_file_get_contents($this->_sEndpoint . $sRequest, $aParams, $sMethod, $aHeaders);
+        if(empty($sResult)) {
+            $this->log($sResult, 'Call (' . $sRequest . '): ');
+            $this->log($aParams);
+            return false;
+        }
+
+        $aResult = json_decode($sResult, true);
+        if(empty($aResult) || !is_array($aResult) || !isset($aResult['success'])) {
+            $this->log($sResult, 'Call (' . $sRequest . '): ');
+            $this->log($aParams);
+            return false;
+        }
+
+        return true;
+    }
+    
+    protected function _onHarmfulContentFound($sModule, $iContentId)
+    {        
+        if(!$sModule || $this->_oConfig->getAntispamOption('lm_report') != 'on') 
+            return;
+
+        $oModule = BxDolModule::getInstance($sModule);
+        $CNF = &$oModule->_oConfig->CNF;
+        $sContentUrl = isset($CNF['URI_VIEW_ENTRY']) ? bx_absolute_url(BxDolPermalinks::getInstance()->permalink('page.php?i=' . $CNF['URI_VIEW_ENTRY'] . '&id=' . $iContentId)) : false;
+        $sManageContentUrl = isset($CNF['URL_MANAGE_ADMINISTRATION']) ? bx_absolute_url(BxDolPermalinks::getInstance()->permalink('page.php?i=' . $CNF['URL_MANAGE_ADMINISTRATION'])) : false;
+
+        $oProfile = BxDolProfile::getInstance();
+        if(!$oProfile)
+            return;
+
+        $aPlus = array(
+            'AuthorUrl' => $oProfile->getUrl(),
+            'AuthorNickName' => $oProfile->getDisplayName(),
+            'Page' => htmlspecialchars_adv($_SERVER['PHP_SELF']),
+            'bx_if:content_url' => [
+                'condition' => boolval($sContentUrl),
+                'content' => ['c_url' => $sContentUrl],
+            ],
+            'bx_if:manage_content_url' => [
+                'condition' => boolval($sManageContentUrl),
+                'content' => ['m_url' => $sManageContentUrl],
+            ],
+        );
+
+        $aTemplate = BxDolEmailTemplates::getInstance()->parseTemplate('bx_antispam_lasso_moderation_report', $aPlus);
+        if(!$aTemplate)
+            trigger_error('Email template or translation missing: bx_antispam_lasso_moderation_report', E_USER_ERROR);
+
+        sendMail(getParam('site_email'), $aTemplate['Subject'], $aTemplate['Body']);
+
+        bx_alert('bx_antispam', 'harmful_content_posted', $iContentId, bx_get_logged_profile_id(), [
+            'module' => $sModule,
+            'entry_id' => $iContentId,
+            'entry_url' => $sContentUrl,
+        ]);
+    }
+}
+
+/** @} */

+ 85 - 1
modules/boonex/antispam/classes/BxAntispamModule.php

@@ -19,6 +19,18 @@ class BxAntispamModule extends BxDolModule
         $this->_bLastSubmittedFormWasToxic = false;
     }
 
+    public function actionContentChecked()
+    {
+        $iResult = 404;
+
+        if($this->_oConfig->getAntispamOption('lm_enable') == 'on') {
+            $oLassoModeration = bx_instance('BxAntispamLassoModeration', [], $this->getName());
+            $iResult = $oLassoModeration->processEvent();    
+        }
+
+        http_response_code($iResult);
+    }
+
     public function serviceUpdateDisposableDomainsLists ()
     {
         $o = bx_instance('BxAntispamDisposableEmailDomains', array(), 'bx_antispam');
@@ -261,10 +273,56 @@ class BxAntispamModule extends BxDolModule
         return $this->_oDb->setCommentStatus($iCmtId, BX_CMT_STATUS_PENDING);
     }
 
-    public function serviceOnFormSubmitted($sModule, $iEntry) {
+    public function serviceOnFormSubmitted($sModule, $iEntry, $sAction, &$oForm)
+    {
         if ($this->_bLastSubmittedFormWasToxic) {
             $this->serviceOnToxicContentPosted($sModule, $iEntry);
         }
+
+        if($this->_oConfig->getAntispamOption('lm_enable') == 'on') {
+            $oModule = BxDolModule::getInstance($sModule);
+
+            $CNF = &$oModule->_oConfig->CNF;
+
+            $iAuthorId = bx_get_logged_profile_id();
+            $iAuthorName = BxDolProfile::getInstance()->getDisplayName();
+
+            $iDataAdded = time();
+
+            $sText = '';
+            if(isset($CNF['FIELD_TEXT'], $oForm->aInputs[$CNF['FIELD_TEXT']]))
+                $sText = $oForm->getCleanValue($CNF['FIELD_TEXT']);
+            if(empty($sText) && isset($oForm->aInputs['text']))
+                $sText = $oForm->getCleanValue('text');
+
+            $aMedias = [
+                'images' => ['fields' => ['FIELD_PHOTO', 'FIELD_PICTURE', 'FIELD_COVER'], 'data' => []], 
+                'videos' => ['fields' => ['FIELD_VIDEO'], 'data' => []]
+            ];
+            foreach($aMedias as $sName => $aMedia) 
+                foreach($aMedia['fields'] as $sField) {
+                    if(!isset($CNF[$sField], $oForm->aInputs[$CNF[$sField]]))
+                        continue;
+
+                    $oStorage = BxDolStorage::getObjectInstance($oForm->aInputs[$CNF[$sField]]['storage_object']);
+                    if(!$oStorage)
+                        continue;
+
+                    $aGhosts = $oStorage->getGhosts($iAuthorId, $sAction == 'insert' ? 0 : $iEntry);
+                    foreach($aGhosts as $aGhost)
+                        $aMedias[$sName]['data'][] = $oStorage->getFileUrlById($aGhost['id']);
+                }
+
+            $oLassoModeration = bx_instance('BxAntispamLassoModeration', [], $this->getName());
+            $oLassoModeration->addContent($sModule, $iEntry, [
+                'author_id' => $iAuthorId,
+                'author_name' => $iAuthorName,
+                'date_added' => $iDataAdded,
+                'text' => $sText,
+                'images' => $aMedias['images']['data'], 
+                'videos' => $aMedias['videos']['data']
+            ]);
+        }
     }
 
     public function serviceOnToxicContentFound(&$sText) {
@@ -525,6 +583,32 @@ class BxAntispamModule extends BxDolModule
         ];
     }
 
+    /**
+     * @return array with avaliable Lasso Moderation actions
+     */
+    public function serviceGetLassoModerationActions ()
+    {
+        return [
+            'none' => _t('_bx_antispam_option_lasso_moderation_action_none'),
+            'disapprove' => _t('_bx_antispam_option_lasso_moderation_action_disapprove'),
+        ];
+    }
+
+    public function log($mixedContents, $sSection = '', $sTitle = '')
+    {
+        if(is_array($mixedContents))
+            $mixedContents = var_export($mixedContents, true);	
+        else if(is_object($mixedContents))
+            $mixedContents = json_encode($mixedContents);
+
+        if(empty($sSection))
+            $sSection = "Core";
+
+        $sTitle .= "\n";
+
+        bx_log('bx_antispam', ":\n[" . $sSection . "] " . $sTitle . $mixedContents);
+    }
+
     protected function getErrorMessageIpBlocked ()
     {
         bx_import('BxDolLanguages');

+ 20 - 0
modules/boonex/antispam/classes/BxAntispamStudioOptions.php

@@ -0,0 +1,20 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Antispam Antispam
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+class BxAntispamStudioOptions extends BxTemplStudioOptions
+{
+    protected function getCustomValueLassoModerationWebhookUrl($aItem, $mixedValue)
+    {
+        return bx_replace_markers($mixedValue, [
+            'site_url' => BX_DOL_URL_ROOT
+        ]);
+    }
+}

+ 14 - 1
modules/boonex/antispam/classes/BxAntispamStudioPage.php

@@ -9,6 +9,8 @@
  * @{
  */
 
+require_once ('BxAntispamStudioOptions.php');
+
 class BxAntispamStudioPage extends BxTemplStudioModule
 {
     protected $oModule;
@@ -28,7 +30,18 @@ class BxAntispamStudioPage extends BxTemplStudioModule
         );
     }
 
-    function getHelp ()
+    protected function getSettings()
+    {
+        $oOptions = new BxAntispamStudioOptions($this->sModule);
+
+        $this->aPageCss = array_merge($this->aPageCss, $oOptions->getCss());
+        $this->aPageJs = array_merge($this->aPageJs, $oOptions->getJs());
+        return BxDolStudioTemplate::getInstance()->parseHtmlByName('module.html', [
+            'content' => $oOptions->getCode(),
+        ]);
+    }
+
+    protected function getHelp ()
     {
         return _t('_bx_antispam_help_text');
     }

+ 24 - 1
modules/boonex/antispam/install/langs/en.xml

@@ -12,7 +12,8 @@
     <li><b>Akismet</b> - automatic spam content blocking using <a target="_blank" href="http://akismet.com">Akismet service</a></li>
     <li><b>StopForumSpam</b> - automatic spam content blocking using <a target="_blank" href="http://www.stopforumspam.com">StopForumSpam service</a></li>
     <li><b>Profanity filter</b> - profanity filter, based on a predefined list of words with the ability to add to words this list</a></li>
-    <li><b>Toxicity filter</b> - toxicity filter, based on a <a target="_blank" href="https://www.perspectiveapi.com/">Perspective API</a> provided by Google</a></li>
+    <li><b>Toxicity filter</b> - toxicity filter, based on a <a target="_blank" href="https://www.perspectiveapi.com/">Perspective API</a> provided by Google</li>
+    <li><b>Harmful filter</b> - harmfulness filter, based on a <a target="_blank" href="https://www.lassomoderation.com/">Lasso Moderation API</a></li>
 </ul>
 ]]></string>
     <string name="_bx_antispam_help_dnsbl"><![CDATA[
@@ -203,5 +204,27 @@ This antispam method scan submitted content for the URLs and check them if any o
 <bx_if:manage_content_url>
 	<b>Manage:</b> <a href="{m_url}">{m_url}</a><br /><br />
 </bx_if:manage_content_url>
+{email_footer}]]></string>
+
+    <string name="_bx_antispam_adm_stg_cpt_category_lasso_moderation"><![CDATA[Lasso Moderation]]></string>
+    <string name="_bx_antispam_option_lasso_moderation_enable"><![CDATA[Enable]]></string>
+    <string name="_bx_antispam_option_lasso_moderation_api_key"><![CDATA[API key]]></string>
+    <string name="_bx_antispam_option_lasso_moderation_webhook_secret"><![CDATA[Webhook Secret]]></string>
+    <string name="_bx_antispam_option_lasso_moderation_webhook_url"><![CDATA[Webhook URL]]></string>
+    <string name="_bx_antispam_option_lasso_moderation_action"><![CDATA[Action]]></string>
+    <string name="_bx_antispam_option_lasso_moderation_action_none"><![CDATA[None]]></string>
+    <string name="_bx_antispam_option_lasso_moderation_action_disapprove"><![CDATA[Disapprove]]></string>
+    <string name="_bx_antispam_option_lasso_moderation_report"><![CDATA[Send report to admin if harmful content discovered]]></string>
+    <string name="_bx_antispam_et_lasso_moderation_report_name"><![CDATA[Harmful content posted report message]]></string>
+    <string name="_bx_antispam_et_lasso_moderation_report_subject"><![CDATA[Harmful content has been posted]]></string>
+    <string name="_bx_antispam_et_lasso_moderation_report_body"><![CDATA[{email_header}
+<b>Profile:</b> <a href="{AuthorUrl}">{AuthorNickName}</a><br />
+<b>Page:</b> {Page}<br /><br />
+<bx_if:content_url>
+	<b>Content:</b> <a href="{c_url}">{c_url}</a><br /><br />
+</bx_if:content_url>
+<bx_if:manage_content_url>
+	<b>Manage:</b> <a href="{m_url}">{m_url}</a><br /><br />
+</bx_if:manage_content_url>
 {email_footer}]]></string>
 </resources>

+ 14 - 1
modules/boonex/antispam/install/sql/enable.sql

@@ -90,6 +90,18 @@ INSERT INTO `sys_options`(`category_id`, `name`, `caption`, `value`, `type`, `ex
 (@iCategoryId, 'bx_antispam_toxicity_filter_report', '_bx_antispam_option_toxicity_report', '', 'checkbox', 'on', '', '', 40),
 (@iCategoryId, 'bx_antispam_toxicity_filter_threshold', '_bx_antispam_option_toxicity_filter_threshold', '60', 'digit', '', '', '', 50);
 
+INSERT INTO `sys_options_categories` (`type_id`, `name`, `caption`, `order` )
+VALUES (@iTypeId, 'bx_antispam_lasso_moderation', '_bx_antispam_adm_stg_cpt_category_lasso_moderation', 9);
+SET @iCategoryId = LAST_INSERT_ID();
+
+INSERT INTO `sys_options`(`category_id`, `name`, `caption`, `value`, `type`, `extra`, `check`, `check_error`, `order`) VALUES
+(@iCategoryId, 'bx_antispam_lasso_moderation_enable', '_bx_antispam_option_lasso_moderation_enable', '', 'checkbox', '', '', '', 10),
+(@iCategoryId, 'bx_antispam_lasso_moderation_api_key', '_bx_antispam_option_lasso_moderation_api_key', '', 'digit', '', '', '', 20),
+(@iCategoryId, 'bx_antispam_lasso_moderation_webhook_secret', '_bx_antispam_option_lasso_moderation_webhook_secret', '', 'digit', '', '', '', 30),
+(@iCategoryId, 'bx_antispam_lasso_moderation_webhook_url', '_bx_antispam_option_lasso_moderation_webhook_url', '{site_url}m/antispam/content_checked', 'value', '', '', '', 40),
+(@iCategoryId, 'bx_antispam_lasso_moderation_action', '_bx_antispam_option_lasso_moderation_action', 'none', 'select', 'a:2:{s:6:"module";s:11:"bx_antispam";s:6:"method";s:28:"get_lasso_moderation_actions";}', '', '', 50),
+(@iCategoryId, 'bx_antispam_lasso_moderation_report', '_bx_antispam_option_lasso_moderation_report', '', 'checkbox', 'on', '', '', 60);
+
 -- page: DNSBL list
 
 INSERT INTO `sys_objects_page`(`object`, `uri`, `title_system`, `title`, `module`, `layout_id`, `visible_for_levels`, `visible_for_levels_editable`, `url`, `meta_description`, `meta_keywords`, `meta_robots`, `cache_lifetime`, `cache_editable`, `deletable`, `override_class_name`, `override_class_file`) VALUES 
@@ -235,7 +247,8 @@ INSERT INTO `sys_alerts` (`unit`, `action`, `handler_id`) VALUES
 INSERT INTO `sys_email_templates` (`Module`, `NameSystem`, `Name`, `Subject`, `Body`) VALUES
 ('bx_antispam', '_bx_antispam_spam_report_name', 'bx_antispam_spam_report', '_bx_antispam_spam_report_subject', '_bx_antispam_spam_report_body'),
 ('bx_antispam', '_bx_antispam_toxicity_blocked_report_name', 'bx_antispam_toxicity_blocked_report', '_bx_antispam_toxicity_blocked_report_subject', '_bx_antispam_toxicity_blocked_report_body'),
-('bx_antispam', '_bx_antispam_toxicity_posted_report_name', 'bx_antispam_toxicity_posted_report', '_bx_antispam_toxicity_posted_report_subject', '_bx_antispam_toxicity_posted_report_body');
+('bx_antispam', '_bx_antispam_toxicity_posted_report_name', 'bx_antispam_toxicity_posted_report', '_bx_antispam_toxicity_posted_report_subject', '_bx_antispam_toxicity_posted_report_body'),
+('bx_antispam', '_bx_antispam_et_lasso_moderation_report_name', 'bx_antispam_lasso_moderation_report', '_bx_antispam_et_lasso_moderation_report_subject', '_bx_antispam_et_lasso_moderation_report_body');
 
 -- cron
 

+ 25 - 1
modules/boonex/russian/data/langs/bx_antispam/ru.xml

@@ -12,6 +12,8 @@
     <li><b>Akismet</b> - автоматическая блокировка спам-контента с использованием <a target="_blank" href="http://akismet.com">Сервиса Akismet</a></li>
     <li><b>StopForumSpam</b> - автоматическая блокировка спам-контента с использованием <a target="_blank" href="http://www.stopforumspam.com">Сервиса StopForumSpam</a></li>
     <li><b>Profanity filter</b> - фильтр ненормативной лексики, основанный на заранее определенных списках слов с возможностью их расширения</a></li>
+    <li><b>Toxicity filter</b> - фильтр токсичности, основанный на <a target="_blank" href="https://www.perspectiveapi.com/">Perspective API</a> предоставленном Google</li>
+    <li><b>Harmful filter</b> - фильтр вредоносности, основанный на <a target="_blank" href="https://www.lassomoderation.com/">Lasso Moderation API</a></li>
 </ul>
 ]]></string>
     <string name="_bx_antispam_help_dnsbl"><![CDATA[
@@ -192,7 +194,7 @@ URI DNSBL - это DNSBL, которые перечисляют доменные
 </pre>
 {email_footer}]]></string>
 
-	<string name="_bx_antispam_toxicity_posted_report_name"><![CDATA[Сообщение о размещенном токсичном контенте]]></string>
+    <string name="_bx_antispam_toxicity_posted_report_name"><![CDATA[Сообщение о размещенном токсичном контенте]]></string>
     <string name="_bx_antispam_toxicity_posted_report_subject"><![CDATA[Токсичный контент был добавлен]]></string>
     <string name="_bx_antispam_toxicity_posted_report_body"><![CDATA[{email_header}
 <b>Профиль:</b> <a href="{AuthorUrl}">{AuthorNickName}</a><br />
@@ -203,5 +205,27 @@ URI DNSBL - это DNSBL, которые перечисляют доменные
 <bx_if:manage_content_url>
 	<b>Управлять:</b> <a href="{m_url}">{m_url}</a><br /><br />
 </bx_if:manage_content_url>
+{email_footer}]]></string>
+
+    <string name="_bx_antispam_adm_stg_cpt_category_lasso_moderation"><![CDATA[Lasso Moderation]]></string>
+    <string name="_bx_antispam_option_lasso_moderation_enable"><![CDATA[Включить]]></string>
+    <string name="_bx_antispam_option_lasso_moderation_api_key"><![CDATA[Ключ API]]></string>
+    <string name="_bx_antispam_option_lasso_moderation_webhook_secret"><![CDATA[Секрет для вебхука]]></string>
+    <string name="_bx_antispam_option_lasso_moderation_webhook_url"><![CDATA[Вебхук URL]]></string>
+    <string name="_bx_antispam_option_lasso_moderation_action"><![CDATA[Действие]]></string>
+    <string name="_bx_antispam_option_lasso_moderation_action_none"><![CDATA[Нет]]></string>
+    <string name="_bx_antispam_option_lasso_moderation_action_disapprove"><![CDATA[Скрывать]]></string>
+    <string name="_bx_antispam_option_lasso_moderation_report"><![CDATA[Отправлять администратору уведомление о вредоносном контенте]]></string>
+    <string name="_bx_antispam_et_lasso_moderation_report_name"><![CDATA[Сообщение о размещенном вредоносном контенте]]></string>
+    <string name="_bx_antispam_et_lasso_moderation_report_subject"><![CDATA[Размещен вредоносный контент]]></string>
+    <string name="_bx_antispam_et_lasso_moderation_report_body"><![CDATA[{email_header}
+<b>Профиль:</b> <a href="{AuthorUrl}">{AuthorNickName}</a><br />
+<b>Страница:</b> {Page}<br /><br />
+<bx_if:content_url>
+    <b>Ссылка:</b> <a href="{c_url}">{c_url}</a><br /><br />
+</bx_if:content_url>
+<bx_if:manage_content_url>
+    <b>Управлять:</b> <a href="{m_url}">{m_url}</a><br /><br />
+</bx_if:manage_content_url>
 {email_footer}]]></string>
 </resources>