Automatic sending of messages to VK to the user by status in Bitrix24
Rus
Eng
Автоматическая отправка сообщений в ВК пользователю по статусу в Битрикс24

All English-language materials have been translated fully automatically using the Google service

Statement of the problem: You need to send Vkontakte users automatic messages on behalf of the group if the associated leads in Bitrix24 have a certain status and the specified amount of time has passed. If the user starts chatting, then sending should stop

Lead Association will remain outside the parentheses of this article. It can be done using the appropriate plugins Vkontakte or manually using API

Let's solve the problem using two scripts. The first one will regularly poll Bitrix24 for new users with the required statute. The second will send a message to these users.

We will also have a pane table in which we will store all the results

Structure of HL tables

  Type: string; Name: UF_NAME; Name: Name
Type: string; Name: UF_LASTNAME; Name: Surname
Type: string; Name: UF_VK_ID; Name: VK Id
Type: string; Name: UF_VK_LINK; Name: Vk link
Type: Yes / No; Name: UF_1DAY_SEND; Name: 1D SMS
Type: Yes / No; Name: UF_2DAY_SEND; Name: 2D SMS
Type: Yes / No; Name: UF_5DAY_SEND; Name: 5D SMS
Type: Yes / No; Name: UF_7DAY_SEND; Name: 7D SMS
Type: Yes / No; Name: UF_30DAY_SEND; Name: 30D SMS
Type: Date with time; Name: UF_DATE_STATUS_CHANG; Title: Start date; Default value: current time
Type: Integer; Name: UF_BITRIX24; Title: Lead ID
Type: String; Name: UF_VK_PREFIX; Name: VK prefix
Type: Yes / No; Name: UF_ACTIVE; Title: Activity  

We will also need 4 small helper classes

Listing high.php

use Bitrix\Highloadblock\HighloadBlockTable;

class tHighload {
    public function getHighloadData($id,$dbClass,$arFilter = array()){
        $hlblock   = Bitrix\Highloadblock\HighloadBlockTable::getById( $id )->fetch();
        $entity   = Bitrix\Highloadblock\HighloadBlockTable::compileEntity( $hlblock );
        $entity_data_class = $entity->getDataClass();

        $ar = array(
            "filter" => $arFilter,
            "select" => array('*')
        );

        // Data
        $arData = $entity_data_class::getList($ar);

        $arData = new CDBResult($arData, $dbClass);

        while($arResult = $arData->Fetch()){
            $result[]=$arResult;
        }

        return $result;
    }

    / * Single entry update * /
    public function updateHighloadData($id,$data){
        $hlblock   = Bitrix\Highloadblock\HighloadBlockTable::getById( $id )->fetch();
        $entity   = Bitrix\Highloadblock\HighloadBlockTable::compileEntity( $hlblock );
        $entity_data_class = $entity->getDataClass();

        $elId = $data['ID'];
        unset($data['ID']);

        $result = $entity_data_class::update($elId, $data);

        return $result;
    }

    public function setHighloadData($id, $arProps){
        $hlblock   = Bitrix\Highloadblock\HighloadBlockTable::getById( $id )->fetch();
        $entity   = Bitrix\Highloadblock\HighloadBlockTable::compileEntity( $hlblock );
        $entity_data_class = $entity->getDataClass();

        $otvet = $entity_data_class::add($arProps);

        if ($otvet->isSuccess()) {
            return 'Success';
        } else {
            return implode(', ', $otvet->getErrors());
        }
    }
}

Listing date.php

class tDate {
    public function dateGap($date1, $date2)
    {
        $time = new DateTime($date1);

        $since_time = $time->diff( new DateTime($date2) );

        $A['days'] = $since_time->days;
        $A['hours'] = $since_time->days * 24 + $since_time->h;
        $A['minutes'] = ($since_time->days * 24 * 60) + ($since_time->h * 60) + $since_time->i;

        return $A;
    }
}

Listing of the file bitrix24.php

class bitrix24 {
    public function getLeadList($arSelect, $arFilter){

        $queryUrl = 'https://BITRIX24_SERVER/REST_API_HOOK_PATH/crm.lead.list'; //Список сделок

        $queryData = http_build_query($arFilter);

        $curl = curl_init();
        curl_setopt_array($curl, array(
            CURLOPT_SSL_VERIFYPEER => 0,
            CURLOPT_POST => 1,
            CURLOPT_HEADER => 0,
            CURLOPT_RETURNTRANSFER => 1,
            CURLOPT_URL => $queryUrl,
            CURLOPT_POSTFIELDS => $queryData,
        ));

        $result = curl_exec($curl);
        curl_close($curl);

        return json_decode($result);
    }
}

Listing of the file vk.php

class tVK
{
    const TOKEN = 'TOKEN';

    public function curlGet($url){
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

        $response = curl_exec($ch);
        curl_close($ch);

        return $response;
    }

    public function getUserInfo($user_id){
        $url='https://api.vk.com/method/users.get?user_ids='.$user_id.'&fields=bdate,photo_200,status&access_token='.self::TOKEN.'&v=5.41';

        $response=$this->curlGet($url);

        return $response;
    }

    public function sendMessage($data){
        $params = array(
            'message' => str_replace("#Имя#", $data['USER_NAME'], $data['MESSAGE']),
            'user_id' => $data['USER_ID'],
            'access_token' => self::TOKEN,
            'v' => '5.81'
        );

        $query = http_build_query($params);

        return file_get_contents('https://api.vk.com/method/messages.send?' . $query);
    }

}

Listing of the file getStatusFromBitrix.php

// Don't forget to calculate the correct path to the site folder
$_SERVER["DOCUMENT_ROOT"] = realpath(dirname(__FILE__)."/../..");
$DOCUMENT_ROOT = $_SERVER["DOCUMENT_ROOT"];

define("NO_KEEP_STATISTIC", true);
define("NOT_CHECK_PERMISSIONS",true);
define("BX_CRONTAB", true);
define('BX_NO_ACCELERATOR_RESET', true);

require_once($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_admin_before.php");

use Bitrix\Main\Type\DateTime;

@set_time_limit(0);
@ignore_user_abort(true);

require_once ($_SERVER['DOCUMENT_ROOT'].'/PATH_TO_PROJECT/lib/bitrix24.php');
require_once ($_SERVER['DOCUMENT_ROOT'].'/PATH_TO_PROJECT/libs/high.php');
require_once ($_SERVER['DOCUMENT_ROOT'].'/PATH_TO_PROJECT/libs/vk.php');

$tHigh = new tHighload;
$tVK = new tVK;

// Current time in Moscow
$date = new DateTime();
$hour = date("H");
$data = $common = array();

// We work only during the day
if($hour>21 || $hour<8){die();}

// Recursively iterate over all users matching the request condition
function getLeads($id=0,$arData = array()){
    $bitrix24 = new bitrix24;

    // Select fields
    $arSelect = array('ID', 'TITLE', 'NAME', 'LAST_NAME', 'ASSIGNED_BY_ID', 'UF_CRM_435324332', 'WEB');

    // Filter
    $arFilter = array(
        'order' => array('ID'=>'DESC'),
        'select' => $arSelect,
        "filter" => array(
            'UF_CRM_435324332' => array(2078,2079), // "Send messages" status and "Start chatting" status
            "!WEB" => false, // Link is complete
        )
    );

    if($id!=0){
        $arFilter['filter']['<ID'] = $id;
    }

     // Get a list of users who have the WEB parameter,
     // and whose status (UF_CRM_435324332) is set to "Send messages"
    $result = json_decode(json_encode($bitrix24->getLeadList($arSelect,$arFilter)), True);

    foreach ($result['result'] as $key => $value){
        $arData[] = $value;
    }

    if($result['next']==50){
        $arData = getLeads($result['result'][49]['ID'],$arData);
    }

    return $arData;
}


$common = getLeads();
$bitrix24 = new bitrix24;

foreach ($common as $key => $value){

    // Get the link to the page
    $link = explode('/',$value['WEB'][0]['VALUE']);
    // Get the last index of the array
    $lastKey = key(array_slice($link, -1, 1, true));

    $vkID = 0;
    if($link){
        // Get information about the user
        $getId = json_decode($tVK->getUserInfo($link[$lastKey]));
        $vkID = $getId->response[0]->id;
    }

    $arProps = array(
        'UF_NAME' => $value['NAME'],
        'UF_LASTNAME' => $value['LAST_NAME'],
        'UF_VK_ID' => $vkID,
        'UF_VK_LINK' => $value['WEB'][0]['VALUE'],
        'UF_DATE_STATUS_CHANG' => $date->toString(),
        'UF_BITRIX24' => $value['ID'],
        'UF_VK_PREFIX' => $link[$lastKey]
    );

    if($value['UF_CRM_435324332']=='2078'){// Status "Send messages"
        $arProps['UF_ACTIVE']=1;
    }

    if($value['UF_CRM_435324332']=='2079'){// Status "Started chatting"
        $arProps['UF_ACTIVE']=0;
    }

    $user = $tHigh->getHighloadData(HL_TABLE_ID,'HL_TABLE_NAME', array('UF_BITRIX24' => $value['ID']));

    // If the statuses haven't changed, then we do nothing
    if($arProps['UF_ACTIVE']==$user[0]['UF_ACTIVE']){continue;}

    if($user){
        $arProps['ID'] = $user[0]['ID'];
        $res = $tHigh->updateHighloadData(HL_TABLE_ID, $arProps);
    }else{
        $res = $tHigh->setHighloadData(HL_TABLE_ID, $arProps);
    }

}

Listing of the file checkIfNeedSMS.php

$_SERVER["DOCUMENT_ROOT"] = realpath(dirname(__FILE__)."/../..");
$DOCUMENT_ROOT = $_SERVER["DOCUMENT_ROOT"];

define("NO_KEEP_STATISTIC", true);
define("NOT_CHECK_PERMISSIONS",true);
define("BX_CRONTAB", true);
define('BX_NO_ACCELERATOR_RESET', true);

require_once($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_admin_before.php");

use Bitrix\Main\Type\DateTime;

@set_time_limit(0);
@ignore_user_abort(true);

require_once ($_SERVER['DOCUMENT_ROOT'].'/PATH_TO_PROJECT/libs/high.php');
require_once ($_SERVER['DOCUMENT_ROOT'].'/PATH_TO_PROJECT/libs/vk.php');
require_once ($_SERVER['DOCUMENT_ROOT'].'/PATH_TO_PROJECT/libs/date.php');

$tHigh = new tHighload;
$tVK = new tVK;

$tDate = new tDate;

// Current time in Moscow
$date = date("Y-m-d H:i:s");
$hour = date("H");
$data = array();

// We work only during the day
if($hour>21 || $hour<8){die();}

$ messages = array (
     '1' => 'Hello # Name #. This is test message 1 ',
     '2' => 'This is test message 2',
     '3' => '# Name #, This is test message 3',
     '7' => 'This is test message 4',
     '30' => 'This is test message 5'
);

$users = $tHigh->getHighloadData(HL_TABLE_ID,'HL_TABLE_NAME', array('UF_ACTIVE'=>'1'));

foreach ($users as $key => $u){

    if(!$u['UF_VK_ID']){
        // Get the link to the page
        $link = explode('/',$u['UF_VK_LINK']);
        // Get the last index of the array
        $lastKey = key(array_slice($link, -1, 1, true));

        if($link){
            // Get information about the user
            $getId = json_decode($tVK->getUserInfo($link[$lastKey]));
            $u['UF_VK_ID'] = $getId->response[0]->id;
        }
    }

    $arProps = array(
        'ID' => $u['ID'],
        'UF_NAME' => $u['UF_NAME'],
        'UF_LASTNAME' => $u['UF_LASTNAME'],
        'UF_VK_ID' => $u['UF_VK_ID'],
        'UF_VK_LINK' => $u['UF_VK_LINK'],
        'UF_BITRIX24' => $u['UF_BITRIX24'],
        'UF_VK_PREFIX' => $u['UF_VK_PREFIX']
    );

    // Find out the difference in dates
    $diff = $tDate->dateGap($u['UF_DATE_STATUS_CHANG'],$date);

    $data = array(
        'USER_ID' => $u['UF_VK_ID'],
        'USER_NAME' => $u['UF_NAME'] ? $u['UF_NAME'] : $u['UF_LASTNAME']
    );

    if($u['UF_1DAY_SEND'] == 0 && $diff['hours']>24){// A day later
        // Create parameters for sending messages
        $data['MESSAGE'] = $messages[1];
        $arProps['UF_1DAY_SEND'] = 1;
    }

    if($u['UF_2DAY_SEND'] == 0 && $diff['hours']>48){// Two days later
        // Create parameters for sending messages
        $data['MESSAGE'] = $messages[2];
        $arProps['UF_2DAY_SEND'] = 1;
    }

    if($u['UF_3DAY_SEND'] == 0 && $diff['hours']>120){// After 5 days
        // Create parameters for sending messages
        $data['MESSAGE'] = $messages[3];
        $arProps['UF_3DAY_SEND'] = 1;
    }

    if($u['UF_7DAY_SEND'] == 0 && $diff['hours']>168){// After 7 days
        // Create parameters for sending messages
        $data['MESSAGE'] = $messages[7];
        $arProps['UF_7DAY_SEND'] = 1;
    }

    if($u['UF_30DAY_SEND'] == 0 && $diff['hours']>720){// After 30 days
        // Create parameters for sending messages
        $data['MESSAGE'] = $messages[30];
        $arProps['UF_30DAY_SEND'] = 1;
    }

    if(isset($data['MESSAGE'])){

       // Send a message to VKontakte
        $vkAnswer = json_decode($tVK->sendMessage($data));

        if(!isset($vkAnswer->error)){
            // Update the record in the database
            $tHigh->updateHighloadData(HL_TABLE_ID, $arProps);
        }else{
            $filename = '/tmp/checkIfNeedSMS.log';

            $data = $vkAnswer->error;
            file_put_contents($filename, date('[Y-m-d H:i:s] ') . print_r($data, true) . PHP_EOL, FILE_APPEND | LOCK_EX);
        }

    }
}

Now it remains to configure the launch of the last two files through crowns. Calling crowns:

  crontab -u bitrix -e  

Add records with execution every hour at 10 and 15 minutes

  10 * / 1 * * * php -f /PATH_TO_YOUR_PROJECT/getStatusFromBitrix.php> /tmp/getStatusFromBitrix.log
15 * / 1 * * * php -f /PATH_TO_YOUR_PROJECT/checkIfNeedSMS.php> /tmp/checkIfNeedSMS.log  

Updating Crowns

  systemctl restart crond.service  

Comments

There are no comments yet, you can be the first to leave it

Leave a comment

The site uses a comment pre-moderation system, so your message will be published only after approval by the moderator

You are replying to a user's comment

Send

FEEDBACK

Email me

Are you developing a new service, making improvements to the existing one and want to be better than your competitors? You have come to the right place. I offer you a comprehensive studio-level website development. From me you can order design, layout, programming, development of non-traditional functionality, implementation of communication between CMS, CRM and Data Analitics, as well as everything else related to sites, except for promotion.

Contact, I will always advise on all questions and help you find the most effective solution for your business. I am engaged in the creation of sites in Novosibirsk and in other regions of Russia, I also work with the CIS countries. You will be satisfied with our cooperation

An error occurred while sending, please try again after a while
Message sent successfully

Phones

+7(993) 007-18-96

Email

info@tichiy.ru

Address

Россия, г. Москва

By submitting the form, you automatically confirm that you have read and accept the Privacy Policy site

Contact with me
Send message
By submitting the form, you automatically confirm that you have read and accept Privacy policy of site
Sending successful!
Thank you for contacting :) I will contact you as soon as possible
Sending failed
An error occurred while sending the request. Please wait and try again after a while or call my phone number