Predložak za jednostavan telegram bot za školarce od 7-9 razreda koji koriste Powershell

Tijekom razgovora s prijateljem odjednom sam saznao da se djeca od 8-10 razreda u njihovoj školi uopće ne uče programiranju. Word, Excel i sve. Nema logotipa, čak ni Pascal, čak ni VBA za Excel.

Bio sam jako iznenađen, otvorio sam internet i počeo čitati -
Jedna od zadaća specijalizirane škole je promicanje obrazovanja nove generacije koja svojim stupnjem razvoja i životnim stilom odgovara uvjetima informacijskog društva.
Ovaj kolegij omogućit će studentima da u praksi učvrste svoje znanje o osnovnim konstruktima programskog jezika Pascal. (iz programa neke gimnazije za 2017. godinu)

Na kraju sam odlučio potrošiti nekoliko sati i skicirati primjer "kako napraviti jednostavnog bota za školarce".

Ispod presjeka je kako napisati još jednog jednostavnog bota u Powershellu i natjerati ga da radi bez webhooka, bijelih IP-ova, namjenskih poslužitelja, postavljenih virtualnih strojeva u oblaku i tako dalje - na običnom kućnom računalu s običnim Windowsima.

TLDR: Još jedan dosadan članak s gramatičkim i činjeničnim pogreškama, ništa za čitanje, bez humora, bez slika.

U članku nema ništa novo, gotovo sve što je prije napisano već je bilo na Habréu, primjerice u člancima Upute: Kako napraviti botove u Telegramu и Telegram bot za administratora sustava.
Štoviše, članak je namjerno suvišan kako se ne bi svaki put pozivao na obrazovnu literaturu. U tekstu nema referenci na Gang 4, PowerShell Deep Dives ili, recimo, The 5 Pillars of the AWS Well-Architected Framework.

Umjesto predgovora, možete preskočiti

Slobodno preskočiteGodine 2006. Microsoft je izdao PowerShell 1.0 za tadašnje Windows XP, Vista i Server 2003. Na neki je način zamijenio stvari kao što su cmdbat skripte, vb skripte, Windows Script Host i JScript.

Čak i sada, PowerShell se može smatrati samo sljedećim korakom nakon Logo opcija, umjesto vjerojatno još uvijek korištenog Delphija (ili nečeg starijeg), unatoč prisutnosti petlji, klasa, funkcija, MS GUI poziva, Git integracija i tako dalje.

Powershell se koristi relativno rijetko; možete ga sresti samo u obliku PowerShell Core, VMware vSphere PowerCLI, Azure PowerShell, MS Exchange, Desired State Configuration, PowerShell web pristup i desetak programa i funkcija koje se rijetko koriste. Možda će s izdanjem dobiti drugi vjetar WSL2, ali nije baš.

Powershell također ima tri velike prednosti:

  1. Relativno je jednostavan, ima puno literature i primjera o tome, pa čak i na ruskom, na primjer, članak o Foreachu - iz knjige PowerShell u dubini - o razlici () i {}
  2. Ide s urednikom ISE, uključen u sustav Windows. Postoji čak i neka vrsta programa za uklanjanje pogrešaka.
  3. Lako je nazvati s njega komponente za izgradnju grafičkog sučelja.

0. Priprema.

Trebat će nam:

  • Windows PC (imam Windows 10)
  • Bar nekakav pristup internetu (preko NAT-a npr.)
  • Za one koji imaju ograničen pristup telegramu - instaliran i konfiguriran freegate u pregledniku, u nekim teškim slučajevima, zajedno sa Simple DNS Crypt
  • Imati radni telegram klijent na svom telefonu
  • Razumijevanje samih osnova - što je varijabla, niz, petlja.

Otvarao i čitao članke - Upute: Kako napraviti botove u Telegramu и Telegram bot za administratora sustava

1. Kreirajmo još jednog testnog bota.

Budući da ovo već svi znaju, i već se dogodilo, možete i preskočitiKao što je navedeno u gornjem članku - Prije svega, bot za Telegram - to je još uvijek aplikacija koja radi na vašoj strani i šalje zahtjeve Telegram Bot API-ju. Štoviše, API je jasan – bot pristupa određenom URL-u s parametrima, a Telegram odgovara JSON objektom.

Povezani problemi: ako na neki nepoznat način uzmete neki kod iz JSON objekta i nekako ga pošaljete na izvršenje (ne namjerno), kod će se izvršiti umjesto vas.

Proces stvaranja je opisan u dva gornja članka, ali ponavljam: u telegramu otvaramo kontakte, tražimo @botfather, kažemo mu /newbot, kreiramo bota Botfortest12344321, zovemo ga Mynext1234bot i primamo poruku s jedinstvenim ključem obrazac 1234544311:AbcDefNNNNNNNNNNNNNN

Čuvajte ključ i ne dajte ga!

Zatim možete konfigurirati bot, na primjer, zabraniti njegovo dodavanje u grupe, ali u prvim koracima to nije potrebno.

Zamolimo BotFather za “/mybot” i prilagodimo postavke ako nam se nešto ne sviđa.

Otvorimo ponovno kontakte, tamo pronađimo @Botfortest12344321 (obavezno započeti pretragu sa @), kliknemo “start” i napišemo botu “/Slava robotima.” Znak / je obavezan, navodnici nisu potrebni.
Bot, naravno, neće ništa odgovoriti.

Provjerimo je li bot kreiran i otvorimo ga.

api.telegram.org/bot1234544311:AbcDefNNNNNNNNNNNNNN/getMe
gdje je 1234544311:AbcDefNNNNNNNNNNNNNN prethodno primljeni ključ,
i dobiti liniju poput
{"ok":true,"result":{""}}

Imamo prvu tajnu frazu (token). Sada moramo saznati drugi tajni broj - ID chata s botom. Svaki chat, grupa itd. je individualan i ima svoj broj (ponekad s minusom - za otvorene grupe). Da bismo saznali ovaj broj, moramo zatražiti u pregledniku (zapravo, to uopće nije potrebno u pregledniku, ali za bolje razumijevanje možete početi s njim) adresu (gdje je 1234544311:NNNNNNNNNN vaš token

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

i dobiti odgovor poput

{"ok":true,"result":[{"update_id":...,... razgovor":{"iskaznica":123456789

Trebamo chat_id.

Provjerimo možemo li ručno pisati u chat: nazovite adresu iz preglednika

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

Ako primite poruku od bota u svom chatu, u redu, prijeđite na sljedeću fazu.

Na ovaj način (putem preglednika) uvijek možete provjeriti ima li problema s generiranjem linkova ili se nešto negdje krije i ne radi.

Što trebate znati prije nastavka čitanja

Telegram ima nekoliko vrsta grupnih razgovora (otvoreni, zatvoreni). Kod ovih chatova neke od funkcija (na primjer, id) su drugačije, što ponekad uzrokuje probleme.

Pretpostavimo da je kraj 2019., pa čak i heroj našeg vremena, dobro poznati Čovjek-orkestar (administrator, odvjetnik, stručnjak za informacijsku sigurnost, programer i praktički MVP) Evgeniy V. razlikuje varijablu $i od niza, je svladao petlje, gledaj u sljedećih par godina će svladati Chocolatey, a onda Paralelna obrada s PowerShell-om и ForEach-Object Parallel doći će.

1. Razmišljamo o tome što će naš bot učiniti

Nisam imao nikakvih ideja, morao sam razmisliti. Već sam napisao bot-bilježnicu. Nisam htio napraviti bota "koji nekamo nešto šalje". Za spajanje na Azure potrebna vam je kreditna kartica, ali odakle je studentu? Treba napomenuti da sve nije tako loše: glavni oblaci daju neku vrstu testnog razdoblja besplatno (ali još uvijek trebate broj kreditne kartice - i čini se da će dolar biti terećen s nje. Ne sjećam se je li vraćeno je kasnije.)

Bez AI ML-a nije tako zanimljivo napraviti bot-jadnog-pjesnika-tkalca.

Odlučio sam napraviti bota koji će me podsjećati (ili ne) na engleske riječi iz rječnika.
Kako bi se izbjeglo petljanje s bazom podataka, rječnik će biti pohranjen u tekstualnu datoteku i ažuriran ručno.
U ovom slučaju zadatak je pokazati osnove rada, a ne napraviti barem djelomično gotov proizvod.

2. Prvi put probati što i kako

Kreirajmo mapu C:poshtranslate
Prvo, da vidimo kakav powershell imamo, pokrenimo ISE preko start-run
powershell ise
ili pronađite Powershell ISE u instaliranim programima.
Nakon pokretanja otvorit će se uobičajeni poznati "neka vrsta uređivača", ako nema tekstualnog polja, uvijek možete kliknuti "Datoteka - stvoriti novu".

Pogledajmo verziju powershell-a - napišite u tekstualno polje:

get-host 

i pritisnite F5.

Powershell će ponuditi spremanje - “Skripta koju namjeravate pokrenuti bit će spremljena.”, slažemo se i spremimo datoteku iz powershell-a s nazivom u C: poshtranslate myfirstbotBT100.

Nakon pokretanja, u donjem tekstualnom prozoru dobivamo podatkovnu tablicu:

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

Imam 5.1 nešto, dosta je. Ako imate stari Windows 7/8 onda ništa strašno - iako će PowerShell trebati ažurirati na verziju 5 - npr. instrukcije.

Upišite Get-Date u naredbeni redak ispod, pritisnite Enter, pogledajte vrijeme, idite u korijensku mapu s naredbom
cd
i očistite zaslon naredbom cls (ne, ne morate koristiti rm)

Sada provjerimo što radi i kako - nemojmo napisati čak ni kod, već dva retka, i pokušajmo razumjeti što rade. Idemo komentirati redak s get-host sa simbolom # i dodati malo.

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

(Zanimljivo je da na padajućem popisu za formatiranje koda na Habréu postoji dvadesetak opcija - ali Powershell nije tu. Dos je tu. Perl je tu.)

I pokrenimo kod pritiskom na F5 ili ">" iz GUI-ja.

Dobivamo sljedeći izlaz:

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

Sada pogledajmo ova dva retka i neke zanimljive točke kako se tome ne bismo vraćali u budućnosti.

Za razliku od Pascala (i ne samo), PowerShell sam pokušava odrediti koji tip dodijeliti varijabli, više detalja o tome napisano je u članku Edukacijski program o tipkanju u programskim jezicima
Stoga, stvaranjem varijable $TimeNow i dodjeljivanjem vrijednosti trenutnog datuma i vremena (Get-Date), ne moramo se previše brinuti o tome kakav će tip podataka biti tamo.

Istina, ovo neznanje može boljeti kasnije, ali to je za kasnije. Ispod u tekstu bit će primjer.
Da vidimo što imamo. Izvršimo (na naredbenom retku)

$TimeNow | Get-member

i dobiti stranicu nerazumljivog teksta

Primjer nerazumljivog teksta broj 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")...                                         

Kao što vidite, stvorena je varijabla tipa TypeName: System.DateTime s hrpom metoda (u smislu onoga što možemo učiniti s ovim objektom varijable) i svojstava.

Nazovimo $TimeNow.DayOfYear — dobivamo broj dana u godini.
Nazovimo $TimeNow.DayOfYear | Get-Member - dobivamo TypeName: System.Int32 i skupina metoda.
Nazovimo $TimeNow.ToUniversalTime() - i dobiti vrijeme u UTC

Program za ispravljanje pogrešaka

Ponekad se dogodi da je potrebno izvršiti program do određene linije i vidjeti stanje programa u tom trenutku. U tu svrhu, ISE ima Debug funkciju - prebacivanje točke prekida
Postavite prijelomnu točku negdje u sredini, pokrenite ove dvije linije i pogledajte kako prijelom izgleda.

3. Razumijevanje interakcije s Telegram botom

Naravno, još je više literature napisano o interakciji s botom, sa svim getpushom i tako dalje, ali pitanje teorije može se razmatrati opcionalno.

U našem slučaju potrebno je:

  • Naučite poslati nešto u korespondenciji
  • Naučite dobiti nešto od dopisivanja

3.1 Naučiti poslati nešto u korespondenciji i primiti od toga

Mali kod - 3. dio

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

a u Ruskoj Federaciji u ovom trenutku dobivamo pogrešku Nije moguće povezati se s udaljenim poslužiteljem.

Ili ga ne primamo - ovisi o telekom operateru i je li proxy konfiguriran i radi
Pa, sve što ostaje je dodati proxy. Imajte na umu - korištenje nekriptiranog i općenito lažnog proxyja iznimno je opasno za vaše zdravlje.

Zadatak pronalaženja proxyja koji radi nije težak - većina objavljenih http proxyja radi. Mislim da mi je peti upalio.

Sintaksa koja koristi proxy:

Invoke-WebRequest -Uri $URL4SEND -Proxy $MyProxy

Ako primite poruku u chatu s botom, onda je sve u redu, možete nastaviti. Ako nije, nastavite s otklanjanjem pogrešaka.

Možete vidjeti u što se pretvara vaš niz $URL4SEND i pokušati ga zatražiti u pregledniku, ovako:

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

3.2. Naučili smo kako napisati "nešto" u chatu, pokušajmo sada to pročitati

Dodajmo još 4 retka i vidimo što je unutra kroz | dobiti-član

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

Ono najzanimljivije nam je pruženo

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

Pogledajmo što je u njima:

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

Ako sve radi za vas, dobit ćete dugačak red poput:

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

Srećom, u prethodno objavljenom članku Telegram bot za administratora sustava ovaj redak (da, prema $MyMessageGet.RawContent | get-member je System.String), već je rastavljen.

4. Obradite ono što dobijete (mi već znamo kako nešto poslati)

Kao što je već napisano ovdje, najpotrebnije stvari leže u sadržaju. Pogledajmo ga pobliže.

Prvo ćemo napisati još nekoliko fraza botu s web sučelja ili s telefona

/message1
/message2
/message3

i kroz preglednik pogledajte adresu koja je formirana u varijabli $URLGET.

Vidjet ćemo nešto poput:

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

Što je? Neki složeni objekt iz niza objekata koji sadrži identifikator poruke s kraja na kraj, identifikator chata, identifikator slanja i puno drugih informacija.

Međutim, ne moramo shvatiti "kakav je to objekt" - dio posla je već obavljen za nas. Pogledajmo što je unutra:

Čitanje primljenih poruka ili dio 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. Što sada trebamo učiniti u vezi s tim?

Spremimo dobivenu datoteku pod imenom myfirstbotBT105 ili kako vam se najviše sviđa, promijenite naslov i komentirajte sav već napisani kod putem

<#start comment 105 end comment 105#>

Sada moramo odlučiti gdje ćemo nabaviti rječnik (dobro, gdje - na disku u datoteci) i kako će izgledati.

Naravno, možete napisati ogroman rječnik u samom tekstu scenarija, ali to je potpuno nebitno.
Pa da vidimo s čime powershell može normalno raditi.
Općenito, nije mu važno s kojom će datotekom raditi, nama je svejedno.
Imamo izbor: txt (možete, ali zašto), csv, xml.
Možemo li gledati sve? Hajdemo vidjeti sve.
Kreirajmo klasu MyVocabClassExample1 i varijablu $MyVocabExample1
Napominjem da je klasa napisana bez $

neki kod #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

Pokušajmo ovo zapisati u datoteke pomoću uzorak.

Neki kod #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

- i dobivamo pogrešku na liniji Out-File -FilePath $MyFilenameExample01 -InputObject -Append $MyVocabExample2.

Ne želi dodati, ah-ah, kakva šteta.

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

Da vidimo što će se dogoditi. Sjajan prikaz teksta - ali kako ga izvesti natrag? Trebam li uvesti neku vrstu razdjelnika teksta, poput zareza?

I na kraju dobijete "vrijednosti odvojene zarezom (CSV) datoteku A PRESTANI ČEKAJ.
#

$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 

Kao što je lako vidjeti, MS se ne ističe posebno svojom logikom; za sličan postupak, u jednom slučaju koristi se -FilePath, u drugom -Path.

Osim toga, u trećoj datoteci nestao je ruski jezik, u četvrtoj datoteci se pokazalo... pa, nešto se dogodilo. #TYPE System.Object[] 00
# “Count”,”Length”,”LongLength”,”Rank”,”SyncRoot”,”IsReadOnly”,”IsFixedSize”,”IsSynchronized”
#
Prepišimo malo:

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

Čini se da je pomoglo, ali još uvijek mi se ne sviđa format.

Posebno mi se ne sviđa što ne mogu staviti linije iz objekta izravno u datoteku.
Usput, budući da smo počeli pisati u datoteke, možemo li početi voditi dnevnik pokretanja? Imamo vrijeme kao varijablu, možemo postaviti naziv datoteke.

Istina, još se nema što napisati, ali možete razmisliti kako najbolje rotirati trupce.
Pokušajmo za sada s xml-om.

Neki 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

Izvoz u xml ima mnoge prednosti - čitljivost, izvoz cijelog objekta i nema potrebe za nadogradnjom.

Pokušajmo čitanje xml datoteke.

Malo čitanja iz xml-a

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

Vratimo se zadatku. Napisali smo testnu datoteku, pročitajte je, format pohrane je jasan, ako je potrebno, možete napisati zasebni uređivač malih datoteka za dodavanje i brisanje redaka.

Podsjećam da je zadatak bio napraviti malog trening bota.

Format rada: šaljem botu naredbu “example”, bot mi šalje nasumično odabranu riječ i transkripciju, a nakon 10 sekundi šalje mi prijevod i komentar. Znamo čitati naredbe, također bismo htjeli naučiti kako automatski birati i provjeravati proxyje, te vraćati brojače poruka u zaborav.

Odkomentirajmo sve što je prethodno komentirano kao nepotrebno, komentirajmo sada nepotrebne primjere s txt i csv i spremimo datoteku kao verziju B106

O da. Pošaljimo opet nešto botu.

6. Otprema s funkcija i drugo

Prije obrade prijema morate kreirati funkciju za slanje "bar nečega" osim testne poruke.

Naravno, u primjeru ćemo imati samo jedno slanje i samo jednu obradu, ali što ako istu stvar trebamo učiniti nekoliko puta?

Lakše je napisati funkciju. Dakle, imamo varijablu tipa object $MyVocabExample4AsArray, pročitanu iz datoteke, u obliku niza od čak dva elementa.
Idemo čitati.

U isto vrijeme ćemo se pozabaviti satom; trebat će nam kasnije (zapravo, u ovom primjeru nam neće trebati :)

Neki kod #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
}

Kao što možete lako vidjeti, funkcija poziva $MyToken i $MyChatID, koji su ranije bili tvrdo kodirani.

Nema potrebe to činiti, a ako je $MyToken jedan za svakog bota, onda će se $MyChatID promijeniti ovisno o chatu.

Međutim, budući da je ovo primjer, za sada ćemo ga zanemariti.

Budući da $MyVocabExample4AsArray nije niz, iako mu je vrlo sličan, tada ne možeš samo uzeti zatražite njegovu duljinu.

Opet ćemo morati učiniti nešto što se ne može - skočiti padobranom ne po kodeksu - uzmi i broji

Neki kod #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)
# Угадайте сами, какой пример легче читается посторонними людьми.

slučajan zanimljiva značajka. Recimo da želimo primiti 0 ili 1 (imamo samo dva elementa u nizu). Kada postavljamo granice 0..1, hoćemo li dobiti "1"?
ne - nećemo ga dobiti, imamo poseban primjer Primjer 2: Nabavite nasumični cijeli broj između 0 i 99 Get-Random -Maximum 100
Stoga, za 0..1 moramo postaviti veličinu 0..2, s maksimalnim brojem elemenata = 1.

7. Obrada dolaznih poruka i maksimalna duljina čekanja

Gdje smo stali ranije? imamo primljenu varijablu $MyMessageGet
i $Content4Pars01 dobiven iz njega, od kojih nas zanimaju elementi niza Content4Pars01.result

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

Pošaljimo botu /message10, /message11, /message12, /word i opet /word i /hello.
Da vidimo što imamo:

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

Pregledajmo sve primljeno i pošaljimo odgovor ako je poruka bila /word
slučaj konstrukta, koji neki opisuju kao if-elseif, naziva se u powershell-u preko prekidača. U isto vrijeme, kod ispod koristi ključ za zamjenu -koji je potpuno nepotreban, pa čak i štetan.

Neki kod #7.1

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

Pokrenimo skriptu nekoliko puta. Dobit ćemo istu riječ dva puta za svaki pokušaj izvršenja, pogotovo ako smo pogriješili u implementaciji slučajnog odabira.

Ali stani. Nismo ponovno poslali /word, pa zašto se poruka ponovno obrađuje?

Red čekanja za slanje poruka botu ima konačnu duljinu (100 ili 200 poruka, mislim) i mora se obrisati ručno.

To je naravno opisano u dokumentaciji, ali morate je pročitati!

U ovom slučaju trebamo parametar ?chat_id, a &timeout, &limit, &parse_mode=HTML i &disable_web_page_preview=true još nisu potrebni.

Dokumentacija za telegram api je ovdje
Piše na bijelom i engleskom:
Identifikator prvog ažuriranja koje se vraća. Mora biti veći za jedan od najvećeg među identifikatorima prethodno primljenih ažuriranja. Prema zadanim postavkama ažuriranja počinju od najranijeg
nepotvrđeno vraćaju se ažuriranja. Ažuriranje se smatra potvrđenim čim se getUpdates pozove s ofset viši nego njegov update_id. Negativni pomak može se navesti za dohvaćanje ažuriranja počevši od -offset update s kraja reda ažuriranja. Sva prethodna ažuriranja bit će zaboravljena.

Pogledajmo:

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

Da, i mi ćemo ga resetirati i malo prepisati funkciju. Imamo dvije opcije - proslijediti cijelu poruku funkciji i obraditi je u cijelosti u funkciji ili dati samo ID poruke i resetirati je. Na primjer, drugi izgleda jednostavnije.

Prethodno je naš niz upita "sve poruke" izgledao ovako

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

i izgledat će

$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 

Nitko vam ne brani da prvo primite sve poruke, obradite ih i tek nakon uspješne obrade zahtjev nepotvrđen -> potvrđen.

Zašto ima smisla pozivati ​​potvrdu nakon završetka svih obrada? Kvar je moguć usred izvršenja, a ako za primjer besplatnog chatbota propuštanje jedne poruke nije ništa posebno, onda ako obrađujete nečiju plaću ili kartičnu transakciju rezultat može biti lošiji.

Još nekoliko redaka koda

$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. Umjesto zaključka

Osnovne funkcije - čitanje poruka, resetiranje čekanja, čitanje iz datoteke i pisanje u datoteku su učinjene i prikazane.

Preostale su samo četiri stvari koje treba učiniti:

  • slanje točnog odgovora na zahtjev u chatu
  • slanje odgovora na BILO KOJI chat u koji je dodan bot
  • izvršavanje koda u petlji
  • pokretanje bota iz Windows planera.

Svi ovi zadaci su jednostavni i lako se mogu izvršiti čitanjem dokumentacije o parametrima kao što su
Set-ExecutionPolicy Unrestricted i -ExecutionPolicy Bypass
ciklus forme

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

Hvala svima koji čitaju.

Izvor: www.habr.com

Dodajte komentar