Model për një bot të thjeshtë telegrami për nxënësit e klasave 7-9 duke përdorur Powershell

Gjatë bisedave me një shok, papritmas mësova se fëmijët e klasave 8-10 në shkollën e tyre nuk mësohen fare programim. Word, Excel dhe gjithçka. Asnjë logo, as Pascal, as VBA për Excel.

U habita shumë, hapa internetin dhe fillova të lexoj -
Një nga detyrat e një shkolle të specializuar është të promovojë edukimin e një brezi të ri që plotëson kushtet e shoqërisë së informacionit në nivelin e saj të zhvillimit dhe stilit të jetesës.
Ky kurs do t'i lejojë studentët të konsolidojnë në praktikë njohuritë e tyre për konstruktet bazë të gjuhës programuese Pascal. (nga programi i disa gjimnazeve për vitin 2017)

Në fund, vendosa të kaloj disa orë dhe të skicoj një shembull se "si të krijojmë një bot të thjeshtë për nxënësit e shkollës".

Më poshtë është se si të shkruani një bot tjetër të thjeshtë në Powershell dhe ta bëni atë të funksionojë pa një uebhook, IP të bardhë, serverë të dedikuar, makina virtuale të vendosura në cloud dhe kështu me radhë - në një kompjuter të zakonshëm shtëpiak me Windows të rregullt.

TLDR: Një tjetër artikull i mërzitshëm me gabime gramatikore dhe faktike, asgjë për të lexuar, pa humor, pa foto.

Nuk ka asgjë të re në artikull, pothuajse çdo gjë e shkruar më parë ka qenë tashmë në Habré, për shembull në artikuj Udhëzime: Si të krijoni bot në Telegram и Telegram bot për administratorin e sistemit.
Për më tepër, artikulli është qëllimisht i tepërt për të mos iu referuar çdo herë literaturës arsimore. Në tekst nuk ka referenca për Gang 4, PowerShell Deep Dives ose, të themi, 5 Shtyllat e Kornizës së Arkitektuar mirë AWS.

Në vend të një parathënie, mund të kaloni

Mos ngurroni të kaloniNë vitin 2006, Microsoft lëshoi ​​​​PowerShell 1.0 për Windows XP, Vista dhe Server 2003 të atëhershëm. Në disa mënyra, ai zëvendësoi gjëra të tilla si skriptet cmdbat, skriptet vb, Windows Script Host dhe JScript.

Edhe tani, PowerShell mund të konsiderohet vetëm si hapi tjetër pas opsioneve Logo, në vend të Delphi-t me siguri ende të përdorur (ose diçka më të vjetër), pavarësisht pranisë së sytheve, klasave, funksioneve, thirrjeve MS GUI, Integrimi Git dhe kështu me radhë.

Powershell përdoret relativisht rrallë; mund ta hasni vetëm në formën e PowerShell Core, VMware vSphere PowerCLI, Azure PowerShell, MS Exchange, Desired State Configuration, Qasja në ueb PowerShell dhe një duzinë apo më shumë programe dhe funksione të përdorura më rrallë. Ndoshta ai do të marrë një erë të dytë me lëshimin WSL2, por nuk është saktësisht.

Powershell gjithashtu ka tre avantazhe të mëdha:

  1. Është relativisht e thjeshtë, ka shumë literaturë dhe shembuj për të, dhe madje edhe në rusisht, për shembull, një artikull rreth Foreach - nga libri PowerShell në thellësi - rreth ndryshimit () dhe {}
  2. Shkon me redaktorin ISE, i përfshirë me Windows. Ka edhe një lloj korrigjuesi atje.
  3. Është e lehtë të telefonosh prej saj komponentë për ndërtimin e një ndërfaqe grafike.

0. Përgatitja.

Ne do të duhet:

  • PC Windows (kam Windows 10)
  • Të paktën një lloj aksesi në internet (për shembull nëpërmjet NAT)
  • Për ata që kanë akses të kufizuar në telegram - freegate i instaluar dhe konfiguruar në shfletues, në disa raste të vështira, së bashku me Symple DNS Crypt
  • Të kesh një klient të telegramit që funksionon në telefonin tënd
  • Kuptimi i bazave - çfarë janë një ndryshore, një grup, një lak.

Artikujt e hapur dhe lexuar - Udhëzime: Si të krijoni bot në Telegram и Telegram bot për administratorin e sistemit

1. Le të krijojmë një bot tjetër testues.

Meqenëse të gjithë e dinë tashmë këtë, dhe tashmë ka ndodhur, ju gjithashtu mund ta kaloni atëSiç u tha në artikullin e mësipërm - Para së gjithash, një bot për Telegram - është ende një aplikacion që funksionon në anën tuaj dhe bën kërkesa në API të Telegram Bot. Për më tepër, API është i qartë - bot akseson një URL specifike me parametra, dhe Telegram përgjigjet me një objekt JSON.

Probleme të ndërlidhura: nëse në një mënyrë të panjohur merrni një kod nga një objekt JSON dhe disi e dërgoni atë për ekzekutim (jo me qëllim), kodi do të ekzekutohet për ju.

Procesi i krijimit përshkruhet në dy artikuj më sipër, por e përsëris: në një telegram hapim kontaktet, kërkojmë @botfather, i tregojmë atij /newbot, krijojmë një bot Botfortest12344321, e quajmë atë Mynext1234bot dhe marrim një mesazh me një çelës unik të formulari 1234544311:AbcDefNNNNNNNNNNNNNN

Kujdesuni për çelësin dhe mos e jepni!

Pastaj mund të konfiguroni botin, për shembull, të ndaloni shtimin e tij në grupe, por në hapat e parë kjo nuk është e nevojshme.

Le të kërkojmë BotFather për "/mybot" dhe të rregullojmë cilësimet nëse nuk na pëlqen diçka.

Le të hapim përsëri kontaktet, të gjejmë @Botfortest12344321 atje (është e detyrueshme të fillojmë kërkimin me @), klikojmë "start" dhe i shkruajmë botit "/Lavdi robotëve". Shenja / kërkohet, thonjëzat nuk nevojiten.
Bot, natyrisht, nuk do të përgjigjet asgjë.

Le të kontrollojmë që roboti është krijuar dhe ta hapim atë.

api.telegram.org/bot1234544311:AbcDefNNNNNNNNNNNNNN/getMe
ku 1234544311:AbcDefNNNNNNNNNNNNNN është çelësi i marrë më parë,
dhe merrni një varg si
{"ok":true,"rezultat":{""}}

Kemi frazën e parë sekrete (token). Tani duhet të zbulojmë numrin e dytë sekret - ID-në e bisedës me botin. Çdo bisedë, grup, etj. është individuale dhe ka numrin e vet (ndonjëherë me një minus - për grupet e hapura). Për të gjetur këtë numër, duhet të kërkojmë në shfletues (në fakt, nuk është aspak e nevojshme në shfletues, por për një kuptim më të mirë mund të filloni me të) adresën (ku 1234544311:NNNNNNNNNN është shenja juaj

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

dhe merrni një përgjigje si

{"ok":true,"rezultat":[{"update_id":...,... bisedë":{"id":123456789

Na duhet chat_id.

Le të kontrollojmë nëse mund të shkruajmë manualisht në bisedë: telefononi adresën nga shfletuesi

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

Nëse merrni një mesazh nga një robot në bisedën tuaj, në rregull, kaloni në fazën tjetër.

Në këtë mënyrë (nëpërmjet shfletuesit) gjithmonë mund të kontrolloni nëse ka probleme me gjenerimin e lidhjeve, ose nëse diçka është e fshehur diku dhe nuk funksionon.

Çfarë duhet të dini përpara se të vazhdoni të lexoni

Telegram ka disa lloje të bisedave në grup (të hapura, të mbyllura). Për këto biseda, disa nga funksionet (për shembull, id) janë të ndryshme, gjë që ndonjëherë shkakton disa probleme.

Le të supozojmë se është fundi i vitit 2019 dhe madje heroi i kohës sonë, Orkestra e mirënjohur Man (administrator, avokat, specialist i sigurisë së informacionit, programues dhe praktikisht MVP) Evgeniy V. dallon variablin $i nga një grup, ka zotëruar sythe, shikoni në dy vitet e ardhshme do të zotërojnë Chocolatey, dhe pastaj Përpunim paralel me PowerShell и Paralele ForÇdo-Objekt do të vijë.

1. Ne mendojmë se çfarë do të bëjë boti ynë

Nuk kisha asnjë ide, duhej të mendoja. Unë kam shkruar tashmë një bot-fletore. Nuk doja të bëja një robot "që dërgon diçka diku". Për t'u lidhur me Azure ju duhet një kartë krediti, por nga e merr studenti? Duhet të theksohet se gjithçka nuk është aq e keqe: retë kryesore japin një lloj periudhe testimi falas (por ju ende keni nevojë për një numër karte krediti - dhe duket sikur një dollar do të debitohet prej tij. Nuk mbaj mend nëse u kthye më vonë.)

Pa AI ML nuk është aq interesante të bësh një bot-poorist.

Vendosa të bëj një bot që do të më kujtojë (ose jo) fjalët angleze nga fjalori.
Për të shmangur ngatërresat me bazën e të dhënave, fjalori do të ruhet në një skedar teksti dhe do të përditësohet manualisht.
Në këtë rast, detyra është të tregohen bazat e punës, dhe jo të bëhet të paktën një produkt pjesërisht i përfunduar.

2. Të provosh çfarë dhe si për herë të parë

Le të krijojmë një dosje C:poshtranslate
Së pari, le të shohim se çfarë lloj powershell kemi, le të lëshojmë ISE përmes start-run
powershell ise
ose gjeni Powershell ISE në programet e instaluara.
Pas nisjes, do të hapet "një lloj redaktuesi" i zakonshëm i njohur; nëse nuk ka fushë teksti, atëherë gjithmonë mund të klikoni "Skedar - krijo të re".

Le të shohim versionin e powershell - shkruani në fushën e tekstit:

get-host 

dhe shtypni F5.

Powershell do të ofrojë për të ruajtur - "Skripti që do të ekzekutoni do të ruhet.", ne jemi dakord dhe ruajeni skedarin nga powershell me emrin në C: poshtranslate myfirstbotBT100.

Pas nisjes, në dritaren e tekstit të poshtëm marrim një tabelë të dhënash:

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

Unë kam 5.1 diçka, mjafton. Nëse keni një Windows 7/8 të vjetër, atëherë nuk ka ndonjë gjë të madhe - megjithëse PowerShell do të duhet të përditësohet në versionin 5 - p.sh. udhëzime.

Shkruani Get-Date në vijën e komandës më poshtë, shtypni Enter, shikoni orën, shkoni te dosja rrënjë me komandën
cd
dhe pastroni ekranin me komandën cls (jo, nuk keni nevojë të përdorni rm)

Tani le të kontrollojmë se çfarë funksionon dhe si - le të mos shkruajmë as kodin, por dy rreshta dhe të përpiqemi të kuptojmë se çfarë bëjnë ata. Le të komentojmë rreshtin me get-host me simbolin # dhe të shtojmë pak.

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

(Ajo që është interesante është se në listën rënëse të formatimit të kodit në Habré ka dy duzina opsione - por Powershell nuk është aty. Dos është atje. Perl është atje.)

Dhe le të ekzekutojmë kodin duke shtypur F5 ose ">" nga GUI.

Ne marrim daljen e mëposhtme:

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

Tani le të shohim këto dy rreshta dhe disa pika interesante në mënyrë që të mos i kthehemi kësaj në të ardhmen.

Ndryshe nga Pascal (dhe jo vetëm), vetë PowerShell përpiqet të përcaktojë se çfarë lloji t'i caktojë një ndryshoreje; më shumë detaje rreth kësaj janë shkruar në artikull Program arsimor për shtypjen në gjuhët e programimit
Prandaj, duke krijuar një variabël $TimeNow dhe duke i caktuar vlerën e datës dhe orës aktuale (Get-Date), nuk duhet të shqetësohemi shumë se çfarë lloji të të dhënave do të ketë atje.

Vërtetë, kjo injorancë mund të dëmtojë më vonë, por kjo është për më vonë. Më poshtë në tekst do të ketë një shembull.
Le të shohim se çfarë kemi. Le të ekzekutojmë (në vijën e komandës)

$TimeNow | Get-member

dhe merrni një faqe me tekst të pakuptueshëm

Shembull i tekstit të pakuptueshëm numër 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")...                                         

Siç mund ta shihni, një variabël i tipit TypeName: System.DateTime është krijuar me një sërë metodash (në kuptimin e asaj që mund të bëjmë me këtë objekt variabël) dhe veti.

Le të thërrasim $TimeNow.DayOfYear — marrim numrin e ditës së vitit.
Le të thërrasim $TimeNow.DayOfYear | Get-Member - marrim TypeName: System.Int32 dhe një grup metodash.
Le të thërrasim $TimeNow.ToUniversalTime() - dhe merrni kohën në UTC

Rregullues

Ndonjëherë ndodh që është e nevojshme të ekzekutohet një program deri në një linjë të caktuar dhe të shihet gjendja e programit në atë moment. Për këtë qëllim, ISE ka një funksion Debug - ndërroni pikën e ndërprerjes
Vendosni një pikë pushimi diku në mes, vendosni këto dy rreshta dhe shikoni se si duket pushimi.

3. Kuptimi i ndërveprimit me botin Telegram

Natyrisht, është shkruar edhe më shumë literaturë për ndërveprimin me bot, me të gjitha getpush e kështu me radhë, por çështja e teorisë mund të konsiderohet opsionalisht.

Në rastin tonë është e nevojshme:

  • Mësoni të dërgoni diçka në korrespondencë
  • Mësoni të merrni diçka nga korrespondenca

3.1 Mësoni të dërgoni diçka në korrespondencë dhe të merrni prej saj

Një kod i vogël - pjesa 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

dhe në Federatën Ruse në këtë pikë kemi gabimin Nuk mund të lidhet me serverin në distancë.

Ose nuk e marrim - varet nga operatori i telekomit dhe nëse përfaqësuesi është i konfiguruar dhe funksionon
Epo, gjithçka që mbetet është të shtoni një përfaqësues. Ju lutemi vini re se përdorimi i një përfaqësuesi të pakriptuar dhe përgjithësisht mashtrues është jashtëzakonisht i rrezikshëm për shëndetin tuaj.

Detyra për të gjetur një përfaqësues të punës nuk është shumë e vështirë - shumica e përfaqësuesve të publikuar http funksionojnë. Mendoj se e pesta funksionoi për mua.

Sintaksa duke përdorur proxy:

Invoke-WebRequest -Uri $URL4SEND -Proxy $MyProxy

Nëse merrni një mesazh në bisedën tuaj me një bot, atëherë gjithçka është në rregull, mund të vazhdoni. Nëse jo, vazhdoni korrigjimin.

Mund të shihni se në çfarë shndërrohet vargu juaj $URL4SEND dhe të provoni ta kërkoni në shfletues, si kjo:

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

3.2. Mësuam se si të shkruajmë "diçka" në chat, tani le të përpiqemi ta lexojmë

Le të shtojmë 4 rreshta të tjerë dhe të shohim se çfarë ka brenda përmes | merrni-anëtar

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

Gjëja më interesante na është dhënë

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

Le të shohim se çfarë ka në to:

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

Nëse gjithçka funksionon për ju, do të merrni një linjë të gjatë si:

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

Për fat të mirë, në artikullin e botuar më parë Telegram bot për administratorin e sistemit kjo linjë (po, sipas $MyMessageGet.RawContent | get-anëtar është System.String), tashmë është çmontuar.

4. Përpunoni atë që merrni (ne tashmë dimë se si të dërgojmë diçka)

Siç është shkruar tashmë këtu, gjërat më të nevojshme qëndrojnë në përmbajtje. Le t'i hedhim një vështrim më të afërt.

Së pari, ne do t'i shkruajmë disa fraza të tjera robotit nga ndërfaqja e uebit ose nga telefoni

/message1
/message2
/message3

dhe shikoni përmes shfletuesit adresën që është formuar në variablin $URLGET.

Do të shohim diçka të tillë:

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

Cfare eshte? Disa objekte komplekse nga grupet e objekteve që përmbajnë një identifikues mesazhi nga fundi në fund, identifikues i bisedës, identifikues dërgues dhe shumë informacione të tjera.

Sidoqoftë, nuk kemi nevojë të kuptojmë "çfarë lloj objekti është ky" - një pjesë e punës tashmë është bërë për ne. Le të shohim se çfarë ka brenda:

Leximi i mesazheve të marra ose pjesa 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. Çfarë duhet të bëjmë për këtë tani?

Le ta ruajmë skedarin që rezulton nën emrin myfirstbotBT105 ose çfarëdo që ju pëlqen më shumë, ndryshoni titullin dhe komentoni të gjithë kodin e shkruar tashmë përmes

<#start comment 105 end comment 105#>

Tani duhet të vendosim se ku ta marrim fjalorin (mirë, ku - në disk në një skedar) dhe si do të duket.

Sigurisht, ju mund të shkruani një fjalor të madh pikërisht në tekstin e skenarit, por kjo është krejtësisht jashtë çështjes.
Pra, le të shohim se me çfarë powershell mund të funksionojë normalisht.
Në fakt, atij nuk i intereson se me çfarë dosje punon, dhe ne nuk na intereson.
Ne kemi një zgjedhje: txt (ju mundeni, por pse), csv, xml.
A mund t'i shikojmë të gjithë? Le t'i shohim të gjithë.
Le të krijojmë një klasë MyVocabClassExample1 dhe një variabël $MyVocabExample1
Vërej se klasa është shkruar pa $

disa kod #5

write-host "This is part 5"
class MyVocabClassExample1 {
    [string]$Original  # слово
    [string]$Transcript
    [string]$Translate
    [string]$Example
    [int]$VocWordID # очень интересный момент. Использование int с его ограничениями может порой приводить к диким последствиям, для примера - недавний случай с SSD HPE. Изначально я не стал добавлять этот элемент, потом все же дописал и закомментировал.
    }

$MyVocabExample1 = [MyVocabClassExample1]::new()
$MyVocabExample1.Original = "Apple"
$MyVocabExample1.Transcript = "[ ˈapəl ]"
$MyVocabExample1.Translate = "Яблоко"
$MyVocabExample1.Example = "An apple is a sweet, edible fruit produced by an apple tree (Malus domestica)"
# $MyVocabExample1.$VocWordID = 1

$MyVocabExample2 = [MyVocabClassExample1]::new()
$MyVocabExample2.Original = "Pear"
$MyVocabExample2.Transcript = "[ pe(ə)r ]"
$MyVocabExample2.Translate = "Груша"
$MyVocabExample2.Example = "The pear (/ˈpɛər/) tree and shrub are a species of genus Pyrus"
# $MyVocabExample1.$VocWordID = 2

Le të përpiqemi ta shkruajmë këtë në skedarë duke përdorur mostër.

Disa 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

- dhe marrim një gabim në linjën Out-File -FilePath $MyFilenameExample01 -InputObject -Append $MyVocabExample2.

Ai nuk dëshiron të shtojë, ah-ah, çfarë turpi.

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

Le të shohim se çfarë ndodh. Pamje e shkëlqyeshme e tekstit - por si ta eksportoni përsëri? A duhet të prezantoj një lloj ndarës teksti, të tilla si presjet?

Dhe në fund ju merrni një skedar "vlerash të ndara me presje (CSV) A STOP PRIT.
#

$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 

Siç mund të shihet lehtë, MS nuk dallohet veçanërisht nga logjika e tij; për një procedurë të ngjashme, në një rast përdoret -FilePath, në një tjetër - Path.

Përveç kësaj, në dosjen e tretë gjuha ruse u zhduk, në dosjen e katërt doli ... mirë, diçka ndodhi. #TYPE System.Object[] 00
# "Numërimi", "Gjatësia", "Gjatësia", "Ranku", "SyncRoot", "IsReadOnly", "IsFixedSize", "IsSynchronized"
#
Le ta rishkruajmë pak:

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

Duket se më ka ndihmuar, por ende nuk më pëlqen formati.

Veçanërisht nuk më pëlqen që nuk mund të vendos linja nga një objekt në një skedar drejtpërdrejt.
Meqë ra fjala, që kur filluam të shkruanim në skedarë, a mund të fillojmë të mbajmë një regjistër fillestar? Kemi kohë si variabël, mund të vendosim emrin e skedarit.

Vërtetë, nuk ka asgjë për të shkruar ende, por mund të mendoni se si t'i rrotulloni më mirë shkrimet.
Le të provojmë xml tani për tani.

Disa 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

Eksportimi në xml ka shumë përparësi - lexueshmëri, eksportim i të gjithë objektit dhe nuk ka nevojë të kryeni një ngritje.

Le të përpiqemi lexoni skedarin xml.

Pak lexim nga xml

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

Le t'i kthehemi detyrës. Ne kemi shkruar një skedar provë, lexojmë atë, formati i ruajtjes është i qartë, nëse është e nevojshme, mund të shkruani një redaktues të vogël të veçantë të skedarëve për të shtuar dhe fshirë rreshta.

Më lejoni t'ju kujtoj se detyra ishte të krijonim një bot të vogël trajnimi.

Formati i punës: Unë dërgoj komandën "shembull" në bot, roboti më dërgon një fjalë dhe transkriptim të zgjedhur rastësisht dhe pas 10 sekondash më dërgon një përkthim dhe koment. Ne dimë të lexojmë komandat, gjithashtu dëshirojmë të mësojmë se si të zgjedhim dhe kontrollojmë automatikisht proxies dhe të rivendosim numëruesit e mesazheve në harresë.

Le të çkomentojmë gjithçka të komentuar më parë si të panevojshme, komentojmë shembujt tani të panevojshëm me txt dhe csv dhe ruajmë skedarin si version B106

Oh po. Le t'i dërgojmë diçka përsëri botit.

6. Dërgimi nga funksionet dhe më shumë

Përpara se të përpunoni pritjen, duhet të krijoni një funksion për dërgimin e "të paktën diçkaje" përveç një mesazhi provë.

Sigurisht, në shembull do të kemi vetëm një dërgim dhe vetëm një përpunim, por çka nëse duhet të bëjmë të njëjtën gjë disa herë?

Është më e lehtë të shkruash një funksion. Pra, ne kemi një variabël të llojit të objektit $MyVocabExample4AsArray, të lexuar nga skedari, në formën e një grupi prej sa dy elementësh.
Le të shkojmë të lexojmë.

Në të njëjtën kohë, ne do të merremi me orën; do të na duhet më vonë (në fakt, në këtë shembull nuk do të na duhet :)

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

Siç mund ta shihni lehtësisht, funksioni thërret $MyToken dhe $MyChatID, të cilat ishin të koduara më parë.

Nuk ka nevojë ta bëni këtë, dhe nëse $MyToken është një për çdo bot, atëherë $MyChatID do të ndryshojë në varësi të bisedës.

Megjithatë, duke qenë se ky është një shembull, ne do ta injorojmë atë për momentin.

Meqenëse $MyVocabExample4AsArray nuk është një grup, megjithëse është shumë i ngjashëm me një, atëherë thjesht nuk mund ta marrësh kërkoni gjatësinë e saj.

Edhe një herë do të duhet të bëjmë diçka që nuk mund të bëhet - parashutë jo sipas kodit - merre dhe numëro

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

i rastësishëm tipar interesant. Le të themi se duam të marrim 0 ose 1 (ne kemi vetëm dy elementë në grup). Kur vendosim kufijtë 0..1, a do të marrim "1"?
jo - nuk do ta marrim, kemi një shembull të veçantë Shembulli 2: Merrni një numër të plotë të rastësishëm midis 0 dhe 99 Merrni-Random -Maksimumi 100
Prandaj, për 0..1 duhet të vendosim madhësinë 0..2, me numrin maksimal të elementit = 1.

7. Përpunimi i mesazheve hyrëse dhe gjatësia maksimale e radhës

Ku u ndalëm më parë? kemi variablin e marrë $MyMessageGet
dhe $Content4Pars01 të marra prej tij, nga të cilat ne jemi të interesuar në elementet e grupit Content4Pars01.result

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

Le të dërgojmë botin /message10, /message11, /message12, /word dhe përsëri /word dhe /hello.
Le të shohim se çfarë kemi:

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

Le të shqyrtojmë gjithçka që kemi marrë dhe të dërgojmë një përgjigje nëse mesazhi ishte /word
rasti i konstruktit, atë që disa e përshkruajnë si if-elseif, quhet në powershell nëpërmjet ndërprerësit. Në të njëjtën kohë, kodi më poshtë përdor çelësin -wildcard, i cili është krejtësisht i panevojshëm dhe madje i dëmshëm.

Disa kode #7.1

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

Le ta ekzekutojmë skenarin disa herë. Do të marrim të njëjtën fjalë dy herë për çdo përpjekje ekzekutimi, veçanërisht nëse kemi bërë një gabim në zbatimin e rastësishëm.

Por ndalo. Ne nuk dërguam /word përsëri, kështu që pse mesazhi po përpunohet përsëri?

Radha për dërgimin e mesazheve te boti ka një gjatësi të kufizuar (100 ose 200 mesazhe, mendoj) dhe duhet të pastrohet manualisht.

Kjo sigurisht përshkruhet në dokumentacion, por duhet ta lexoni!

Në këtë rast, ne kemi nevojë për parametrin ?chat_id dhe ende nuk nevojiten &koha, &limit, &parse_mode=HTML dhe &disable_web_page_preview=true.

Dokumentacioni për telegram api është këtu
Ai thotë në të bardhë dhe anglisht:
Identifikuesi i përditësimit të parë që do të kthehet. Duhet të jetë më i madh për një se më i larti midis identifikuesve të përditësimeve të marra më parë. Si parazgjedhje, përditësimet fillojnë me më të hershmit
e pakonfirmuar përditësimet janë kthyer. Një përditësim konsiderohet i konfirmuar sapo getUpdates thirret me një ofset më i lartë sesa përditësimi_id i tij. Kompensimi negativ mund të specifikohet për të tërhequr përditësimet duke filluar nga përditësimi -offset nga fundi i radhës së përditësimeve. Të gjitha përditësimet e mëparshme do të harrohen.

Le të shohim:

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

Po, dhe ne do ta rivendosim atë dhe do ta rishkruajmë pak funksionin. Ne kemi dy opsione - të kalojmë të gjithë mesazhin te funksioni dhe ta përpunojmë tërësisht në funksion, ose të japim vetëm ID-në e mesazhit dhe ta rivendosim atë. Për shembull, e dyta duket më e thjeshtë.

Më parë, vargu ynë i pyetjeve "të gjitha mesazhet" dukej kështu

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

dhe do të duket si

$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 

Askush nuk ju ndalon që së pari të merrni të gjitha mesazhet, t'i përpunoni ato dhe vetëm pasi kërkesa për përpunim të suksesshëm të pakonfirmohet -> të konfirmohet.

Pse ka kuptim të telefononi konfirmimin pasi të ketë përfunduar i gjithë përpunimi? Një dështim është i mundur në mes të ekzekutimit, dhe nëse për shembullin e një chatbot falas, humbja e një mesazhi të vetëm nuk është asgjë e veçantë, atëherë nëse jeni duke përpunuar transaksionin e pagës ose kartës së dikujt, rezultati mund të jetë më i keq.

Disa rreshta të tjerë kodi

$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. Në vend të një përfundimi

Funksionet bazë - leximi i mesazheve, rivendosja e radhës, leximi nga skedari dhe shkrimi në skedar kryhen dhe shfaqen.

Kanë mbetur vetëm katër gjëra për të bërë:

  • dërgimi i përgjigjes së saktë për një kërkesë në chat
  • dërgimi i një përgjigjeje për çdo bisedë në të cilën është shtuar roboti
  • ekzekutimi i kodit në një lak
  • nisja e një boti nga programuesi i Windows.

Të gjitha këto detyra janë të thjeshta dhe mund të realizohen lehtësisht duke lexuar dokumentacionin rreth parametrave si p.sh
Set-ExecutionPolicy e pakufizuar dhe -ExecutionPolicy Bypass
ciklit të formës

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

Faleminderit të gjithëve që lexuan.

Burimi: www.habr.com

Shto një koment