Shablloni i një boti të thjeshtë për Telegram për nxënësit e klasave 7-9 në Powershell

Gjatë bisedave me një shok, papritur zbulova se fëmijët në klasat 8-10 në shkollën e tyre nuk mësohen fare programim. Word, Excel dhe mjaft. As Logo, as madje Pascal, as madje VBA për Excel.

ShumĂ« u befasova, hapi internetin dhe fillova tĂ« lexoj —
Një nga detyrat e shkollës profesionale është të ndihmojë në ndërtimin e një brezi të ri që i përgjigjet përgjithësisht niveleve të zhvillimit dhe mënyrës së jetesës në kushtet e shoqërisë informacionale.
Ky kurs do të lejojë konsolidimin praktik të njohurive të nxënësve mbi ndërtimet kryesore të gjuhës së programimit Pascal. (nga programi i ndonjë gjimnazi në vitin 2017)

Si rezultat, vendosa tĂ« kaloj disa orĂ« dhe tĂ« skicoj njĂ« shembull «si tĂ« krijosh njĂ« bot tĂ« thjeshtĂ« — pĂ«r nxĂ«nĂ«sit».

NĂ« vazhdim Ă«shtĂ« se si tĂ« shkruani njĂ« tjetĂ«r bot tĂ« thjeshtĂ« nĂ« Powershell dhe ta bĂ«ni atĂ« tĂ« punojĂ« pa webhook, IP tĂ« bardha, servera tĂ« dedikuar, makineri virtuale tĂ« zhvilluara nĂ« cloud dhe gjithĂ« ato — nĂ« njĂ« PC tĂ« zakonshĂ«m nĂ« shtĂ«pi me Windows tĂ« zakonshme.

TLDR: Një tjetër artikull i mërzitshëm me gabime gramatikore dhe faktike, nuk ka gjë për të lexuar, nuk ka humor, nuk ka figura.

Nuk ka asgjë të re në artikull, gati gjithçka e shkruar më parë është publikuar në Habr, për shembull në artikujt e tij. Udhëzues: Si të krijoni bota në Telegram dhe Bot Telegram për administratën sistemike.
Madje, artikulli është qëllimisht i tepruar, për të mos iu referuar çdo herë literaturës mësimore. Nuk ka asnjë referencë për banda 4, PowerShell Deep Dives apo, le të themi, The 5 Pillars of the AWS Well-Architected Framework në tekst.

Mund ta kaloni parathënien

Me guxim mund ta kalojmëNë vitin 2006, Microsoft lëshoi PowerShell 1.0 për atëherë Windows XP, Vista dhe serverin 2003. Në disa aspekte, ai zëvendësoi gjëra si skenat cmdbat, skenat vb, Windows Script Host dhe JScript.

Edhe tani, PowerShell mund të konsiderohet vetëm si një hap tjetër pas varianteve Logo, përveç ndoshta të përdorura akoma Delphi (ose ndonjë gjë më të vjetër), megjithëse përmban cikle, klasa, funksione, thirrje MS GUI, integrimi me Git etj.

Përdorimi i PowerShell është relativisht i rrallë, mund ta hasni ndonjëherë në formën PowerShell Core, VMware vSphere PowerCLI, Azure PowerShell, MS Exchange, Desired State Configuration, PowerShell Web Access dhe një duzinë tjetër programesh dhe funksionesh të rralla. Mundësisht, do të ketë një rritje të re me daljen WSL2, por kjo nuk është e sigurt.

PowerShell ka tre avantazhe të mëdha:

  1. Ai Ă«shtĂ« relativisht i thjeshtĂ«, pĂ«r tĂ« ka shumĂ« literaturĂ« dhe shembuj, madje edhe nĂ« rusisht, pĂ«r shembull, njĂ« artikull mbi Foreach — nga libri PowerShell in depth — mbi diferencĂ«n () dhe {}
  2. Ai vjen së bashku me redaktorin ISE, i përfshirë në Windows. Aty ka edhe ndonjë debugger.
  3. Nga ai thjesht thirren komponentët për ndërtimin e ndërfaqeve grafike.

0. Përgatitja.

Na nevojitet:

  • NjĂ« PC me Windows (unĂ« kam Windows 10)
  • Disa lloj akses nĂ« internet (pĂ«rmes NAT, pĂ«r shembull)
  • PĂ«r ata qĂ« kanĂ« qasje tĂ« kufizuar nĂ« Telegram — njĂ« Freegate i instaluar dhe i konfiguruar nĂ« shfletues, nĂ« disa raste tĂ« komplikuara sĂ« bashku me Symple DNS Crypt
  • NjĂ« klient funksional i Telegramit nĂ« telefon
  • Kuptimi i bazave — çfarĂ« Ă«shtĂ« njĂ« variabĂ«l, njĂ« array, njĂ« cikĂ«l.

Artikuj tĂ« hapur dhe tĂ« lexuar — UdhĂ«zues: Si tĂ« krijoni bota nĂ« Telegram dhe Bot Telegram pĂ«r administratĂ«n sistemike

1. Do të krijojmë një bot testues.

Duke qenĂ« se tĂ« gjithĂ« e dinĂ« kĂ«tĂ« tashmĂ«, dhe ka qenĂ« edhe mĂ« parĂ«, mund ta kalojmĂ« edhe kĂ«tĂ«Siç thotĂ« artikulli mĂ« lart — SĂ« pari, boti pĂ«r Telegram — Ă«shtĂ« ende njĂ« aplikacion qĂ« ekzekutohet nĂ« anĂ«n tuaj dhe bĂ«n kĂ«rkesa nĂ« Telegram Bot API. Dhe API Ă«shtĂ« e qartĂ« — boti i drejtohet njĂ« URL-je tĂ« caktuar me parametra, dhe Telegram pĂ«rgjigjet me njĂ« objekt JSON.

Problemet e lidhura me kĂ«tĂ«: nĂ«se ndonjĂ«herĂ« merrni njĂ« kod nga objekti JSON dhe e dĂ«rgoni pĂ«r ta ekzekutuar (jo qĂ«llimisht) — kodi do tĂ« ekzekutohet aty.

Procesi i krijimit është përshkruar në dy artikujt e mësipërm, por përserit: në Telegram hapim kontaktet, kërkojmë @botfather, i themi /newbot, krijojmë një bot Botfortest12344321, e quajmë Mynext1234bot, dhe marrim një mesazh me një çelës unik të formatit 1234544311:AbcDefNNNNNNNNNNNNN.

Ruani çelësin dhe mos e ndani atë!

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

Do ta pyesim BotFather "/mybot" dhe do të rregullojmë konfigurimet nëse diçka nuk na pëlqen.

SĂ«rish do tĂ« hapim kontaktet, do ta gjejmĂ« @Botfortest12344321 (fillimi i kĂ«rkimit me @ Ă«shtĂ« e detyrueshme), do tĂ« klikojmĂ« "fillo" dhe do t'i shkruajmĂ« bordin "/Lavdi robotĂ«ve". Shkronja / Ă«shtĂ« e detyrueshme, citatet — jo.
Sigurisht, boti nuk do të përgjigjet.

Do tĂ« kontrollojmĂ« nĂ«se boti Ă«shtĂ« krijuar — do tĂ« hapim.

api.telegram.org/bot1234544311:AbcDefNNNNNNNNNNNNN/getMe
ku 1234544311:AbcDefNNNNNNNNNNNNN — çelĂ«si i marrĂ« mĂ« parĂ«,
dhe do të marrim një varg si
{«ok»:true,«result»:{«»}}

Kemi tani njĂ« frazĂ« sekrete tĂ« parĂ« (token) qĂ« kemi. Tani na nevojitet tĂ« mĂ«sojmĂ« numrin e dytĂ« tĂ« sekreteve — ID-nĂ« e bisedĂ«s me robotin. Çdo bisedĂ«, grup dhe kĂ«shtu me radhĂ« — janĂ« individuale dhe kanĂ« numrin e tyre tĂ« veçantĂ« (ndonjĂ«herĂ« me minus — pĂ«r grupet e hapura). PĂ«r tĂ« gjetur kĂ«tĂ« numĂ«r, na nevojitet tĂ« kĂ«rkojmĂ« nĂ« shfletues (nĂ« tĂ« vĂ«rtetĂ« nuk Ă«shtĂ« e nevojshme tĂ« jetĂ« nĂ« shfletues, por pĂ«r njĂ« kuptim mĂ« tĂ« mirĂ« mund tĂ« fillojmĂ« nga aty) adresĂ«n (ku 1234544311:NNNNNNNNN — Ă«shtĂ« tokeni juaj)

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

dhe të marrim një përgjigje të tipit

{«ok»:true,«result»:[{«update_id»:
,
 chat«:{«id»:123456789

Na nevojitet saktësisht chat_id.

Do ta verifikojmë nëse mund të shkruajmë në bisedë manualisht: do të thërrasim nga shfletuesi adresën

https://api.telegram.org/botvahtoken/sendMessage?chat_id=123456789&text="Jeta është një lëvizje e drejtuar"

NĂ«se nĂ« bisedĂ«n tuaj ka ardhur njĂ« mesazh nga roboti — ok, kaloni nĂ« fazĂ«n tjetĂ«r.

NĂ« kĂ«tĂ« mĂ«nyrĂ« (nĂ«pĂ«rmjet shfletuesit) gjithmonĂ« mund ta kontrolloni se ku janĂ« problemet — nĂ« gjenerimin e lidhjes nga ana juaj, ose ndonjĂ« gjĂ« diku qĂ« Ă«shtĂ« e mbuluar dhe nuk funksionon.

ÇfarĂ« duhet tĂ« dini para se tĂ« vazhdoni leximin

Në Telegram ka disa lloje grupesh (të hapura, të mbyllura). Për këto grupe disa funksione (p.sh., id) ndryshojnë, gjë që ndonjëherë shkakton disa probleme.

Le të supozojmë se jemi në fund të vitit 2019, dhe madje edhe hero i kohës sonë, njeriu i njohur si Orkestri (administrator, avokat, ekspert në sigurinë e informacionit, programues dhe praktikisht MVP) Evgeni V. e ndan variablen $i nga matrica, ka mësuar ciklet, ndoshta në vitet e ardhshme do të zotërojë gjithashtu Chocolatey, dhe pastaj do Përpunimi paralel me PowerShell dhe ForEach-Object Paralel arrijë.

1. Mendojmë, çfarë do të bëjë boti ynë

Nuk kisha ide, kĂ«shtu qĂ« mĂ« duhej tĂ« mendoja. Kam shkruar tashmĂ« njĂ« bot-libĂ«r, nuk mĂ« pĂ«lqeu tĂ« bĂ«ja njĂ« bot "qĂ« dĂ«rgon diçka diku". PĂ«r lidhjen me Azure kĂ«rkohet njĂ« kartĂ« krediti, por nga e di unĂ« njĂ« student nuk e ka atĂ«. Duhet tĂ« theksoj se gjĂ«rat nuk janĂ« aq keq: shĂ«rbimet kryesore tĂ« cloud ofrojnĂ« njĂ« periudhĂ« prove falas (por numri i kartĂ«s sĂ« kreditit Ă«shtĂ« prapĂ« i nevojshĂ«m — dhe do tĂ« tĂ«rhiqet njĂ« dollar, mbase. Nuk e di nĂ«se mĂ« Ă«shtĂ« kthyer ndonjĂ«herĂ«.)

Pa AI ML, nuk është aq interesante të bësh një bot të paqëndrueshëm-poet.

Vendosa të bëj një bot, i cili do të më kujtonte (ose jo) fjalët angleze nga fjalori.
Fjalori, në mënyrë që të mos merrem me BD-në, do të jetë në një skedar tekstual dhe do të plotësohet manualisht.
Në këtë rast, qëllimi është të tregojmë baza në punë, dhe jo të krijojmë edhe një produkt të gatshëm pjesërisht.

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

Të krijojmë dosjen C:poshtranslate
Së pari do të shikojmë se çfarë është powershell, do ta hapim ISE përmes startit-ekzekutimit
powershell ise
ose do ta gjejmë Powershell ISE në programet e instaluara.
Pas hapjes do tĂ« shfaqet njĂ« «editor i zakonshĂ«m», nĂ«se nuk ka fushĂ« teksti, gjithmonĂ« mund tĂ« klikoni «File — create new».

TĂ« shikojmĂ« versionin e powershell — do tĂ« shkruajmĂ« nĂ« fushĂ«n e tekstit:

get-host 

dhe do të shtypim F5.

Powershell do tĂ« ofrojĂ« tĂ« ruani — «Skedari qĂ« ju do tĂ« funksiononi do tĂ« ruhet.», pranoni dhe ruani nĂ« C:poshtranslate skedarin nga powershell me emrin myfirstbotBT100.

Pas ekzekutimit, në dritaren e poshtme do të shohim një tabelë të dhënash:

Emri             : Windows PowerShell ISE Host
Version          : 5.1.(dhe kështu me radhë)

UnĂ« kam 5.1 me diçka tjetĂ«r, kjo Ă«shtĂ« e mjaftueshme. NĂ«se keni Windows 7/8 tĂ« vjetĂ«r, nuk Ă«shtĂ« problem — megjithatĂ« PowerShell duhet tĂ« pĂ«rditĂ«sohet nĂ« versionin 5 — pĂ«r shembull, pĂ«r udhĂ«zues.

Të shkruajmë në linjën komandë poshtë Get-Date, shtypim Enter, shohim orën, kalojmë në dosjen kryesore me komandën
cd
dhe pastrojmë ekranin me komandën cls (jo, mos përdorni rm)

Tani do tĂ« shohim se si funksionon — do tĂ« shkruajmĂ« jo kod, por dy rreshta, dhe do tĂ« pĂ«rpiqemi tĂ« kuptojmĂ« se çfarĂ« bĂ«jnĂ«. Do ta komentojmĂ« rreshtin me simbolin get-host # dhe do tĂ« shkruajmĂ« pak mĂ« shumĂ«.

# ĐŸŃ€ĐžĐŒĐ”Ń€ ŃˆĐ°Đ±Đ»ĐŸĐœĐ° Đ±ĐŸŃ‚Đ° 
# get-host
<# ŃŃ‚ĐŸ ĐżŃ€ĐžĐŒĐ”Ń€ ĐŒĐœĐŸĐłĐŸŃŃ‚Ń€ĐŸŃ‡ĐœĐŸĐłĐŸ ĐșĐŸĐŒĐŒĐ”ĐœŃ‚Đ°Ń€ĐžŃ #>
$TimeNow = Get-Date
$TimeNow

(ÇfarĂ« Ă«shtĂ« interesante. NĂ« listĂ«n e zbritshme tĂ« formatimit tĂ« kodit nĂ« Habr, ka dy gati dhjetĂ«ra variante — por powershell nuk Ă«shtĂ« aty. Ka Dos. Ka Perl.)

Dhe do ta ekzekutojmë kodin, duke shtypur F5 ose '>' nga GUI.

Do të marrim rezultat:

E shtunë, 8 Dhjetor 2019, 21:00:50 PM (ose diçka e tillë)

Tani do të merremi me këta dy rreshta, dhe disa aspekte interesante, që më pas të mos kthehemi për këtë.

Ndryshe nga pascal (dhe jo vetëm), powershell përpiqet vetë të përcaktojë se çfarë lloji t'i japë variables, më shumë për këtë është shkruar në artikullin Udhëzues për tipizimin në gjuhët e programimit
Prandaj, duke krijuar variable $TimeNow, dhe duke i dhënë atij vlerën e datës dhe orës aktuale (Get-Date), nuk duhet të shqetësohemi shumë për se çfarë lloji të dhënash do të jetë aty.

E vërteta, nga mosdija e këtij, më vonë mund të jetë e dhimbshme, por kjo është më vonë. Më poshtë në tekst do të ketë një shembull.
Le të shohim çfarë kemi arritur. Do të ekzekutojmë (në komandën e linjës)

$TimeNow | Get-member

dhe do të marrim një faqe me tekst të paqartë

Shembulli i parë i tekstit të paqartë

PS C:&gt; $TimeNow | Get-member
   TypeName: System.DateTime
Name                 MemberType     Definition                                                                                                                                       
----                 ----------     ----------                                                                                                                                       
Shto                  <b>Metoda         </b>datetime Shto(timespan vlera)  
..
DisplayHint          NoteProperty   DisplayHintType DisplayHint=DateTime                                                                                                             
Data                 <b>Pronë       </b>datetime Data {merr;}                                                                                                                             
Viti                 Pronë       int Viti {merr;}   
..
DateTime             ScriptProperty System.Object DateTime {merr=po ((&amp; { Set-StrictMode -Version 1; $this.DisplayHint }) -ieq  "Data")...                                         

Siç duket, u krijua një variabël e tipit TypeName: System.DateTime me shumë metoda (në kuptimin se çfarë mund të bëjmë me këtë variabël objekti) dhe pronash.

Le tĂ« thĂ«rrasim $TimeNow.DayOfYear — do tĂ« marrim numrin e ditĂ«s nĂ« vit.
Le tĂ« thĂ«rrasim $TimeNow.DayOfYear | Get-Member — do tĂ« marrim TypeName: System.Int32 dhe grupin e metodave.
Le tĂ« thĂ«rrasim $TimeNow.ToUniversalTime() — dhe do tĂ« marrim kohĂ«n nĂ« UTC

Debugger

NdonjĂ«herĂ« ndodh qĂ« nevojitet tĂ« ekzekutohet njĂ« program deri nĂ« njĂ« rresht tĂ« caktuar dhe tĂ« shikojmĂ« gjendjen e programit nĂ« atĂ« moment. PĂ«r kĂ«tĂ«, nĂ« ISE ka funksionin Debug — toggle break point
Vendosni një pikë ndalese diku në mes, ekzekutoni këto dy rreshta dhe shikoni si duket ndalimi.

3. Mësojmë për ndërveprimin me botin Telegram

Sigurisht, për ndërveprimin me botin, me të gjitha getpush dhe kështu me radhë, është shkruar edhe më shumë literaturë, megjithatë, çështja e teorisë mund të shqyrtohet fakultativisht.

Në rastin tonë është e nevojshme:

  • TĂ« mĂ«sojmĂ« tĂ« dĂ«rgojmĂ« diçka nĂ« bisedĂ«
  • TĂ« mĂ«sojmĂ« tĂ« marrim diçka nga biseda

3.1 Mësojmë të dërgojmë diçka në bisedë dhe të marrim nga ajo

Pak kod — pjesa 3

Shkruaj rezultatin "Kjo është pjesa 3"
$MyToken = "1234544311:AbcDefNNNNNNNNNNNNN"
$MyChatID = "123456789"
$MyProxy = "http://1.2.3.4:5678" 

$TimeNow = Merr-Datën
$TimeNow.ToUniversalTime()
$ScriptDir = Ndaj-Përmbajtjen $script:MyInvocation.MyCommand.Path
$BotVersion = "BT102"

$MyText01 = "Jeta është lëvizje e drejtuar - " + $TimeNow

$URL4SEND = "https://api.telegram.org/bot$MyToken/sendMessage?chat_id=$MyChatID&text=$MyText01"

Invoke-WebRequest -Uri $URL4SEND

dhe në RF në këtë vend marrim gabimin Unable to connect to the remote server.

Ose nuk marrim – varet nga operatori i komunikimit dhe nĂ«se proxy Ă«shtĂ« i konfiguruar dhe funksionon.
ÇfarĂ« tĂ« thuash – mbetet tĂ« shtojmĂ« proxy. Kini parasysh – pĂ«rdorimi i proxy-ve tĂ« pakriptuar dhe fqinjĂ«ve tĂ« huaj Ă«shtĂ« jashtĂ«zakonisht i rrezikshĂ«m pĂ«r shĂ«ndetin tuaj.

Detyra pĂ«r tĂ« gjetur njĂ« proxy qĂ« funksionon nuk Ă«shtĂ« shumĂ« e vĂ«shtirĂ« – pjesa mĂ« e madhe e proxy-ve http tĂ« publikuar punon. MĂ« ndodhi qĂ« ndoshta provoja tĂ« pestin.

Sintaksa me përdorimin e proxy:

Invoke-WebRequest -Uri $URL4SEND -Proxy $MyProxy

NĂ«se keni marrĂ« njĂ« mesazh nĂ« bisedĂ«n tuaj me programin – atĂ«herĂ« gjithçka Ă«shtĂ« nĂ« rregull, mund tĂ« vazhdoni. NĂ«se jo – vazhdoni debugging.

Mund të shikoni se çfarë bëhet me stringun tuaj $URL4SEND dhe të provoni ta kërkoni në shfletues, për shembull kështu:

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

3.2. Të shkruajmë "diçka" në bisedë e mësuam, tani do të përpiqemi të lexojmë.

Shtojmë edhe 4 rreshta dhe shohim se çfarë ka brenda përmes | 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

Informacionin më interesant na e ofron

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

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

Write-Host "ParsedHtml"
$MyMessageGet.ParsedHtml # këtu është interesante
Write-Host "RawContent"
$MyMessageGet.RawContent # dhe këtu është interesante, por edhe lexueshëm. 
Write-Host "Content"
$MyMessageGet.Content

Nëse gjithçka funksionon, do të merrni një varg të gjatë si:

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

FatmirĂ«sisht, nĂ« njĂ« artikull tĂ« mĂ«parshĂ«m "Telegram-boti pĂ«r administratorin sistemik" kjo varg (po, sipas $MyMessageGet.RawContent | get-member — Ă«shtĂ« System.String), tashmĂ« Ă«shtĂ« trajtuar.

4. Të përpunojmë atë që morëm (tani dimë si të dërgojmë diçka)

Siç është shkruar më parë këtu, gjëja më e nevojshme ndodhet në përmbajtje. Le ta shohim më me kujdes.

Së pari, do të shkruajmë disa fraza për botin nga ndërfaqja web ose nga telefoni

/message1
/message2
/message3

dhe do të shohim në shfletues adresën që u formua në variablën $URLGET.

Ne do të shohim diçka si:

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

ÇfarĂ« Ă«shtĂ« kjo? NjĂ« objekt i komplikuar nga array objektesh, qĂ« pĂ«rmban njĂ« identifikues tĂ« pĂ«rgjithshĂ«m tĂ« mesazhit, identifikues tĂ« bisedĂ«s, identifikues tĂ« dĂ«rgimit dhe shumĂ« informacion tjetĂ«r.

MegjithatĂ«, nuk na nevojitet tĂ« shqyrtojmĂ« "çfarĂ« Ă«shtĂ« ky objekt" — njĂ« pjesĂ« e punĂ«s Ă«shtĂ« bĂ«rĂ« tashmĂ« pĂ«r ne. Le tĂ« shohim se çfarĂ« ka brenda:

Lexojmë mesazhet e marra ose pjesën 4

Write-Host "Kjo është pjesa 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Ă« tani me kĂ«tĂ«

Do ta ruajmë skedarin e marrë me emrin myfirstbotBT105 ose çfarëdo emri tjetër që ju pëlqen, do të ndryshojmë titullin dhe do të komentojmë të gjithë kodin e shkruar tashmë përmes

<#start comment 105 end comment 105#>

Tani na duhet tĂ« vendosim se ku do ta marrĂ«im fjalorin (jo si ku — nĂ« disqet nĂ« skedarin) dhe si do tĂ« duket ai.

Sigurisht, është e mundur të krijohet një fjalor të madh direkt në tekstin e skriptit, por kjo nuk është në rregull.
Prandaj, le ta shohim se me çfarë mund të punojë Powershell standardisht.
Në të vërtetë, nuk ka rëndësi me cilin skedar të punojë, por na intereson neve.
Në dispozicion kemi: txt (mundet, por përse), csv, xml.
A kemi mundësinë të shohim të gjithë? Le të shohim të gjithë.
Do të krijojmë klasën MyVocabClassExample1 dhe variablen $MyVocabExample1
Vërej se klasa shkruhet pa $

pak kod #5

write-host "Kjo është pjesa 5"
class MyVocabClassExample1 {
    [string]$Original  # fjala
    [string]$Transcript
    [string]$Translate
    [string]$Example
    [int]$VocWordID # një pikë shumë interesante. Përdorimi i int me kufizimet e tij mund të çojë herë pas here në pasojat e çuditshme, për shembull - rasti i fundit me SSD HPE. Fillimisht nuk e shtova këtë element, më vonë e shtova dhe e komentova.
    }

$MyVocabExample1 = [MyVocabClassExample1]::new()
$MyVocabExample1.Original = "Apple"
$MyVocabExample1.Transcript = "[ ˈapəl ]"
$MyVocabExample1.Translate = "Mollë"
$MyVocabExample1.Example = "Një mollë është një frut i ëmbël dhe i ngrënshëm i prodhuar nga një pemë molle (Malus domestica)"
# $MyVocabExample1.$VocWordID = 1

$MyVocabExample2 = [MyVocabClassExample1]::new()
$MyVocabExample2.Original = "Pear"
$MyVocabExample2.Transcript = "[ pe(ə)r ]"
$MyVocabExample2.Translate = "Dardhë"
$MyVocabExample2.Example = "Pemë dhe grumbujt e dardhës janë një specie e gjinisë Pyrus"
# $MyVocabExample1.$VocWordID = 2

Le të përpiqemi ta shkruajmë këtë në skedarë. sipas modelit.

Pak kod #5.1

Write-Host $ScriptDir # shpresoj që nuk e keni komentuar $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 do tĂ« marrim njĂ« gabim nĂ« rreshtin Out-File -FilePath $MyFilenameExample01 -InputObject -Append $MyVocabExample2.

Nuk do të shtojë, oi oi çfarë keqardhje.

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

Le tĂ« shohim çfarĂ« doli. NjĂ« pamje e shkĂ«lqyer tekstuale — dhe si ta eksportojmĂ« sĂ«rish nga ajo? TĂ« futim ndonjĂ« ndarĂ«s teksti, pĂ«r shembull presje?

Dhe në fund të marrim "një skedë me ndarës - presje, vlerat e ndara me presje (CSV) A NDALUNI PAK.
#

$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ç duket lehtë, MS nuk është shumë dalluar në logjikë, për procedura të ngjashme në një rast përdoret -FilePath, për një tjetër -Path.

Përveç kësaj, në skedën e tretë u humb gjuha ruse, në skedën e katërt doli... siç ka dalë ndonjë gjë. #TYPE System.Object[] 00
# „Count“,»Length»,«LongLength»,«Rank»,«SyncRoot»,«IsReadOnly»,«IsFixedSize»,«IsSynchronized»
#
Pak do ndryshojmë pak:

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

Duket se ndihmoi — por forma akoma nuk mĂ« pĂ«lqen.

Sidomos nuk më pëlqen që nuk mund të vendos rreshtat nga objekti direkt në një skedë.
MeqenĂ«se po fillojmĂ« tĂ« shkruajmĂ« nĂ« skedĂ« — ndoshta mund tĂ« fillojmĂ« tĂ« mbajmĂ« njĂ« log tĂ« nisjes? Koha si ndryshore e kemi, emrin e skedĂ«s e dimĂ« si ta vendosim.

Së pari, për momentin nuk kemi çfarë të shkruajmë, por mund të mendojmë si ta bëjmë më mirë rotacionin e logëve.
Për tani, le të provojmë xml.

Pak 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

Ekspotimi nĂ« xml ka plot avantazhe — lexueshmĂ«ri, eksportimi i tĂ« gjithĂ« objektit, dhe nuk Ă«shtĂ« nevoja tĂ« bĂ«jmĂ« uppend.

Le të provojmë të lexojmë skedën xml.

Pak leximi nga xml

$MyFilenameExample06 = $ScriptDir + "Example06.xml"
$MyVocabExample4AsArray = Import-Clixml -Path $MyFilenameExample06
# $MyVocabExample4AsArray 
# $MyVocabExample4AsArray[0]
# dhe pak për disa nuanca që nuk janë krejt të qarta. Powershell herë pas here sillet ndryshe nga sa duket se do të pritej.
# për shembull, këto dy daljet e mia duken ndryshe
# Write-Output $MyVocabExample4AsArray 
# write-host $MyVocabExample4AsArray 

Le të kthehemi te detyra. Ne kemi regjistruar një skedë provuese, e lexuam, formati i ruajtjes është i kuptueshëm, dhe nëse është e nevojshme, mund të shkruajmë një redaktues të vogël të skedës për të shtuar dhe fshirë rreshta.

Më kujtohet se detyra ishte të krijonim një robot të vogël mësimor.

Formati i punës: unë i dërgoj robotit komandën "shembull", roboti më dërgon një fjalë të rastësishme dhe transkriptimin, dhe pas 10 sekondash dërgon përkthimin dhe komentarin. Ne dimë të lexojmë komandat, do të ishte gjithashtu mirë të mësojmë automatikisht të gjejmë dhe kontrollojmë proxy, dhe të zgjidhim numëruesit e mesazheve në harresë.

Le të çaktivizojmë gjithçka që kemi aktivizuar më parë si të panevojshme, të aktivizojmë shembujt e bëra të panevojshme me txt dhe csv, dhe ta ruajmë skedën si version B106.

Ah, po. Le të dërgojmë diçka robotit përsëri.

6. Dërgimi nga funksionet dhe jo vetëm

Para se processe pranimi, duhet të krijoni një funksion që dërgon "ndonjë gjë", përveç mesazhit test.

Sigurisht, në shembullin tonë do të ketë vetëm një dërgim dhe vetëm një përpunim, por çfarë nëse na nevojitet të bëjmë të njëjtën gjë disa herë?

Më e lehtë është të shkruash një funksion. Pra, ne kemi një variabël të tipit objekt $MyVocabExample4AsArray, e lexuar nga skedari, si një varg me dy elemente.
Le të fillojmë të lexojmë.

NĂ« tĂ« njĂ«jtĂ«n kohĂ«, do tĂ« merremi me orĂ«t, do na nevojiten mĂ« vonĂ« (nĂ« tĂ« vĂ«rtetĂ« nĂ« kĂ«tĂ« shembull — nuk do tĂ« na duhen 🙂

Pak kodi #6.1

Write-Output "Ky është Pjesa 6"
$Timezone = (Get-TimeZone)
IF($Timezone.SupportsDaylightSavingTime -eq $True){
    $TimeAdjust =  ($Timezone.BaseUtcOffset.TotalSeconds + 3600) } # koha e korrigjuar
    ELSE{$TimeAdjust = ($Timezone.BaseUtcOffset.TotalSeconds) 
    }
    
function MyFirstFunction($SomeExampleForFunction1){
$TimeNow = Get-Date
$TimeNow.ToUniversalTime()
# $MyText02 = $TimeNow + " " + $SomeExampleForFunction1 # dhe këtu ne do të marrim një gabim
$MyText02 = $SomeExampleForFunction1 + " " + $TimeNow # dhe këtu nuk do të marrim, kush e kupton pse - është një fitues.

$URL4SendFromFunction = "https://api.telegram.org/bot$MyToken/sendMessage?chat_id=$MyChatID&text=$MyText02"
Invoke-WebRequest -Uri $URL4SendFromFunction -Proxy $MyProxy
}

Siç shihet lehtësisht, në funksionin thirret $MyToken dhe $MyChatID, që ishin caktuar më parë.

Kjo nuk është mënyra si duhet vepruar, dhe, nëse $MyToken është i njëjtë për çdo bot, atëherë $MyChatID do të ndryshojë në varësi të bisedës.

Megjithatë, pasi ky është një shembull, tani do ta injorojmë këtë.

Duke qenë se $MyVocabExample4AsArray nuk është një array, megjithëse duket shumë si një, atëherë nuk mund ta marrësh thjesht dhe të kërkosh gjatësi të tij.

Do tĂ« duhet sĂ«rish tĂ« bĂ«sh atĂ« qĂ« nuk duhet bĂ«rĂ« — tĂ« zbresĂ«sh jashtĂ« kodeve — tĂ« marrĂ«sh dhe tĂ« numĂ«rosh

Disa kod #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)
# ose në një vijë
# MyFirstFunction($MyVocabExample4AsArray[Get-Random -Minimum 0 -Maximum ($MaxRandomExample -1)].Example)
# Pritni ta zbuloni vetë, cili shembull është më i lehtë për t'u lexuar nga të tjerët.

RastĂ«sor funksion interesant. Le tĂ« themi se duam tĂ« marrim 0 ose 1 (ne kemi vetĂ«m dy elemente nĂ« array). NĂ«se caktojmĂ« kufijtĂ« 0..1 — a do tĂ« marrim "1"?
jo — nuk do ta marrim, kemi bĂ«rĂ« qĂ«llimisht shembujt Example 2: Merr njĂ« numĂ«r rastĂ«sor mes 0 dhe 99 Get-Random -Maximum 100
Prandaj, për 0..1 do të duhet të caktojmë madhësinë 0..2, ku numri maksimal i elementit është = 1.

7. Përpunimi i mesazheve të pranuara dhe gjatësi maksimale e radhës

ÇfarĂ« kishim biseduar mĂ« parĂ«? Kemi njĂ« variabĂ«l tĂ« marrĂ« $MyMessageGet
dhe një tjetër që e ka marrë atë $Content4Pars01, nga të cilat na interesojnë elementët e vargut Content4Pars01.result

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

Do të dërgojmë botit /message10, /message11, /message12, /word dhe përsëri /word dhe /përshëndetje.
Të shohim çfarë kemi marrë:

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

Do të shqyrtojmë të gjitha të marra dhe do të dërgojmë përgjigjen nëse mesazhi ishte /word
struktura case of, ajo që disa e përshkruajnë si if-elseif, në powershell thirret nëpërmjet switch. Në kodin më poshtë është përdorur çelësi -wildcard, që nuk është në të vërtetë e nevojshme dhe madje e dëmshme.

Pak kodi #7.1

Write-Output "Kjo është pjesa 7"
Foreach ($Result in $Content4Pars01.result) # Po, mund të bëhet më shpejt 
 { 
    switch -wildcard ($Result.message.text) 
            {
            "/word" {MyFirstFunction($TextForExample1)}
            }
}

Do ta ekzekutojmë skriptin disa herë. Do të marrim dy herë të njëjtin fjalë për çdo përpjekje ekzekutimi, sidomos nëse kemi gabuar në implementimin random.

Por ndal. Ne s'kemi dërguar /word përsëri, pse mesazhi po përpunojë përsëri?

Radhitja për dërgimin e mesazheve në bot ka një gjatësi maksimale (dukesh si 100 ose 200 mesazhe), dhe duhet të pastrohet manualisht.

Sigurisht që është e dokumentuar, por duhet ta lexoni!

Në këtë rast na nevojitet parametri ?chat_id, ndërsa &timeout, &limit, &parse_mode=HTML dhe &disable_web_page_preview=true për momentin nuk janë të nevojshme.

Dokumentacioni mbi api-në e telegramit ndodhet këtu
NĂ« anglishte aty shkruhet:
Identifikuesi i azhurnimit të parë që do të kthehet. Duhet të jetë më i madh me një se ai më i larti nga identifikuesit e azhurnimeve të marra më parë. Në parazgjedhje, azhurnimet fillojnë nga më të hershmit
të pa konfirmuara azhurnimi kthehet. Një azhurnim konsiderohet i konfirmuar sa herë që getUpdates thirret me një offset më të lartë se identifikuesi i tij i azhurnimit. Offset negativ mund të specifikohet për të rikuperuar azhurnimet duke filluar nga azhurnimi -offset nga fundi i radhës së azhurnimeve. Të gjitha azhurnimet e mëparshme do të harrohen.

Le të shohim në:

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

Dhe do ta rishkruajmĂ« — paksa do ta riprodhojmĂ« funksionin. Ne kemi dy mundĂ«si — tĂ« kalojmĂ« nĂ« funksion tĂ« gjitha mesazhet dhe t'i pĂ«rpunojmĂ« ato nĂ« tĂ«rĂ«si, ose tĂ« japim vetĂ«m ID-nĂ« e mesazhit dhe ta rarisim atĂ«. PĂ«r shembull, e dyta duket mĂ« e thjeshtĂ«.

Më parë, rreshti i pyetjes për "të gjitha mesazhet" dukej si

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

ndërsa 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 

Asnjëra nuk ndalon të merrni fillimisht të gjitha mesazhet, t'i përpunoni ato dhe vetëm pas përpunimit të suksesshëm të kërkoni unconfirmed -> confirmed.

Pse ka kuptim të thërrasësh konfirmimin pas përfundimit të të gjitha përpunimeve? Mund të ndodhin dështime gjatë ekzekutimit, dhe, nëse, për shembull, për një chatbot falas, humbja e ndonjë mesazhi të veçantë nuk është diçka e veçantë, atëherë, nëse po procesoni pagën e dikujt ose një transaksion me kartë, rezultati mund të jetë më i keq.

Disa rreshta kod të tjerë

$LastMessageId = ($Content4Pars01.result | select -last 1).update_id  #pritet që të korrigjohet gabimi në këtë vend. 
$URLGET1 = "https://api.telegram.org/bot$mytoken/getUpdates?offset=$LastMessageId&limit=100" 
Invoke-WebRequest -Uri $URLGET1 -Method Get -Proxy $MyProxy

8. Në vend të përfundimit

Funksionet kryesore — leximi i mesazheve, rivendosja e radhĂ«s, leximi nga skedari dhe shkarkimi nĂ« skedar janĂ« realizuar dhe shfaqur.

Kanë mbetur vetëm katër gjëra:

  • dĂ«rgimi i pĂ«rgjigjes sĂ« duhur nĂ« kĂ«rkesĂ« nĂ« bisedĂ«
  • dĂ«rgimi i pĂ«rgjigjes nĂ« ÇDO bisedĂ« nĂ« tĂ« cilĂ«n Ă«shtĂ« shtuar bot
  • ekzekutimi i kodit nĂ« cikĂ«l
  • nisja e botit nga planifikuesi i Windows.

Të gjitha këto detyra janë të thjeshta dhe lehtësisht të realizueshme duke lexuar dokumentacionin mbi parametra të tillë si
Set-ExecutionPolicy Unrestricted dhe -ExecutionPolicy Bypass
cikli i tipit

$TimeToSleep = 3 # kontroll çdo 3 sekonda
$TimeToWork = 10 # minuta
$HowManyTimes = $TimeToWork*60/$TimeToSleep # numëruesi për ciklin
$MainCounter = 0
for ($MainCounter=0; $MainCounter -le $HowManyTimes) {
sleep $TimeToSleep
$MainCounter ++

Faleminderit të gjithëve që e lexuat deri në fund.

Burimi: habr.com

Bli njĂ« hosting tĂ« besueshĂ«m pĂ«r faqet me mbrojtje DDoS, VPS VDS serverĂ« đŸ”„ Bli njĂ« hosting tĂ« besueshĂ«m pĂ«r faqet me mbrojtje DDoS, VPS VDS serverĂ« | ProHoster