Integrate Salesforce with Telegram

Усім привіт!

У цій статті ми поговоримо про те, як інтегрувати Telegram з Salesforce, використовуючи webhook та public site, а також полегшимо процес спілкування з клієнтом через automation tools та LWC component.

Перш за все необхідно створити власного Telegram-бота. Зробити це можна легко, ввівши “BotFather” в пошукову стрічку в застосунку Telegram.

Далі потрібно виконати такі операції: /start → /newbot → “Input bot name” → “Input bot username (camelCase or snake_case)”.

Готово! У вас з’явиться наступне повідомлення:

У цьому повідомленні ви можете знайти адресу вашого бота та токен для взаємодії з ним.

Оскільки метою нашого застосунку є те, щоб ми могли спілкуватись з клієнтами, необхідно налаштувати нашу організацію в Salesforce. Процес спілкування буде відбуватись наступним чином: клієнт знаходить нашого Telegram бота та починає з ним взаємодіяти через команду /start. Ми повинні отримати ідентифікатор чату, щоб потім мати змогу надсилати повідомлення клієнту.
Для цього нам необхідно використати webhook listener, який може перехоплювати події, які надходять від користувача. Наприклад створити (якщо це новий користувач) або оновити (якщо користувач вже створений) запис об’єкта “Contact”.

Для цього нам потрібно зареєструвати цей webhook за допомогою запиту GET по такому URL - посиланню:

https://api.telegram.org/bot{API_KEY}/setWebhook?url={REST_RESOURCE_URL}

  • {API_KEY} - токен, який ви отримали від BotFather.
  • {REST_RESOURCE_URL} - адреса середовища, де ви хочете використовувати webhook (у нашому прикладі це посилання на public site).

Приклад {REST_RESOURCE_URL}:

https://instance.salesforce.com/services/apexrest/{urlMapping}

При успішному результаті ви отримаєте web - сторінку з таким вмістом:

Тепер перейдемо до нашої Salesforce організації. Спочатку нам необхідно додати Telegram API до Remote Site settings. Необхідно перейти в Setup → Remote Site Settings → select Remote Site Settings → New Remote Site і додати адресу: https://api.telegram.org.

Далі потрібно зберегти наш Telegram_Bot_API_key (токен) у Custom Settings. Для цього заходимо в Setup → Custom Settings → New , вводимо назву та API name. Далі обираємо: Setting type: List та Visibility: Public. Після цього додаємо поле, з типом Text та вписуємо туди токен.

Оскільки наш приклад побудований на взаємодії з клієнтом, нам необхідно кастомізувати об’єкт “Contact”, а саме додати поле Telegram_User_ID__c типу Number (18, 0). Це потрібно для того, аби зберегти ідентифікатор чату з кожним клієнтом.

Далі створимо Apex клас для того, щоб створити нового користувача та відправити йому повідомлення про успішну реєстрацію.

TelegramWebhook.cls

@RestResource(urlMapping = '/telegramWebhook')
global class TelegramWebhook {
    
    @HTTPPOST
    global static void createUser() {
        
        Map<String, Object> dataReceived = (Map<String, Object>) JSON.deserializeUntyped(RestContext.request.requestBody.toString());
        
        Map<String, Object> message = (Map<String, Object>) dataReceived.get('message');
        Map<String, Object> chat = (Map<String, Object>) message.get('chat');
        Map<String, Object> userInfo = (Map<String, Object>) message.get('from');
        
        Integer userId = Integer.valueOf(userInfo.get('id'));
        String reply = '';
        String firstName = '';
        String lastName = '';
        
        List<Contact> contacts = [SELECT id 
                                    FROM Contact 
                                    WHERE Telegram_User_ID__c = :userId];
        
        if(contacts.size() == 0) {
            if(String.isBlank(String.valueOf(userInfo.get('last_name')))) {
                reply = 'Please add your last name in the Telegram settings.';
            } else {
                lastName = String.valueOf(userInfo.get('last_name'));
                firstName = String.valueOf(userInfo.get('first_name'));
                Contact contact = new Contact(FirstName = firstName, LastName = lastName, Telegram_User_ID__c = userId);
                insert contact;
                reply = 'Contact Created! You can now receive updates from Salesforce.\nThanks';
            }
        } else {
            reply = 'You can receive updates from Salesforce.\nThanks';
        }
        
        sendMessage(userId, reply);
    }
    
    @future(callout = true)
    private static void sendMessage(Integer userId, String reply) {
        TelegramUtility.Message message = new TelegramUtility.Message(userId, reply);
        TelegramUtility.sendMessage(message);
    }
}

У цьому класі присутні два методи:

  • createUser() - для створення нового запису для об’єкта Contact;
  • sendMessage() - метод для відправки користувачу повідомлення про реєстрацію або про те, що користувач вже зареєстрований.

Додатковий Apex клас для відправки запиту до Telegram:

TelegramUtility.cls

public class TelegramUtility {
    public static Telegram_Bot_API_key__c BOT_KEY = Telegram_Bot_API_key__c.getValues('Token');

    public static void sendMessage(Message message) {
        Http http = new Http();
        HttpRequest request = new HttpRequest();
        request.setMethod('POST');
        request.setHeader('Content-Type', 'application/json');
        request.setHeader('Accept', 'application/json');
        request.setEndpoint('https://api.telegram.org/bot' + BOT_KEY.Token__c + '/sendMessage');
        String body = JSON.serialize(Message);
        request.setBody(body);
        HttpResponse response = http.send(request);
    }

    public class Message {
        public Integer chat_id;
        public String text;
       
        public Message(Integer chat_id, String text) {
            this.chat_id = chat_id;
            this.text = text;
        }
    }
}

Тепер, коли користувач розпочне роботу з нашим Telegram ботом, йому прийде ось таке сповіщення:

Готово! Ми з’єднали Telegram бота з нашою Salesforce організацією.

Наступним кроком необхідно створити custom Lightning component і додати його на Contact Record Page для того, щоб спростити спілкування з клієнтом.

SendMessageToTelegram.js

import { LightningElement,api } from 'lwc';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
import sendMessage from '@salesforce/apex/SendMessageToTelegramController.sendMessage'

export default class SendMessageToTelegram extends LightningElement {
    @api recordId;

    handleClick(){
        this.sendMessage();
    }

    sendMessage(){
        let textArea = this.template.querySelector('lightning-textarea');

        sendMessage({
            contactId: this.recordId,
            messageBody: textArea.value
        }).then(() => {
            this.showToast(this, 'Message was sent successfully!', 'success', 'Successful operation');
        }).catch(error => {
            this.showToast(this, error.message, 'error', 'Something went wrong...');
        })
    }

    showToast(component, message, type, title){
        component.dispatchEvent(
            new ShowToastEvent(
                {
                    title: title,
                    message: message,
                    variant: type
                }
            )
        );
    }
}

SendMessageToTelegram.html

<template>
    <lightning-card>
        <lightning-record-view-form record-id={recordId} object-api-name="Contact">
            <p class="slds-p-horizontal_small">
                <lightning-textarea required="true" value="" placeholder="Write a message..." label="Send Message To Telegram" maxlength="140" message-when-value-missing="An empty message cannot be sent."></lightning-textarea>
                <lightning-button variant="brand" label="Send Message" title="Brand action" onclick={handleClick}></lightning-button>
            </p>
        </lightning-record-view-form>
    </lightning-card>
</template>

SendMessageToTelegramController.cls

public class SendMessageToTelegramController {

    @AuraEnabled
    public static void sendMessage(String contactId, String messageBody) {
        try {
            List<Contact> contacts = [SELECT id,Telegram_User_ID__c
                                        FROM Contact
                                        WHERE Id = :contactId
                                        AND Telegram_User_ID__c != null];
            if(contacts.size() > 0) {
                TelegramUtility.Message message = new TelegramUtility.Message(Integer.valueOf(contacts[0].Telegram_User_ID__c), messageBody);
                TelegramUtility.sendMessage(message);
            } else {
                throw new TelegramException('Message cannot be sent as the contact is not registered to receive updates.');    
            }
        }catch (Exception e) {
            throw new AuraHandledException(e.getMessage());    
        } 
    }

    public class TelegramException extends Exception {}
}

В результаті отримаємо ось таку компоненту:

Розміщуємо її на Contact Record page. Тепер, якщо ми надішлемо повідомлення, клієнт побачить його у чаті з Telegram ботом:

Також ми можемо використати Automation Tools для побудови автоматизованого процесу надсилання оповіщення про зміну електронної адреси контакту. Для цього використаємо Flow Builder, який буде викликати логіку відправки повідомлення користувачу з Apex класу.

TelegramInvocable.cls

public class TelegramInvocable {

    @InvocableMethod(label='Send Via Telegram' description='Send Message to Contact Via Telegram')
    public static void logData(List<ContactData> data) {
        Map<Id, String> contactMessage = new Map<Id, String>();
        for(ContactData item : data) {
            contactMessage.put(item.contactId, item.message);
        }
        for(Contact contact : [SELECT id,Telegram_User_ID__c
                                FROM Contact
                                WHERE Id in :contactMessage.keySet()
                                AND Telegram_User_ID__c != null]) {
            sendMessage(Integer.valueOf(contact.Telegram_User_ID__c), contactMessage.get(contact.Id));
        }
    }

    @future(callout = true)
    private static void sendMessage(Integer userId, String reply) {
        TelegramUtility.Message message = new TelegramUtility.Message(userId, reply);
        TelegramUtility.sendMessage(message);
    }

    public class ContactData {

        @InvocableVariable(label = 'Contact ID')
        public ID contactId;
        @InvocableVariable(label = 'Message')
        public String message;
    }
}

Після створення Apex класу перейдемо до створення Flow. Для цього зайдіть у розділ Setup → Flows → New Flow. Далі обираємо тип Record-Triggered Flow і налаштовуємо так, як показано на малюнку нижче:

Після цього додаємо ще один елемент, і в розділі Interaction обираємо Action. Налаштовуємо так, як показано на малюнку нижче.

Для змінної “Message” обираємо New Resource → Formula і далі вводимо параметри як на малюнку нижче:

Після цього зберігаємо Flow та активуємо його. Якщо ми спробуємо змінити email у контакту, нам прийде ось таке оповіщення в Telegram:

Як саме працює увесь процес, який ми розглянули у цій статті, можна побачити на діаграмі нижче.

Отже, у цій статті ми розглянули як саме можна поєднати Salesforce з Telegram за допомогою webhook, зробили власну LWC компоненту для відправки повідомлення з організації до месенджера, а також використали Flow Builder для створення автоматичного оповіщення користувача в Telegram при зміні електронного адресу.

8 Likes

Дякую за цікаву практику!

А що робити, якщо це поле не редагується? Як це виправити?

tg

Думаю цей пост допоможе: https://help.salesforce.com/s/articleView?id=000383145&type=1