# Динамические агенты очередей

Периодически возникает необходимость добавлять и удалять сотрудников из очереди. До сих пор это было возможно сделать только через web интерфейс телефонной станции.

В текущей статье я расскажу как реализовать возможность подключиться и отключиться из очереди средствами набора служебного внутреннего номера.

1. Создайте новую очередь с четырехзначным внутренним номером. К примеру **2001**. (см. документацию «[Очереди вызовов](../../manual/telephony/call-queues)»)
2. Опишите новое «**Приложение диалпланов**»

<figure><img src="https://3704471835-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MPK4TuzRBnP7rt8htho-887967055%2Fuploads%2FYL0EQTmwSRkN2h01vdKB%2F6.png?alt=media&#x26;token=2bc96dde-a550-47af-8443-b1081820a847" alt=""><figcaption></figcaption></figure>

3. Назначьте «**Номер для вызова приложения**» - **999XXXXX** первые три цифры можете переопределить своей комбинацией

&#x20;      Тип кода - «**PHP AGI скрипт**»

<figure><img src="https://3704471835-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MPK4TuzRBnP7rt8htho-887967055%2Fuploads%2FoQe33KaXgcujx3EeFt7r%2F7.png?alt=media&#x26;token=a48b5731-fb78-4c87-a63e-7cf7fdb07051" alt=""><figcaption></figcaption></figure>

4. На вкладке «**Программный код**» вставьте следующее содержимое:

```php
<?php

use MikoPBX\Common\Models\CallDetailRecordsTmp;
use MikoPBX\Common\Models\CallQueueMembers;
use MikoPBX\Common\Models\CallQueues;
use MikoPBX\Common\Models\Extensions;
use MikoPBX\Core\Asterisk\AGI;
use MikoPBX\Core\Asterisk\Configs\QueueConf;

require_once 'Globals.php';

$agi = new AGI();
$agi->answer();

$extension = $agi->get_variable("CHANNEL(peername)", true);
if(empty($extension)){
    $extension = $agi->get_variable("CALLERID(num)", true);
}
$q_exten   = substr($agi->request['agi_extension'], 4);
$add_agent = substr($agi->request['agi_extension'], 3, 1);

$agi->noop("$extension $q_exten $add_agent");

$res = Extensions::findFirst("number='{$extension}'");
if(!$res){
    // Ошибка, такого внутреннего номера не существует.
    $agi->hangup();
}
$res = CallQueues::findFirst("extension='{$q_exten}'");
if(!$res){
    // Ошибка, такой очереди не существует.
    $agi->hangup();
}
$a_count = CallQueueMembers::maximum([ "queue='{$res->uniqid}'", 'column' => 'priority'] ) + 1;
$member  = CallQueueMembers::findFirst("queue='{$res->uniqid}' AND extension='{$extension}'");

if($add_agent === '1' && !$member){
    $member = new CallQueueMembers();
    $member->extension  = $extension;
    $member->queue      = $res->uniqid;
    $member->priority   = $a_count;
    $member->save();
    QueueConf::queueReload();
}

if($add_agent == false && $member){
    $member->delete();
    QueueConf::queueReload();
}

$linkedid = $agi->get_variable("CDR(linkedid)", true);
$res = CallDetailRecordsTmp::find("linkedid='{$linkedid}'");
foreach ($res as $data){
    $data->delete();
}
sleep(2);
$agi->hangup();
```

Нажмите "**Сохранить**"

<figure><img src="https://3704471835-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MPK4TuzRBnP7rt8htho-887967055%2Fuploads%2FgZD9hCEbVheG6hSYmyOL%2F8.png?alt=media&#x26;token=6f4b3166-8f48-41aa-96ff-58191da1eef2" alt=""><figcaption></figcaption></figure>

Приложение готово!&#x20;

{% hint style="info" %}
1. Наберите комбинацию 9991**2001** чтобы присоединиться к очереди 2001
2. Наберите комбинацию 9990**2001** чтобы отключиться от очереди 2001
{% endhint %}
