Paprasto telegramų roboto šablonas 7–9 klasių moksleiviams naudojant Powershell

Per pokalbius su draugu netikėtai sužinojau, kad jų mokykloje 8-10 klasių vaikai iš viso nemokomi programuoti. Word, Excel ir viskas. Jokio logotipo, net Pascal, net VBA for Excel.

Labai nustebau, atsidariau internetą ir pradėjau skaityti -
Vienas iš specializuotos mokyklos uždavinių – skatinti naujos kartos, atitinkančios informacinės visuomenės sąlygas, ugdymą savo išsivystymo lygiu ir gyvenimo būdu.
Šis kursas leis studentams praktiškai įtvirtinti savo žinias apie pagrindines Pascal programavimo kalbos konstrukcijas. (iš kai kurios gimnazijos 2017 m. programos)

Galų gale nusprendžiau praleisti kelias valandas ir nupiešti pavyzdį, „kaip sukurti paprastą robotą moksleiviams“.

Žemiau pateikiama informacija, kaip parašyti kitą paprastą robotą Powershell ir priversti jį veikti be „webhook“, baltų IP, dedikuotų serverių, debesyje įdiegtų virtualių mašinų ir t. t. – įprastame namų kompiuteryje su įprasta „Windows“.

TLDR: Kitas nuobodus straipsnis su gramatinėmis ir faktinėmis klaidomis, nėra ką skaityti, nėra humoro, nėra nuotraukų.

Straipsnyje nėra nieko naujo, beveik viskas, kas parašyta anksčiau, jau buvo Habré, pavyzdžiui, straipsniuose Instrukcijos: Kaip sukurti robotus „Telegram“. и Telegram botas sistemos administratoriui.
Be to, straipsnis yra sąmoningai perteklinis, kad nebūtų kiekvieną kartą nuoroda į mokomąją literatūrą. Tekste nėra nuorodų į „Gang 4“, „PowerShell Deep Dives“ ar, tarkime, „The 5 Pillars of the AWS Well-Architected Framework“.

Vietoj pratarmės galite praleisti

Nedvejodami praleiskite2006 m. „Microsoft“ išleido „PowerShell 1.0“, skirtą tuometinėms „Windows XP“, „Vista“ ir „Server 2003“. Tam tikrais būdais jis pakeitė tokius dalykus kaip cmdbat scenarijai, vb scenarijai, Windows Script Host ir JScript.

Net ir dabar PowerShell gali būti laikomas tik kitu žingsniu po logotipo parinkčių, o ne tikriausiai vis dar naudojamo Delphi (ar kažko senesnio), nepaisant kilpų, klasių, funkcijų, MS GUI iškvietimų, Git integracija ir taip toliau.

„Powershell“ naudojamas palyginti retai; su juo galite susidurti tik „PowerShell Core“, „VMware vSphere PowerCLI“, „Azure PowerShell“, „MS Exchange“, pageidaujamos būsenos konfigūracijos, „PowerShell“ žiniatinklio prieiga ir keliolika rečiau naudojamų programų ir funkcijų. Galbūt išleisdamas jis gaus antrą vėją WSL2, bet taip nėra tiksliai.

„Powershell“ taip pat turi tris didelius pranašumus:

  1. Tai gana paprasta, apie tai yra daug literatūros ir pavyzdžių, o net rusiškai, pavyzdžiui, straipsnis apie Foreach - iš knygos PowerShell nuodugniai - apie skirtumą () ir {}
  2. Jis eina su redaktoriumi ISE, įtraukta į „Windows“. Ten netgi yra kažkoks derintuvas.
  3. Iš jo nesunku paskambinti grafinės sąsajos kūrimo komponentai.

0. Paruošimas.

Mums reikės:

  • „Windows“ kompiuteris (turiu „Windows 10“)
  • Bent tam tikra prieiga prie interneto (pvz., per NAT)
  • Tiems, kurie turi ribotą prieigą prie telegramos - naršyklėje įdiegtas ir sukonfigūruotas „freegate“, kai kuriais sunkiais atvejais kartu su „Symple DNS Crypt“
  • Telefone veikiantis telegramos klientas
  • Suprasti pačius pagrindus – kas yra kintamasis, masyvas, kilpa.

Atidarė ir skaitė straipsnius - Instrukcijos: Kaip sukurti robotus „Telegram“. и Telegram botas sistemos administratoriui

1. Sukurkime kitą bandomąjį robotą.

Kadangi visi tai jau žino ir jau nutiko, galite tai praleistiKaip nurodyta aukščiau esančiame straipsnyje – Visų pirma, „Telegram“ robotas – tai vis dar yra jūsų pusėje veikianti programa ir teikianti užklausas Telegram Bot API. Be to, API yra aiški – robotas pasiekia konkretų URL su parametrais, o „Telegram“ atsako su JSON objektu.

Susijusios problemos: jei kokiu nors nežinomu būdu paimsite kodą iš JSON objekto ir kažkaip išsiųsite jį vykdyti (ne tyčia), kodas bus įvykdytas už jus.

Kūrimo procesas aprašytas dviejuose aukščiau esančiuose straipsniuose, bet kartoju: telegramoje atidarome kontaktus, ieškome @botfather, pasakome jam /newbot, sukuriame botą Botfortest12344321, vadiname Mynext1234bot ir gauname pranešimą su unikaliu raktu forma 1234544311:AbcDefNNNNNNNNNNNNNN

Rūpinkitės raktu ir neduok jo!

Tada galite sukonfigūruoti robotą, pavyzdžiui, uždrausti įtraukti jį į grupes, tačiau pirmaisiais veiksmais tai nėra būtina.

Paklauskime „BotFather“ „/mybot“ ir pakoreguosime nustatymus, jei kažkas nepatinka.

Dar kartą atidarykime kontaktus, suraskime ten @Botfortest12344321 (paiešką pradėti būtina su @), spaudžiame „start“ ir į botą parašome „/Glory to the robots“. Reikalingas / ženklas, kabučių nereikia.
Botas, žinoma, nieko neatsakys.

Patikrinkime, ar robotas sukurtas, ir atidarykime jį.

api.telegram.org/bot1234544311:AbcDefNNNNNNNNNNNNNN/getMe
kur 1234544311:AbcDefNNNNNNNNNNNNNN yra anksčiau gautas raktas,
ir gauti eilutę kaip
{"ok":true"result":{""}}

Turime pirmąją slaptą frazę (žetoną). Dabar turime išsiaiškinti antrąjį slaptą numerį – pokalbio su robotu ID. Kiekvienas pokalbis, grupė ir pan. yra individualus ir turi savo numerį (kartais su minusu – atviroms grupėms). Norėdami sužinoti šį numerį, turime paprašyti naršyklėje (tiesą sakant, naršyklėje jis visai nebūtinas, bet kad geriau suprastumėte, galite pradėti nuo jo) adreso (kur 1234544311:NNNNNNNNNN yra jūsų prieigos raktas

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

ir gauti atsakymą kaip

{"ok":true"result":[{"update_id":...,... kalbėtis":{"id":123456789

Mums reikia chat_id.

Patikrinkime, ar galime į pokalbį rašyti rankiniu būdu: paskambinkite adresu iš naršyklės

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

Jei pokalbyje gaunate pranešimą iš roboto, gerai, pereikite į kitą etapą.

Tokiu būdu (per naršyklę) visada galima patikrinti, ar nėra problemų su nuorodų generavimu, ar kažkas kažkur paslėpta ir neveikia.

Ką reikia žinoti prieš tęsiant skaitymą

„Telegram“ turi kelių tipų grupinius pokalbius (atvirus, uždarus). Šių pokalbių kai kurios funkcijos (pavyzdžiui, id) skiriasi, todėl kartais kyla tam tikrų problemų.

Tarkime, kad 2019-ųjų pabaiga, ir net mūsų laikų herojus, žinomas „Man-Orchestra“ (administratorius, teisininkas, informacijos saugumo specialistas, programuotojas ir praktiškai MVP) Jevgenijus V. skiria $i kintamąjį nuo masyvo, įvaldė kilpas, pažiūrėkite per ateinančius porą metų įvaldys Chocolatey, o tada Lygiagretus apdorojimas su PowerShell и Lygiagretus kiekvienam objektui tai ateis.

1. Mes galvojame, ką darys mūsų robotas

Neturėjau jokių minčių, turėjau galvoti. Aš jau parašiau „bot“ užrašų knygelę. Nenorėjau sukurti roboto, „kuris kažką kažkur siunčia“. Norint prisijungti prie Azure, reikia kredito kortelės, bet iš kur studentas ją gauna? Reikia pastebėti, kad viskas nėra taip blogai: pagrindiniai debesys duoda kažkokį bandomąjį periodą nemokamai (bet dar reikia kreditinės kortelės numerio - ir atrodo, kad nuo jo bus nurašytas doleris. Nepamenu ar jis buvo grąžintas vėliau.)

Be AI ML nėra taip įdomu daryti botą-vargšą-poetą-audėją.

Nusprendžiau sukurti robotą, kuris man (arba ne) primintų angliškus žodžius iš žodyno.
Kad nereikėtų suktis su duomenų baze, žodynas bus saugomas tekstiniame faile ir atnaujinamas rankiniu būdu.
Šiuo atveju užduotis – parodyti darbo pagrindus, o ne pagaminti bent iš dalies gatavą gaminį.

2. Pirmą kartą išbandymas, kas ir kaip

Sukurkime aplanką C:poshtranslate
Pirmiausia pažiūrėkime, kokį „powershell“ turime, paleiskite ISE per start-run
powershell ise
arba suraskite Powershell ISE įdiegtose programose.
Po paleidimo atsidarys įprastas pažįstamas „tam tikras redaktorius“; jei teksto lauko nėra, visada galite spustelėti „Failas - sukurti naują“.

Pažiūrėkime į powershell versiją – teksto laukelyje parašykite:

get-host 

ir paspauskite F5.

„Powershell“ pasiūlys išsaugoti - „Scenarijus, kurį ketinate paleisti, bus išsaugotas.“, sutinkame ir išsaugokite failą iš „powershell“ pavadinimu C: poshtranslate myfirstbotBT100.

Po paleidimo apatiniame teksto lange gauname duomenų lentelę:

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

Turiu kažką 5.1, užtenka. Jei turite seną „Windows 7/8“, nieko blogo – nors „PowerShell“ reikės atnaujinti į 5 versiją – pvz. instrukcijos.

Žemiau esančioje komandinėje eilutėje įveskite Get-Date, paspauskite Enter, pažiūrėkite laiką, eikite į šakninį aplanką su komanda
cd
ir išvalykite ekraną naudodami cls komandą (ne, jums nereikia naudoti rm)

Dabar patikrinkime, kas ir kaip veikia – parašykime net ne kodą, o dvi eilutes ir pabandykime suprasti, ką jie daro. Pakomentuokime eilutę su get-host su simboliu # ir šiek tiek pridėkime.

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

(Įdomu tai, kad Habré kodo formatavimo išskleidžiamajame sąraše yra dvi dešimtys parinkčių, bet Powershell nėra. Dos yra. Yra Perl.)

Ir paleiskime kodą paspausdami F5 arba ">" iš GUI.

Gauname tokią išvestį:

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

Dabar pažvelkime į šias dvi eilutes ir keletą įdomių dalykų, kad ateityje prie to negrįžtume.

Skirtingai nuo Pascal (ir ne tik), PowerShell pati bando nustatyti, kokį tipą priskirti kintamajam; daugiau apie tai parašyta straipsnyje Mokomoji programa rašyti programavimo kalbomis
Todėl sukūrę $TimeNow kintamąjį ir priskyrę jam dabartinės datos ir laiko reikšmę (Get-Date), neturime per daug jaudintis dėl to, kokio tipo duomenys ten bus.

Tiesa, šis nežinojimas vėliau gali pakenkti, bet tai vėliau. Žemiau tekste bus pavyzdys.
Pažiūrėkime, ką gavome. Vykdykime (komandinėje eilutėje)

$TimeNow | Get-member

ir gauti nesuprantamo teksto puslapį

Nesuprantamo teksto numeris 1 pavyzdys

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

Kaip matote, TypeName: System.DateTime tipo kintamasis buvo sukurtas naudojant daugybę metodų (ta prasme, ką galime padaryti su šiuo kintamuoju objektu) ir ypatybėmis.

Paskambinkime $TimeNow.DayOfYear — gauname metų dienos skaičių.
Paskambinkime $TimeNow.DayOfYear | Get-Member - mes gauname TypeName: System.Int32 ir metodų grupė.
Paskambinkime $TimeNow.ToUniversalTime() - ir gaukite laiką UTC

Derintuvas

Kartais nutinka taip, kad reikia paleisti programą iki tam tikros eilutės ir pamatyti programos būseną tuo momentu. Tam tikslui ISE turi Debug funkciją – perjungti lūžio tašką
Padėkite pertraukos tašką kažkur viduryje, paleiskite šias dvi eilutes ir pažiūrėkite, kaip atrodo pertrauka.

3. Sąveikos su „Telegram“ robotu supratimas

Žinoma, parašyta dar daugiau literatūros apie sąveiką su robotu, su visais getpush ir pan., tačiau teorijos klausimą galima svarstyti pasirinktinai.

Mūsų atveju būtina:

  • Išmokite ką nors išsiųsti korespondencijai
  • Išmokite ką nors gauti iš korespondencijos

3.1 Išmokti ką nors išsiųsti korespondencija ir gauti iš jos

Šiek tiek kodo – 3 dalis

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

ir Rusijos Federacijoje šiuo metu gauname klaidą Nepavyko prisijungti prie nuotolinio serverio.

Arba negauname – priklauso nuo telekomunikacijų operatoriaus ir nuo to, ar tarpinis serveris sukonfigūruotas ir veikia
Na, belieka pridėti tarpinį serverį. Atkreipkite dėmesį – nešifruoto ir paprastai apgaulingo tarpinio serverio naudojimas yra labai pavojingas jūsų sveikatai.

Užduotis rasti veikiantį tarpinį serverį nėra labai sudėtinga – veikia dauguma paskelbtų http tarpinių serverių. Manau, kad penktasis man pasiteisino.

Sintaksė naudojant tarpinį serverį:

Invoke-WebRequest -Uri $URL4SEND -Proxy $MyProxy

Jei pokalbyje su robotu gaunate pranešimą, tada viskas gerai, galite judėti toliau. Jei ne, tęskite derinimą.

Galite pamatyti, į ką paverčia jūsų $URL4SEND eilutė, ir pabandyti pateikti užklausą naršyklėje, pavyzdžiui:

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

3.2. Išmokome „kažką“ parašyti pokalbyje, dabar pabandykime tai perskaityti

Pridėkime dar 4 eilutes ir pažiūrėkime, kas yra viduje per | tapti nariu

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

Įdomiausias dalykas yra mums pateiktas

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

Pažiūrėkime, kas juose yra:

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

Jei viskas jums tinka, gausite ilgą eilutę, pavyzdžiui:

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

Laimei, anksčiau paskelbtame straipsnyje Telegram bot sistemos administratoriui ši eilutė (taip, pagal $MyMessageGet.RawContent | get-member yra System.String), jau buvo išardytas.

4. Apdorokite tai, ką gaunate (jau žinome, kaip ką nors išsiųsti)

Kaip jau parašyta čia, reikalingiausi dalykai slypi turinyje. Pažvelkime į tai atidžiau.

Pirmiausia į robotą iš žiniatinklio sąsajos arba telefono parašysime dar keletą frazių

/message1
/message2
/message3

ir per naršyklę peržiūrėkite adresą, kuris buvo suformuotas kintamajame $URLGET.

Pamatysime kažką panašaus:

{"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 tai yra? Kai kurie sudėtingi objektai iš objektų masyvų, kuriuose yra nuo galo iki galo pranešimo identifikatorius, pokalbio identifikatorius, siuntimo identifikatorius ir daug kitos informacijos.

Tačiau mums nereikia išsiaiškinti, „koks tai objektas“ – dalis darbų jau atlikta už mus. Pažiūrėkime, kas yra viduje:

Gautų žinučių ar 4 dalies skaitymas

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. Ką turėtume daryti dabar?

Išsaugokime gautą failą pavadinimu myfirstbotBT105 arba kaip jums labiausiai patinka, pakeiskite pavadinimą ir pakomentuokite visą jau parašytą kodą per

<#start comment 105 end comment 105#>

Dabar turime nuspręsti, kur gauti žodyną (na, kur - diske faile) ir kaip jis atrodys.

Žinoma, galite parašyti didžiulį žodyną tiesiai į scenarijaus tekstą, bet tai visiškai nereikalinga.
Taigi pažiūrėkime, su kuo „powershell“ gali veikti įprastai.
Tiesą sakant, jam nerūpi, su kokia byla jis dirba, o mums nerūpi.
Turime pasirinkimą: txt (galite, bet kodėl), csv, xml.
Ar galime stebėti visus? Pažiūrėkime visus.
Sukurkime klasę MyVocabClassExample1 ir kintamąjį $MyVocabExample1
Pastebiu, kad klasė parašyta be $

kažkoks kodas Nr.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

Pabandykime tai įrašyti į failus naudodami pavyzdingas.

Kažkoks kodas #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

- ir mes gauname klaidą eilutėje Out-File -FilePath $MyFilenameExample01 -InputObject -Append $MyVocabExample2.

Jis nenori pridurti, ah-ah, kokia gėda.

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

Pažiūrėkim, kas nutiks. Puikus teksto vaizdas – bet kaip jį eksportuoti atgal? Ar turėčiau įvesti kažkokius teksto skyriklius, pvz., kablelius?

Galų gale gausite „kableliais atskirtų reikšmių (CSV) failą A STOP PALAUKITE.
#

$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 

Kaip nesunku pastebėti, MS nėra ypatingai išsiskirianti savo logika, panašiai procedūrai vienu atveju naudojamas -FilePath, kitu -Path.

Be to, trečioje byloje dingo rusų kalba, ketvirtoje pasirodė... na, kažkas atsitiko. #TIPAS Sistema.Objektas[] 00
# "Count", "Length", "LongLength", "Rank", "SyncRoot", "IsReadOnly", "IsFixedSize", "IsSynchronized"
#
Šiek tiek perrašykime:

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

Atrodo, kad tai padėjo, bet man vis tiek nepatinka formatas.

Man ypač nepatinka, kad negaliu tiesiogiai įdėti eilučių iš objekto į failą.
Beje, nuo tada, kai pradėjome rašyti į failus, ar galime pradėti vesti paleisties žurnalą? Mes turime laiko kaip kintamąjį, galime nustatyti failo pavadinimą.

Tiesa, dar nėra ką rašyti, bet galima pagalvoti, kaip geriausia sukti rąstus.
Kol kas pabandykime xml.

Kai kurie 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

Eksportavimas į xml turi daug privalumų – skaitomumas, viso objekto eksportavimas ir nereikia atlikti papildymo.

Pabandykime skaityti xml failą.

Šiek tiek skaitymo iš xml

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

Grįžkime prie užduoties. Parašėme bandomąjį failą, perskaitykite, saugojimo formatas aiškus, jei reikia, galite parašyti atskirą nedidelį failų redaktorių eilutėms pridėti ir ištrinti.

Leiskite jums priminti, kad užduotis buvo padaryti nedidelį mokymo botą.

Darbo formatas: siunčiu botui komandą „pavyzdys“, botas atsiunčia man atsitiktinai parinktą žodį ir transkripciją, o po 10 sekundžių atsiunčia vertimą ir komentarą. Mes mokame skaityti komandas, taip pat norėtume išmokti automatiškai pasirinkti ir patikrinti tarpinius serverius bei atstatyti pranešimų skaitiklius į užmarštį.

Komentuokime viską, kas anksčiau buvo komentuota kaip nereikalinga, pakomentuokime dabar nereikalingus pavyzdžius naudodami txt ir csv ir išsaugokime failą kaip B106 versiją

O taip. Vėl ką nors atsiųsk botui.

6. Išsiuntimas iš funkcijų ir kt

Prieš apdorodami priėmimą, turite sukurti funkciją, skirtą siųsti „bent ką nors“, išskyrus bandomąjį pranešimą.

Žinoma, pavyzdyje turėsime tik vieną siuntimą ir tik vieną apdorojimą, bet ką daryti, jei tą patį reikės atlikti kelis kartus?

Funkciją parašyti lengviau. Taigi, mes turime objekto $MyVocabExample4AsArray tipo kintamąjį, nuskaitytą iš failo, net dviejų elementų masyvo pavidalu.
Eime skaityti.

Tuo pat metu susitvarkysime su laikrodžiu, jo prireiks vėliau (tiesą sakant, šiame pavyzdyje mums jo nereikės :)

Kažkoks kodas #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
}

Kaip lengvai matote, funkcija iškviečia $MyToken ir $MyChatID, kurios anksčiau buvo užkoduotos.

To daryti nereikia ir jei $MyToken yra vienas kiekvienam robotui, $MyChatID pasikeis priklausomai nuo pokalbio.

Tačiau, kadangi tai yra pavyzdys, kol kas jo nepaisysime.

Kadangi $MyVocabExample4AsArray nėra masyvas, nors ir labai panašus į vieną, tada tu negali tiesiog paimti paprašyti jo ilgio.

Eilinį kartą turėsime daryti tai, ko negalima padaryti – parašiutu ne pagal kodą – imk ir suskaičiuok

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

atsitiktinis įdomi savybė. Tarkime, kad norime gauti 0 arba 1 (masyve turime tik du elementus). Ar nustatydami ribas 0..1 gausime „1“?
ne – mes to negausime, turime specialų pavyzdį 2 pavyzdys: gaukite atsitiktinį sveikąjį skaičių nuo 0 iki 99 Gauti atsitiktinai – Maksimalus 100
Todėl 0..1 turime nustatyti dydį 0..2, maksimalus elemento skaičius = 1.

7. Gaunamų pranešimų apdorojimas ir maksimalus eilės ilgis

Kur mes sustojome anksčiau? turime gautą kintamąjį $MyMessageGet
ir iš jo gautas $Content4Pars01, iš kurių mus domina masyvo Content4Pars01.result elementai

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

Išsiųskime botą /pranešimas10, /pranešimas11, /pranešimas12, /žodis ir dar kartą /žodis ir /labas.
Pažiūrėkime, ką gavome:

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

Peržiūrėkime viską, kas gauta, ir atsiųsime atsakymą, jei pranešimas buvo /word
konstrukcijos atvejis, kurį kai kurie apibūdina kaip jei-elseif, vadinamas powershell per jungiklį. Tuo pačiu metu toliau pateiktame kode naudojamas -pakeisto simbolio klavišas, kuris yra visiškai nereikalingas ir netgi žalingas.

Kažkoks kodas #7.1

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

Paleiskite scenarijų porą kartų. Tą patį žodį gausime du kartus už kiekvieną vykdymo bandymą, ypač jei suklydome atsitiktinai.

Bet sustok. Vėl neišsiuntėme /word, tai kodėl pranešimas vėl apdorojamas?

Pranešimų siuntimo į robotą eilė yra riboto ilgio (manau, kad 100 arba 200 pranešimų) ir turi būti išvalyta rankiniu būdu.

Žinoma, tai aprašyta dokumentacijoje, bet jūs turite tai perskaityti!

Šiuo atveju mums reikia parametro ?chat_id ir &timeout, &limit, &parse_mode=HTML ir &disable_web_page_preview=true dar nereikalingi.

Dokumentacija skirta telegramos api yra čia
Jame balta ir angliškai parašyta:
Pirmojo grąžintino atnaujinimo identifikatorius. Turi būti vienu didesnis nei didžiausias iš anksčiau gautų naujinių identifikatorių. Pagal numatytuosius nustatymus naujinimai prasideda anksčiausiai
nepatvirtintas atnaujinimas grąžinamas. Atnaujinimas laikomas patvirtintu, kai tik iškviečiama getUpdates su an kompensuoti aukštesnis nei jo update_id. Neigiamas poslinkis gali būti nurodytas norint gauti naujinimus, pradedant nuo -offset atnaujinimo nuo naujinimų eilės pabaigos. Visi ankstesni atnaujinimai bus pamiršti.

Pažiūrėkime:

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

Taip, mes jį iš naujo nustatysime ir šiek tiek perrašysime funkciją. Turime dvi parinktis – perduoti visą pranešimą funkcijai ir visiškai jį apdoroti funkcijoje arba pateikti tik pranešimo ID ir jį nustatyti iš naujo. Pavyzdžiui, antrasis atrodo paprastesnis.

Anksčiau mūsų užklausos eilutė „visi pranešimai“ atrodė taip

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

ir atrodys

$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 

Niekas nedraudžia pirmiausia gauti visus pranešimus, juos apdoroti ir tik sėkmingai apdoroti užklausa nepatvirtinta -> patvirtinta.

Kodėl prasminga skambinti patvirtinimui pasibaigus visam apdorojimui? Gedimas galimas vykdymo viduryje, o jei, pavyzdžiui, nemokamo pokalbių roboto pavyzdyje, praleisti vieną pranešimą nėra nieko ypatingo, tada, jei apdorojate kažkieno atlyginimą ar kortelės operaciją, rezultatas gali būti prastesnis.

Dar pora kodo eilučių

$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. Vietoj išvados

Pagrindinės funkcijos – pranešimų skaitymas, eilės atstatymas, skaitymas iš failo ir rašymas į failą yra atliekami ir rodomi.

Liko atlikti tik keturis dalykus:

  • siunčiant teisingą atsakymą į užklausą pokalbyje
  • siunčiant atsakymą į BET KOKĮ pokalbį, prie kurio buvo pridėtas robotas
  • kodo vykdymas cikle
  • paleisti robotą iš „Windows“ planavimo priemonės.

Visos šios užduotys yra paprastos ir lengvai jas galima atlikti perskaičius dokumentus apie tokius parametrus kaip
Set-ExecutionPolicy Unstricted ir -ExecutionPolicy Bypass
formos ciklas

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

Ačiū visiems, kad skaitėte.

Šaltinis: www.habr.com

Добавить комментарий