Mallen för den enklaste telegramboten för skolbarn i årskurs 7-9 på Powershell

Under samtal med en kompis fick jag plötsligt veta att barn i årskurs 8-10 på deras skola inte alls får lära sig programmering. Word, Excel och allt. Ingen logotyp, inte ens Pascal, inte ens VBA för Excel.

Jag blev mycket förvånad, öppnade internet och började läsa -
En av en specialiserad skolas uppgifter är att främja utbildningen av en ny generation som uppfyller informationssamhällets villkor i dess utvecklingsnivå och livsstil.
Denna kurs kommer att tillåta studenter att i praktiken konsolidera sina kunskaper om de grundläggande konstruktionerna av programmeringsspråket Pascal. (från programmet för något gymnasium för 2017)

Till slut bestämde jag mig för att spendera ett par timmar och skissa på ett exempel på "hur man skapar en enkel bot för skolbarn."

Nedanför snittet är hur man skriver ytterligare en enkel bot i Powershell och får den att fungera utan en webhook, vita IP-adresser, dedikerade servrar, utplacerade virtuella maskiner i molnet och så vidare - på en vanlig hemdator med vanliga Windows.

TLDR: Ännu en tråkig artikel med grammatiska och faktafel, inget att läsa, ingen humor, inga bilder.

Det är inget nytt i artikeln, nästan allt som skrivits tidigare har redan funnits på Habré, till exempel i artiklar Instruktioner: Hur man skapar bots i Telegram и Telegram bot för systemadministratör.
Dessutom är artikeln medvetet överflödig för att inte referera till utbildningslitteratur varje gång. Det finns inga referenser till Gang 4, PowerShell Deep Dives eller, säg, The 5 Pillars of the AWS Well-Architected Framework i texten.

Istället för ett förord ​​kan du hoppa över

Hoppa gärna över2006 släppte Microsoft PowerShell 1.0 för dåvarande Windows XP, Vista och Server 2003. På vissa sätt ersatte det sådana saker som cmdbat-skript, vb-skript, Windows Script Host och JScript.

Till och med nu kan PowerShell bara betraktas som nästa steg efter logotypalternativen, istället för det förmodligen fortfarande använda Delphi (eller något äldre), trots närvaron av loopar, klasser, funktioner, MS GUI-anrop, Git integration och så vidare.

Powershell används relativt sällan; du kan bara stöta på det i form av PowerShell Core, VMware vSphere PowerCLI, Azure PowerShell, MS Exchange, Desired State Configuration, PowerShell Web Access och ett dussintal mer sällan använda program och funktioner. Kanske får han en andra vind med släppet WSL2, men det är det inte precis.

Powershell har också tre stora fördelar:

  1. Det är relativt enkelt, det finns mycket litteratur och exempel om det, och även på ryska, till exempel, en artikel om Foreach - från boken PowerShell på djupet - om skillnaden () och {}
  2. Han följer med redaktören ISE, ingår i Windows. Det finns till och med någon typ av felsökning där.
  3. Det är lätt att ringa från den komponenter för att bygga ett grafiskt gränssnitt.

0. Förberedelse.

Vi behöver:

  • Windows PC (jag har Windows 10)
  • Åtminstone någon form av internetåtkomst (via NAT till exempel)
  • För dig som har begränsad tillgång till telegram - installerad och konfigurerad freegate i webbläsaren, i vissa svåra fall, tillsammans med Symple DNS Crypt
  • Att ha en fungerande telegramklient på din telefon
  • Förstå grunderna - vad en variabel, array, loop är.

Öppnade och läste artiklar - Instruktioner: Hur man skapar bots i Telegram и Telegram bot för systemadministratör

1. Låt oss skapa en annan testbot.

Eftersom alla redan vet detta, och redan har hänt, kan du också hoppa över detSom anges i artikeln ovan - Först och främst en bot för Telegram - det är fortfarande ett program som körs på din sida och gör förfrågningar till Telegram Bot API. Dessutom är API:et tydligt - boten kommer åt en specifik URL med parametrar, och Telegram svarar med ett JSON-objekt.

Relaterade problem: om du på något okänt sätt tar någon kod från ett JSON-objekt och på något sätt skickar den för exekvering (inte med avsikt), kommer koden att exekveras åt dig.

Skapandeprocessen beskrivs i två artiklar ovan, men jag upprepar: i ett telegram öppnar vi kontakter, letar efter @botfather, berättar för honom /newbot, skapar en bot Botfortest12344321, kallar den Mynext1234bot och får ett meddelande med en unik nyckel för blankett 1234544311:AbcDefNNNNNNNNNNNNNN

Ta hand om nyckeln och ge bort den inte!

Sedan kan du konfigurera boten, till exempel förbjuda att lägga till den i grupper, men i de första stegen är detta inte nödvändigt.

Låt oss fråga BotFather om "/mybot" och justera inställningarna om vi inte gillar något.

Låt oss öppna kontakterna igen, hitta @Botfortest12344321 där (det är obligatoriskt att starta sökningen med @), klicka på "start" och skriv till boten "/Glory to the robots." Tecknet / krävs, offerter behövs inte.
Boten kommer naturligtvis inte att svara på någonting.

Låt oss kontrollera att boten har skapats och öppna den.

api.telegram.org/bot1234544311:AbcDefNNNNNNNNNNNNNN/getMe
där 1234544311:AbcDefNNNNNNNNNNNNNN är den tidigare mottagna nyckeln,
och få en rad som
{"ok":true,"result":{""}}

Vi har den första hemliga frasen (token). Nu måste vi ta reda på det andra hemliga numret - ID för chatten med boten. Varje chatt, grupp etc. är individuell och har sitt eget nummer (ibland med minus - för öppna grupper). För att ta reda på detta nummer måste vi begära adressen i webbläsaren (det är faktiskt inte alls nödvändigt i webbläsaren, men för en bättre förståelse kan du börja med det) (där 1234544311:NNNNNNNNNN är din token

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

och få ett svar som

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

Vi behöver chat_id.

Låt oss kontrollera att vi kan skriva till chatten manuellt: ring adressen från webbläsaren

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

Om du får ett meddelande från en bot i din chatt, okej, du går vidare till nästa steg.

På så sätt (via webbläsaren) kan du alltid kontrollera om det är problem med länkgenereringen, eller om något är gömt någonstans och inte fungerar.

Vad du behöver veta innan du fortsätter läsa

Telegram har flera typer av gruppchatt (öppen, stängd). För dessa chattar är vissa av funktionerna (till exempel id) olika, vilket ibland orsakar vissa problem.

Låt oss anta att det är slutet av 2019, och till och med vår tids hjälte, den välkända Man-Orchestra (administratör, advokat, informationssäkerhetsspecialist, programmerare och praktiskt taget MVP) Evgeniy V. skiljer $i-variabeln från en array, har bemästrat loopar, se under de närmaste åren kommer att behärska Chocolatey, och sedan Parallell bearbetning med PowerShell и För varje objekt parallellt det kommer.

1. Vi funderar på vad vår bot kommer att göra

Jag hade inga idéer, jag var tvungen att tänka. Jag har redan skrivit en bot-anteckningsbok. Jag ville inte göra en bot "som skickar något någonstans." För att ansluta till Azure behöver du ett kreditkort, men var får studenten det ifrån? Det bör noteras att allt inte är så illa: huvudmolnen ger någon form av testperiod gratis (men du behöver fortfarande ett kreditkortsnummer - och det verkar som om en dollar kommer att debiteras från det. Jag kommer inte ihåg om den återlämnades senare.)

Utan AI ML är det inte så intressant att göra en bot-fattig-poet-vävare.

Jag bestämde mig för att göra en bot som kommer att påminna mig (eller inte mig) om engelska ord från ordboken.
För att undvika att krångla med databasen kommer ordboken att lagras i en textfil och uppdateras manuellt.
I det här fallet är uppgiften att visa grunderna i arbetet, och inte att göra åtminstone en delvis färdig produkt.

2. Prova vad och hur för första gången

Låt oss skapa en mapp C:poshtranslate
Låt oss först se vilken typ av powershell vi har, låt oss lansera ISE via start-run
powershell ise
eller hitta Powershell ISE i installerade program.
Efter lanseringen öppnas den vanliga välbekanta "någon sorts redigerare"; om det inte finns något textfält kan du alltid klicka på "Arkiv - skapa ny".

Låt oss titta på versionen av powershell - skriv i textfältet:

get-host 

och tryck på F5.

Powershell kommer att erbjuda att spara - "Skriptet du ska köra kommer att sparas.", vi håller med och sparar filen från powershell med namnet i C: poshtranslate myfirstbotBT100.

Efter lanseringen får vi en datatabell i det nedre textfönstret:

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

Jag har 5.1 något, det räcker. Om du har ett gammalt Windows 7/8 så är det ingen stor grej - även om PowerShell kommer att behöva uppdateras till version 5 - t.ex. Avstånd.

Skriv Get-Date på kommandoraden nedan, tryck på Enter, titta på tiden, gå till rotmappen med kommandot
cd
och rensa skärmen med kommandot cls (nej, du behöver inte använda rm)

Låt oss nu kolla vad som fungerar och hur - låt oss inte ens skriva koden, utan två rader, och försöka förstå vad de gör. Låt oss kommentera raden med get-host med #-symbolen och lägga till lite.

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

(Det som är intressant är att det i rullgardinsmenyn för kodformatering på Habré finns två dussin alternativ - men Powershell finns inte där. Dos finns där. Perl finns där.)

Och låt oss köra koden genom att trycka på F5 eller ">" från GUI.

Vi får utdata:

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

Låt oss nu titta på dessa två linjer och några intressanta punkter så att vi inte återkommer till detta i framtiden.

Till skillnad från Pascal (och inte bara), försöker PowerShell själv bestämma vilken typ som ska tilldelas till en variabel; mer information om detta skrivs i artikeln Utbildningsprogram om att skriva på programmeringsspråk
Därför, genom att skapa en $TimeNow-variabel och tilldela den värdet av det aktuella datumet och tiden (Get-Date), behöver vi inte oroa oss för mycket om vilken typ av data som kommer att finnas där.

Det är sant att denna okunskap kan skada senare, men det är för senare. Nedan i texten kommer ett exempel.
Låt oss se vad vi har. Låt oss köra (på kommandoraden)

$TimeNow | Get-member

och få en sida med obegriplig text

Exempel på obegriplig text nummer 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")...                                         

Som du kan se har en variabel av typen TypeName: System.DateTime skapats med en massa metoder (i betydelsen vad vi kan göra med detta variabelobjekt) och egenskaper.

Låt oss ringa $TimeNow.DayOfYear — vi får numret på årets dag.
Låt oss ringa $TimeNow.DayOfYear | Get-Member - vi får TypeName: System.Int32 och en grupp metoder.
Låt oss ringa $TimeNow.ToUniversalTime() - och få tiden i UTC

Felsökare

Ibland händer det att du behöver köra ett program upp till en viss rad och se tillståndet för programmet i det ögonblicket. För detta ändamål har ISE en Debug-funktion - växla brytpunkt
Sätt en brytpunkt någonstans i mitten, kör dessa två linjer och se hur brytningen ser ut.

3. Förstå interaktionen med Telegram-boten

Naturligtvis har ännu mer litteratur skrivits om interaktion med boten, med all getpush och så vidare, men frågan om teori kan övervägas valfritt.

I vårt fall är det nödvändigt:

  • Lär dig att skicka något i korrespondens
  • Lär dig att få något från korrespondens

3.1 Lära sig att skicka något i korrespondens och ta emot från det

En liten kod - del 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

och i Ryska federationen får vi vid det här laget felet Det går inte att ansluta till fjärrservern.

Eller så tar vi inte emot det - beror på teleoperatören och om proxyn är konfigurerad och fungerar
Nåväl, allt som återstår är att lägga till en proxy. Observera att det är extremt farligt för din hälsa att använda en okrypterad och allmänt bedräglig proxy.

Uppgiften att hitta en fungerande proxy är inte särskilt svår - de flesta av de publicerade http-proxies fungerar. Jag tror att den femte fungerade för mig.

Syntax med proxy:

Invoke-WebRequest -Uri $URL4SEND -Proxy $MyProxy

Om du får ett meddelande i din chatt med en bot så är allt bra, du kan gå vidare. Om inte, fortsätt felsökningen.

Du kan se vad din $URL4SEND-sträng förvandlas till och prova att begära den i webbläsaren, så här:

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

3.2. Vi lärde oss hur man skriver "något" i chatten, nu ska vi försöka läsa det

Låt oss lägga till ytterligare fyra rader och se vad som finns inuti | bli medlem

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

Det mest intressanta ges till oss

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

Låt oss se vad som finns i dem:

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

Om allt fungerar för dig kommer du att få en lång rad som:

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

Lyckligtvis, i den tidigare publicerade artikeln Telegram bot för systemadministratör denna rad (ja, enligt $MyMessageGet.RawContent | get-member är System.String), har redan tagits isär.

4. Bearbeta det du får (vi vet redan hur man skickar något)

Som redan skrivits här, de mest nödvändiga sakerna ligger i innehållet. Låt oss ta en närmare titt på det.

Först kommer vi att skriva ytterligare ett par fraser till boten från webbgränssnittet eller från telefonen

/message1
/message2
/message3

och titta genom webbläsaren på adressen som bildades i variabeln $URLGET.

Vi kommer att se något i stil med:

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

Vad det är? Vissa komplexa objekt från arrayer av objekt som innehåller en end-to-end meddelandeidentifierare, chattidentifierare, sändningsidentifierare och mycket annan information.

Vi behöver dock inte ta reda på "vad det här är för objekt" - en del av arbetet har redan gjorts för oss. Låt oss se vad som finns inuti:

Läser mottagna meddelanden eller del 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. Vad ska vi göra åt det nu?

Låt oss spara den resulterande filen under namnet myfirstbotBT105 eller vad du tycker bäst om, ändra titeln och kommentera all redan skriven kod via

<#start comment 105 end comment 105#>

Nu måste vi bestämma var vi ska hämta ordboken (tja, var - på disk i en fil) och hur den kommer att se ut.

Naturligtvis kan du skriva en enorm ordbok direkt i texten i manuset, men detta är helt vidrigt.
Så låt oss se vad powershell kan fungera med normalt.
I allmänhet bryr han sig inte om vilken fil han ska arbeta med, det spelar ingen roll för oss.
Vi har ett val: txt (du kan, men varför), csv, xml.
Kan vi titta på alla? Låt oss se alla.
Låt oss skapa en klass MyVocabClassExample1 och en variabel $MyVocabExample1
Jag noterar att klassen är skriven utan $

någon 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

Låt oss försöka skriva in detta i filer med hjälp av exemplarisk.

Någon 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

- och vi får ett felmeddelande på raden Out-File -FilePath $MyFilenameExample01 -InputObject -Append $MyVocabExample2.

Han vill inte tillägga, ah-ah, vad synd.

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

Vi får se vad som händer. Bra textvy - men hur exporterar jag tillbaka den? Ska jag införa någon typ av textavgränsare, till exempel kommatecken?

Och till slut får du en "kommaseparerade värden (CSV) fil A SLUTA VÄNTA.
#

$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 

Som det är lätt att se är MS inte särskilt utmärkande av sin logik, för en liknande procedur används i ett fall -FilePath, i en annan -Path.

Dessutom, i den tredje filen försvann det ryska språket, i den fjärde filen visade det sig... ja, något hände. #TYPE System.Object[] 00
# "Count","Length","LongLength","Rank","SyncRoot","IsReadOnly","IsFixedSize","IsSynchronized"
#
Låt oss skriva om det lite:

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

Det verkar ha hjälpt, men jag gillar fortfarande inte formatet.

Jag gillar särskilt inte att jag inte kan lägga in linjer från ett objekt i en fil direkt.
Förresten, sedan vi började skriva till filer, kan vi börja föra en startlogg? Vi har tid som variabel, vi kan ställa in filnamnet.

Det finns visserligen inget att skriva ännu, men man kan fundera på hur man bäst roterar stockarna.
Låt oss prova xml nu.

Lite 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

Att exportera till xml har många fördelar - läsbarhet, export av hela objektet och inget behov av att göra en uppgradering.

Låt oss försöka läs xml-fil.

Lite läsning från xml

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

Låt oss återgå till uppgiften. Vi skrev en testfil, läs den, lagringsformatet är tydligt, om det behövs kan du skriva en separat liten filredigerare för att lägga till och ta bort rader.

Låt mig påminna om att uppgiften var att göra en liten träningsbot.

Arbetsformat: Jag skickar kommandot "exempel" till boten, boten skickar mig ett slumpmässigt valt ord och transkription, och efter 10 sekunder skickar jag en översättning och kommentar till mig. Vi vet hur man läser kommandon, vi skulle också vilja lära oss hur man automatiskt väljer och kontrollerar proxyservrar och återställer meddelanderäknare till glömska.

Låt oss avkommentera allt som tidigare kommenterats som onödigt, kommentera de nu onödiga exemplen med txt och csv och spara filen som version B106

Åh, ja. Låt oss skicka något till boten igen.

6. Utskick från funktioner och mer

Innan du behandlar mottagningen måste du skapa en funktion för att skicka "minst något" annat än ett testmeddelande.

Naturligtvis kommer vi i exemplet att ha bara en sändning och bara en bearbetning, men vad händer om vi behöver göra samma sak flera gånger?

Det är lättare att skriva en funktion. Så vi har en variabel av typen objekt $MyVocabExample4AsArray, läst från filen, i form av en array med så många som två element.
Låt oss gå och läsa.

Samtidigt kommer vi att ta itu med klockan; vi kommer att behöva den senare (i själva verket kommer vi inte att behöva den i det här exemplet :)

Någon 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
}

Som du lätt kan se anropar funktionen $MyToken och $MyChatID, som hårdkodades tidigare.

Det finns inget behov av att göra detta, och om $MyToken är en för varje bot, kommer $MyChatID att ändras beroende på chatten.

Men eftersom detta är ett exempel kommer vi att ignorera det för tillfället.

Eftersom $MyVocabExample4AsArray inte är en array, även om den är väldigt lik en, så du kan inte bara ta det begära dess längd.

Återigen måste vi göra något som inte kan göras - hoppa fallskärm inte enligt koden - ta det och räkna

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

Slumpmässig intressant funktion. Låt oss säga att vi vill ta emot 0 eller 1 (vi har bara två element i arrayen). När vi sätter gränserna 0..1, får vi "1"?
nej - vi kommer inte att få det, vi har ett speciellt exempel Exempel 2: Få ett slumpmässigt heltal mellan 0 och 99 Get-Random -Max 100
Därför måste vi för 0..1 ställa in storleken 0..2, med maximalt antal element = 1.

7. Behandling av inkommande meddelanden och maximal kölängd

Var slutade vi tidigare? vi har den mottagna variabeln $MyMessageGet
och $Content4Pars01 erhållen från den, av vilka vi är intresserade av elementen i Content4Pars01.result-matrisen

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

Låt oss skicka boten /meddelande10, /meddelande11, /meddelande12, /ord och igen /ord och /hej.
Låt oss se vad vi har:

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

Låt oss gå igenom allt mottaget och skicka ett svar om meddelandet var /word
fallet med konstruktion, vad vissa beskriver som if-elseif, kallas i powershell via switch. Samtidigt använder koden nedan nyckeln -jokertecken, vilket är helt onödigt och till och med skadligt.

Någon kod #7.1

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

Låt oss köra skriptet ett par gånger. Vi kommer att få samma ord två gånger för varje exekveringsförsök, speciellt om vi gjorde ett misstag i implementeringen av slumpmässigt.

Men sluta. Vi skickade inte /word igen, så varför bearbetas meddelandet igen?

Kön för att skicka meddelanden till boten har en ändlig längd (100 eller 200 meddelanden, tror jag) och måste rensas manuellt.

Detta står givetvis beskrivet i dokumentationen, men du måste läsa det!

I det här fallet behöver vi parametern ?chat_id, och &timeout, &limit, &parse_mode=HTML och &disable_web_page_preview=true behövs inte ännu.

Dokumentation för telegram api är här
Det står på vitt och engelska:
Identifierare för den första uppdateringen som ska returneras. Måste vara en större än den högsta bland identifierarna för tidigare mottagna uppdateringar. Som standard, uppdateringar som börjar med den tidigaste
obekräftad uppdateringen returneras. En uppdatering anses vara bekräftad så snart getUpdates anropas med en offset högre än dess update_id. Den negativa offseten kan specificeras för att hämta uppdateringar från -offsetuppdatering från slutet av uppdateringskön. Alla tidigare uppdateringar kommer att glömmas.

Låt oss titta på:

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

Ja, och vi återställer den och skriver om funktionen lite. Vi har två alternativ - skicka hela meddelandet till funktionen och bearbeta det helt i funktionen, eller ge bara meddelande-ID och återställ det. Till exempel ser den andra enklare ut.

Tidigare såg vår frågesträng "alla meddelanden" ut

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

och det kommer att se ut

$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 

Ingen förbjuder dig att först ta emot alla meddelanden, bearbeta dem, och först efter framgångsrik bearbetning begäran obekräftad -> bekräftad.

Varför är det vettigt att ringa bekräftelse efter att all behandling har slutförts? Ett misslyckande är möjligt mitt under exekveringen, och om det till exempel med en gratis chatbot inte är något speciellt att sakna ett enda meddelande, då kan resultatet bli värre om du behandlar någons lön eller korttransaktion.

Ett par rader kod till

$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. Istället för en slutsats

Grundfunktioner - att läsa meddelanden, återställa kö, läsa från fil och skriva till fil görs och visas.

Det finns bara fyra saker kvar att göra:

  • skicka rätt svar på en förfrågan i chatten
  • skicka ett svar till ALLA chatt som boten har lagts till
  • exekvera kod i en loop
  • starta en bot från Windows Schemaläggare.

Alla dessa uppgifter är enkla och kan enkelt utföras genom att läsa dokumentationen om parametrar som t.ex
Set-ExecutionPolicy Unrestricted och -ExecutionPolicy Bypass
formulärets cykel

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

Tack till alla som läser.

Källa: will.com

Lägg en kommentar