Техподдержка - api коробка



модуль подключить
CModule::IncludeModule('support');
получить тикеты
$by = "ID";
$order = "asc";
$arFilter = ["UF_1C_ORDER"=>false,'DATE_CLOSE_1'=>false,'DATE_CLOSE_2'=>date('d.m.Y H:i:s',time()-3*86400),'!STATUS_ID'=>9];
$isFiltered = null;
$checkRights = "N";
$getUserName = "Y";
$getExtraNames = "Y";
$siteID = false; 
$arParams = ['SELECT'=>['UF_1C_ORDER','UF_TICKET_CRM']];

$rs = CTicket::GetList($by, $order,$arFilter,$isFiltered,$checkRights, $getUserName,$getExtraNames,$siteID,$arParams);

while($arTicket = $rs->Fetch()){
  //
}
получить сообщения тикета
В массиве фильтра очень полезный элемент "IS_MESSAGE" => "Y". В этом случае можно получить список именно сообщений. В противном случае в списке сообщений будет много мусора, например, сообщения об изменении статуса.
$text = "";    
$dbMess = CTicket::GetMessageList("s_id", "asc", array("TICKET_ID" => $arTicket["ID"],"IS_MESSAGE" => "Y"), false, "N");
         
while($mess = $dbMess->Fetch()){       
        $text .= $mess["MESSAGE"]."<br>-------------------------<br>";            
}
обновить тикет
$arFields = array(
    "UF_1C_ORDER" => 1
);   
CTicket::Set($arFields, $MESSAGE_ID, 1, "N",$mid,"N","N");

Обработчики
стадия с ID 9 - не в рамках договора
при переводе в нее автоматом создается ЛИД в отделе продаж с данными тикета
AddEventHandler("support","OnAfterTicketUpdate","MyOnAfterTicketUpdate");
function MyOnAfterTicketUpdate($arTicket){   
   if($arTicket["STATUS_ID"]==9){
      AddMessage2Log($arTicket);      
      $arFields = [];
      $rsUser = CUser::GetByID(intval($arTicket["OWNER_USER_ID"]));
      if(($arUser = $rsUser->Fetch()) && CModule::IncludeModule("crm")){         
         $lead = new CCrmLead;
         $arFields["TITLE"] = "Из тикета №".$arTicket["ID"]." техподдержки";
         $arFields["ASSIGNED_BY_ID"] = 101;  
         $arFields["STATUS_ID"] = "NEW";
         $arFields["UF_CRM_1628420869530"] = $arTicket["ID"]; //свойство в лиде, где хранится номер тикета
         $arFields["UF_CRM_1602060930"] = 5; //подразделение ОП
         if(!empty($arUser["UF_CRM"])){
            $t = explode("_", $arUser["UF_CRM"]);   
            if($t[0] == "CO"){               
               $arFields["COMPANY_ID"] = $t[1];
            }
            elseif($t[0] == "C"){
               $arFields["CONTACT_ID"] = $t[1];
               $arFields["CONTACT_IDS"] = array($t[1]);
            }            
         }         
         $arFields["COMMENTS"] =  "Дата начала договора: ".$arUser["UF_DATE_CLIENT_START"]."<br>";
         $arFields["COMMENTS"] .= "Дата окончания договора: ".$arUser["UF_DATE_CLIENT_END"]."<br>";
         $arFields["COMMENTS"] .= "Ответственный за тикет: ".$arFields["OWNER_SID"];
         $arFields["COMMENTS"] .= "Описание проблемы: <br>";
         $dbMess = CTicket::GetMessageList("s_id", "asc", array("TICKET_ID" => $arTicket["ID"],"IS_MESSAGE" => "Y"), false, "N");
         
         while($mess = $dbMess->Fetch()){
            // AddMessage2Log($mess);
            $arFields["COMMENTS"] .= $mess["MESSAGE"]."<br>-------------------------<br>";            
         }
         $leadId = $lead->Add($arFields);
         if(!empty($arTicket["RESPONSIBLE_USER_ID"])){
            //добавляем сотрудника ТП как наблюдателя, чтобы можно было быстро уточнить
            $arAdd = array(  
               'ENTITY_TYPE_ID' => CCrmOwnerType::Lead, //
               'ENTITY_ID' => $leadId,
               'USER_ID' => $arTicket["RESPONSIBLE_USER_ID"],
               //'SORT' => '',
               'CREATED_TIME' => new Bitrix\Main\Type\DateTime(),
               'LAST_UPDATED_TIME' => new Bitrix\Main\Type\DateTime()
            );
            $oObserver = \Bitrix\Crm\Observer\Entity\ObserverTable::add($arAdd);
         }

         
      }
   }
}
уведомления ответственному за тикет или главному ответственному техподдержки при изменении тикета
AddEventHandler("support", "OnBeforeSendMailToSupport", "MyOnBeforeSendMailToSupportHandler");
function MyOnBeforeSendMailToSupportHandler($arFields, $is_new){
   
    if(CModule::IncludeModule('im')){ 
       
        if($is_new){
           $message = "Новый тикет: ".$arFields["TITLE"]."[".$arFields["ID"]."]\r\n";   
        }
        else{
           $message = "Изменения в тикете: ".$arFields["TITLE"]."[".$arFields["ID"]."]\r\n";
        }
        
        $message .= $arFields["WHAT_CHANGE"]."\r\n";
        $message .= "От кого: ".$arFields["MESSAGE_SOURCE"]." ".$arFields["MESSAGE_AUTHOR_SID"]." ".$arFields["MESSAGE_AUTHOR_TEXT"]."\r\n";
        if($arFields["MESSAGE_BODY"]){
           $message .= $arFields["MESSAGE_HEADER"]."\r\n";
           $message .= $arFields["MESSAGE_BODY"]."\r\n";
           $message .= $arFields["MESSAGE_FOOTER"]."\r\n";   
        }
        
        $message .= "Ссылка:\r\n";
        $message .= "https://b24.alpha-soft.ru/asupport/".$arFields["ID"]."/"."\r\n";


        
      $userSupport = $arFields["RESPONSIBLE_USER_ID"] ?? 15;           
      
       $arFields = array(
         "MESSAGE_TYPE" => IM_MESSAGE_SYSTEM, 
         "TO_USER_ID" => $userSupport,
         "FROM_USER_ID" => 1,
         "MESSAGE" => $message,        

         "NOTIFY_TYPE" => IM_NOTIFY_SYSTEM,  # 1 - confirm, 2 - notify single from, 4 - notify single
         "NOTIFY_MODULE" => "main", # module id sender (ex: xmpp, main, etc)
         "NOTIFY_EVENT" => "manage", # module event id for search (ex, IM_GROUP_INVITE)         
      );
      if($is_new){
         $arFields["NOTIFY_TITLE"] = "Новый тикет №".$arFields["ID"];
      }
      else{
         $arFields["NOTIFY_TITLE"] = "Изменения в тикете №".$arFields["ID"];
      }
      
      CIMMessenger::Add($arFields);
   }
}
Тикеты из модуля в свою БД, чтобы было удобно читать 1С и создавать наряды
UF_1C_ORDER = пользовательское свойство тикета (да-нет), что он выгружен в базу
CModule::IncludeModule('support');

$by = "ID";
$order = "asc";
$arFilter = ["UF_1C_ORDER"=>false,'DATE_CLOSE_1'=>false,'DATE_CLOSE_2'=>date('d.m.Y H:i:s',time()-3*86400),'!STATUS_ID'=>9];
$isFiltered = null;
$checkRights = "N";
$getUserName = "Y";
$getExtraNames = "Y";
$siteID = false; 
$arParams = ['SELECT'=>['UF_1C_ORDER','UF_TICKET_CRM']];

$rs = CTicket::GetList($by, $order,$arFilter,$isFiltered,$checkRights, $getUserName,$getExtraNames,$siteID,$arParams);

global $DB;

while($arTicket = $rs->Fetch()){/*
   $text = ""; 
   $dbMess = CTicket::GetMessageList("s_id", "asc", array("TICKET_ID" => $arTicket["ID"],"IS_MESSAGE" => "Y"), false, "N");         
    while($mess = $dbMess->Fetch()){
        $text .= $mess["MESSAGE"]."<br>-------------------------<br>";            
    }   
    $arFields = [
       "TICKET_ID" => $arTicket["ID"],
       "TITLE" => $arTicket["TITLE"],
       "RESPONSIBLE_ID" => $arTicket["RESPONSIBLE_USER_ID"],
       "CLIENT" => $arTicket["UF_TICKET_CRM"],
       "DATE_CREATE" => $arTicket["DATE_CREATE"],
       "DATE_CLOSE" => $arTicket["DATE_CLOSE"],
       "TEXT" => $text,
       "STATUS_NAME" => $arTicket["STATUS_NAME"]
    ];
    $arInsert = $DB->PrepareInsert("a_tickets_buffer", $arFields);    
    $strSql = "INSERT INTO a_tickets_buffer (".$arInsert[0].") VALUES (".$arInsert[1].")";
    $DB->Query($strSql, false, $err_mess.__LINE__);

   
    if (strlen($strError)<=0){
      $DB->Commit(); //сохранить последние изменения в базе и закрыть транзакцию
      $arFields = array(
               "UF_1C_ORDER" => 1
           );   
      CTicket::Set($arFields, $mesId, $arTicket["ID"], "N",$mid,"N","N"); //помечаем, что тикет выгружен в базу
   }
   else{
      $DB->Rollback(); //откатить изменения  и закрыть транзакцию

   }  
   // echo "<pre>";
   // print_r($arTicket);
   // echo "</pre>";
}
Если блог был полезным, можете угостить меня "чашечкой кофе" :)

Сбер по номеру телефона +7 (953) 585-13-09 Вероника.
Спасибо!