Skabelon til en simpel telegrambot til skolebørn i 7-9 klasse ved hjælp af Powershell

Under samtaler med en ven lærte jeg pludselig, at børn i 8.-10. klasse på deres skole slet ikke bliver undervist i programmering. Word, Excel og det hele. Intet logo, ikke engang Pascal, ikke engang VBA til Excel.

Jeg blev meget overrasket, åbnede internettet og begyndte at læse -
En af en specialskoles opgaver er at fremme uddannelsen af ​​en ny generation, der opfylder informationssamfundets betingelser i dets udviklingsniveau og livsstil.
Dette kursus vil give eleverne mulighed for i praksis at konsolidere deres viden om de grundlæggende konstruktioner af Pascal-programmeringssproget. (fra programmet for en eller anden gymnastiksal for 2017)

Til sidst besluttede jeg at bruge et par timer og skitsere et eksempel på "hvordan man laver en simpel bot til skolebørn."

Nedenfor snittet er, hvordan man skriver endnu en simpel bot i Powershell og får den til at fungere uden en webhook, hvide IP'er, dedikerede servere, installerede virtuelle maskiner i skyen og så videre - på en almindelig hjemme-pc med almindelig Windows.

TLDR: Endnu en kedelig artikel med grammatiske og faktuelle fejl, intet at læse, ingen humor, ingen billeder.

Der er ikke noget nyt i artiklen, næsten alt skrevet før har allerede været på Habré, for eksempel i artikler Instruktioner: Sådan opretter du bots i Telegram и Telegram bot til systemadministrator.
Desuden er artiklen bevidst overflødig for ikke at referere til undervisningslitteratur hver gang. Der er ingen referencer til Gang 4, PowerShell Deep Dives eller for eksempel The 5 Pillars of the AWS Well-Architected Framework i teksten.

I stedet for et forord kan du springe over

Spring gerne overI 2006 udgav Microsoft PowerShell 1.0 til den daværende Windows XP, Vista og Server 2003. På nogle måder erstattede det sådanne ting som cmdbat-scripts, vb-scripts, Windows Script Host og JScript.

Selv nu kan PowerShell kun betragtes som det næste trin efter Logo-indstillingerne, i stedet for det sandsynligvis stadig brugte Delphi (eller noget ældre), på trods af tilstedeværelsen af ​​loops, klasser, funktioner, MS GUI-kald, Git integration og så videre.

Powershell bruges relativt sjældent; du kan kun støde på det i form af PowerShell Core, VMware vSphere PowerCLI, Azure PowerShell, MS Exchange, Desired State Configuration, PowerShell Web Access og et dusin mere sjældent brugte programmer og funktioner. Måske får han en anden vind med udgivelsen WSL2, men det er det ikke ligefrem.

Powershell har også tre store fordele:

  1. Det er relativt enkelt, der er meget litteratur og eksempler om det, og selv på russisk f.eks. en artikel om Foreach - fra bogen PowerShell i dybden - om forskellen () og {}
  2. Han går med redaktøren ISE, inkluderet med Windows. Der er endda en slags debugger der.
  3. Det er nemt at ringe fra den komponenter til opbygning af en grafisk grænseflade.

0. Forberedelse.

Vi skal bruge:

  • Windows PC (jeg har Windows 10)
  • I det mindste en form for internetadgang (via NAT for eksempel)
  • For dem, der har begrænset adgang til telegram - installeret og konfigureret freegate i browseren, i nogle vanskelige tilfælde, sammen med Symple DNS Crypt
  • At have en fungerende telegramklient på din telefon
  • Forstå det helt grundlæggende - hvad en variabel, array, loop er.

Åbnet og læst artikler - Instruktioner: Sådan opretter du bots i Telegram и Telegram bot til systemadministrator

1. Lad os oprette endnu en testbot.

Da alle allerede ved dette, og allerede er sket, kan du også springe det overSom nævnt i artiklen ovenfor - Først og fremmest en bot til Telegram - det er stadig et program, der kører på din side og sender anmodninger til Telegram Bot API. Desuden er API'en klar - botten tilgår en bestemt URL med parametre, og Telegram svarer med et JSON-objekt.

Relaterede problemer: Hvis du på en ukendt måde tager noget kode fra et JSON-objekt og på en eller anden måde sender det til eksekvering (ikke med vilje), vil koden blive eksekveret for dig.

Oprettelsesprocessen er beskrevet i to artikler ovenfor, men jeg gentager: i et telegram åbner vi kontakter, leder efter @botfather, fortæller ham /newbot, laver en bot Botfortest12344321, kalder den Mynext1234bot og modtager en besked med en unik nøgle til formular 1234544311:AbcDefNNNNNNNNNNNNNN

Pas på nøglen og giv den ikke væk!

Så kan du konfigurere botten, for eksempel, forbyde at tilføje den til grupper, men i de første trin er dette ikke nødvendigt.

Lad os bede BotFather om "/mybot" og justere indstillingerne, hvis vi ikke kan lide noget.

Lad os åbne kontakterne igen, find @Botfortest12344321 der (det er obligatorisk at starte søgningen med @), klik på "start" og skriv til botten "/Glory to the robots." Tegnet / er påkrævet, tilbud er ikke nødvendigt.
Botten vil selvfølgelig ikke svare på noget.

Lad os kontrollere, at botten er oprettet og åbne den.

api.telegram.org/bot1234544311:AbcDefNNNNNNNNNNNNNN/getMe
hvor 1234544311:AbcDefNNNNNNNNNNNNNN er den tidligere modtagne nøgle,
og få en linje som
{"ok":true,"result":{""}}

Vi har den første hemmelige sætning (token). Nu skal vi finde ud af det andet hemmelige nummer - ID'et for chatten med botten. Hver chat, gruppe osv. er individuel og har sit eget nummer (nogle gange med minus - for åbne grupper). For at finde ud af dette nummer skal vi anmode om adressen i browseren (faktisk er det slet ikke nødvendigt i browseren, men for en bedre forståelse kan du starte med det) (hvor 1234544311:NNNNNNNNNN er dit token

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

og få et svar som

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

Vi har brug for chat_id.

Lad os tjekke, at vi kan skrive til chatten manuelt: ring til adressen fra browseren

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

Hvis du modtager en besked fra en bot i din chat, okay, du går videre til næste fase.

På denne måde (via browseren) kan du altid tjekke om der er problemer med linkgenereringen, eller om noget er gemt et sted og ikke virker.

Hvad du skal vide, før du fortsætter med at læse

Telegram har flere typer gruppechat (åben, lukket). For disse chats er nogle af funktionerne (for eksempel id) forskellige, hvilket nogle gange forårsager nogle problemer.

Lad os antage, at det er slutningen af ​​2019, og endda vores tids helt, det velkendte Man-Orchestra (administrator, advokat, informationssikkerhedsspecialist, programmør og praktisk talt MVP) Evgeniy V. adskiller $i-variablen fra et array, har mestret loops, se i de næste par år vil mestre Chocolatey, og så Parallel behandling med PowerShell и For hvert objekt parallelt det kommer.

1. Vi tænker over, hvad vores bot vil gøre

Jeg havde ingen idéer, jeg måtte tænke. Jeg har allerede skrevet en bot-notesbog. Jeg ville ikke lave en bot "der sender noget et sted hen." For at oprette forbindelse til Azure skal du bruge et kreditkort, men hvor får eleven det fra? Det skal bemærkes, at alt ikke er så slemt: de vigtigste skyer giver en form for testperiode gratis (men du har stadig brug for et kreditkortnummer - og det ser ud til, at der vil blive debiteret en dollar fra det. Jeg kan ikke huske, om den blev returneret senere.)

Uden AI ML er det ikke så interessant at gøre en bot-fattig.

Jeg besluttede at lave en bot, der minder mig (eller ikke mig) om engelske ord fra ordbogen.
For at undgå at rode med databasen vil ordbogen blive gemt i en tekstfil og opdateret manuelt.
I dette tilfælde er opgaven at vise det grundlæggende i arbejdet og ikke at lave mindst et delvist færdigt produkt.

2. At prøve hvad og hvordan for første gang

Lad os oprette en mappe C:poshtranslate
Lad os først se, hvilken slags powershell vi har, lad os starte ISE via start-run
powershell ise
eller find Powershell ISE i installerede programmer.
Efter lanceringen åbnes den sædvanlige velkendte "en slags editor"; hvis der ikke er noget tekstfelt, kan du altid klikke på "Filer - opret ny".

Lad os se på versionen af ​​powershell - skriv i tekstfeltet:

get-host 

og tryk på F5.

Powershell vil tilbyde at gemme - "Scriptet du er ved at køre vil blive gemt.", vi er enige, og gemmer filen fra powershell med navnet i C: poshtranslate myfirstbotBT100.

Efter lanceringen får vi i det nederste tekstvindue en datatabel:

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

Jeg har 5.1 noget, det er nok. Hvis du har en gammel Windows 7/8 så er der ingen big deal - selvom PowerShell skal opdateres til version 5 - f.eks. Kørselsvejledning.

Skriv Get-Date i kommandolinjen nedenfor, tryk på Enter, se på tiden, gå til rodmappen med kommandoen
cd
og ryd skærmen med cls-kommandoen (nej, du behøver ikke bruge rm)

Lad os nu tjekke, hvad der virker og hvordan - lad os ikke engang skrive koden, men to linjer, og prøve at forstå, hvad de gør. Lad os kommentere linjen med get-host med #-symbolet og tilføje lidt.

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

(Det interessante er, at der i rullelisten til kodeformatering på Habré er to dusin muligheder - men Powershell er der ikke. Dos er der. Perl er der.)

Og lad os køre koden ved at trykke på F5 eller ">" fra GUI'en.

Vi får output:

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

Lad os nu se på disse to linjer og nogle interessante punkter, så vi ikke vender tilbage til dette i fremtiden.

I modsætning til Pascal (og ikke kun), forsøger PowerShell selv at bestemme, hvilken type der skal tildeles til en variabel; flere detaljer om dette er skrevet i artiklen Uddannelsesprogram om at skrive på programmeringssprog
Derfor, ved at oprette en $TimeNow-variabel og tildele den værdien af ​​den aktuelle dato og klokkeslæt (Get-Date), behøver vi ikke at bekymre os for meget om, hvilken type data der vil være der.

Sandt nok kan denne uvidenhed skade senere, men det er til senere. Nedenfor i teksten vil der være et eksempel.
Lad os se, hvad vi har. Lad os udføre (på kommandolinjen)

$TimeNow | Get-member

og få en side med uforståelig tekst

Eksempel på uforståelig tekst 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, er en variabel af typen TypeName: System.DateTime blevet oprettet med en masse metoder (i betydningen af, hvad vi kan gøre med dette variable objekt) og egenskaber.

Lad os ringe $TimeNow.DayOfYear — vi får nummeret på årets dag.
Lad os ringe $TimeNow.DayOfYear | Get-Member - vi får TypeName: System.Int32 og en gruppe af metoder.
Lad os ringe $TimeNow.ToUniversalTime() - og få tiden i UTC

Debugger

Nogle gange sker det, at det er nødvendigt at udføre et program op til en bestemt linje og se programmets tilstand på det tidspunkt. Til dette formål har ISE en Debug-funktion - skifte pausepunkt
Sæt et brudpunkt et sted i midten, kør disse to linjer og se, hvordan bruddet ser ud.

3. Forstå interaktionen med Telegram-bot

Selvfølgelig er der skrevet endnu mere litteratur om interaktion med botten, med alle getpush og så videre, men spørgsmålet om teori kan overvejes valgfrit.

I vores tilfælde er det nødvendigt:

  • Lær at sende noget i korrespondance
  • Lær at få noget fra korrespondance

3.1 At lære at sende noget i korrespondance og modtage fra det

En lille kode - 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

og i Den Russiske Føderation får vi på dette tidspunkt fejlen Kan ikke oprette forbindelse til fjernserveren.

Eller vi modtager det ikke - afhænger af teleoperatøren og om proxyen er konfigureret og fungerer
Nå, det eneste, der er tilbage, er at tilføje en proxy. Bemærk venligst, at det er ekstremt farligt for dit helbred at bruge en ukrypteret og generelt svigagtig proxy.

Opgaven med at finde en fungerende proxy er ikke særlig vanskelig - de fleste af de offentliggjorte http-proxies fungerer. Jeg tror, ​​den femte virkede for mig.

Syntaks ved hjælp af proxy:

Invoke-WebRequest -Uri $URL4SEND -Proxy $MyProxy

Hvis du modtager en besked i din chat med en bot, så er alt i orden, du kan komme videre. Hvis ikke, fortsæt med fejlretningen.

Du kan se, hvad din $URL4SEND-streng bliver til, og prøv at anmode om det i browseren, sådan her:

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

3.2. Vi lærte at skrive "noget" i chat, lad os nu prøve at læse det

Lad os tilføje 4 linjer mere og se, hvad der er inde gennem | få-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 interessante er givet til os

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

Lad os se, hvad der er i dem:

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

Hvis alt fungerer for dig, vil du få en lang linje som:

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

Heldigvis, i den tidligere publicerede artikel Telegram bot for systemadministrator denne linje (ja, ifølge $MyMessageGet.RawContent | get-medlem er System.String), er allerede blevet adskilt.

4. Behandle det, du modtager (vi ved allerede, hvordan man sender noget)

Som allerede skrevet her, de mest nødvendige ting ligger i indholdet. Lad os se nærmere på det.

Først vil vi skrive et par sætninger mere til botten fra webgrænsefladen eller fra telefonen

/message1
/message2
/message3

og se gennem browseren på adressen, der blev dannet i $URLGET-variablen.

Vi vil se noget som:

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

Hvad er det? Nogle komplekse objekter fra arrays af objekter, der indeholder en ende-til-ende-meddelelse-id, chat-id, afsender-id og en masse anden information.

Vi behøver dog ikke finde ud af "hvilken slags objekt dette er" - en del af arbejdet er allerede gjort for os. Lad os se, hvad der er indeni:

Læsning af modtagne beskeder 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. Hvad skal vi gøre ved det nu?

Lad os gemme den resulterende fil under navnet myfirstbotBT105 eller hvad du bedst kan lide, ændre titlen og kommentere al den allerede skrevne kode via

<#start comment 105 end comment 105#>

Nu skal vi beslutte, hvor vi skal hente ordbogen (nå, hvor - på disk i en fil), og hvordan den vil se ud.

Selvfølgelig kan du skrive en kæmpe ordbog lige i teksten til manuskriptet, men det er fuldstændig ved siden af.
Så lad os se, hvad powershell kan arbejde med normalt.
Faktisk er han ligeglad med, hvilken fil han arbejder med, og vi er ligeglade.
Vi har et valg: txt (du kan, men hvorfor), csv, xml.
Kan vi se alle? Lad os se alle.
Lad os oprette en klasse MyVocabClassExample1 og en variabel $MyVocabExample1
Jeg bemærker, at klassen er skrevet uden $

noget 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

Lad os prøve at skrive dette ind i filer vha eksemplarisk.

Noget 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

- og vi får en fejl på linjen Out-File -FilePath $MyFilenameExample01 -InputObject -Append $MyVocabExample2.

Han vil ikke tilføje, ah-ah, sikke en skam.

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

Lad os se, hvad der sker. Fantastisk tekstvisning - men hvordan eksporteres det tilbage? Skal jeg indføre en form for tekstseparatorer, såsom kommaer?

Og i sidste ende får du en "kommaseparerede værdier (CSV) fil A STOP VENT.
#

$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 du nemt kan se, er MS ikke særlig kendetegnet ved sin logik; for en lignende procedure bruges i et tilfælde -FilePath, i et andet -Path.

Derudover forsvandt det russiske sprog i den tredje fil, i den fjerde fil viste det sig... ja, der skete noget. #TYPE System.Object[] 00
# "Tæl","Længde","LangLængde","Rank","SyncRoot","IsReadOnly","IsFixedSize","IsSynchronized"
#
Lad os omskrive det lidt:

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

Det ser ud til at have hjulpet, men jeg kan stadig ikke lide formatet.

Jeg kan især ikke lide, at jeg ikke kan lægge linjer fra et objekt ind i en fil direkte.
Forresten, siden vi begyndte at skrive til filer, kan vi så begynde at føre en opstartslog? Vi har tid som variabel, vi kan indstille filnavnet.

Sandt nok er der ikke noget at skrive endnu, men du kan tænke på, hvordan du bedst roterer loggene.
Lad os prøve xml for nu.

Nogle 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

Eksport til xml har mange fordele - læsbarhed, eksport af hele objektet og ingen grund til at udføre en udvidelse.

Lad os prøve læs xml-fil.

Lidt læsning fra xml

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

Lad os vende tilbage til opgaven. Vi skrev en testfil, læs den, lagringsformatet er klart, om nødvendigt kan du skrive en separat lille fileditor for at tilføje og slette linjer.

Lad mig minde dig om, at opgaven var at lave en lille træningsbot.

Arbejdsformat: Jeg sender kommandoen "eksempel" til botten, botten sender mig et tilfældigt udvalgt ord og transskription, og efter 10 sekunder sender jeg mig en oversættelse og kommentar. Vi ved, hvordan man læser kommandoer, vi vil også gerne lære, hvordan man automatisk vælger og kontrollerer proxyer og nulstiller beskedtællere til glemsel.

Lad os fjerne alt, der tidligere er kommenteret ud som unødvendigt, kommentere de nu unødvendige eksempler med txt og csv, og gemme filen som version B106

Åh ja. Lad os sende noget til botten igen.

6. Afsendelse fra funktioner og mere

Før du behandler modtagelsen, skal du oprette en funktion til at sende "i det mindste noget" andet end en testmeddelelse.

Selvfølgelig vil vi i eksemplet kun have én afsendelse og kun én behandling, men hvad nu hvis vi skal gøre det samme flere gange?

Det er nemmere at skrive en funktion. Så vi har en variabel af typen objekt $MyVocabExample4AsArray, læst fra filen, i form af en matrix med så mange som to elementer.
Lad os læse.

Samtidig vil vi beskæftige os med uret; vi får brug for det senere (faktisk har vi ikke brug for det i dette eksempel :)

Noget 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
}

Som du nemt kan se, kalder funktionen $MyToken og $MyChatID, som tidligere var hårdkodet.

Det er ikke nødvendigt at gøre dette, og hvis $MyToken er en for hver bot, så vil $MyChatID ændre sig afhængigt af chatten.

Men da dette er et eksempel, vil vi ignorere det indtil videre.

Da $MyVocabExample4AsArray ikke er et array, selvom det minder meget om en, så du kan ikke bare tage det anmode om dens længde.

Endnu en gang bliver vi nødt til at gøre noget, der ikke kan lade sig gøre - springe i faldskærm ikke i henhold til koden - tag det og tæl

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

Tilfældig interessant funktion. Lad os sige, at vi ønsker at modtage 0 eller 1 (vi har kun to elementer i arrayet). Når vi sætter grænser 0..1, får vi "1"?
nej - vi får det ikke, vi har et særligt eksempel Eksempel 2: Få et tilfældigt heltal mellem 0 og 99 Get-Random -Maksimum 100
Derfor skal vi for 0..1 indstille størrelsen 0..2, med det maksimale elementantal = 1.

7. Behandling af indgående beskeder og maksimal kølængde

Hvor stoppede vi tidligere? vi har den modtagne variabel $MyMessageGet
og $Content4Pars01 opnået fra det, hvoraf vi er interesserede i elementerne i Content4Pars01.result-arrayet

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

Lad os sende botten /message10, /message11, /message12, /word og igen /word og /hello.
Lad os se, hvad vi har:

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

Lad os gennemgå alt modtaget og sende et svar, hvis beskeden var /word
tilfældet med konstruktion, hvad nogle beskriver som if-elseif, kaldes i powershell via switch. Samtidig bruger koden nedenfor -wildcard-nøglen, hvilket er helt unødvendigt og endda skadeligt.

Noget kode #7.1

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

Lad os køre scriptet et par gange. Vi får det samme ord to gange for hvert udførelsesforsøg, især hvis vi lavede en fejl i implementeringen af ​​tilfældig.

Men stop. Vi sendte ikke /word igen, så hvorfor behandles beskeden igen?

Køen for at sende beskeder til botten har en begrænset længde (100 eller 200 beskeder, tror jeg) og skal ryddes manuelt.

Dette er selvfølgelig beskrevet i dokumentationen, men du skal læse det!

I dette tilfælde har vi brug for parameteren ?chat_id, og &timeout, &limit, &parse_mode=HTML og &disable_web_page_preview=true er ikke nødvendige endnu.

Dokumentation for telegram api er her
Der står på hvidt og engelsk:
Identifikator for den første opdatering, der skal returneres. Skal være én større end den højeste blandt identifikatorerne for tidligere modtagne opdateringer. Som standard starter opdateringer med den tidligste
ubekræftet opdatering returneres. En opdatering betragtes som bekræftet, så snart getUpdates kaldes med en offset højere end dens update_id. Den negative offset kan specificeres for at hente opdateringer startende fra -offset update fra slutningen af ​​opdateringskøen. Alle tidligere opdateringer vil blive glemt.

Lad os se på:

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

Ja, og vi nulstiller det og omskriver funktionen lidt. Vi har to muligheder - videregive hele beskeden til funktionen og behandle den helt i funktionen, eller giv kun besked-id'et og nulstil den. For eksempel ser den anden enklere ud.

Tidligere så vores "alle meddelelser" forespørgselsstreng sådan ud

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

og det vil se ud

$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 forbyder dig først at modtage alle beskeder, behandle dem, og kun efter vellykket behandling anmodning ubekræftet -> bekræftet.

Hvorfor giver det mening at ringe til bekræftelse efter al behandling er afsluttet? En fejl er mulig midt i udførelsen, og hvis det for eksempel med en gratis chatbot ikke er noget særligt at mangle en enkelt besked, så hvis du behandler en persons løn eller korttransaktion, kan resultatet blive værre.

Et par linjer kode mere

$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. I stedet for en konklusion

Grundlæggende funktioner - læsning af beskeder, nulstilling af kø, læsning fra fil og skrivning til fil udføres og vises.

Der er kun fire ting tilbage at gøre:

  • sende det rigtige svar på en anmodning i chat
  • at sende et svar til ENHVER chat, som botten blev tilføjet til
  • eksekvere kode i en løkke
  • lancering af en bot fra Windows Scheduler.

Alle disse opgaver er enkle og kan nemt udføres ved at læse dokumentationen om parametre som f.eks
Set-ExecutionPolicy Unrestricted og -ExecutionPolicy Bypass
cyklus af formen

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

Tak til alle, der læste.

Kilde: www.habr.com

Tilføj en kommentar