📜 ⬆️ ⬇️

Bored mail or how to send messages from the site to Telegram via Node.js (Express)

logicSchema

After several emails sent from the site to my email, I realized that it was rather inconvenient, not modern (perhaps), at least not cool. I set out to abandon the use of smtp for the form in favor of api Telegram.

Since my application runs on a node, I thought why not pump the form. The general logic is painfully simple. When the form is sent, a request is made to the api application, where the bot token is stored, data is processed, and then a request is made to the api telegram, which sends a message to the chat.

But let's get everything in order.

To begin with, of course, you need to create a bot that will receive data from the form and send it to you. In fact, it is only an intermediary between you and the api telegram.
')
So, we knock on the parent of all bots, namely to @BotFather and ask him to create one for us (enter / newbot ). Enter the name, nickname and get the bot token . Just we need it. Note that the bot nickname must be < your > _bot or < Your > Bot.

@BotFather

They created it, well, but you have to revive it. We look for it in search by nickname and write / start . Everything, now we can address it through api.

@BotFather

Next, you need to create a group where the bot will throw messages, do not forget to add it to the chat.

createChat


addMembers


We enter / join @ nick_bota in the created chat, because it happens that a record about the bot's invitation to the group is not added to the logs.

Go to the browser and enter in the address bar:

https://api.telegram.org/botXXXXXXXXXXXXXXXXXXXXXXX/getUpdates 

where XXXXXXXXXXXXXXXXXXXXXXXX is a bot token that kindly gave you @BotFather .

If everything went well, we will get something like a sheet of letters, where you need to find the “chat” object : {“id: XXXXXXXXXX ...} . Usually the group chat id starts with a minus.

getUpdates

Ok, we got a bot token and chat id where messages will come.
Now let's get down to the application.

Front


Let's start first from the front.

I used Node to work with the Express wrapper, which in turn can render files of various template engines. Decided to use Pug . It is quite simple to learn, so if you come across it for the first time, it’s hard to get to know it. For example, did not use collectors, so the scripts are connected in the old manner.
The structure of the application is generated using the Express Generator .

Markup form


views / layout.pug:

 doctype html html head title= title link(rel="stylesheet", href="https://cdnjs.cloudflare.com/ajax/libs/sweetalert/1.1.3/sweetalert.min.css") link(rel='stylesheet', href='/stylesheets/style.css') body block content 

views / index.pug:

 extends layout block content .wrapper .wrapper__bg img.wrapper__bg-img(src='/images/bg.jpg' alt='bg') form(action="/telegram", method="post" class="form" id='telegramForm' enctype="application/x-www-form-urlencoded") .form__container .form__blur .form__title .form__title-line h3.form__title-text    .form__title-line .form__inputs input(type="text" name='name' placeholder="" class="form__input" required) input(type="email" name='email' placeholder="Email" class="form__input" required) textarea(name="text" placeholder=" " class="form__input form__message" required) .form__buttons input(type="submit" class="form__submit" value="") .form__clean  script(src="https://cdnjs.cloudflare.com/ajax/libs/sweetalert/1.1.3/sweetalert.min.js") script(src="/javascripts/app.js") 

Do not forget that in Pug the nesting of elements is defined by indents , as in python, so consider this.

We add styles and this is how I got it.

form

The message will be sent without reloading the page, so we hang the handler on the form, collect the data, convert it to json and send it asynchronously to ourselves in api + display the message about the status of the request.

public / javascripts / app.js:

 const formId = 'telegramForm' const form = document.getElementById(formId) //         JSON- function toJSONString(form) { var obj = {} var elements = form.querySelectorAll('input, select, textarea') for (var i = 0; i < elements.length; ++i) { var element = elements[i] var name = element.name var value = element.value if (name) { obj[ name ] = value } } return JSON.stringify(obj) } if (form) { form.addEventListener('submit', event => { event.preventDefault() //    const json = toJSONString(form) //  const formReq = new XMLHttpRequest() formReq.open('POST', '/telegram', true) /////////////////////////////////// /////////////SweetAlert////////// /////////////////////////////////// //   formReq.onload = function(oEvent) { if (formReq.status === 200) { swal({ title: ' !', icon: 'success', timer: 2000 }) document.querySelector('.sa-success').style.display = 'block' document.querySelector('.sa-button-container').style.opacity = '0' } if (formReq.status !== 200) { swal({ title: ' !', icon: 'error', timer: 2000 }) document.querySelector('.sa-error').style.display = 'block' document.querySelector('.sa-button-container').style.opacity = '0' } } //////////////////////////// //////////////////////////// formReq.setRequestHeader('Content-Type', 'application/json') // formReq.send(json) }) } 

Back


On the server side, first you need to catch the request from the client , for this we write in the router:

routes / index.js:

 //        const ctrlTelegram = require('../api/telegramMsg'); router.post('/telegram', ctrlTelegram.sendMsg); 

api / telegramMsg.js:

 module.exports.sendMsg = (req, res) => { //  id    config.json const config = require('../config/config.json'); let http = require('request') let reqBody = req.body //      let fields = [ '<b>Name</b>: ' + reqBody.name, '<b>Email</b>: ' + reqBody.email, reqBody.text ] let msg = '' //         fields.forEach(field => { msg += field + '\n' }); //   ,    msg = encodeURI(msg) //  http.post(`https://api.telegram.org/bot${config.telegram.token}/sendMessage?chat_id=${config.telegram.chat}&parse_mode=html&text=${msg}`, function (error, response, body) { //    console.log('error:', error); console.log('statusCode:', response && response.statusCode); console.log('body:', body); if(response.statusCode===200){ res.status(200).json({status: 'ok', message: ' !'}); } if(response.statusCode!==200){ res.status(400).json({status: 'error', message: ' !'}); } }); } 

To simplify the request process, the ' request ' package is installed.

 npm i request 

config / config.json:

 { "telegram": { "token": "bot_token", "chat": "chat_id" } } 

So what happens here?


In the request, we passed json, so on the server side we can work with data as with a regular object.

For convenience, we push each value of the object into an array.
The API telegram allows you to transfer data via text in the address bar, so we go through the array and create a long string. In order to transfer HTML tags, it is necessary to encode a string into a universal identifier ( encodeURI () method) in order to avoid an error.

Now you can finally send it all to the server telegram. We make a request (press the 'Send' button) and voila, the message has been sent. Do not forget to process the answer , but then you never know what.

After all the manipulations, the answer comes to the front and notifies if all the rules have passed or not.
Due to the fact that for example I did not use the collector, and the library of the pop-up was designed for a modular assembly, I had to do a bit when calling it on the front.

formSent

message

If you look at the application logs on the server, you can see something like the following:

image

Congratulations! Now you know how to send messages from your site to Telegram.

I described only the general concept of this process, so I strongly recommend that you familiarize yourself with the source code of this example .

Source: https://habr.com/ru/post/348332/


All Articles