• Как отправить сообщение из группы человеку написавшему боту в Телеграм?

    alexk111
    @alexk111
    Автор Ботодрома (автоматизация Telegram, VK и др.)
    Если не программист, то вот готовый поток для Ботодрома, реализующий эту логику.

    1. Импортируйте JSON код из окошка ниже в ваш Ботодром
    2. В настройках конфиг-узла "Мой Telegram Бот" установите токен вашего Telegram бота
    3. В узле "Id супергруппы" установите id вашей супер-группы, куда будут форвардиться сообщения приходящие боту
    4. Нажмите "Развернуть"
    5. Затем нажмите кнопку узла "Настроить хранение данных"
    6. Готово

    602b93d6be8ac408845624.png

    [{"id":"20fc1f49.0ac97","type":"drom-tg-updates","z":"816191d5.cb781","name":"","method":"longpoll","property":"tgUpdate","client":"8ab3ffbd.097a1","x":440,"y":320,"wires":[["581f6191.a03c4"]]},{"id":"581f6191.a03c4","type":"drom-tg-switch-update","z":"816191d5.cb781","name":"Какое событие?","tgUpdate":"tgUpdate","property":"tgUpdateObj","updates":["message"],"outputs":1,"x":770,"y":320,"wires":[["f1b47a6d.c871d8"]]},{"id":"9a5462b0.20203","type":"drom-tg-api-call","z":"816191d5.cb781","name":"Форвард сообщения","data":"apiData","dataType":"msg","method":"forwardMessage","methodType":"str","property":"apiRes","client":"8ab3ffbd.097a1","x":1400,"y":300,"wires":[["d700d74.3b99228"]]},{"id":"1f5ca683.997369","type":"change","z":"816191d5.cb781","name":" Id супергруппы","rules":[{"t":"set","p":"apiData.chat_id","pt":"msg","to":"-123456","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":1390,"y":220,"wires":[["a2ffad93.bc7eb"]]},{"id":"f1b47a6d.c871d8","type":"switch","z":"816191d5.cb781","name":"Сообщение в личку Боту?","property":"tgUpdateObj.from.id","propertyType":"msg","rules":[{"t":"eq","v":"tgUpdateObj.chat.id","vt":"msg"},{"t":"else"}],"checkall":"false","repair":false,"outputs":2,"x":1100,"y":320,"wires":[["1f5ca683.997369"],["7b7d959c.a503ac"]],"outputLabels":["Да","Нет"]},{"id":"63e53df1.7d73a4","type":"drom-tg-api-call","z":"816191d5.cb781","name":"Отправка ответа","data":"apiData","dataType":"msg","method":"sendMessage","methodType":"str","property":"payload","client":"8ab3ffbd.097a1","x":1690,"y":420,"wires":[[]]},{"id":"6c4344ad.334b9c","type":"change","z":"816191d5.cb781","name":"Данные tg api","rules":[{"t":"set","p":"apiData.chat_id","pt":"msg","to":"message_sender[0].value2","tot":"msg"},{"t":"set","p":"apiData.text","pt":"msg","to":"tgUpdateObj.text","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":1680,"y":380,"wires":[["63e53df1.7d73a4"]]},{"id":"a2ffad93.bc7eb","type":"change","z":"816191d5.cb781","name":"Данные tg api","rules":[{"t":"set","p":"apiData.from_chat_id","pt":"msg","to":"tgUpdateObj.from.id","tot":"msg"},{"t":"set","p":"apiData.message_id","pt":"msg","to":"tgUpdateObj.message_id","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":1380,"y":260,"wires":[["9a5462b0.20203"]]},{"id":"7e643f.62614bc","type":"drom-data-relationships-num","z":"816191d5.cb781","storage":"6c999ed1.7d41f","action":"setup-rels","rels":"message_sender","relsType":"storId","value1":"inviter","value1Type":"msg","value2":"invitee","value2Type":"msg","value1Req":"inviter","value1ReqType":"msg","value2Req":"invitee","value2ReqType":"msg","limitRes":"20","limitResType":"num","offsetRes":"0","offsetResType":"num","name":"","property":"payload","x":800,"y":140,"wires":[[]]},{"id":"f553b75.a386048","type":"inject","z":"816191d5.cb781","name":"Настроить хранение данных","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":460,"y":140,"wires":[["7e643f.62614bc"]]},{"id":"d700d74.3b99228","type":"drom-data-relationships-num","z":"816191d5.cb781","storage":"6c999ed1.7d41f","action":"add","rels":"message_sender","relsType":"storId","value1":"inviter","value1Type":"msg","value2":"invitee","value2Type":"msg","value1Req":"apiRes.message_id","value1ReqType":"msg","value2Req":"tgUpdateObj.from.id","value2ReqType":"msg","limitRes":"20","limitResType":"num","offsetRes":"0","offsetResType":"num","name":"Добав в message_sender","property":"payload","x":1710,"y":260,"wires":[[]]},{"id":"7b7d959c.a503ac","type":"switch","z":"816191d5.cb781","name":"Ответ?","property":"tgUpdateObj","propertyType":"msg","rules":[{"t":"hask","v":"reply_to_message","vt":"str"}],"checkall":"false","repair":false,"outputs":1,"x":1160,"y":380,"wires":[["3c811c29.b17d74"]],"outputLabels":["Да"]},{"id":"3c811c29.b17d74","type":"drom-data-relationships-num","z":"816191d5.cb781","storage":"6c999ed1.7d41f","action":"get","rels":"message_sender","relsType":"storId","value1":"tgUpdateObj.reply_to_message.message_id","value1Type":"msg","value2":"","value2Type":"undef","value1Req":"apiRes.message_id","value1ReqType":"msg","value2Req":"tgUpdateObj.from.id","value2ReqType":"msg","limitRes":"","limitResType":"undef","offsetRes":"0","offsetResType":"num","name":"Найти в message_sender","property":"message_sender","x":1410,"y":380,"wires":[["ed52d334.5457c"]]},{"id":"ed52d334.5457c","type":"switch","z":"816191d5.cb781","name":"Есть?","property":"message_sender","propertyType":"msg","rules":[{"t":"nempty"}],"checkall":"false","repair":false,"outputs":1,"x":1470,"y":420,"wires":[["6c4344ad.334b9c"]],"outputLabels":["Да"]},{"id":"35df003b.499d4","type":"comment","z":"816191d5.cb781","name":"Настройка","info":"","x":400,"y":100,"wires":[]},{"id":"8ab3ffbd.097a1","type":"drom-tg-api-config","name":"Мой Telegram Бот"},{"id":"6c999ed1.7d41f","type":"drom-data-config","name":"","dbType":"sqlite","sqliteFile":"my-data.sqlite"}]
    Ответ написан
  • Почему при отправке PUT запроса приходит undefined?

    alexk111
    @alexk111
    Автор Ботодрома (автоматизация Telegram, VK и др.)
    Проблема по всей видимости в том, что middleware асинхронный, а об окончании его выполнения нет оповещения (не вызывается next()).

    Вариант 1. Либо уберите async - он, судя по синхронной работе содержимого, тут не нужен:

    router.put('/', (req, res) => {
        const {id} = req.body;
        console.log(id);
        res.send(id);
    });


    Вариант 2. Еслии все таки планируется какая-то асинхронная работа внутри middleware, тогда используйте next(), чтобы объявить окончание выполнения асинхронного middleware

    router.put('/', async (req, res, next) => {
        const {id} = req.body;
        console.log(id);
        res.send(id);
        next();
    });


    UPD1: В клиентской части при обращении к /api не передается заголовок "content-type", соответствующий передаваемому body.

    Должно быть так:

    fetch('http://localhost:5000/api', {
                method: 'PUT',
                headers: {
                  'Content-Type': 'application/json',
                },
                body: JSON.stringify({
                    "id": "2"
                })
            })


    UPD2: как верно подметил Игорь Махов - console.log в res.send вам вряд ли нужен.
    Ответ написан
  • Не работает выставление счёта qiwi?

    alexk111
    @alexk111
    Автор Ботодрома (автоматизация Telegram, VK и др.)
    Сейчас код в серверной части после обращения к PUT /create-payment вызывает qiwi(), который ничего не возвращает (возвращает undefined), и это парсится в JSON.parse.

    Вы, видимо, хотите отпарсить результат вызова qiwiApi.createBill( billId, fields ). Если это так, тогда исследуйте - как работать с async-функциями и/или использовать Promise.

    Если правильно понял то, что вы хотели сделать, то серверный код будет таким:

    app.put('/create-payment', async function (req,res,next) {
      const data = await qiwi(); // получаем в data результат вызова qiwiApi.createBill
      const p = JSON.parse(data);
      // тут делаем что-то еще, если нужно
      next(); // т.к. функция асинхронная, вызываем next, чтобы объявить о завершении выполнения этого middleware
    });
    
    
    async function qiwi() {
      const billId = qiwiApi.generateId();
    
      const fields = {
          amount: 1.00,
          currency: 'RUB',
          comment: 'test',
          expirationDateTime: '2018-03-02T08:44:07',
          successUrl: 'http://test.ru/'
      };
    
      const data = await qiwiApi.createBill( billId, fields );
      // тут делаем что-то еще, если нужно
      return data; // возвращаем результат вызова qiwiApi.createBill
    }
    Ответ написан
    1 комментарий
  • Как отправить фото с текстом?

    alexk111
    @alexk111
    Автор Ботодрома (автоматизация Telegram, VK и др.)
    В официальной документации есть описание всего процесса загрузки фото: https://vk.com/dev/upload_files?f=4.+%D0%97%D0%B0%...

    Для отправки сообщения используется метод messages.send. Чтобы прикрепить фото к сообщению, нужно после ее загрузки передать данные в параметре attachment.
    Ответ написан
  • Как получить id автора сообщения в беседе с ботом?

    alexk111
    @alexk111
    Автор Ботодрома (автоматизация Telegram, VK и др.)
    Получить id написавшего - через событие "message_new".
    Узнать имя пользователя - используя полученный id, вызвать метод "users.get".
    Ответ написан
    1 комментарий
  • Как получить id только своих сообщений в ВК?

    alexk111
    @alexk111
    Автор Ботодрома (автоматизация Telegram, VK и др.)
    Специального метода для этого нет. Только "messages.getHistory", затем отфильтровать список по id получателя/отправителя.
    Ответ написан
    Комментировать
  • TelegramBotAPI как сделать клавиатуру?

    alexk111
    @alexk111
    Автор Ботодрома (автоматизация Telegram, VK и др.)
    Это делается параметром reply_markup в методе sendMessage. Подробнее тут: https://core.telegram.org/bots/api#sendmessage
    Ответ написан
    4 комментария
  • Не возможна рассылка по пользователям в pytelegrambotapi?

    alexk111
    @alexk111
    Автор Ботодрома (автоматизация Telegram, VK и др.)
    Если python - не обязательное требование, то, возможно, будет быстрее, проще и наглядней сделать такой рассыльщик в Ботодроме, к примеру. Могу расшарить готовый поток рассыльщика в Телеграм, если нужно.
    Ответ написан
    1 комментарий
  • Как получить последние 10 сообщений в группе через Telegram API?

    alexk111
    @alexk111
    Автор Ботодрома (автоматизация Telegram, VK и др.)
    В Telegram API нет такого метода, который бы возвращал историю сообщений.

    Желательно найти способ как внутри бота все-таки учитывать, что в данную группу уже отправлялось такое уведомление. Если никак, тогда остается только ловить апдейты вебхуком или лонг-поллом, и запоминать историю последних 10 сообщений.
    Ответ написан
    1 комментарий
  • Как подсчитать общее количество подписчиков из нескольких групп в ВК?

    alexk111
    @alexk111
    Автор Ботодрома (автоматизация Telegram, VK и др.)
    Если нужно готовое решение, тогда вот поток для Ботодрома. Возвращает страницу на урле /group-stats, которая выводит статсы по каждой группе и сумму во всех группах. В узле "Данные VK API" вставить id групп, для которых выводить данные, в "Мой акк" - свой токен для доступа к VK API и готово.

    [
        {
            "id": "1a53fed2.b20021",
            "type": "change",
            "z": "398791b.201f36e",
            "name": "Данные VK API",
            "rules": [
                {
                    "t": "set",
                    "p": "apiData.group_ids",
                    "pt": "msg",
                    "to": "business,donut",
                    "tot": "str"
                },
                {
                    "t": "set",
                    "p": "apiData.fields",
                    "pt": "msg",
                    "to": "members_count",
                    "tot": "str"
                }
            ],
            "action": "",
            "property": "",
            "from": "",
            "to": "",
            "reg": false,
            "x": 600,
            "y": 380,
            "wires": [
                [
                    "4baee50a.80781c"
                ]
            ]
        },
        {
            "id": "4baee50a.80781c",
            "type": "drom-vk-api-call",
            "z": "398791b.201f36e",
            "name": "Получ инфо о группах",
            "data": "apiData",
            "dataType": "msg",
            "method": "groups.getById",
            "methodType": "str",
            "property": "payload",
            "client": "f6e8a943.b2d388",
            "apiV": "5.126",
            "x": 630,
            "y": 420,
            "wires": [
                [
                    "e8e387ac.a92108"
                ]
            ]
        },
        {
            "id": "bb769f50.7776f",
            "type": "drom-template",
            "z": "398791b.201f36e",
            "name": "HTML",
            "field": "payload",
            "fieldType": "msg",
            "syntax": "handlebars",
            "htmlEscape": true,
            "template": "<html>\n<head></head>\n<body>\n<ul>\n{{#each payload}}\n<li>{{this.name}} - {{this.members_count}}</li>\n{{/each}}\n</ul>\n\n<p>\n  Всего: {{total}}\n</p>\n</body>\n</html>",
            "x": 1090,
            "y": 380,
            "wires": [
                [
                    "4ebdbb53.73c5f4"
                ]
            ]
        },
        {
            "id": "e7643afd.a46498",
            "type": "http in",
            "z": "398791b.201f36e",
            "name": "",
            "url": "/group-stats",
            "method": "get",
            "upload": false,
            "swaggerDoc": "",
            "x": 360,
            "y": 400,
            "wires": [
                [
                    "1a53fed2.b20021"
                ]
            ]
        },
        {
            "id": "4ebdbb53.73c5f4",
            "type": "http response",
            "z": "398791b.201f36e",
            "name": "",
            "statusCode": "",
            "headers": {},
            "x": 1090,
            "y": 420,
            "wires": []
        },
        {
            "id": "e8e387ac.a92108",
            "type": "change",
            "z": "398791b.201f36e",
            "name": "Сумма всех",
            "rules": [
                {
                    "t": "set",
                    "p": "total",
                    "pt": "msg",
                    "to": "$sum(payload.members_count)\t",
                    "tot": "jsonata"
                }
            ],
            "action": "",
            "property": "",
            "from": "",
            "to": "",
            "reg": false,
            "x": 870,
            "y": 400,
            "wires": [
                [
                    "bb769f50.7776f"
                ]
            ]
        },
        {
            "id": "f6e8a943.b2d388",
            "type": "drom-vk-api-config",
            "apiV": "5.126",
            "name": "Мой акк"
        }
    ]
    Ответ написан
    Комментировать
  • Как делаются многоуровневые боты ВКонтакте?

    alexk111
    @alexk111
    Автор Ботодрома (автоматизация Telegram, VK и др.)
    Для этого нужно всем стадиям присвоить, например, цифровой ид. Для каждого пользователя хранить его текущее состояние, включая ид стадии. При получении сообщений от пользователя применять логику в зависимости от текущей стадии, и обновлять ид при переходе на другую стадию.
    Ответ написан
    Комментировать
  • Как отправить рандомную гифку через бота в VK?

    alexk111
    @alexk111
    Автор Ботодрома (автоматизация Telegram, VK и др.)
    Судя по возвращенной ошибке, был вызван метод VK API docs.getUploadServer с токеном группы. Должно вызываться с ключом доступа пользователя. Источник: https://vk.com/dev/docs.getUploadServer
    Ответ написан
  • Телеграм ботов лучше писать на Python, PHP или Node.js?

    alexk111
    @alexk111
    Автор Ботодрома (автоматизация Telegram, VK и др.)
    Делаю ботов в Ботодроме (на Node.js фундаменте)
    Ответ написан
    Комментировать
  • Как сделать правильную проверку делится ли число на другое число?

    alexk111
    @alexk111
    Автор Ботодрома (автоматизация Telegram, VK и др.)
    Во-первых, в `a % 3 && a % 5 == 0` для `a%3` истиной будет если a не делится на 3. Исходя из строки для консоль-лога, вы хотите сделать наоборот, чтобы истина была если делится на 3. Тогда нужно `a%3===0 && a%5===0`.
    Во-вторых, `a%3===0 && a%5===0` должно быть первым условием if, иначе a%5===0 и a%3===0 в отдельности имеют высший приоритет и до проверки соответствия и тому, и тому условию оно никогда не будет доходить.
    В-третьих, последний if - избыточен. Его можно заменить на просто else.

    И parseInt во-второй строке также не нужен. Так как 'Math.random() * 24 + 1' итак возвращает значение типа Number(Число)

    Итого:
    var a= Math.random() * 24 + 1;
    
    if (a % 3 === 0 && a % 5 === 0) {
        console.log(a + " делится на 3 и 5");
    } else if(a % 5 === 0){
        console.log(a + " делится на 5")
    } else if(a % 3 === 0){
        console.log(a + " делится на 3");
    } else {
        console.log(a + " не делится на 3 и 5");
    }
    Ответ написан
    Комментировать
  • Как найти юзернейм пользователя нажавшего на колбек кнопку, если кнопка выведена в группе?

    alexk111
    @alexk111
    Автор Ботодрома (автоматизация Telegram, VK и др.)
    message - это объект оригинального сообщения, в котором висит кнопка. Попробуйте `call.from.id`.

    Upd: `call.from.id` - это ид пользователя. Для username - `call.from.username`
    Ответ написан
  • Какой вариант экспорта компонентов более оптимальный?

    alexk111
    @alexk111
    Автор Ботодрома (автоматизация Telegram, VK и др.)
    Этот подход рекомендован в официальным гайде реакта как удобный способ обращения к компонентам, когда один модуль экспортирует множество компонентов.
    Ответ написан
    Комментировать
  • Как исправить ошибку в pre-commit?

    alexk111
    @alexk111
    Автор Ботодрома (автоматизация Telegram, VK и др.)
    Судя по "JavaScript heap out of memory" имеет место проблема нехватки памяти. Если ситуация с неконтроллируемым пожиранием всей памяти каким-то процессом исключена, тогда должно помочь увеличение размера выделяемой для Node.js памяти через установку такой переменной среды:

    NODE_OPTIONS=--max_old_space_size=8192

    По умолчанию Node.js выделяется 4гб памяти. Установка значения 8192 увеличит до 8гб.
    Ответ написан
  • Как очистить историю канала с помощью телеграм бота?

    alexk111
    @alexk111
    Автор Ботодрома (автоматизация Telegram, VK и др.)
    Готовый код не выдам, но алгоритм будет следующий:

    - при добавлении сообщения методом `sendMessage` - запоминаем его `message_id`
    - по таймеру удаляем сообщения методом `deleteMessage` для каждого `message_id`
    Ответ написан
    Комментировать
  • Как правильно оформить вычисляемые свойства с TS, чтобы линтер не ругался?

    alexk111
    @alexk111
    Автор Ботодрома (автоматизация Telegram, VK и др.)
    Задайте явное определение "this" для геттера/сеттера. Это делается первым "this" параметром сигнатуры функции. Параметр в данном случае фэйковый, то есть используется только для определения типа "this". Например:

    get(this: {text: string}): string {
       return this.text;
    },
    set(this: {someMethod: (value: string) => void}, value: string) {
       this.someMethod(value);
    }
    Ответ написан
    Комментировать
  • Есть телеграм бот и 2 страницы как сделать так чтобы я мог управлять куда переадресуется клиент с помощью кнопки в боте тг?

    alexk111
    @alexk111
    Автор Ботодрома (автоматизация Telegram, VK и др.)
    В объекте сообщения нужно передать в свойстве "reply_markup" объект типа InlineKeyboardMarkup, например (JS):
    {
      "inline_keyboard": [{
        "text": "Кнопка 1",
        "url: "https://website1.com/"
      }, {
        "text": "Кнопка 2",
        "url: "https://website2.com/"
      }]
    }
    Ответ написан