Predloga najpreprostejšega telegramskega bota za šolarje od 7. do 9. razreda na Powershell

Med pogovori s prijateljem sem nenadoma izvedel, da otrok v 8.-10. razredu njihove šole sploh ne učijo programiranja. Word, Excel in vse. Nobenega logotipa, niti Pascala, niti VBA za Excel.

Bil sem zelo presenečen, odprl sem internet in začel brati -
Ena od nalog specializirane šole je spodbujanje izobraževanja nove generacije, ki po svoji stopnji razvoja in življenjskem slogu ustreza pogojem informacijske družbe.
Ta predmet bo študentom omogočil, da v praksi utrdijo svoje znanje osnovnih konstruktov programskega jezika Pascal. (iz programa neke gimnazije za leto 2017)

Na koncu sem se odločil, da bom porabil nekaj ur in skiciral primer, "kako ustvariti preprostega bota za šolarje."

Spodaj je opisano, kako napisati še enega preprostega bota v Powershell in omogočiti, da deluje brez webhooka, belih IP-jev, namenskih strežnikov, nameščenih virtualnih strojev v oblaku in tako naprej – na običajnem domačem računalniku z običajnim sistemom Windows.

TLDR: Še en dolgočasen članek s slovničnimi in stvarnimi napakami, nič za branje, brez humorja, brez slik.

V članku ni nič novega, skoraj vse prej napisano je že bilo na Habréju, na primer v člankih Navodila: Kako ustvariti bote v Telegramu и Telegram bot za sistemskega administratorja.
Poleg tega je članek namerno odvečen, da se ne bi vsakič skliceval na izobraževalno literaturo. V besedilu ni nobenih sklicevanj na Gang 4, PowerShell Deep Dives ali, recimo, 5 stebrov dobro zgrajenega ogrodja AWS.

Namesto predgovora lahko preskočite

Lahko preskočiteLeta 2006 je Microsoft izdal PowerShell 1.0 za takratne Windows XP, Vista in Server 2003. Na nek način je nadomestil stvari, kot so skripti cmdbat, skripti vb, Windows Script Host in JScript.

Celo zdaj lahko PowerShell štejemo le kot naslednji korak po možnostih Logo, namesto verjetno še vedno uporabljenega Delphija (ali česa starejšega), kljub prisotnosti zank, razredov, funkcij, MS GUI klicev, Integracija Git in tako naprej.

Powershell se uporablja relativno redko, srečate ga lahko le v obliki PowerShell Core, VMware vSphere PowerCLI, Azure PowerShell, MS Exchange, Desired State Configuration, Spletni dostop PowerShell in nekaj ducat bolj redko uporabljenih programov in funkcij. Morda bo z izidom dobil drugi veter WSL2, vendar ni ravno.

Powershell ima tudi tri velike prednosti:

  1. Je razmeroma preprosto, o tem je veliko literature in primerov, tudi v ruščini je na primer članek o Foreachu - iz knjige PowerShell poglobljeno - o razliki () in {}
  2. Gre z urednikom ISE, vključen v sistem Windows. Tam je celo nekakšen razhroščevalnik.
  3. Z njega je enostavno klicati komponente za izdelavo grafičnega vmesnika.

0. Priprava.

Potrebovali bomo:

  • Windows PC (imam Windows 10)
  • Vsaj nekakšen dostop do interneta (na primer prek NAT)
  • Za tiste, ki imajo omejen dostop do telegrama - nameščen in konfiguriran freegate v brskalniku, v nekaterih težkih primerih, skupaj s Simple DNS Crypt
  • V telefonu imate delujoč odjemalec telegram
  • Razumevanje samih osnov – kaj je spremenljivka, matrika, zanka.

Odprl in prebral članke - Navodila: Kako ustvariti bote v Telegramu и Telegram bot za sistemskega administratorja

1. Ustvarimo še enega testnega bota.

Ker to že vsi vedo in se je že zgodilo, lahko to tudi preskočiteKot je navedeno v zgornjem članku - Najprej bot za Telegram - še vedno je aplikacija, ki se izvaja na vaši strani in pošilja zahteve API-ju Telegram Bot. Poleg tega je API jasen - bot dostopa do določenega URL-ja s parametri, Telegram pa se odzove z objektom JSON.

Povezane težave: če na neznan način vzamete kodo iz objekta JSON in jo nekako pošljete v izvedbo (ne namenoma), se bo koda izvršila namesto vas.

Postopek ustvarjanja je opisan v dveh zgornjih člankih, vendar ponavljam: v telegramu odpremo kontakte, poiščemo @botfather, mu povemo /newbot, ustvarimo bota Botfortest12344321, ga poimenujemo Mynext1234bot in prejmemo sporočilo z edinstvenim ključem obrazec 1234544311:AbcDefNNNNNNNNNNNNNN

Poskrbite za ključ in ga ne dajte!

Nato lahko konfigurirate bota, na primer, prepovete dodajanje v skupine, vendar v prvih korakih to ni potrebno.

Vprašajmo BotFather za “/mybot” in prilagodimo nastavitve, če nam kaj ni všeč.

Ponovno odpremo kontakte, tam poiščemo @Botfortest12344321 (iskanje obvezno začnemo z @), kliknemo »start« in napišemo botu »/Slava robotom«. Znak / je obvezen, narekovaji niso potrebni.
Bot seveda ne bo odgovoril ničesar.

Preverimo, ali je bot ustvarjen in ga odpremo.

api.telegram.org/bot1234544311:AbcDefNNNNNNNNNNNNNNNN/getMe
kjer je 1234544311:AbcDefNNNNNNNNNNNNNN predhodno prejeti ključ,
in dobite vrstico, kot je
{"ok":true,"result":{""}}

Imamo prvo skrivno frazo (žeton). Zdaj moramo ugotoviti drugo tajno številko - ID klepeta z botom. Vsak klepet, skupina itd. je individualen in ima svojo številko (včasih z minusom - za odprte skupine). Da bi izvedeli to številko, moramo v brskalniku zahtevati (pravzaprav to sploh ni potrebno v brskalniku, vendar za boljše razumevanje lahko začnete z njim) naslov (kjer je 1234544311:NNNNNNNNNN vaš žeton

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

in dobite odgovor, kot je

{"ok":true,"result":[{"update_id":...,... klepet":{"id":123456789

Potrebujemo chat_id.

Preverimo, ali lahko ročno pišemo v klepet: pokličite naslov iz brskalnika

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

Če prejmete sporočilo od bota v svojem klepetu, v redu, pojdite na naslednjo stopnjo.

Na ta način (preko brskalnika) lahko vedno preverite, ali so težave pri generiranju povezav, ali se kje kaj skriva in ne deluje.

Kaj morate vedeti, preden nadaljujete z branjem

Telegram ima več vrst skupinskih klepetov (odprti, zaprti). Za te klepete so nekatere funkcije (na primer id) drugačne, kar včasih povzroča težave.

Predpostavimo, da je konec leta 2019 in celo junak našega časa, dobro znani Man-Orchestra (administrator, odvetnik, strokovnjak za informacijsko varnost, programer in praktično MVP) Evgeniy V. loči spremenljivko $i od matrike, je obvladal zanke, poglej v naslednjih nekaj letih bo obvladal Chocolatey, in potem Vzporedna obdelava s PowerShell и ForEach-Object Parallel bo prišlo.

1. Razmišljamo, kaj bo naredil naš bot

Nisem imel nobenih idej, moral sem razmišljati. Sem že napisal bot-notebook. Nisem hotel narediti bota, "ki nekam nekaj pošlje." Za povezavo z Azure potrebujete kreditno kartico, toda od kod jo študent dobi? Treba je opozoriti, da vse ni tako slabo: glavni oblaki dajejo nekakšno testno obdobje brezplačno (vendar še vedno potrebujete številko kreditne kartice - in zdi se, da bo od nje bremenjen dolar. Ne spomnim se, ali pozneje je bilo vrnjeno.)

Brez AI ML ni tako zanimivo narediti bot-poor-poet-weaver.

Odločil sem se narediti bota, ki me bo spominjal (ali pa tudi ne) na angleške besede iz slovarja.
Da bi se izognili ubadanju z bazo podatkov, bo slovar shranjen v besedilni datoteki in posodobljen ročno.
V tem primeru je naloga prikazati osnove dela, ne pa narediti vsaj delno dokončan izdelek.

2. Prvič poskusiti kaj in kako

Ustvarimo mapo C:poshtranslate
Najprej poglejmo, kakšen powershell imamo, zaženimo ISE prek start-run
powershell ise
ali poiščite Powershell ISE v nameščenih programih.
Po zagonu se odpre običajni znani »nekakšen urejevalnik«; če ni besedilnega polja, lahko vedno kliknete »Datoteka - ustvari novo«.

Poglejmo različico powershell - v besedilno polje vpišite:

get-host 

in pritisnite F5.

Powershell bo ponudil shranjevanje - "Skript, ki ga boste zagnali, bo shranjen.", se strinjamo in shranimo datoteko iz powershell z imenom v C: poshtranslate myfirstbotBT100.

Po zagonu v spodnjem besedilnem oknu dobimo podatkovno tabelo:

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

Imam 5.1 nekaj, to je dovolj. Če imate star Windows 7/8, potem nič hudega - čeprav bo treba PowerShell posodobiti na različico 5 - npr. Navodila.

Vnesite Get-Date v spodnjo ukazno vrstico, pritisnite Enter, poglejte uro, pojdite v korensko mapo z ukazom
cd
in počistite zaslon z ukazom cls (ne, ni vam treba uporabiti rm)

Zdaj pa preverimo, kaj deluje in kako - ne napišimo niti kode, ampak dve vrstici, in poskusimo razumeti, kaj počnejo. Komentirajmo vrstico z get-host s simbolom # in malo dodamo.

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

(Zanimivo je, da je na spustnem seznamu za oblikovanje kode na Habré dva ducata možnosti - vendar Powershell ni tam. Dos je tam. Perl je tam.)

In zaženimo kodo s pritiskom na F5 ali ">" v GUI.

Dobimo naslednji rezultat:

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

Zdaj pa si poglejmo ti dve vrstici in nekaj zanimivih točk, da se k temu ne bomo več vračali v prihodnosti.

Za razliko od Pascala (in ne samo), PowerShell sam poskuša določiti, kateri tip naj dodeli spremenljivki, več podrobnosti o tem je napisano v članku Izobraževalni program o tipkanju v programskih jezikih
Če torej ustvarimo spremenljivko $TimeNow in ji dodelimo vrednost trenutnega datuma in ure (Get-Date), nam ni treba preveč skrbeti, kakšne vrste podatkov bodo tam.

Res je, da lahko ta nevednost kasneje boli, a to je za kasneje. Spodaj v besedilu bo primer.
Poglejmo, kaj imamo. Izvedimo (v ukazni vrstici)

$TimeNow | Get-member

in dobite stran z nerazumljivim besedilom

Primer nerazumljivega besedila številka 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")...                                         

Kot lahko vidite, je bila ustvarjena spremenljivka tipa TypeName: System.DateTime s kopico metod (v smislu, kaj lahko naredimo s tem objektom spremenljivke) in lastnosti.

Pokličimo $TimeNow.DayOfYear — dobimo številko dneva v letu.
Pokličimo $TimeNow.DayOfYear | Get-Member - dobimo TypeName: System.Int32 in skupino metod.
Pokličimo $TimeNow.ToUniversalTime() - in dobite čas v UTC

Razhroščevalec

Včasih se zgodi, da je treba izvesti program do določene vrstice in videti stanje programa v tem trenutku. V ta namen ima ISE funkcijo za odpravljanje napak - preklop točke prekinitve
Postavite prelomno točko nekje na sredino, zaženite ti dve vrstici in poglejte, kako izgleda prelom.

3. Razumevanje interakcije z botom Telegram

Seveda je bilo napisanega še več literature o interakciji z botom, z vsem getpush in tako naprej, vendar je vprašanje teorije mogoče obravnavati poljubno.

V našem primeru je potrebno:

  • Naučite se poslati nekaj v korespondenci
  • Naučite se dobiti nekaj iz korespondence

3.1 Naučiti se poslati nekaj v korespondenci in prejeti iz nje

Malo kode - 3. del

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

in v Ruski federaciji na tej točki dobimo napako Ni mogoče vzpostaviti povezave z oddaljenim strežnikom.

Ali pa ga ne prejmemo - odvisno od telekomunikacijskega operaterja in ali je proxy nastavljen in deluje
No, vse kar ostane je dodati proxy. Upoštevajte, da je uporaba nešifriranega in na splošno goljufivega proxyja izjemno nevarna za vaše zdravje.

Naloga iskanja delujočega proxyja ni zelo težka - večina objavljenih http proxyjev deluje. Mislim, da mi je peti uspel.

Sintaksa z uporabo posrednika:

Invoke-WebRequest -Uri $URL4SEND -Proxy $MyProxy

Če prejmete sporočilo v klepetu z botom, je vse v redu, lahko nadaljujete. Če ne, nadaljujte z odpravljanjem napak.

Vidite lahko, v kaj se spremeni vaš niz $URL4SEND, in ga poskusite zahtevati v brskalniku, takole:

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

3.2. Naučili smo se napisati »nekaj« v klepetu, zdaj pa poskusimo to prebrati

Dodajmo še 4 vrstice in poglejmo, kaj je notri skozi | 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

Najbolj zanimiva stvar nam je na voljo

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

Poglejmo, kaj je v njih:

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

Če vam vse deluje, boste dobili dolgo vrstico, kot je:

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

Na srečo je v prej objavljenem članku Telegram bot za sistemskega skrbnika ta vrstica (da, glede na $MyMessageGet.RawContent | get-member je System.String), je že razstavljen.

4. Prejeto obdelamo (nekaj že znamo poslati)

Kot že napisano tukaj, najnujnejše se skriva v vsebini. Oglejmo si ga pobližje.

Najprej bomo botu napisali še nekaj fraz iz spletnega vmesnika ali iz telefona

/message1
/message2
/message3

in poglejte v brskalniku naslov, ki je bil oblikovan v spremenljivki $URLGET.

Videli bomo nekaj takega:

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

Kaj je to? Neki kompleksen objekt iz nizov objektov, ki vsebuje identifikator sporočila od konca do konca, identifikator klepeta, identifikator pošiljanja in veliko drugih informacij.

Vendar nam ni treba ugotoviti, "kakšen predmet je to" - del dela je že opravljen za nas. Poglejmo, kaj je notri:

Branje prejetih sporočil ali 4. del

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. Kaj naj zdaj storimo glede tega?

Shranimo nastalo datoteko pod imenom myfirstbotBT105 ali kako vam je najbolj všeč, spremenite naslov in komentirajte vso že napisano kodo prek

<#start comment 105 end comment 105#>

Zdaj se moramo odločiti, kje dobiti slovar (no, kje - na disku v datoteki) in kako bo izgledal.

Seveda lahko napišete ogromen slovar kar v besedilo scenarija, vendar je to popolnoma nepomembno.
Pa poglejmo, s čim lahko powershell normalno deluje.
Na splošno mu je vseeno, s katero datoteko naj dela, za nas je vseeno.
Na izbiro imamo: txt (lahko, ampak zakaj), csv, xml.
Ali lahko gledamo vse? Poglejmo vse.
Ustvarimo razred MyVocabClassExample1 in spremenljivko $MyVocabExample1
Opažam, da je razred napisan brez $

nekaj kode #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

Poskusimo to zapisati v datoteke z uporabo zgleden.

Nekaj ​​kode #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

- in dobimo napako v vrstici Out-File -FilePath $MyFilenameExample01 -InputObject -Append $MyVocabExample2.

Noče dodati, ah-ah, kakšna škoda.

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

Poglejmo, kaj se zgodi. Odličen pogled besedila - toda kako ga izvoziti nazaj? Ali naj uvedem nekakšna ločila besedila, na primer vejice?

In na koncu dobite datoteko A z vrednostmi, ločenimi z vejicami (CSV). STOP POČAKAJ.
#

$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 

Kot je lahko videti, se MS ne odlikuje posebej po svoji logiki; za podoben postopek se v enem primeru uporablja -FilePath, v drugem -Path.

Poleg tega je v tretji datoteki izginil ruski jezik, v četrti datoteki se je izkazalo ... no, nekaj se je zgodilo. #TYPE System.Object[] 00
# “Count”, “Length”, “LongLength”, “Rank”, “SyncRoot”, “IsReadOnly”, “IsFixedSize”, “IsSynchronized”
#
Napišimo malo na novo:

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

Zdi se, da je pomagalo, vendar mi oblika še vedno ni všeč.

Predvsem mi ni všeč, da ne morem neposredno postaviti vrstic iz predmeta v datoteko.
Mimogrede, odkar smo začeli pisati v datoteke, lahko začnemo voditi dnevnik zagona? Čas imamo kot spremenljivko, lahko nastavimo ime datoteke.

Res je, da še ni kaj za napisati, lahko pa razmislite, kako bi bilo bolje vrteti hlode.
Zaenkrat poskusimo xml.

Nekaj ​​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 v xml ima številne prednosti - berljivost, izvoz celotnega predmeta in ni potrebe po dodajanju.

Poskusimo branje xml datoteke.

Malo branja iz xml

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

Vrnimo se k nalogi. Napisali smo testno datoteko, jo prebrali, oblika shranjevanja je jasna, po potrebi lahko napišete ločen urejevalnik majhnih datotek za dodajanje in brisanje vrstic.

Naj vas spomnim, da je bila naloga narediti majhnega trening bota.

Format dela: botu pošljem ukaz “example”, ta mi pošlje naključno izbrano besedo in transkripcijo ter po 10 sekundah prevod in komentar. Ukaze znamo brati, prav tako bi se radi naučili avtomatsko izbirati in preverjati posrednike ter ponastavljati števce sporočil v pozabo.

Odkomentirajmo vse, kar je bilo prej komentirano kot nepotrebno, zdaj nepotrebne primere komentirajte s txt in csv ter shranite datoteko kot različico B106

o ja Dajmo še enkrat nekaj poslati botu.

6. Odprema s funkcij in več

Pred obdelavo sprejema morate ustvariti funkcijo za pošiljanje "vsaj nečesa", razen testnega sporočila.

Seveda bomo imeli v primeru samo eno pošiljanje in samo eno obdelavo, a kaj, če moramo isto stvar narediti večkrat?

Lažje je napisati funkcijo. Imamo torej spremenljivko tipa object $MyVocabExample4AsArray, prebrano iz datoteke, v obliki niza kar dveh elementov.
Gremo brati.

Hkrati se bomo ukvarjali z uro, potrebovali jo bomo kasneje (pravzaprav je v tem primeru ne bomo potrebovali :)

Nekaj ​​kode #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
}

Kot lahko preprosto vidite, funkcija pokliče $MyToken in $MyChatID, ki sta bila predhodno trdo kodirana.

Tega ni treba narediti in če je $MyToken en za vsakega bota, se bo $MyChatID spremenil glede na klepet.

Ker pa je to primer, ga za zdaj ne bomo upoštevali.

Ker $MyVocabExample4AsArray ni matrika, čeprav ji je zelo podobna, potem ne moreš kar vzeti zahtevajte njeno dolžino.

Spet bomo morali narediti nekaj, kar se ne da - padalo ne po kodeksu - vzemi in štej

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

Naključen zanimiva lastnost. Recimo, da želimo prejeti 0 ali 1 (v matriki imamo samo dva elementa). Ali bomo pri nastavitvi meja 0..1 dobili "1"?
ne - ne bomo ga dobili, imamo poseben primer Primer 2: Pridobite naključno celo število med 0 in 99 Get-Random -Maximum 100
Zato moramo za 0..1 nastaviti velikost 0..2, z največjim številom elementov = 1.

7. Obdelava dohodnih sporočil in največja dolžina čakalne vrste

Kje smo se prej ustavili? imamo prejeto spremenljivko $MyMessageGet
in iz njega pridobljeni $Content4Pars01, od tega nas zanimajo elementi matrike Content4Pars01.result

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

Pošljimo botu /message10, /message11, /message12, /word in še enkrat /word in /hello.
Poglejmo, kaj imamo:

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

Poglejmo vse prejeto in pošljimo odgovor, če je bilo sporočilo /word
primer konstrukta, kar nekateri opisujejo kot if-elseif, se imenuje v lupini powershell prek stikala. Hkrati pa spodnja koda uporablja nadomestni ključ, ki je popolnoma nepotreben in celo škodljiv.

Nekaj ​​kode #7.1

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

Nekajkrat zaženimo skript. Za vsak poskus izvedbe bomo dvakrat dobili isto besedo, še posebej, če smo naredili napako pri izvajanju naključnega.

Ampak nehaj. Nismo ponovno poslali /word, zakaj se torej sporočilo ponovno obdeluje?

Čakalna vrsta za pošiljanje sporočil botu ima končno dolžino (mislim, da 100 ali 200 sporočil) in jo je treba počistiti ročno.

To je seveda opisano v dokumentaciji, vendar jo morate prebrati!

V tem primeru potrebujemo parameter ?chat_id, &timeout, &limit, &parse_mode=HTML in &disable_web_page_preview=true pa še niso potrebni.

Dokumentacija za telegram api je tukaj
Piše v belem in angleškem jeziku:
Identifikator prve vrnjene posodobitve. Biti mora za ena večji od najvišjega med identifikatorji predhodno prejetih posodobitev. Privzeto se posodobitve začnejo z najzgodnejšimi
nepotrjeno posodobitve so vrnjene. Posodobitev se šteje za potrjeno takoj, ko je getUpdates poklican z odmik več kot njegov update_id. Negativni odmik je mogoče določiti za pridobivanje posodobitev, ki se začnejo z -offset posodobitev s konca čakalne vrste posodobitev. Vse prejšnje posodobitve bodo pozabljene.

Poglejmo si:

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

Da, ponastavili ga bomo in funkcijo nekoliko prepisali. Imamo dve možnosti - celotno sporočilo posredujemo funkciji in ga v celoti obdelamo v funkciji ali podamo samo ID sporočila in ga ponastavimo. Na primer, drugi je videti preprostejši.

Prej je naš poizvedbeni niz »vsa sporočila« izgledal takole

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

in izgledalo bo

$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 

Nihče vam ne prepoveduje, da vsa sporočila najprej prejmete, obdelate in šele po uspešni obdelavi zahteva nepotrjena -> potrjena.

Zakaj je smiselno klicati potrditev po zaključku vseh obdelav? Napaka je možna sredi izvajanja in če za primer brezplačnega chatbota manjkajoče sporočilo ni nič posebnega, pa je lahko rezultat slabši, če obdelujete plačo ali kartično transakcijo nekoga.

Še nekaj vrstic kode

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

Osnovne funkcije - branje sporočil, ponastavitev čakalne vrste, branje iz datoteke in pisanje v datoteko so izvedene in prikazane.

Samo še štiri stvari je treba storiti:

  • pošiljanje pravilnega odgovora na zahtevo v klepetu
  • pošiljanje odgovora na KATERI KOLI klepet, v katerega je bil dodan bot
  • izvajanje kode v zanki
  • zagon bota iz razporejevalnika Windows.

Vse te naloge so preproste in jih je mogoče enostavno izvesti z branjem dokumentacije o parametrih, kot je npr
Set-ExecutionPolicy Unrestricted in -ExecutionPolicy Bypass
cikel obrazca

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

Hvala vsem, ki berete.

Vir: www.habr.com

Dodaj komentar