Vienkārša telegrammas robota veidne 7.–9. klašu skolēniem, izmantojot Powershell

Sarunās ar draugu pēkšņi uzzināju, ka viņu skolā 8.-10.klases bērniem programmēšanu nemāca vispār. Word, Excel un viss. Nav logotipa, pat ne Pascal, pat ne VBA for Excel.

Es biju ļoti pārsteigts, atvēru internetu un sāku lasīt -
Viens no specializētās skolas uzdevumiem ir veicināt informācijas sabiedrības nosacījumiem atbilstošas ​​jaunas paaudzes izglītošanu savā attīstības līmenī un dzīvesveidā.
Šis kurss ļaus studentiem praksē nostiprināt zināšanas par Pascal programmēšanas valodas pamatkonstrukcijām. (no kādas ģimnāzijas programmas 2017. gadam)

Beigās nolēmu pavadīt pāris stundas un ieskicēt piemēru “kā izveidot vienkāršu robotu skolēniem”.

Tālāk ir norādīts, kā uzrakstīt citu vienkāršu robotu programmā Powershell un panākt, lai tas darbotos bez tīmekļa aizķeres, baltiem IP, īpašiem serveriem, mākonī izvietotām virtuālajām mašīnām un tā tālāk — parastā mājas datorā ar parasto Windows.

TLDR: Kārtējais garlaicīgs raksts ar gramatiskām un faktu kļūdām, nav ko lasīt, bez humora, bez bildēm.

Rakstā nav nekā jauna, gandrīz viss iepriekš rakstītais jau ir bijis uz Habrē, piemēram, rakstos Norādījumi: kā izveidot robotprogrammatūras programmā Telegram и Telegrammas robots sistēmas administratoram.
Turklāt raksts ir apzināti lieks, lai katru reizi neatsauktos uz mācību literatūru. Tekstā nav atsauces uz Gang 4, PowerShell Deep Dives vai, teiksim, The 5 Pillars of the AWS Well-Architected Framework.

Priekšvārda vietā varat izlaist

Jūtieties brīvi izlaist2006. gadā Microsoft izlaida PowerShell 1.0 operētājsistēmām Windows XP, Vista un Server 2003. Dažos veidos tas aizstāja tādas lietas kā cmdbat skripti, vb skripti, Windows Script Host un JScript.

Pat tagad PowerShell var uzskatīt tikai par nākamo soli pēc Logo opcijām, nevis, iespējams, joprojām izmantoto Delphi (vai kaut ko vecāku), neskatoties uz cilpu, klašu, funkciju, MS GUI izsaukumu klātbūtni, Git integrācija un tā tālāk.

Powershell tiek izmantots salīdzinoši reti; ar to var saskarties tikai kā PowerShell Core, VMware vSphere PowerCLI, Azure PowerShell, MS Exchange, vēlamā stāvokļa konfigurācija, PowerShell tīmekļa piekļuve un apmēram duci retāk izmantotu programmu un funkciju. Iespējams, ar atbrīvošanu viņš iegūs otru elpu WSL2, bet tā nav gluži.

Powershell ir arī trīs lielas priekšrocības:

  1. Tas ir salīdzinoši vienkārši, par to ir daudz literatūras un piemēru, un pat krievu valodā, piemēram, raksts par Foreach - no grāmatas PowerShell padziļināti - par atšķirību () un {}
  2. Viņš iet kopā ar redaktoru ISE, kas iekļauts sistēmā Windows. Tur pat ir kaut kāds atkļūdotājs.
  3. No tā ir viegli piezvanīt komponenti grafiskā interfeisa izveidei.

0. Sagatavošana.

Mums būs nepieciešams:

  • Windows dators (man ir Windows 10)
  • Vismaz kāda veida piekļuve internetam (piemēram, izmantojot NAT)
  • Tiem, kuriem ir ierobežota piekļuve telegrammai - pārlūkprogrammā instalēta un konfigurēta freegate, dažos sarežģītos gadījumos kopā ar Simple DNS Crypt
  • Tālrunī darbojas telegrammas klients
  • Izpratne par pašiem pamatiem – kas ir mainīgais, masīvs, cilpa.

Atvērti un lasīti raksti - Norādījumi: kā izveidot robotprogrammatūras programmā Telegram и Telegrammas robots sistēmas administratoram

1. Izveidosim vēl vienu testa robotu.

Tā kā visi to jau zina un tas jau ir noticis, varat to arī izlaistKā teikts iepriekš rakstā - Pirmkārt, bot Telegram - tā joprojām ir lietojumprogramma, kas darbojas jūsu pusē un veic pieprasījumus Telegram Bot API. Turklāt API ir skaidra - robots piekļūst noteiktam URL ar parametriem, un Telegram atbild ar JSON objektu.

Saistītās problēmas: ja kādā nezināmā veidā paņemat kodu no JSON objekta un kaut kādā veidā nosūtāt to izpildei (nevis ar nolūku), kods tiks izpildīts jūsu vietā.

Izveidošanas process ir aprakstīts divos rakstos iepriekš, bet es atkārtoju: telegrammā mēs atveram kontaktus, meklējam @botfather, sakām viņam /newbot, izveidojam botu Botfortest12344321, nosaucam to par Mynext1234bot un saņemam ziņojumu ar unikālu atslēgu veidlapa 1234544311: AbcDefNNNNNNNNNNNNNN

Rūpējieties par atslēgu un neatdodiet to!

Pēc tam jūs varat konfigurēt botu, piemēram, aizliegt to pievienot grupām, taču pirmajās darbībās tas nav nepieciešams.

Pieprasīsim BotFather “/mybot” un noregulēsim iestatījumus, ja mums kaut kas nepatīk.

Atveram vēlreiz kontaktus, atrodam tur @Botfortest12344321 (meklēšana ir jāsāk ar @), noklikšķiniet uz "sākt" un ierakstiet botam "/Glory to the robots." Nepieciešama / zīme, pēdiņas nav vajadzīgas.
Bots, protams, neko neatbildēs.

Pārbaudīsim, vai robots ir izveidots, un atveram to.

api.telegram.org/bot1234544311:AbcDefNNNNNNNNNNNNNN/getMe
kur 1234544311:AbcDefNNNNNNNNNNNNNN ir iepriekš saņemtā atslēga,
un iegūstiet virkni patīk
{"ok":true"result":{""}}

Mums ir pirmā slepenā frāze (žetons). Tagad mums ir jānoskaidro otrs slepenais numurs - tērzēšanas ar robotu ID. Katrs čats, grupa utt. ir individuāla un tam ir savs numurs (dažreiz ar mīnusu - atvērtām grupām). Lai uzzinātu šo numuru, mums ir jāpieprasa pārlūkprogrammā (patiesībā tas pārlūkprogrammā nemaz nav nepieciešams, bet labākai izpratnei varat sākt ar to) adrese (kur 1234544311:NNNNNNNNNN ir jūsu marķieris

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

un saņemiet atbildi patīk

{"ok":true"result":[{"update_id":...,... tērzēšana":{"id":123456789

Mums ir nepieciešams chat_id.

Pārbaudīsim, vai varam rakstīt tērzēšanai manuāli: zvaniet uz adresi no pārlūkprogrammas

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

Ja savā tērzēšanā saņemat ziņojumu no robota, pārejiet uz nākamo posmu.

Tādā veidā (caur pārlūkprogrammu) vienmēr var pārbaudīt, vai nav problēmas ar saišu ģenerēšanu, vai kaut kas nav kaut kur paslēpts un nedarbojas.

Kas jums jāzina, pirms turpināt lasīt

Telegram ir vairāki grupu tērzēšanas veidi (atvērta, slēgta). Šīm tērzēšanas sarunām dažas funkcijas (piemēram, id) ir atšķirīgas, kas dažkārt rada dažas problēmas.

Pieņemsim, ka ir 2019. gada beigas, un pat mūsu laika varonis Man-Orchestra (administrators, jurists, informācijas drošības speciālists, programmētājs un praktiski MVP) Jevgeņijs V. atšķir $i mainīgo no masīva, ir apguvis cilpas, paskaties tuvāko pāris gadu laikā apgūs Chocolatey, un tad Paralēlā apstrāde ar PowerShell и Katram objektam paralēli tas nāks.

1. Mēs domājam par to, ko mūsu robots darīs

Man nebija nekādu ideju, man bija jādomā. Esmu jau uzrakstījis bot-piezīmju grāmatiņu. Es negribēju izveidot robotu, "kas kaut kur kaut ko sūta". Lai izveidotu savienojumu ar Azure, jums ir nepieciešama kredītkarte, bet no kurienes students to iegūst? Jāpiebilst, ka viss nav tik slikti: galvenie mākoņi dod kaut kādu testa periodu bez maksas (bet tomēr vajag kredītkartes numuru - un šķiet, ka no tā tiks norakstīts dolārs. Neatceros vai tas tika atgriezts vēlāk.)

Bez AI ML nav tik interesanti veidot botu-nabagu-dzejnieku-audēju.

Nolēmu uztaisīt botu, kas man (vai ne) atgādinās angļu vārdus no vārdnīcas.
Lai izvairītos no kņadas ar datu bāzi, vārdnīca tiks saglabāta teksta failā un atjaunināta manuāli.
Šajā gadījumā uzdevums ir parādīt darba pamatus, nevis izgatavot vismaz daļēji gatavu produktu.

2. Pirmo reizi izmēģinot ko un kā

Izveidosim mapi C:poshtranslate
Vispirms apskatīsim, kāda veida powershell mums ir, palaidīsim ISE, izmantojot start-run
powershell ise
vai atrodiet Powershell ISE instalētajās programmās.
Pēc palaišanas tiks atvērts parastais pazīstamais “kaut kāds redaktors”; ja teksta lauka nav, vienmēr varat noklikšķināt uz “Fails - izveidot jaunu”.

Apskatīsim powershell versiju - teksta laukā ierakstiet:

get-host 

un nospiediet F5.

Powershell piedāvās saglabāt - "Skripts, kuru gatavojaties palaist, tiks saglabāts." Mēs piekrītam un saglabājam failu no Powershell ar nosaukumu C: poshtranslate myfirstbotBT100.

Pēc palaišanas apakšējā teksta logā mēs iegūstam datu tabulu:

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

Man ir 5.1 kaut kas, ar to pietiek. Ja jums ir veca operētājsistēma Windows 7/8, tad tas nav nekas liels - lai gan PowerShell būs jāatjaunina uz 5. versiju - piem. instrukcijas.

Zemāk esošajā komandrindā ierakstiet Get-Date, nospiediet taustiņu Enter, skatieties laiku, dodieties uz saknes mapi ar komandu
cd
un notīriet ekrānu ar komandu cls (nē, jums nav jāizmanto rm)

Tagad pārbaudīsim, kas un kā darbojas - rakstīsim pat nevis kodu, bet divas rindiņas un mēģināsim saprast, ko viņi dara. Komentēsim rindiņu ar get-host ar simbolu # un pievienosim nedaudz.

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

(Interesanti ir tas, ka Habré koda formatēšanas nolaižamajā sarakstā ir divi desmiti opciju, taču Powershell nav. Dos ir. Tur ir Perl.)

Palaidīsim kodu, nospiežot F5 vai ">" no GUI.

Mēs iegūstam šādu izvadi:

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

Tagad apskatīsim šīs divas līnijas un dažus interesantus punktus, lai mēs pie tā vairs neatgrieztos nākotnē.

Atšķirībā no Pascal (un ne tikai), PowerShell pati mēģina noteikt, kāda veida mainīgajam piešķirt; sīkāka informācija par to ir rakstīta rakstā. Izglītības programma par rakstīšanu programmēšanas valodās
Tāpēc, izveidojot $TimeNow mainīgo un piešķirot tam pašreizējā datuma un laika vērtību (Get-Date), mums nav pārāk jāuztraucas par to, kāda veida dati tur būs.

Tiesa, šī neziņa vēlāk var kaitēt, bet tas attiecas uz vēlāku laiku. Zemāk tekstā būs piemērs.
Paskatīsimies, kas mums ir. Izpildīsim (komandrindā)

$TimeNow | Get-member

un dabū lapu ar nesaprotamu tekstu

Nesaprotama teksta 1. piemērs

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")...                                         

Kā redzat, mainīgais tipa TypeName: System.DateTime ir izveidots ar virkni metožu (tādā nozīmē, ko mēs varam darīt ar šo mainīgā objektu) un īpašībām.

Piezvanīsim $TimeNow.DayOfYear — iegūstam gada dienas skaitli.
Piezvanīsim $TimeNow.DayOfYear | Get-Member - saņemam TypeName: System.Int32 un metožu grupa.
Piezvanīsim $TimeNow.ToUniversalTime() - un iegūstiet laiku UTC

Atkļūdotājs

Dažkārt gadās, ka ir nepieciešams izpildīt programmu līdz noteiktai rindai un redzēt programmas stāvokli tajā brīdī. Šim nolūkam ISE ir Debug funkcija - pārslēgt pārtraukuma punktu
Ievietojiet pārtraukuma punktu kaut kur vidū, palaidiet šīs divas līnijas un skatiet, kā pārtraukums izskatās.

3. Izpratne par mijiedarbību ar Telegram robotu

Protams, ir uzrakstīts vēl vairāk literatūras par mijiedarbību ar robotprogrammatūru, ar visiem getpush un tā tālāk, taču teorijas jautājumu var izskatīt pēc izvēles.

Mūsu gadījumā ir nepieciešams:

  • Iemācieties kaut ko nosūtīt sarakstē
  • Iemācieties kaut ko iegūt no sarakstes

3.1. Mācīšanās kaut ko nosūtīt sarakstē un saņemt no tās

Mazs kods - 3. daļa

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

un Krievijas Federācijā šajā brīdī tiek parādīta kļūda Nevar izveidot savienojumu ar attālo serveri.

Vai arī mēs to nesaņemam — tas ir atkarīgs no telekomunikāciju operatora un no tā, vai starpniekserveris ir konfigurēts un darbojas
Nu, atliek tikai pievienot starpniekserveri. Lūdzu, ņemiet vērā, ka nešifrēta un parasti krāpnieciska starpniekservera izmantošana ir ārkārtīgi bīstama jūsu veselībai.

Uzdevums atrast strādājošu starpniekserveri nav īpaši grūts - darbojas lielākā daļa publicēto http starpniekserveru. Es domāju, ka piektais man noderēja.

Sintakse, izmantojot starpniekserveri:

Invoke-WebRequest -Uri $URL4SEND -Proxy $MyProxy

Ja tērzēšanā ar botu saņemat ziņojumu, tad viss ir kārtībā, varat doties tālāk. Ja nē, turpiniet atkļūdošanu.

Varat redzēt, par ko tiek pārveidota jūsu $URL4SEND virkne, un mēģināt to pieprasīt pārlūkprogrammā, piemēram:

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

3.2. Mēs iemācījāmies tērzēšanā uzrakstīt “kaut ko”, tagad mēģināsim to izlasīt

Pievienosim vēl 4 rindas un redzēsim, kas ir iekšā caur | kļūt par biedru

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

Interesantākais mums ir sniegts

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

Apskatīsim, kas tajos ir:

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

Ja viss darbojas jūsu labā, jūs saņemsit garu rindu, piemēram:

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

Par laimi, iepriekš publicētajā rakstā Telegram bot sistēmas administratoram šī rinda (jā, saskaņā ar $MyMessageGet.RawContent | get-member ir System.String), jau ir izjaukts.

4. Apstrādājiet saņemto (mēs jau zinām, kā kaut ko nosūtīt)

Kā jau rakstīts šeit, nepieciešamākās lietas slēpjas saturā. Apskatīsim to tuvāk.

Pirmkārt, mēs robotam ierakstīsim vēl dažas frāzes no tīmekļa saskarnes vai tālruņa

/message1
/message2
/message3

un pārlūkprogrammā meklējiet adresi, kas tika izveidota mainīgajā $URLGET.

Mēs redzēsim kaut ko līdzīgu:

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

Kas tas ir? Daži sarežģīti objekti no objektu masīviem, kas satur tiešu ziņojuma identifikatoru, tērzēšanas identifikatoru, sūtīšanas identifikatoru un daudz citas informācijas.

Tomēr mums nav jāizdomā, “kāds objekts tas ir” - daļa darba jau ir paveikta mūsu vietā. Apskatīsim, kas ir iekšā:

Saņemto ziņojumu vai 4. daļas lasīšana

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. Kas mums tagad ar to būtu jādara?

Saglabāsim iegūto failu ar nosaukumu myfirstbotBT105 vai kā jums patīk vislabāk, mainīsim nosaukumu un komentēsim visu jau uzrakstīto kodu, izmantojot

<#start comment 105 end comment 105#>

Tagad mums jāizlemj, kur iegūt vārdnīcu (labi, kur - diskā failā) un kā tā izskatīsies.

Protams, jūs varat ierakstīt milzīgu vārdnīcu tieši skripta tekstā, taču tas ir pilnīgi blakus.
Tātad, redzēsim, ar ko Powershell var strādāt normāli.
Kopumā viņam ir vienalga, ar kuru failu strādāt, mums tas nav svarīgi.
Mums ir izvēle: txt (var, bet kāpēc), csv, xml.
Vai mēs varam skatīties visus? Apskatīsim visus.
Izveidosim klasi MyVocabClassExample1 un mainīgo $MyVocabExample1
Es atzīmēju, ka klase ir rakstīta bez $

kāds kods #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

Mēģināsim to ierakstīt failos, izmantojot paraugs.

Kāds kods #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

- un tiek parādīta kļūda rindā Out-File -FilePath $MyFilenameExample01 -InputObject -Append $MyVocabExample2.

Viņš nevēlas piebilst, ah-ah, kāds kauns.

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

Paskatīsimies, kas notiks. Lielisks teksta skats — bet kā to eksportēt atpakaļ? Vai man vajadzētu ieviest kaut kādus teksta atdalītājus, piemēram, komatus?

Un beigās jūs saņemat “komatatdalīto vērtību (CSV) failu A APSTĀJIET, GAIDIET.
#

$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 

Kā redzams, MS ar savu loģiku īpaši neizceļas, līdzīgai procedūrai vienā gadījumā tiek izmantots -FilePath, citā -Path.

Turklāt trešajā failā pazuda krievu valoda, ceturtajā failā izrādījās... nu, kaut kas notika. #TIPS Sistēma.Objekts[] 00
# “Count”,”Length”,”LongLength”,”Rank”,”SyncRoot”,”IsReadOnly”,”IsFixedSize”,”IsSynchronized”
#
Nedaudz pārrakstīsim:

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

Šķiet, ka tas palīdzēja, bet man joprojām nepatīk formāts.

Īpaši man nepatīk, ka nevaru ievietot rindiņas no objekta tieši failā.
Starp citu, kopš mēs sākām rakstīt failos, vai mēs varam sākt glabāt startēšanas žurnālu? Mums ir laiks kā mainīgais, mēs varam iestatīt faila nosaukumu.

Tiesa, vēl nav ko rakstīt, bet var padomāt, kā vislabāk rotēt baļķus.
Pagaidām mēģināsim xml.

Daži 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ēšanai uz xml ir daudz priekšrocību – lasāmība, visa objekta eksportēšana un nav jāveic augšupvēršana.

Mēģināsim lasīt xml failu.

Mazliet lasāma no xml

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

Atgriezīsimies pie uzdevuma. Uzrakstījām testa failu, izlasījām, uzglabāšanas formāts skaidrs, ja nepieciešams, var uzrakstīt atsevišķu nelielu failu redaktoru, lai pievienotu un dzēstu rindas.

Atgādināšu, ka uzdevums bija uztaisīt nelielu mācību botu.

Darba formāts: es nosūtu robotam komandu “example”, bots man atsūta nejauši izvēlētu vārdu un transkripciju un pēc 10 sekundēm nosūta tulkojumu un komentāru. Mēs zinām, kā lasīt komandas, mēs vēlētos arī uzzināt, kā automātiski atlasīt un pārbaudīt starpniekserverus un atiestatīt ziņojumu skaitītājus uz aizmirstību.

Atzīmēsim visu, kas iepriekš tika komentēts kā nevajadzīgs, komentēsim tagad nevajadzīgos piemērus ar txt un csv un saglabāsim failu kā versiju B106

O jā. Atkal nosūtīsim kaut ko botam.

6. Nosūtīšana no funkcijām un vairāk

Pirms saņemšanas apstrādes jums ir jāizveido funkcija, lai nosūtītu "vismaz kaut ko", kas nav testa ziņojums.

Protams, piemērā mums būs tikai viena nosūtīšana un tikai viena apstrāde, bet ko darīt, ja viena un tā pati darbība ir jādara vairākas reizes?

Vienkāršāk ir uzrakstīt funkciju. Tātad mums ir objekta $MyVocabExample4AsArray mainīgais, kas nolasīts no faila masīva veidā, kurā ir divi elementi.
Ejam lasīt.

Tajā pašā laikā mēs nodarbosimies ar pulksteni; mums tas būs vajadzīgs vēlāk (patiesībā šajā piemērā mums tas nebūs vajadzīgs :)

Kāds kods #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
}

Kā jūs viegli varat redzēt, funkcija izsauc $MyToken un $MyChatID, kas iepriekš tika kodēti.

Tas nav jādara, un, ja $MyToken ir viens katram robotam, $MyChatID mainīsies atkarībā no tērzēšanas.

Tomēr, tā kā šis ir piemērs, mēs to pagaidām ignorēsim.

Tā kā $MyVocabExample4AsArray nav masīvs, lai gan tas ir ļoti līdzīgs vienam, tad jūs to nevarat vienkārši paņemt pieprasīt tā garumu.

Kārtējo reizi būs jādara tas, ko nevar izdarīt - izpletni ne pēc koda - ņem un skaita

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

nejaušs interesanta iezīme. Pieņemsim, ka mēs vēlamies saņemt 0 vai 1 (mums masīvā ir tikai divi elementi). Nosakot robežas 0..1, iegūsim “1”?
nē — mēs to nesaņemsim, mums ir īpašs piemērs 2. piemērs: iegūstiet nejaušu veselu skaitli no 0 līdz 99 Get-Random —Maksimums 100
Tāpēc 0..1 mums jāiestata izmērs 0..2 ar maksimālo elementu skaitu = 1.

7. Ienākošo ziņojumu apstrāde un maksimālais rindas garums

Kur mēs apstājāmies agrāk? mums ir saņemts mainīgais $MyMessageGet
un no tā iegūtais $Content4Pars01, no kuriem mūs interesē masīva Content4Pars01.result elementi.

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

Nosūtīsim botu /ziņa10, /ziņa11, /ziņa12, /word un vēlreiz /word un /sveiki.
Apskatīsim, ko esam ieguvuši:

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

Izskatīsim visu saņemto un nosūtīsim atbildi, ja ziņojums bija /word
Konstrukcijas gadījumu, ko daži raksturo kā if-elseif, sauc powershell caur slēdzi. Tajā pašā laikā tālāk norādītajā kodā tiek izmantots -aizstājējzīmes taustiņš, kas ir pilnīgi nevajadzīgs un pat kaitīgs.

Kāds kods #7.1

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

Palaidīsim skriptu pāris reizes. Mēs saņemsim vienu un to pašu vārdu divreiz par katru izpildes mēģinājumu, it īpaši, ja esam kļūdījušies nejaušības ieviešanā.

Bet apstājies. Mēs vēlreiz nenosūtījām /word, kāpēc ziņojums atkal tiek apstrādāts?

Rindai ziņojumu nosūtīšanai robotam ir ierobežots garums (manuprāt, 100 vai 200 ziņojumi), un tā ir jādzēš manuāli.

Tas, protams, ir aprakstīts dokumentācijā, bet jums tas ir jāizlasa!

Šajā gadījumā mums ir nepieciešams parametrs ?chat_id, un &timeout, &limit, &parse_mode=HTML un &disable_web_page_preview=true vēl nav nepieciešami.

Dokumentācija priekš telegrammas api ir šeit
Tas baltā un angļu valodā saka:
Pirmā atgriežamā atjauninājuma identifikators. Jābūt par vienu lielākam par augstāko no iepriekš saņemto atjauninājumu identifikatoriem. Pēc noklusējuma atjauninājumi sākas ar agrāko
neapstiprināts atjauninājumi tiek atgriezti. Atjauninājums tiek uzskatīts par apstiprinātu, tiklīdz tiek izsaukts getUpdates ar an kompensācija augstāks nekā tā update_id. Negatīvo nobīdi var norādīt, lai izgūtu atjauninājumus, sākot no -offset update no atjauninājumu rindas beigām. Visi iepriekšējie atjauninājumi tiks aizmirsti.

Apskatīsim:

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

Jā, un mēs to atiestatīsim un nedaudz pārrakstīsim funkciju. Mums ir divas iespējas - nodot visu ziņojumu funkcijai un pilnībā to apstrādāt funkcijā vai norādīt tikai ziņojuma ID un atiestatīt to. Piemēram, otrais izskatās vienkāršāks.

Iepriekš mūsu vaicājuma virkne “visi ziņojumi” izskatījās šādi

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

un tā izskatīsies

$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 

Neviens neaizliedz vispirms saņemt visus ziņojumus, tos apstrādāt un tikai pēc veiksmīgas apstrādes pieprasījuma neapstiprināts -> apstiprināts.

Kāpēc ir jēga izsaukt apstiprinājumu pēc tam, kad visa apstrāde ir pabeigta? Izpildes vidū ir iespējama kļūme, un, ja, piemēram, bezmaksas tērzēšanas robota gadījumā, nokavēt vienu ziņojumu nav nekas īpašs, tad, ja apstrādājat kāda algu vai kartes darījumu, rezultāts var būt sliktāks.

Vēl pāris koda rindiņas

$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. Secinājuma vietā

Tiek veiktas un parādītas pamatfunkcijas - ziņojumu lasīšana, rindas atiestatīšana, lasīšana no faila un rakstīšana failā.

Atlikušas tikai četras darbības:

  • nosūtot pareizo atbildi uz pieprasījumu tērzēšanā
  • nosūtot atbildi uz JEBKURU tērzēšanu, kurai tika pievienots robots
  • koda izpilde cilpā
  • bota palaišana no Windows plānotāja.

Visi šie uzdevumi ir vienkārši, un tos var viegli paveikt, izlasot dokumentāciju par tādiem parametriem kā
Set-ExecutionPolicy Unrestricted un -ExecutionPolicy Bypass
formas cikls

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

Paldies visiem, kas lasa.

Avots: www.habr.com

Pievieno komentāru