The template of the simplest telegram bot for schoolchildren in grades 7-9 on Powershell

During conversations with a friend, I suddenly found out for myself that children in grades 8-10 are not taught programming at all in their school. Word, Excel and all. No logo, not even Pascal, not even VBA for Excel.

I was very surprised, opened the Internet and climbed to read -
One of the tasks of the profile school is to contribute to the education of a new generation that meets the conditions of the information society in terms of its level of development and lifestyle.
This course will allow to consolidate in practice the knowledge of students on the basic constructions of the Pascal programming language. (from the program of some gymnasium for 2017)

As a result, I decided to spend a couple of hours and sketch out an example “how to create a simple bot for schoolchildren”.

Under the cut, about how to write another simple bot in Powershell and make it work without webhooks, white IPs, dedicated servers, deployable virtual machines in the cloud, and other things - on a regular home PC with regular Windows.

TLDR: Another boring article with grammatical and factual errors, nothing to read, no humor, no pictures.

There is nothing new in the article, almost everything written earlier was already on Habré, for example, in articles Instructions: How to create bots in Telegram и Telegram bot for system administrator.
Moreover, the article is deliberately redundant so as not to refer to educational literature every time. There are no references to gang 4, PowerShell Deep Dives, or, say, The 5 Pillars of the AWS Well-Architected Framework in the text.

Instead of a preface, you can skip

Feel free to skipIn 2006, Microsoft released PowerShell 1.0 for what was then Windows XP, Vista, and 2003 servers. In some ways, it has replaced such things as cmdbat scripts, vb scripts, Windows Script Host and JScript.

Even now, PowerShell can only be considered as the next step after the Logo options, instead of Delphi (or something older), which is probably still used somewhere, despite the presence of cycles, classes, functions, MS GUI calls, integration with Git and so on.

Powershell is used relatively rarely, you can only encounter it in the form of PowerShell Core, VMware vSphere PowerCLI, Azure PowerShell, MS Exchange, Desired State Configuration, PowerShell Web Access and a dozen or so rarely used programs and functions. Perhaps he will get a second wind with the release WSL2, but it is not exactly.

Powershell also has three big pluses:

  1. It is relatively simple, there is a lot of literature and examples about it, and even in Russian, for example, an article about Foreach is from the book PowerShell in depth - about the difference () and {}
  2. It comes with an editor ISE, bundled with Windows. There's even some kind of debugger.
  3. From it are easily called components for building a graphical interface.

0. Training.

We will need:

  • Windows PC (I have Windows 10)
  • At least some kind of Internet access (through NAT for example)
  • For those who have limited access to the telegram - installed and configured freegate in the browser, in some difficult cases, together with Symple DNS Crypt
  • The presence of a working telegram client on the phone
  • Understanding the very basics - what is a variable, array, cycle.

Opened and read articles - Instructions: How to create bots in Telegram и Telegram bot for system administrator

1. Let's create another test bot.

Since everyone already knows this, and it has already happened, you can also skipAs stated in the article above – First of all, a bot for Telegram – it is still an application running on your side making requests to the Telegram Bot API. Moreover, the API is understandable - the bot accesses a specific URL with parameters, and Telegram responds with a JSON object.

Related problems: if in some unknown way you take some code from the JSON object and somehow send it for execution (not on purpose), the code will be executed for you.

The creation process is described in the two articles above, but I repeat: in the telegram, open contacts, look for @botfather, tell him / newbot, create a Botfortest12344321 bot, let's call it Mynext1234bot, and get a message with a unique key like 1234544311:AbcDefNNNNNNNNNNNN

Keep the key and don't give it away!

Then you can configure the bot, for example, prohibit adding it to groups, but this is not necessary in the first steps.

Let's ask BotFather "/mybot" and fix the settings if we don't like something.

Open the contacts again, find @Botfortest12344321 there (beginning the search with @ is mandatory), click "start" and write to the bot "/Glory to the robots". The / sign is required, quotes are not needed.
The bot, of course, will not answer anything.

Let's check that the bot has been created - open it.

api.telegram.org/bot1234544311:AbcDefNNNNNNNNNNNN/getMe
where 1234544311:AbcDefNNNNNNNNNNNN is the previously obtained key,
and get a line like
{"ok":true,"result":{""}}

We have the first secret phrase (token). Now we need to find out the second secret number - the chat ID with the bot. Each chat, group, and so on is individual and has its own number (sometimes with a minus for open groups). In order to find out this number, we need to request in the browser (in fact, it is not necessary at all in the browser, but for a better understanding you can start with it) the address (where 1234544311:NNNNNNNN is your token

https://api.telegram.org/bot1234544311:NNNNNNNNN/getUpdates

and get a response like

{"ok":true,"result":[{"update_id":…,… chat":{"id":123456789

We need exactly chat_id.

Let's check that we can write to the chat manually: call the address from the browser

https://api.telegram.org/botваштокен/sendMessage?chat_id=123456789&text="Life is directed motion"

If you received a message from the bot in the chat - okay, you go to the next step.

Thus (through the browser) you can always check where the problems are - you have when generating a link, or something somewhere is covered up and does not work.

What you need to know before continuing reading

Telegram has several types of group chats (open, closed). For these chats, some of the functions (for example, id) are different, which sometimes causes some problems.

We will assume that it is the end of 2019, and even the hero of our time, the well-known Man-Orchestra (administrator, lawyer, information security officer, programmer and practically MVP) Evgeny V. distinguishes the $i variable from an array, has mastered cycles, you look in the next couple of years will master Chocolatey, and there to Parallel processing with PowerShell и ForEach-Object Parallel will come.

1. We think what our bot will do

I had no ideas, I had to think. I already wrote a bot-notebook. I didn’t want to make a bot “that sends something somewhere”. To connect Azure, you need a credit card, but where does the student get it from? It should be noted that everything is not so bad: the main clouds give some kind of test period for free (but you still need a credit card number - and it will be deducted from it, it seems a dollar. I don’t remember if he returned later.)

Without AI ML, it's not so interesting to make a moron-poetry bot.

I decided to make a bot that will remind me (or not me) of English words in a dictionary.
The dictionary, so as not to mess with the database, will be in a text file and replenished manually.
In this case, the task is to show the basics at work, and not to make at least a partially finished product.

2. Trying what and how for the first time

Create folder C:poshtranslate
First, let's see what kind of powershell we have, run ISE through start-run
powershell ise
or find Powershell ISE in installed programs.
After launch, the usual familiar “some kind of editor” will open, if there is no text field, then you can always click “File - create new”.

Let's see the powershell version - write in the text field:

get-host 

and press F5.

Powershell will offer to save - "The script you are about to run will be saved.", We agree, and save the file from powershell in C: poshtranslate with the name myfirstbotBT100.

After starting, in the lower text box we get a data plate:

Name             : Windows PowerShell ISE Host
Version          : 5.1.(и так далее)

I have 5.1 with something, that's enough. If you have an old Windows 7/8, then it's okay - although PowerShell needs to be updated to version 5 - for example, instructions.

Type Get-Date on the command line below, press Enter, look at the time, go to the root folder with the command
cd
and clear the screen with the cls command (no, you don't need to use rm)

Now let's check what works and how - let's write not even code, but two lines, and try to understand what they do. Let's comment out the line with the get-host symbol # and add a little.

# Пример шаблона бота 
# get-host
<# это пример многострочного комментария #>
$TimeNow = Get-Date
$TimeNow

(Interesting. There are two dozen options in the code design drop-down list on Habré - but powershell is not there. Dos is. Perl is.)

And run the code by pressing F5 or ">" from the GUI.

We get the output:

Saturday, December 8, 2019 21:00:50 PM (или что-то типа)

Now let's deal with these two lines, and some interesting points, so as not to return to this in the future.

Unlike Pascal (and not only), powershell itself tries to determine what type to assign to a variable, more about this is written in the article Educational program on typing in programming languages
Therefore, by setting up the $TimeNow variable and assigning it the value of the current date and time (Get-Date), we do not have to worry too much about what type of data will be there.

True, this ignorance can then hurt, but that's later. Below is an example in the text.
Let's see what we got. Execute (on the command line)

$TimeNow | Get-member

and get a page of incomprehensible text

Example of incomprehensible text number 1

PS C:> $TimeNow | Get-member
   TypeName: System.DateTime
Name                 MemberType     Definition                                                                                                                                       
----                 ----------     ----------                                                                                                                                       
Add                  <b>Method         </b>datetime Add(timespan value)  
..
DisplayHint          NoteProperty   DisplayHintType DisplayHint=DateTime                                                                                                             
Date                 <b>Property       </b>datetime Date {get;}                                                                                                                             
Year                 Property       int Year {get;}   
..                                                                                                                               
DateTime             ScriptProperty System.Object DateTime {get=if ((& { Set-StrictMode -Version 1; $this.DisplayHint }) -ieq  "Date")...                                         

As you can see, a variable of type TypeName: System.DateTime has been created with a bunch of methods (in the sense of what we can do with this variable object) and properties.

Let's call $TimeNow.DayOfYear - get the number of the day in the year.
Let's call $TimeNow.DayOfYear | Get-Member - get TypeName: System.Int32 and a group of methods.
Let's call $TimeNow.ToUniversalTime() - and get the time in UTC

Debugger

Sometimes it happens that you need to execute a program up to a certain line and see the state of the program at that moment. To do this, ISE has a Debug function - toggle break point
Put a breakpoint somewhere in the middle, run these two lines and see what the break looks like.

3. Understanding the interaction with the Telegram bot

Of course, even more literature has been written on interaction with the bot, with all getpush, and so on, but the question of theory can be considered optional.

In our case, we need:

  • Learn to send something to correspondence
  • Learn to get something from correspondence

3.1 Learning to send something to correspondence and receive from it

Some code - part 3

Write-output "This is part 3"
$MyToken = "1234544311:AbcDefNNNNNNNNNNNNN"
$MyChatID = "123456789"
$MyProxy = "http://1.2.3.4:5678" 

$TimeNow = Get-Date
$TimeNow.ToUniversalTime()
$ScriptDir = Split-Path $script:MyInvocation.MyCommand.Path
$BotVersion = "BT102"

$MyText01 = "Life is directed motion - " + $TimeNow

$URL4SEND = "https://api.telegram.org/bot$MyToken/sendMessage?chat_id=$MyChatID&text=$MyText01"

Invoke-WebRequest -Uri $URL4SEND

and in RF at this place we get the error Unable to connect to the remote server.

Or we don’t get it - it depends on the telecom operator and whether the proxy is configured and working
Well - it remains to add a proxy. Please note - using an unencrypted and generally left proxy is extremely dangerous for your health.

The task of finding a working proxy is not very difficult - most of the published http proxies work. It seems to work for me the fifth in a row.

Syntax using proxy:

Invoke-WebRequest -Uri $URL4SEND -Proxy $MyProxy

If you received a message in your chat with the bot, then everything is fine, you can move on. If not, continue debugging.

You can see what your $URL4SEND string turns into and try requesting it in the browser, like this:

$URL4SEND2 = '"'+$URL4SEND+'"'
start chrome $URL4SEND2 

3.2. We have learned to write “something” in the chat, now we will try to read

Let's add 4 more lines and see what's inside through | get-member

$URLGET = "https://api.telegram.org/bot$MyToken/getUpdates"
$MyMessageGet = Invoke-WebRequest -Uri $URLGET -Method Get -Proxy $MyProxy
Write-Host "Get-Member"
$MyMessageGet | Get-Member

The most interesting gives us

Content           Property   string Content {get;}  
ParsedHtml        Property   mshtml.IHTMLDocument2 ParsedHtml {get;}                                    
RawContent        Property   string RawContent {get;set;}

Let's see what's in them:

Write-Host "ParsedHtml"
$MyMessageGet.ParsedHtml # тут интересное
Write-Host "RawContent"
$MyMessageGet.RawContent # и тут интересное, но еще к тому же и читаемое. 
Write-Host "Content"
$MyMessageGet.Content

If everything works for you, you will get a long line like:

{"ok":true,"result":[{"update_id":12345678,
"message":{"message_id":3,"from":{"id"

Fortunately, in the previously published article Telegram bot for the system administrator, this line (yes, according to $MyMessageGet.RawContent | get-member is System.String) has already been dismantled.

4. Process the received (we already know how to send at least something)

As already written here, the most necessary lies in content. Let's look at it more carefully.

First, let's write a couple more phrases to the bot from the web interface or from the phone

/message1
/message2
/message3

and look through the browser at the address that was generated in the $URLGET variable.

We will see something like:

{"ok":true,"result":[{"update_id":NNNNNNN,
"message":{"message_id":10, .. "text":"/message1"
"message":{"message_id":11, .. "text":"/message2 
"message":{"message_id":12, .. "text":"/message3 

What it is? Some complex object from arrays of objects containing a through message identifier, chat identifier, dispatch identifier and a lot of information.

However, we don’t need to analyze “what kind of object this is” - part of the work has already been done for us. Let's see what's inside:

Reading received messages or part 4

Write-Host "This is part 4" <# конечно эта строка нам не нужна в итоговом тексте, но по ней удобно искать. #> 

$Content4Pars01 = ConvertFrom-Json $MyMessageGet.Content
$Content4Pars01 | Get-Member
$Content4Pars01.result
$Content4Pars01.result[0]
$Content4Pars01.result[0] | Get-Member
$Content4Pars01.result[0].update_id
$Content4Pars01.result[0].message
$Content4Pars01.result[0].message.text
$Content4Pars01.result[1].message.text
$Content4Pars01.result[2].message.text

5. What do we do with it now

Save the resulting file under the name myfirstbotBT105 or whatever you like, change the title and comment out all the code already written through

<#start comment 105 end comment 105#>

Now we need to decide where to get the dictionary (well, where - on disk in a file) and how it will look.

Of course, you can fill a huge dictionary right in the text of the script, but this is absolutely not the case.
Therefore, let's see what powershell can work with normally.
Actually, he doesn't care what file to work with, we don't care.
We have a choice: txt (it is possible, but why), csv, xml.
And you can see everyone Let's see everyone.
Create class MyVocabClassExample1 and variable $MyVocabExample1
I note that the class is written without $

some code #5

write-host "This is part 5"
class MyVocabClassExample1 {
    [string]$Original  # слово
    [string]$Transcript
    [string]$Translate
    [string]$Example
    [int]$VocWordID # очень интересный момент. Использование int с его ограничениями может порой приводить к диким последствиям, для примера - недавний случай с SSD HPE. Изначально я не стал добавлять этот элемент, потом все же дописал и закомментировал.
    }

$MyVocabExample1 = [MyVocabClassExample1]::new()
$MyVocabExample1.Original = "Apple"
$MyVocabExample1.Transcript = "[ ˈapəl ]"
$MyVocabExample1.Translate = "Яблоко"
$MyVocabExample1.Example = "An apple is a sweet, edible fruit produced by an apple tree (Malus domestica)"
# $MyVocabExample1.$VocWordID = 1

$MyVocabExample2 = [MyVocabClassExample1]::new()
$MyVocabExample2.Original = "Pear"
$MyVocabExample2.Transcript = "[ pe(ə)r ]"
$MyVocabExample2.Translate = "Груша"
$MyVocabExample2.Example = "The pear (/ˈpɛər/) tree and shrub are a species of genus Pyrus"
# $MyVocabExample1.$VocWordID = 2

Let's try to write it to the files by sample.

Some code #5.1

Write-Host $ScriptDir # надеюсь $ScriptDir вы не закомментировали 
$MyFilenameExample01 = $ScriptDir + "Example01.txt"
$MyFilenameExample02 = $ScriptDir + "Example02.txt"
Write-Host $MyFilenameExample01
Out-File  -FilePath $MyFilenameExample01 -InputObject $MyVocabExample1

Out-File  -FilePath $MyFilenameExample01 -InputObject -Append $MyVocabExample2
notepad $MyFilenameExample01

- and get an error on the line Out-File -FilePath $MyFilenameExample01 -InputObject -Append $MyVocabExample2.

Doesn't want to add, ah-ah what a shame.

$MyVocabExample3AsArray = @($MyVocabExample1,$MyVocabExample2)
Out-File  -FilePath $MyFilenameExample02 -InputObject $MyVocabExample3AsArray
notepad $MyFilenameExample02

Let's see what happened. Beautiful text view - but how to export back from it? Enter some kind of text separators, such as commas?

And as a result, get a "file with separators - commas, comma-separated values ​​(CSV) A STOP WAIT.
#

$MyFilenameExample03 = $ScriptDir + "Example03.csv"
$MyFilenameExample04 = $ScriptDir + "Example04.csv"
Export-Csv  -Path $MyFilenameExample03 -InputObject $MyVocabExample1 
Export-Csv  -Path $MyFilenameExample03 -InputObject $MyVocabExample2 -Append 
Export-Csv  -Path $MyFilenameExample04 -InputObject $MyVocabExample3AsArray 

As you can easily see, MS is not particularly distinguished by logic, for a similar procedure, -FilePath is used in one case, and -Path for the other.

In addition, the Russian language disappeared in the third file, in the fourth file it turned out ... well, something happened. #TYPE System.Object[] 00
# "Count","Length","LongLength","Rank","SyncRoot","IsReadOnly","IsFixedSize","IsSynchronized"
#
Let's rewrite it a bit:

Export-Csv  -Path $MyFilenameExample03 -InputObject $MyVocabExample1 -Encoding Unicode
Export-Csv  -Path $MyFilenameExample03 -InputObject $MyVocabExample2 -Append -Encoding Unicode
notepad $MyFilenameExample03
notepad $MyFilenameExample04

It seems to have helped, but I still don't like the format.

I especially don't like that I can't put lines from an object into a file directly.
By the way, since we started writing to files, can we start logging the launch? We have time as a variable, we can set the file name.

True, there is nothing to write yet, but you can think about how best to do the rotation of the logs.
Let's try xml for now.

some xml

$MyFilenameExample05 = $ScriptDir + "Example05.xml"
$MyFilenameExample06 = $ScriptDir + "Example06.xml"
Export-Clixml  -Path $MyFilenameExample05 -InputObject $MyVocabExample1 
Export-Clixml  -Path $MyFilenameExample05 -InputObject $MyVocabExample2 -Append -Encoding Unicode
Export-Clixml  -Path $MyFilenameExample06 -InputObject $MyVocabExample3AsArray
notepad $MyFilenameExample05
notepad $MyFilenameExample06

Exporting to xml has solid advantages - readability, export of the entire object, and no need to perform uppend.

Try read xml file.

A bit of reading from xml

$MyFilenameExample06 = $ScriptDir + "Example06.xml"
$MyVocabExample4AsArray = Import-Clixml -Path $MyFilenameExample06
# $MyVocabExample4AsArray 
# $MyVocabExample4AsArray[0]
# и немного о совершенно неочевидных нюансах. Powershell время от времени ведет себя не так, как вроде бы как бы стоило бы ожидать бы.
# например у меня эти два вывода отличаются
# Write-Output $MyVocabExample4AsArray 
# write-host $MyVocabExample4AsArray 

Let's return to the task. We wrote a test file, read it, the storage format is understandable, if necessary, you can write a separate small file editor to add and delete lines.

Let me remind you that the task was to make a small training bot.

Format of work: I send the “example” command to the bot, the bot sends me a randomly selected word and transcription, and after 10 seconds it sends a translation and comment. We know how to read commands, and of course, learn how to automatically select and check proxies, and reset message counters to oblivion.

Let's uncomment everything previously commented out as unnecessary, comment out the examples with txt and csv that have become unnecessary, and save the file as version B106

Ah, yes. Let's send something to the bot again.

6. Sending from functions and more

Before processing the reception, you need to make the function of sending "at least something", except for the test message.

Of course, in the example we will have only one send and only one processing, but what if we need to do the same thing several times?

It's easier to write a function. So, we have a variable of the $MyVocabExample4AsArray object type, read from the file, as an array of two whole elements.
Let's go read.

At the same time, we will deal with the clock, we will need it later (in fact, in this example, we won’t need it 🙂

Some code #6.1

Write-Output "This is Part 6"
$Timezone = (Get-TimeZone)
IF($Timezone.SupportsDaylightSavingTime -eq $True){
    $TimeAdjust =  ($Timezone.BaseUtcOffset.TotalSeconds + 3600) } # приведенное время
    ELSE{$TimeAdjust = ($Timezone.BaseUtcOffset.TotalSeconds) 
    }
    
function MyFirstFunction($SomeExampleForFunction1){
$TimeNow = Get-Date
$TimeNow.ToUniversalTime()
# $MyText02 = $TimeNow + " " + $SomeExampleForFunction1 # и вот тут мы получим ошибку
$MyText02 = $SomeExampleForFunction1 + " " + $TimeNow # а тут не получим, кто догадается почему - тот молодец.

$URL4SendFromFunction = "https://api.telegram.org/bot$MyToken/sendMessage?chat_id=$MyChatID&text=$MyText02"
Invoke-WebRequest -Uri $URL4SendFromFunction -Proxy $MyProxy
}

As you can easily see, $MyToken and $MyChatID are called in the function, which were hard-coded earlier.

You don't need to do this, and if $MyToken is one for each bot, then $MyChatID will change depending on the chat.

However, since this is an example, we will ignore it for now.

Since $MyVocabExample4AsArray is not an array, although it is very similar, then you can't just take ask for its length.

Once again we will have to do what cannot be done - to parachute not according to the code - to take and count

Some code #6.2

$MaxRandomExample = 0 
foreach ($Obj in $MyVocabExample4AsArray) {
$MaxRandomExample ++
}
Write-Output $MaxRandomExample
$RandomExample = Get-Random -Minimum 0 -Maximum ($MaxRandomExample)
$TextForExample1 = $MyVocabExample4AsArray[$RandomExample].Original
# MyFirstFunction($TextForExample1)
# или в одну строку
# MyFirstFunction($MyVocabExample4AsArray[Get-Random -Minimum 0 -Maximum ($MaxRandomExample -1)].Example)
# Угадайте сами, какой пример легче читается посторонними людьми.

Random interesting feature. Let's say we want to receive 0 or 1 (we only have two elements in the array). When setting boundaries 0..1 - will we get "1"?
no - we won’t get it, we have specially given an example Example 2: Get a random integer between 0 and 99 Get-Random -Maximum 100
Therefore, for 0..1, we need to set the size to 0..2, while the maximum element number = 1.

7. Processing of incoming messages and the maximum length of the queue

Where did we stop earlier? we have a received variable $MyMessageGet
and the $Content4Pars01 obtained from it, from which we are interested in the elements of the array Content4Pars01.result

$Content4Pars01.result[0].update_id
$Content4Pars01.result[0].message
$Content4Pars01.result[0].message.text

Let's send the bot /message10, /message11, /message12, /word and again /word and /hello.
Let's see what we got:

$Content4Pars01.result[0].message.text
$Content4Pars01.result[2].message.text

Let's iterate over everything received and send a response if the message was / word
the case of construct, what some describe as if-elseif, is called in powershell via switch. At the same time, the -wildcard key is used in the code below, which is completely unnecessary and even harmful.

Some code #7.1

Write-Output "This is part 7"
Foreach ($Result in $Content4Pars01.result) # Да, можно сделать быстрее 
 { 
    switch -wildcard ($Result.message.text) 
            {
            "/word" {MyFirstFunction($TextForExample1)}
            }
}

Let's run the script a couple of times. We will get the same word twice for each execution attempt, especially if we made a mistake in the implementation of random.

But stop. We didn't send /word again, why is the message being processed again?

The queue for sending messages to the bot has a finite length (I think 100 or 200 messages), and it must be cleared manually.

Of course, this is described in the documentation, but it is necessary to read it!

In this case, we need the ?chat_id parameter, and &timeout, &limit, &parse_mode=HTML and &disable_web_page_preview=true are not needed yet.

Documentation telegram api is here
It says in English and white:
Identifier of the first update to be returned. Must be greater by one than the highest among the identifiers of previously received updates. By default, updates starting with the earliest
unconfirmed update are returned. An update is considered confirmed as soon as getUpdates is called with an offset higher than its update_id. The negative offset can be specified to retrieve updates starting from -offset update from the end of the updates queue. All previous updates will be forgotten.

Let's look at:

$Content4Pars01.result[0].update_id
$Content4Pars01.result[1].update_id 
$Content4Pars01.result | select -last 1
($Content4Pars01.result | select -last 1).update_id

Yes, and let's reset - we will rewrite the function a little. We have two options - pass the entire message to the function and process it entirely in the function, or give only the message ID and discard it. For example, the second one looks simpler.

Previously, our "all messages" query string looked like

$URLGET = "https://api.telegram.org/bot$MyToken/getUpdates"

and it will look like

$LastMessageId = ($Content4Pars01.result | select -last 1).update_id
$URLGET1 = "https://api.telegram.org/bot$mytoken/getUpdates?offset=$LastMessageId&limit=100" 
$MyMessageGet = Invoke-WebRequest -Uri $URLGET1 -Method Get -Proxy $MyProxy 

No one forbids you to first receive all messages, process them, and only after successful processing request unconfirmed -> confirmed.

Why does it make sense to call confirmation after all processing is complete? It can fail in the middle of execution, and if for the example of a free chatbot skipping a single message is still nothing special, then if you are processing someone's salary or card transaction, then the result may be worse.

A couple more lines of code

$LastMessageId = ($Content4Pars01.result | select -last 1).update_id  #ошибку в этом месте предполагается исправить самостоятельно. 
$URLGET1 = "https://api.telegram.org/bot$mytoken/getUpdates?offset=$LastMessageId&limit=100" 
Invoke-WebRequest -Uri $URLGET1 -Method Get -Proxy $MyProxy

8. Instead of a conclusion

The main functions - reading messages, flushing the queue, reading from a file and writing to a file are completed and shown.

There are only four things left to do:

  • sending the correct answer to the request in the chat
  • sending a response to ANY chat where a bot has been added
  • executing code in a loop
  • launching the bot from the windows scheduler.

All these tasks are simple and easily implemented by reading the documentation about parameters such as
Set-ExecutionPolicy Unrestricted and -ExecutionPolicy Bypass
cycle of the form

$TimeToSleep = 3 # опрос каждые 3 секунды
$TimeToWork = 10 # минут
$HowManyTimes = $TimeToWork*60/$TimeToSleep # счетчик для цикла
$MainCounter = 0
for ($MainCounter=0; $MainCounter -le $HowManyTimes) {
sleep $TimeToSleep
$MainCounter ++

Thank you all for reading.

Source: habr.com

Add a comment