Simple alert module to Telegram in Drupal 9

Today we will make a simple module for Drupal 9 that will send messages to the Telegram bot about new messages from the webform and order from Basic cart module.

We will have a settings page where we first set the token of our bot and the chat id with it. After that, it will be possible to mark from which forms of the webforms module the messages will be sent. And a separate checkbox for notifications about orders in Basic cart.
Of course, ideally all these messages arrive in the mailbox of the administrator, but sometimes it is faster to look in the Telegram bot than in the mail.

Create folder for our module - dartharth_telegram_alert. Inside create:

dartharth_telegram_alert.info.yml

name: 'Dartharth Telegram Alert'
type: module
description: 'Sends webform results to a specified Telegram bot.'
package: DARTHARTH
core_version_requirement: ^8 || ^9
dependencies:
  - drupal:webform

dartharth_telegram_alert.links.menu.yml

dartharth_telegram_alert.admin_settings:
  title: 'Dartharth Telegram Alert Settings'
  description: 'Configure settings for Dartharth Telegram Alert.'
  parent: system.admin_config_system
  route_name: dartharth_telegram_alert.settings
  weight: 100

dartharth_telegram_alert.module

<?php

use GuzzleHttp\Exception\RequestException;
use Drupal\webform\Entity\WebformSubmission;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Form\FormStateInterface;

/**
 * Implements hook_webform_submission_insert().
 */
function dartharth_telegram_alert_webform_submission_insert(WebformSubmission $submission) {
    $config = \Drupal::config('dartharth_telegram_alert.settings');
    $webforms = $config->get('webforms');
    $webform_id = $submission->getWebform()->id();

    if (!empty($webforms[$webform_id]) && $webforms[$webform_id]) {
        _dartharth_telegram_alert_send_message($submission);
    }
}

/**
 * Implements hook_basic_cart_order_insert().
 */
function dartharth_telegram_alert_basic_cart_order_insert($order) {
    $config = \Drupal::config('dartharth_telegram_alert.settings');
    if ($config->get('notify_orders')) {
        _dartharth_telegram_alert_send_order_message($order);
    }
}


function _dartharth_telegram_alert_send_message(WebformSubmission $submission) {
    $config = \Drupal::config('dartharth_telegram_alert.settings');
    $token = $config->get('telegram_bot_token');
    $chat_id = $config->get('telegram_chat_id');
    $data = $submission->getData();
    $elements = $submission->getWebform()->getElementsDecodedAndFlattened();

    if (empty($token) || empty($chat_id)) {
        \Drupal::logger('dartharth_telegram_alert')->error('Telegram bot token or chat ID is not configured.');
        return;
    }

    $base_url = \Drupal::request()->getSchemeAndHttpHost();

    $message = "New webform message ".$base_url.": \n";

    foreach ($data as $key => $value) {
        $label = isset($elements[$key]['#title']) ? $elements[$key]['#title'] : $key;
        $message .= "$label: $value\n";
    }

    $client = \Drupal::httpClient();
    $url = "https://api.telegram.org/bot{$token}/sendMessage";

    try {
        $response = $client->post($url, [
            'json' => [
                'chat_id' => $chat_id,
                'text' => $message,
            ]
        ]);

        if ($response->getStatusCode() !== 200) {
            \Drupal::logger('dartharth_telegram_alert')->error('Error when sending message to Telegram. Code status: @code', ['@code' => $response->getStatusCode()]);
        }
    } catch (RequestException $e) {
        \Drupal::logger('dartharth_telegram_alert')->error('Error sending request to Telegram: @message', ['@message' => $e->getMessage()]);
    }
}

function _dartharth_telegram_alert_send_order_message($order) {
    error_log(print_r($order, true));

    $config = \Drupal::config('dartharth_telegram_alert.settings');
    $token = $config->get('telegram_bot_token');
    $chat_id = $config->get('telegram_chat_id');
    $client = \Drupal::httpClient();

    $client_name = $order['title'][0]['value'];
    $client_mail = $order['basic_cart_email'][0]['value'];
    $client_phone = $order['basic_cart_phone'][0]['value'];
    $client_comment = $order['basic_cart_message'][0]['value'];

    $base_url = \Drupal::request()->getSchemeAndHttpHost();

    $message = "New basic cart order from ".$base_url.":\n";
    $message .= "Name: " . $client_name . "\n";
    $message .= "E-mail: " . $client_name . "\n";
    $message .= "Phone: " . $client_name . "\n";
    $message .= "Order comment: " . $client_name . "\n";

    try {
        $response = $client->post("https://api.telegram.org/bot{$token}/sendMessage", [
            'json' => [
                'chat_id' => $chat_id,
                'text' => $message,
            ]
        ]);

        if ($response->getStatusCode() !== 200) {
            \Drupal::logger('dartharth_telegram_alert')->error('Error when sending order message to Telegram. Code status: @code', ['@code' => $response->getStatusCode()]);
        }
    } catch (RequestException $e) {
        \Drupal::logger('dartharth_telegram_alert')->error('An error occurred when sending an order request to Telegram: @message', ['@message' => $e->getMessage()]);
    }
}


/**
 * Implements hook_form_FORM_ID_alter() for node-basic-cart-order-form.
 */
/**
 * Implements hook_form_FORM_ID_alter() for node-basic-cart-order-form.
 */
function dartharth_telegram_alert_form_node_basic_cart_order_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
    $current_path = \Drupal::service('path.current')->getPath();
    $form_id_from_element = isset($form['#id']) ? $form['#id'] : '';

    if ($form_id_from_element == 'node-basic-cart-order-form' && $current_path == '/checkout') {
        static $form_alter_executed = FALSE;

        if (!$form_alter_executed) {

            $submit_element = array_filter($form, function($element) {
                return !empty($element['#type']) && $element['#type'] == 'submit';
            });

            if (!empty($submit_element)) {
                $submit_key = key($submit_element);
                $form[$submit_key]['#submit'][] = 'dartharth_telegram_alert_basic_cart_order_submit';
            }

            if (isset($form['actions']['submit']['#submit'])) {
                array_push($form['actions']['submit']['#submit'], 'dartharth_telegram_alert_basic_cart_order_submit');
            } else {
                $form['actions']['submit']['#submit'][] = 'dartharth_telegram_alert_basic_cart_order_submit';
            }

            $form_alter_executed = TRUE;
        }
    }
}


/**
 * Custom submit handler for the basic cart order form.
 */
function dartharth_telegram_alert_basic_cart_order_submit($form, \Drupal\Core\Form\FormStateInterface $form_state) {

    $order_data = $form_state->getValues();

    _dartharth_telegram_alert_send_order_message($order_data);
}

dartharth_telegram_alert.routing.yml

dartharth_telegram_alert.settings:
  path: '/admin/config/system/dartharth_telegram_alert'
  defaults:
    _form: '\Drupal\dartharth_telegram_alert\Form\SettingsForm'
    _title: 'Dartharth Telegram Alert Settings'
  requirements:
    _permission: 'administer site configuration'

In src/Form folder create file setting page - SettingsForm.php

<?php

namespace Drupal\dartharth_telegram_alert\Form;

use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;

/**
 * Class SettingsForm.
 */
class SettingsForm extends ConfigFormBase {

    /**
     * {@inheritdoc}
     */
    protected function getEditableConfigNames() {
        return [
            'dartharth_telegram_alert.settings',
        ];
    }

    /**
     * {@inheritdoc}
     */
    public function getFormId() {
        return 'dartharth_telegram_alert_settings_form';
    }

    /**
     * {@inheritdoc}
     */
    public function buildForm(array $form, FormStateInterface $form_state) {
        $config = $this->config('dartharth_telegram_alert.settings');

        $form['telegram_bot_token'] = [
            '#type' => 'textfield',
            '#title' => $this->t('Telegram Bot Token'),
            '#description' => $this->t('Enter the token for your Telegram bot.'),
            '#default_value' => $config->get('telegram_bot_token'),
            '#required' => TRUE,
        ];

        $form['telegram_chat_id'] = [
            '#type' => 'textfield',
            '#title' => $this->t('Telegram Chat ID'),
            '#description' => $this->t('Enter the chat ID for where the messages should be sent.'),
            '#default_value' => $config->get('telegram_chat_id'),
            '#required' => TRUE,
        ];


        $webform_ids = \Drupal::entityQuery('webform')->execute();
        $webforms = \Drupal\webform\Entity\Webform::loadMultiple($webform_ids);

        $form['webforms'] = [
            '#type' => 'checkboxes',
            '#title' => $this->t('Select Webforms'),
            '#description' => $this->t('Select the webforms that you want to send alerts from.'),
            '#options' => [],
        ];

        foreach ($webforms as $webform) {
            // Check if the webform is not a template and is open.
            if (!$webform->isTemplate() && $webform->isOpen()) {
                $form['webforms']['#options'][$webform->id()] = $webform->label();
                // Set the default value if it was previously selected.
                $form['webforms'][$webform->id()] = [
                    '#default_value' => $config->get('webforms.' . $webform->id()),
                ];
            }
        }

        $form['notify_orders'] = [
            '#type' => 'checkbox',
            '#title' => $this->t('Notify on new orders'),
            '#description' => $this->t('Check this box to enable notifications for new orders modules Basic_cart.'),
            '#default_value' => $config->get('notify_orders'),
        ];

        return parent::buildForm($form, $form_state);
    }

    /**
     * {@inheritdoc}
     */
    public function submitForm(array &$form, FormStateInterface $form_state) {
        $values = $form_state->getValues();
        $config = $this->config('dartharth_telegram_alert.settings');

        $config->set('telegram_bot_token', $values['telegram_bot_token']);
        $config->set('telegram_chat_id', $values['telegram_chat_id']);

        foreach ($values['webforms'] as $webform_id => $enabled) {
            $config->set('webforms.' . $webform_id, $enabled);
        }

        $config->set('notify_orders', $values['notify_orders']);

        $config->save();

        parent::submitForm($form, $form_state);
    }

}

Link to GitHub

Plain text

  • No HTML tags allowed.
  • Lines and paragraphs break automatically.
  • Web page addresses and email addresses turn into links automatically.
The comment language code.