I samtaler med en ven opdagede jeg pludselig, at børn i 8.-10. klasse på deres skole slet ikke lærer programmering. Word, Excel og alt det der. Ingen Logo, ikke engang Pascal, og slet ikke VBA til Excel.
Jeg blev meget overrasket, åbnede internettet og begyndte at læse —
En af opgaverne for den specialiserede skole er at fremme dannelsen af en ny generation, der svarer til informationssamfundets krav med deres udviklingsniveau og livsstil.
Dette kursus gør det muligt for eleverne at praktisere deres viden om de grundlæggende strukturer i programmeringssproget Pascal. (fra et eller andet gymnasieprogram fra 2017)
Jeg besluttede derfor at bruge et par timer på at skitsere et eksempel på 'hvordan man opretter en simpel bot — til skoleelever'.
Under cut'en om hvordan man skriver en ny simpel bot i PowerShell og får den til at fungere uden webhook, hvide IP-adresser, dedikerede servere, udrulbare virtuelle maskiner i skyen og alt det andet — på en almindelig hjemme-PC med almindelig Windows.
TLDR: Endnu en kedelig artikel med grammatiske og faktiske fejl, ikke meget at læse, intet humor, ingen billeder.
Der er ikke noget nyt i artiklen, næsten alt det skrevet tidligere har allerede været på Habr, for eksempel i artiklerne og .
Desuden er artiklen specielt overflødig for ikke at skulle henvise til lærebøger hver gang. Ingen henvisninger til Band 4, PowerShell Deep Dives eller for eksempel The 5 Pillars of the AWS Well-Architected Framework i teksten.
I stedet for et forord kan vi springe det over
Lad os roligt springe det overI 2006 udgav Microsoft PowerShell 1.0 til dengang Windows XP, Vista og Server 2003. På en måde erstattede det ting som cmd-batch scripts, vb-scripts, Windows Script Host og JScript.
Selv nu kan PowerShell betragtes som det næste skridt efter versioner af Logo, i stedet for måske stadig brugte Delphi (eller noget ældre), på trods af at det indeholder løkker, klasser, funktioner, MS GUI-opkald, og så videre.
PowerShell anvendes relativt sjældent, man kan støde på det kun i form af PowerShell Core, VMware vSphere PowerCLI, Azure PowerShell, MS Exchange, Desired State Configuration, og et dusin andre sjældent brugte programmer og funktioner. Måske vil det få et nyt liv med udgivelsen , men det er ikke sikkert.
PowerShell har også tre store fordele:
- Det er relativt simpelt, der er masser af litteratur og eksempler om det, også på russisk, for eksempel artiklen om Foreach — fra bogen — om forskellen mellem () og {}
- Det kommer sammen med editoren , i pakken med Windows. Der er endda en slags debugger.
- Det er nemt at kalde på .
0. Forberedelse.
Vi har brug for:
- En PC med Windows (jeg har Windows 10)
- En eller anden internetforbindelse (gennem NAT for eksempel)
- For dem med begrænset adgang til Telegram — en installeret og konfigureret Freegate i browseren, i nogle komplekse tilfælde i samarbejde med Symple DNS Crypt
- En fungerende Telegram-klient på telefonen
- Forståelse af helt grundlæggende ting — hvad er en variabel, et array, en løkke.
Åbne og læste artikler — og
1. Lad os oprette en endnu en testbot.
Da alle allerede kender til dette, kan det også springes overSom nævnt i den ovenstående artikel — Først og fremmest er en bot for Telegram — det er stadig en applikation, der kører på din side og foretager forespørgsler til Telegram Bot API. Og API'et er simpelt — bot'en henvender sig til en bestemt URL med parametre, og Telegram svarer med et JSON-objekt.
Relaterede problemer: hvis du på en eller anden uforklarlig måde tager en kode fra JSON-objektet og på en eller anden måde sender det til udførelse (ikke med vilje) — vil koden blive udført hos dig.
Processen for at oprette den er beskrevet i de to artikler ovenfor, men lad mig gentage: i Telegram åbner vi kontakter, leder efter @botfather, siger til ham /newbot, opretter botten Botfortest12344321, navngiver den Mynext1234bot og modtager en meddelelse med en unik nøgle af typen 1234544311:AbcDefNNNNNNNNNNNNN
Pas på nøglen og del den ikke!
Derefter kan botten konfigureres, for eksempel for at forbyde tilføjelse til grupper, men i de første trin er det ikke nødvendigt.
Spørg BotFather om «/mybot» og ret indstillingerne, hvis noget ikke er tilfredsstillende.
Åbn igen kontakterne, find @Botfortest12344321 der (det er obligatorisk at starte søgningen med @), tryk på «start» og skriv til botten «/Skaff robotterne». Symbolet / er obligatorisk, anførselstegnene er ikke nødvendige.
Botten vil selvfølgelig ikke svare.
Lad os tjekke, at botten er oprettet — vi åbner.
:AbcDefNNNNNNNNNNNNN/getMe
hvor 1234544311:AbcDefNNNNNNNNNNNNN — den tidligere modtagne nøgle,
og vi får en streng af typen
{«ok»:true,«result»:{«»}}
Den første hemmelige sætning (token) har vi. Nu skal vi finde det andet hemmelige nummer — chat-ID'et med botten. Hver chat, gruppe osv. er individuel og har sit eget nummer (nogle gange med minus — for åbne grupper). For at finde dette nummer skal vi anmode om adressen i browseren (det er egentlig ikke nødvendigt at bruge browseren, men for bedre forståelse kan vi starte der) adressen (hvor 1234544311:NNNNNNNNN — det er dit token
https://api.telegram.org/bot1234544311:NNNNNNNNN/getUpdates
og få et svar af typen
{«ok»:true,«result»:[{«update_id»:…,… chat«:{«id»:123456789
Vi har brug for chat_id.
Lad os tjekke, om vi kan skrive i chatten manuelt: vi kalder adressen fra browseren
https://api.telegram.org/botdittoken/sendMessage?chat_id=123456789&text="Life is directed motion"Hvis der er kommet en besked fra botten til din chat — okay, så går du videre til næste trin.
På denne måde (gennem browseren) kan du altid tjekke, hvor problemerne opstår — hos dig under genereringen af linket, eller om noget er dækket og ikke fungerer.
Hvad du skal vide, før du fortsætter med læsningen
I Telegram er der flere typer af gruppechats (åbne, lukkede). For disse chats varierer nogle funktioner (for eksempel id), hvilket nogle gange forårsager problemer.
Lad os antage, at det er slutningen af 2019, og selv helten i vores tid, den velkendte Manden-Orkester (administrator, jurist, informationssikkerhedsekspert, programmør og praktisk talt MVP) Evgeny V. kan skelne mellem variablen $i og array'et, har mestret loops, og hvem ved, måske om et par år vil han mestre Chocolatey, og så når han til og komme dertil.
1. Vi tænker over, hvad vores bot skal gøre
Jeg havde ingen idéer, måtte tænke. Jeg har allerede lavet en bot-notesbog. At lave en bot 'som sender noget et sted hen' ønskede jeg ikke. For at tilslutte Azure skal man have et kreditkort, og hvor får en skoleelev det fra? Det skal bemærkes, at alt ikke er så dårligt: de vigtigste skyer giver en slags gratis prøveperiode (men et kreditkortnummer er stadig nødvendigt — og det vil blive trukket et eller andet sted, tror jeg en dollar. Jeg kan ikke huske, om det kom tilbage senere.)
Uden AI ML er det ikke så interessant at lave en bot-ørsla-verse.
Jeg besluttede at lave en bot, som vil minde mig (eller ikke mig) om engelske ord fra ordbogen.
Ordbogen, så jeg ikke skal bøvle med en database, vil ligge i en tekstfil og blive opdateret manuelt.
I dette tilfælde er opgaven at vise grundlæggende funktioner i arbejdet, ikke at lave et produkt, der i det mindste er delvist færdigt.
2. Vi prøver noget for første gang
Vi opretter mappen C:poshtranslate
For at starte, lad os se, hvad vi har af PowerShell, og åbne ISE via kør
powershell ise
eller find PowerShell ISE blandt de installerede programmer.
Efter opstart åbnes en almindelig redigerer; hvis der ikke vises et tekstfelt, kan du altid klikke på "Fil - opret ny".
Lad os se versionen af PowerShell - skriv i tekstfeltet:
get-host
og tryk på F5.
PowerShell vil spørge, om vi vil gemme - "The script you are about to run will be saved.", vi accepterer og gemmer filen fra PowerShell med navnet myfirstbotBT100.
Efter opsætningen får vi en datatabel i det nederste tekstvindue:
Navn : Windows PowerShell ISE Host
Version : 5.1.(osv.)
Jeg har 5.1 med noget ekstra, det er tilstrækkeligt. Hvis du har en ældre Windows 7/8, er der ikke noget at frygte - det er dog nødvendigt at opdatere PowerShell til version 5 - for eksempel via .
Skriv i kommandolinjen nedenfor Get-Date, tryk Enter, se på tiden, gå til rodmappen med kommandoen
cd
og ryd skærmen med kommandoen cls (nej, brug ikke rm)
Nu skal vi tjekke, hvad og hvordan det virker - vi skriver ikke engang kode, men to linjer, og prøver at forstå, hvad de gør. Vi kommenterer linjen med get-host med symbolet # og tilføjer lidt.
# Пример шаблона бота
# get-host
<# это пример многострочного комментария #>
$TimeNow = Get-Date
$TimeNow
(Det interessante er, at der i rullelisten til kodesyntax på Habr er flere dusin muligheder - men PowerShell er ikke der. Dos er der. Perl er der.)
Og vi kører koden ved at trykke på F5 eller ">" fra GUI.
Vi får output:
Lørdag, 8. december 2019 21:00:50 PM (eller noget lignende)
Nu skal vi se nærmere på disse to linjer, og nogle interessante punkter, så vi ikke skal tilbage til dette senere.
I modsætning til Pascal (og ikke kun), forsøger PowerShell selv at bestemme, hvilken type der skal tildeles variablen, mere om dette står i artiklen
Derfor, når vi opretter variablen $TimeNow og tildeler den værdien af den nuværende dato og tid (Get-Date), behøver vi ikke at bekymre os meget om, hvilken datatypen vil være.
Sandt nok kan uvidenheden om dette senere være smertefuld, men det er senere. Nedenfor i teksten vil der være et eksempel.
Lad os se, hvad vi har fået. Udfør (i kommandolinjen)
$TimeNow | Get-memberog få en side med uforståelig tekst
Eksempel på uforståelig tekst nummer 1
PS C:> $TimeNow | Get-member
TypeName: System.DateTime
Navn MedlemsType Definition
---- ---------- ----------
Tilføj <b>Metode </b>datetime Tilføj(timespan værdi)
..
Visningshint NoteProperty VisningshintType Visningshint=DateTime
Dato <b>Egenskab </b>datetime Dato {get;}
År Egenskab int År {get;}
..
DateTime ScriptProperty System.Object DateTime {get=if ((& { Set-StrictMode -Version 1; $this.Visningshint }) -ieq "Dato")...
Som det ses, er variablen af typen TypeName: System.DateTime med masser af metoder (dvs. hvad vi kan gøre med dette objekt/variabel) og egenskaber.
Lad os kalde $TimeNow.DayOfYear — vi får dagen i året.
Lad os kalde $TimeNow.DayOfYear | Get-Member — vi får TypeName: System.Int32 og gruppen af metoder.
Lad os kalde $TimeNow.ToUniversalTime() — og får tiden i UTC
er oversat
Some gange er det nødvendigt at køre et program op til en bestemt linje og se, hvordan programmet står i det øjeblik. Til dette har ISE en debugger - toggle break point
Sæt et breakpoint et sted midt i koden, kør disse to linjer, og se hvordan stoppet ser ud.
3. Forstå hvordan man interagerer med Telegram-botten
Selvom der er skrevet meget mere om interaktionen med botten, med alle getpush osv., kan vi vælge at overveje teorien.
I vores tilfælde er det nødvendigt:
- At lære at sende noget i samtalen
- At lære at modtage noget fra samtalen
3.1 Lær at sende noget i samtalen og modtage det også
Lidt kode — del 3
Write-output "Dette er del 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 = "Livet er rettet bevægelse - " + $TimeNow
$URL4SEND = "https://api.telegram.org/bot$MyToken/sendMessage?chat_id=$MyChatID&text=$MyText01"
Invoke-WebRequest -Uri $URL4SEND
og i Rusland får vi her en fejl: Unable to connect to the remote server.
Eller måske ikke — det afhænger af udbyderen og om proxyen er konfigureret og fungerer.
Nå — vi skal tilføje en proxy. Vær opmærksom på, at brug af en ukrypteret eller generelt suspekte proxyer er yderst farligt for dit helbred.
At finde en fungerende proxy er ikke så svært — de fleste offentligt tilgængelige http proxyer virker. Det var sandsynligvis den femte, der virkede for mig.
Syntaks med brug af proxy:
Invoke-WebRequest -Uri $URL4SEND -Proxy $MyProxy
Hvis du har fået en besked i din chat med botten — så er alt godt, og du kan gå videre. Hvis ikke — fortsæt med at debugge.
Du kan se, hvad din streng $URL4SEND bliver til, og prøve at anmode om den i din browser, for eksempel sådan her:
$URL4SEND2 = '"'+$URL4SEND+'"'
start chrome $URL4SEND2
3.2. Vi har lært at sende "noget" til chatten, nu prøver vi at læse det
Lad os tilføje endnu 4 linjer og se hvad der er indeni med | 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
Det mest interessante kommer til os fra
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 # her er noget interessant
Write-Host "RawContent"
$MyMessageGet.RawContent # og her er også interessant, men ligeledes læseligt.
Write-Host "Content"
$MyMessageGet.Content
Hvis alt fungerer, vil du få en lang streng som denne:
{"ok":true,"result":[{"update_id":12345678,
"message":{"message_id":3,"from":{"id"Heldigvis er denne linje allerede blevet behandlet i en tidligere artikel om Telegram-bot til systemadministratorer (ja, ifølge $MyMessageGet.RawContent | get-member — det er System.String), allerede blevet analyseret.
4. Behandle det modtagne (vi ved allerede, hvordan man sender noget)
Som allerede beskrevet , det mest nødvendige ligger i content. Lad os se nærmere på det.
Først vil vi skrive et par sætninger til bot'en via webgrænsefladen eller telefonen
/message1
/message2
/message3og se gennem browseren på adressen, der er dannet i variablen $URLGET.
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? En eller anden kompleks objekt af objekter, der indeholder en gennemgående identifikation af beskeden, chat-id, senders ID og en masse anden information.
Dog er det ikke nødvendigt for os at finde ud af "hvad er det for et objekt" — noget af arbejdet er allerede gjort for os. Lad os se hvad der er indeni:
Vi læser de modtagne beskeder eller del 4
Write-Host "Dette er del 4" <# selvfølgelig er denne linje ikke nødvendig i den endelige tekst, men den er praktisk at søge efter. #>
$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 så gøre med dette
Vi gemmer den modtagne fil under navnet myfirstbotBT105 eller hvad du nu synes er bedst, ændrer titlen og kommenterer hele den allerede skrevne kode ud gennem
<#start comment 105 end comment 105#>
Nu skal vi beslutte, hvor vi tager ordbogen fra (altså hvor — på disken i en fil) og hvordan den vil se ud.
Selvfølgelig kan man fylde en kæmpe ordbog direkte ind i scripts teksten, men det er ikke smart.
Så lad os se, hvad powershell normalt arbejder med.
Faktisk er det ligegyldigt for det, hvilken fil det arbejder med, men det er det ikke for os.
Til rådighed har vi: txt (kan bruges, men hvorfor), csv, xml.
Vi kan også kigge på alle mulighederne. Lad os se på alle.
Lad os oprette klassen MyVocabClassExample1 og variablen $MyVocabExample1
jeg bemærker, at klassen skrives uden $
lidt kode #5
write-host "Dette er del 5"
class MyVocabClassExample1 {
[string]$Original # ord
[string]$Transcript
[string]$Translate
[string]$Example
[int]$VocWordID # en meget interessant pointe. Brugen af int med dens begrænsninger kan nogle gange føre til vilde konsekvenser, som for eksempel - en nylig hændelse med SSD HPE. Oprindeligt tilføjede jeg ikke dette element, men senere tilføjede jeg det alligevel og kommenterede det.
}
$MyVocabExample1 = [MyVocabClassExample1]::new()
$MyVocabExample1.Original = "Apple"
$MyVocabExample1.Transcript = "[ ˈapəl ]"
$MyVocabExample1.Translate = "Æble"
$MyVocabExample1.Example = "Et æble er en sød, spiselig frugt produceret af et æbletræ (Malus domestica)"
# $MyVocabExample1.$VocWordID = 1
$MyVocabExample2 = [MyVocabClassExample1]::new()
$MyVocabExample2.Original = "Pear"
$MyVocabExample2.Transcript = "[ pe(ə)r ]"
$MyVocabExample2.Translate = "Pære"
$MyVocabExample2.Example = "Pæretræet (ˈpɛər) og busken er en art af genus Pyrus"
# $MyVocabExample1.$VocWordID = 2
Lad os prøve at skrive dette til filer efter .
Lidt kode #5.1
Write-Host $ScriptDir # jeg håber, du ikke har kommenteret $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å linje Out-File -FilePath $MyFilenameExample01 -InputObject -Append $MyVocabExample2.
Vil ikke tilføje, åh hvor ærgerligt.
$MyVocabExample3AsArray = @($MyVocabExample1,$MyVocabExample2)
Out-File -FilePath $MyFilenameExample02 -InputObject $MyVocabExample3AsArray
notepad $MyFilenameExample02
Lad os se hvad vi har fået. Vidunderlig tekstvisning — men hvordan eksporterer jeg det tilbage? Skal jeg indtaste nogle tekstseparatorer, som for eksempel kommaer?
Og til sidst få "filer med separatorer — kommaer, comma-separated values (CSV) A .
#
$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
Det er let at se, at MS ikke rigtig skiller sig ud med logikken, for en lignende procedure bruges der i ét tilfælde -FilePath, i det andet -Path.
Desuden er det tredje fil desværre blevet renset for dansk, og det fjerde fil er blevet... nå, noget er kommet ud. #TYPE System.Object[] 00
# „Count“,»Length»,«LongLength»,«Rank»,«SyncRoot»,«IsReadOnly»,«IsFixedSize»,«IsSynchronized»
#
Lad os omskrive 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 formatet tilfredsstiller mig stadig ikke.
Jeg bryder mig især ikke om, at jeg ikke kan placere strenge fra objektet direkte i filen.
Forresten, når vi er i gang med at skrive til filer — skal vi så ikke begynde at føre en log for opstart? Vi har jo tid som variabel, og vi kan give filnavnet.
Der er ikke meget at skrive endnu, men vi kan overveje, hvordan vi bedst kan håndtere logrotation.
Lad os prøve xml.
Lidt 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
Der er mange fordele ved eksport til xml — læsbarhed, eksport af hele objektet, og det er ikke nødvendigt at udføre append.
Lad os prøve .
Lidt læsning fra xml
$MyFilenameExample06 = $ScriptDir + "Example06.xml"
$MyVocabExample4AsArray = Import-Clixml -Path $MyFilenameExample06
# $MyVocabExample4AsArray
# $MyVocabExample4AsArray[0]
# og lidt om de helt ukendte nuancer. PowerShell opfører sig fra tid til anden ikke som man egentligt ville forvente.
# for eksempel er disse to output forskellige
# Write-Output $MyVocabExample4AsArray
# write-host $MyVocabExample4AsArray
Lad os vende tilbage til opgaven. Vi har skrevet en prøvefil, læst den, og opbevaringsformatet er klart; ved behov kan vi skrive en separat lille editor til filen for at tilføje og fjerne linjer.
Jeg minder om, at opgaven var at lave en lille træningsbot.
Arbejdsmåde: jeg sender botten kommandoen "eksempel", botten sender mig et tilfældigt valgt ord og transkription, og efter 10 sekunder sender den oversættelse og kommentar. Vi kan læse kommandoer, men vi skal også lære at automatisere proksisøgningen og nulstille beskedstællerne.
Lad os afkommentere alt det tidligere kommentar 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. Sending fra funktioner og ikke kun det
Før vi behandler modtagelsen, skal vi lave en sende-funktion "noget som helst" ud over testbeskeder.
Selvfølgelig vil vi kun have én sending i dette eksempel, med kun én proces, men hvad hvis vi skal gøre det flere gange?
Det er nemmere at skrive en funktion. Så vi har en objekttype variabel $MyVocabExample4AsArray, der er læst fra filen, som et array med to elementer.
Samtidig skal vi se på klokken; det får vi brug for senere (faktisk er det ikke nødvendigt i dette eksempel 🙂
Lidt kode #6.1
Write-Output "Dette er Del 6"
$Timezone = (Get-TimeZone)
IF($Timezone.SupportsDaylightSavingTime -eq $True){
$TimeAdjust = ($Timezone.BaseUtcOffset.TotalSeconds + 3600) } # det korrigerede tidspunkt
ELSE{$TimeAdjust = ($Timezone.BaseUtcOffset.TotalSeconds)
}
function MyFirstFunction($SomeExampleForFunction1){
$TimeNow = Get-Date
$TimeNow.ToUniversalTime()
# $MyText02 = $TimeNow + " " + $SomeExampleForFunction1 # og her får vi en fejl
$MyText02 = $SomeExampleForFunction1 + " " + $TimeNow # men her får vi ikke en fejl, hvem gætter hvorfor - den person er dygtig.
$URL4SendFromFunction = "https://api.telegram.org/bot$MyToken/sendMessage?chat_id=$MyChatID&text=$MyText02"
Invoke-WebRequest -Uri $URL4SendFromFunction -Proxy $MyProxy
}
Som det er nemt at se, kaldes $MyToken og $MyChatID i funktionen, som tidligere er hårdt tildelt.
Det bør ikke gøres, og hvis $MyToken er den samme for hver bot, vil $MyChatID ændre sig afhængigt af chatten.
Men da dette er et eksempel, ignorerer vi det for nu.
Da $MyVocabExample4AsArray ikke er et array, selvom det ligner et, kan man ikke bare tage og anmode om dets længde.
Man må endnu en gang lave det, man ikke skal gøre — udsætte sig selv uden for kodeks — tage og tælle
Lidt 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)
# eller i én linje
# MyFirstFunction($MyVocabExample4AsArray[Get-Random -Minimum 0 -Maximum ($MaxRandomExample -1)].Example)
# Gæt selv, hvilket eksempel der er lettere at læse for udenforstående.
Random . Antag, at vi ønsker at få 0 eller 1 (vi har kun to elementer i arrayet). Vil vi ved at angive grænserne 0..1 få "1"?
nej — vi får ikke det; vi har specielt angivet eksempel Example 2: Få et tilfældigt heltal mellem 0 og 99 Get-Random -Maximum 100
Derfor skal vi for 0..1 angive størrelsen 0..2, hvor den maksimale indeksnummer = 1.
7. Behandling af modtagne beskeder og maksimallængden på køen
Hvor stoppede vi før? Vi har den modtagne variabel $MyMessageGet
og den udtrukne $Content4Pars01, hvor vi er interesseret i elementerne i arrayet Content4Pars01.result
$Content4Pars01.result[0].update_id
$Content4Pars01.result[0].message
$Content4Pars01.result[0].message.text Vi sender til botten /message10, /message11, /message12, /word og igen /word og /hej.
Lad os se hvad vi har modtaget:
$Content4Pars01.result[0].message.text
$Content4Pars01.result[2].message.text Vi gennemgår alt det modtagne og sender et svar, hvis beskeden var /word
konstruktionen case of, som nogle beskriver som if-elseif, kaldes i PowerShell . I koden nedenfor er der anvendt en nøgle -wildcard, hvilket ikke er nødvendigt og endda skadeligt.
Lidt kode #7.1
Write-Output "Dette er del 7"
Foreach ($Result in $Content4Pars01.result) # Ja, det kan gøres hurtigere
{
switch -wildcard ($Result.message.text)
{
"\/word" {MyFirstFunction($TextForExample1)}
}
}
Lad os køre scriptet et par gange. Vi får det samme ord hver gang, især hvis vi laver en fejl i implementeringen af random.
Men vent. Vi har jo ikke sendt \/word igen, hvorfor bliver beskeden behandlet igen?
Køen til at sende beskeder til botten har en begrænset længde (tilsyneladende 100 eller 200 beskeder), og den skal ryddes manuelt.
Dette er selvfølgelig beskrevet i dokumentationen, men den skal man jo læse!
I dette tilfælde har vi brug for parameteren ?chat_id, mens &timeout, &limit, &parse_mode=HTML og &disable_web_page_preview=true ikke er nødvendige lige nu.
Dokumentationen til Der står klart og tydeligt på engelsk:
Identifier for den første opdatering, der skal returneres. Skal være større med én end den højeste blandt de tidligere modtagne opdateringer. Som standard returneres opdateringer, der starter med den tidligste
ubekræftet opdatering. En opdatering betragtes som bekræftet, så snart getUpdates kaldes med en offset højere end dens update_id. Den negative offset kan angives for at hente opdateringer, der starter fra -offset opdatering 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_idOg lad os nulstille — vi omskriver funktionen lidt. Vi har to muligheder — enten at sende hele beskeden til funktionen og behandle den der, eller kun at give ID'et på beskeden og også nulstille den. For eksempel ser det andet lettere ud.
Tidligere så forespørgslen "alle beskeder" sådan ud
$URLGET = "https:\/\/api.telegram.org\/bot$MyToken\/getUpdates"mens det nu vil se sådan 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 at få alle beskeder først, behandle dem, og først efter en vellykket behandling anmode om unconfirmed -> confirmed.
Hvorfor giver det mening at bekræfte efter at alle behandlinger er afsluttet? Der kan opstå en fejl midt i udførelsen, og hvis en enkelt besked for en gratis chatbot ikke er så kritisk, kan det være værre, hvis du behandler nogens løn eller en korttransaktion.
Et par ekstra linjer kode
$LastMessageId = ($Content4Pars01.result | select -last 1).update_id #Fejlen her skal rettes selv.
$URLGET1 = "https://api.telegram.org/bot$mytoken/getUpdates?offset=$LastMessageId&limit=100"
Invoke-WebRequest -Uri $URLGET1 -Method Get -Proxy $MyProxy
8. I stedet for konklusion
De vigtigste funktioner — læsning af beskeder, nulstilling af kø, læsning fra fil og skrivning til fil er udført og vist.
Der er kun fire ting tilbage at gøre:
- sende det korrekte svar på forespørgslen i chatten
- sende svaret til ENHVER chat, hvor botten er tilføjet
- udføre koden i en løkke
- starte botten fra Windows Task Scheduler.
Alle disse opgaver er enkle og lette at implementere ved hjælp af dokumentationen for parametre som
Set-ExecutionPolicy Unrestricted og -ExecutionPolicy Bypass
en løkke af typen
$TimeToSleep = 3 # forespørgsel hvert 3. sekund
$TimeToWork = 10 # minutter
$HowManyTimes = $TimeToWork*60/$TimeToSleep # tælleren til løkken
$MainCounter = 0
for ($MainCounter=0; $MainCounter -le $HowManyTimes) {
sleep $TimeToSleep
$MainCounter ++
Tak til alle, der har læst færdig.
Kilde: habr.com
