A leg egyszerűbb Telegram bot sablon középiskolás diákok számára a Powershell segítségével.

Egy barátommal folytatott beszélgetés során hirtelen megtudtam, hogy az ő iskolájukban a 8-10. osztályos gyerekeket egyáltalán nem tanítják programozásra. Csak Word, Excel és ennyi. Se logo, se Pascal, sőt még VBA az Excelhez sem.

Nagyon meglepődtem, internetet nyitottam és elkezdtem olvasni —
A profiliskola egyik feladata, hogy támogassa egy új generáció nevelését, amely a fejlődésének és életstílusának megfelelő szintet képvisel az információs társadalomban.
Ez a kurzus lehetővé teszi a diákok számára a programozási nyelv, a Pascal főbb konstrukcióinak ismereteinek gyakorlati megszilárdítását. (egy 2017-es gimnáziumi programból)

Végül úgy döntöttem, hogy eltöltök pár órát, és összedobok egy példát arról, hogy 'hogyan készítsünk egy egyszerű botot — iskolásoknak'.

A cikkben arról van szó, hogyan írjunk egy újabb egyszerű botot Powershellben, és hogyan működtessük azt webhook, nyilvános IP, dedikált szerverek, telepített virtuális gépek és hasonlók nélkül — egy átlagos otthoni PC-n, normál Windows alatt.

TLDR: Még egy unalmas cikk nyelvtani és tényleges hibákkal, nincs mit olvasni, humor nincs, képek nincsenek.

A cikkben semmi új nincs, szinte minden, ami benne van, már korábban megjelent a Habr-on, például cikkekben mint Útmutató: Hogyan készítsünk botokat a Telegramon és Telegram-bot rendszergazdák számára.
Továbbá, a cikk szándékosan túlterhelt, hogy ne kelljen minden alkalommal hivatkozni a tananyagra. Nincsenek hivatkozások a 4-es bandára, a PowerShell Deep Dives-re vagy a The 5 Pillars of the AWS Well-Architected Framework-re a szövegben.

Előszó helyett átugorhatjuk

Bátran átugorjuk2006-ban a Microsoft kiadta a PowerShell 1.0-t, amely akkor még Windows XP, Vista és 2003 Server verziókra készült. Bizonyos szempontból olyan dolgokat helyettesített, mint a cmdbat-scriptek, vb-scriptek, Windows Script Host és JScript.

Még most is a PowerShell-t csak a Logo alternatívájaként lehet nézni, a valahol talán még használt Delphi (vagy valami még régebbi) helyett, annak ellenére, hogy tartalmaz ciklusokat, osztályokat, funkciókat, MS GUI hívást, Git integráció és így tovább.

A PowerShell szokatlanul ritkán használt, leginkább a PowerShell Core, VMware vSphere PowerCLI, Azure PowerShell, MS Exchange, Desired State Configuration formájában lehet vele találkozni, PowerShell Web Access és még egy tucat ritkán használt programmal és funkcióval. Lehetséges, hogy második lélegzetet kap, amikor megjelenik WSL2, de ez nem biztos.

A PowerShell-nek három nagy előnye van:

  1. Viszonylag egyszerű, rengeteg irodalom és példa létezik róla, még oroszul is, például a Foreach-ről szóló cikk — egy könyvből PowerShell mélységei — a () és {} közötti különbségről
  2. Ez együtt jár a szerkesztővel ISE, a Windows részeként. Még egy kis hibakereső is található benne.
  3. Könnyen hívhatók belőle a grafikus felhasználói felület felépítéséhez szükséges komponensek.

0. Előkészítés.

A következőkre lesz szükség:

  • PC Windows rendszerrel (nekem Windows 10 van)
  • Bármilyen internetelérés (például NAT-on keresztül)
  • Azok számára, akiknek korlátozott a hozzáférésük a Telegramhoz — egy működő és beállított freegate böngészőben, néhány bonyolult esetben a Symple DNS Crypt-tel együtt
  • Egy működő Telegram kliens a telefonon
  • Alapvető ismeretek — mi az a változó, tömb, ciklus.

Megnyitott és elolvasott cikkek — Útmutató: Hogyan készítsünk botokat a Telegramon és Telegram-bot rendszergazdák számára

1. Hozzuk létre a következő tesztbotot.

Mivel ezt mindenki tudja és már megvalósították, ezt is átugorhatjukAhogyan a fenti cikkben is szerepel — Először is, a Telegram bot — még mindig egy az Ön oldalán futó alkalmazás, amely kéréseket intéz a Telegram Bot API-hoz. Az API pedig világos — a bot egy adott URL-re hívja meg a paraméterekkel, és a Telegram JSON objektummal válaszol.

Ahhoz kapcsolódó problémák: ha valamilyen ismeretlen módon kódot vesz egy JSON objektumból, és azt valahogy végrehajtja (nem szándékosan) — a kód elindul.

A létrehozási folyamatot a két korábbi cikkben leírtam, de megismétlem: a Telegramban nyissuk meg a kontakthálózatot, keressük meg a @botfather-t, mondjuk neki \/newbot, hozzuk létre a Botfortest12344321 botot, nevezzük el Mynext1234bot-nak, és kapunk egy üzenetet egy egyedi kulccsal, mint például 1234544311:AbcDefNNNNNNNNNNNNN

A kulcsot őrizze meg és ne ossza meg!

Ezután beállíthatjuk a botot, például megtilthatjuk, hogy csoportokba lehessen hozzáadni, de az első lépések során erre nincs szükség.

Megkérdezzük BotFathertől „\/mybot” és módosítjuk a beállításokat, ha valami nem megfelel.

Ismét megnyitjuk a kontakthálózatot, ott találjuk a @Botfortest12344321-t (a keresést @-tól kezdjük), rákattintunk az „elkezdés” gombra, és írunk a botnak „\/Dicsőség a robotoknak”. A \/ jel kötelező, a idézőjelek nem szükségesek.
A bot természetesen nem fog válaszolni.

Ellenőrizzük, hogy a bot létrejött-e — nyissuk meg.

api.telegram.org\/bot1234544311:AbcDefNNNNNNNNNNNNN\/getMe
ahol 1234544311:AbcDefNNNNNNNNNNNNN — a korábban kapott kulcs,
és megkapunk egy vonalat, mint
{„ok”:true,„result”:{„”}}

Az első titkos szónk (token) megvan. Most tudnunk kell a második titkos számot — a bot chat azonosítóját. Minden chat, csoport és így tovább egyedi, saját számuk van (néha mínusz jellel — nyitott csoportok esetén). Ahhoz, hogy megtudjuk ezt a számot, kérjük a böngészőben (valójában nem szükséges a böngésző, de a jobb megértés érdekében érdemes ezt kezdeni) az alábbi címet (ahol 1234544311:NNNNNNNNN — ez az Ön tokenje

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

és a választ az alábbi módon kapjuk

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

Kifejezetten a chat_id-ra van szükségünk.

Ellenőrizzük, hogy tudunk-e manuálisan írni a chatbe: hívjuk meg a böngészőből a címet

https://api.telegram.org/botazontoken/sendMessage?chat_id=123456789&text="Az élet irányított mozgás"

Ha üzenetet kaptál a botról a chatbe — rendben, lépj a következő lépésre.

Így (a böngészőn keresztül) mindig ellenőrizheted, hol van a probléma — nálad a link generálásakor, vagy valami más nem működik.

Amit tudni érdemes, mielőtt folytatnád az olvasást

A Telegramon többféle csoportos chat létezik (nyitott, zárt). Ezeknél a chatoknál egyes funkciók (például az id) eltérnek, ami néha problémákat okoz.

Tegyük fel, hogy 2019 végén járunk, és még a korunk hőse, a közismert Emberi Portfólió (adminisztrátor, jogász, információbiztonsági szakember, programozó és gyakorlatilag MVP) Jevgenyij V. megkülönbözteti az $i változót a tömbtől, elsajátította a ciklusokat, és talán a következő pár évben megtanulja a Chocolatey-t, aztán a Paralel feldolgozást PowerShell-lel és ForEach-Object párhuzamosan eljut.

1. Gondolkozunk, mit is fog csinálni a botunk

Nem volt igazán ötletem, gondolkodnom kellett. Már írtam egy jegyzetelő botot. Nem volt kedvem olyan botot csinálni, "ami valamit átirányít valahová". Az Azure-hoz hitelkártya szükséges, de honnan szerezzen egy iskolás gyerek? Meg kell jegyezni, hogy a helyzet nem olyan rossz: a fő felhők ingyenes tesztidőszakot kínálnak (de a hitelkártyaszám még mindig szükséges — és úgy tűnik, hogy egy dollár levonásra kerül. Nem emlékszem, hogy visszajött-e később.)

AI nélkül a ML nem annyira érdekes a bot létrehozása szempontjából.

Egy botot szeretnék létrehozni, ami emlékeztet angol szavakra a szótár alapján.
A szótár, hogy ne kelljen bajlódni az adatbázissal, egy szöveges fájlban lesz, és kézzel fogom bővíteni.
Ebben az esetben a feladat az alapok bemutatása, nem pedig egy részben kész termék létrehozása.

2. Próbáljuk ki, mi és hogyan működik először

Hozzuk létre a C:poshtranslate mappát
Először nézzük meg, mi van a powershell-en, indítsuk el az ISE-t a Start — Futtatás menüből
powershell ise
vagy keressük meg a Powershell ISE-t az telepített programok között.
A megnyitás után egy megszokott "valamilyen szerkesztő" fog megnyílni, ha nem lesz szövegdoboz, akkor mindig megnyomhatjuk a "File - új létrehozása" gombot.

Nézzük meg a powershell verzióját — írjuk be a szövegdobozba:

get-host 

és nyomjunk F5-öt.

A Powershell felajánlja, hogy mentse — "A script, amelyet futtatni fog, mentésre kerül.", egyetérthetünk, és mentjük a C:poshtranslate mappába a powershell fájlt a következő névvel myfirstbotBT100.

A futtatás után az alsó szövegdobozban egy adatokat tartalmazó táblázat jelenik meg:

Name             : Windows PowerShell ISE Host
Version          : 5.1.(és így tovább)

Nálam 5.1 valamilyen verzió van, ez elegendő. Ha régi Windows 7/8 rendszered van, az nem nagy probléma — bár a PowerShellet frissíteni kell 5-re — például emiatt utasítást.

Írjunk be a parancssorba alul Get-Date, nyomjunk Enter-t, nézzük meg az időt, és menjünk a gyökérmappába a parancs segítségével
cd
és töröljük a képernyőt a cls parancs segítségével (nem, nem kell használni a rm-et)

Most ellenőrizzük, hogy működik-e — nem is kódot írunk, hanem két sort, és próbáljuk megérteni, mit csinálnak. Kommentáljuk ki a get-host sorát a # jellel és írjunk hozzá egy kicsit.

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

(Ami érdekes. A kódformázó legördülő menüjében a Habr-on körülbelül húsz lehetőség van — de a powershell ott nincs. Dos van. Perl van.)

Futtassuk a kódot, megnyomva az F5-öt vagy a ">"-t a GUI-ból.

A következő kimenetet kapjuk:

2019. december 8., szombat 21:00:50 (vagy valami ilyesmi)

Most nézzük át ezt a két sort, és néhány érdekes szempontot, hogy később ne kelljen újra a témával foglalkozni.

Szal, ellentétben a Pascallal (és nem csak), a Powershell maga próbálja meghatározni, hogy milyen típust rendeljen a változóhoz, erről részletesebben a cikkben A típusokkal kapcsolatos alapok a programozási nyelvekben
Ezért, amikor létrehozzuk a $TimeNow változót, és hozzárendeljük a jelenlegi dátumot és időt (Get-Date), nem kell különösebben aggódnunk, hogy milyen adat típust kap.

Igaz, hogy ennek a tudatlanságnak később lehetnek következményei, de ez később kidomborodik. Az alábbi szövegben lesz egy példa.
Nézzük meg, mi jött össze. Hajtsuk végre (a parancssorban)

$TimeNow | Get-member

és kapjunk egy képernyőt a zavaros szöveggel

Példa a zavaros szövegre 1

PS C:&gt; $TimeNow | Get-member
   TypeName: System.DateTime
Name                 MemberType     Definition                                                                                                                                       
----                 ----------     ----------                                                                                                                                       
Add                  <b>Method         </b>datetime Add(timespan value)  
..
DisplayHint          NoteProperty   DisplayHintType DisplayHint=DateTime                                                                                                             
Date                 <b>Tulajdonság       </b>datetime Date {get;}                                                                                                                             
Year                 Tulajdonság       int Year {get;}   
..                                                                                                                               
DateTime             ScriptProperty System.Object DateTime {get=if ((&amp; { Set-StrictMode -Version 1; $this.DisplayHint }) -ieq  "Date")...                                         

Ahogy látszik, egy TypeName: System.DateTime típusú változót hoztunk létre, rengeteg módszerrel (értsd, mit tehetünk ezzel az objektummal) és tulajdonsággal.

Hívjuk meg $TimeNow.DayOfYear — megkapjuk az év napját.
Hívjuk meg $TimeNow.DayOfYear | Get-Member — megkapjuk TypeName: System.Int32 és a metódusok csoportját.
Hívjuk meg $TimeNow.ToUniversalTime() — és megkapjuk az időt UTC szerint

Debugger

Időnként előfordul, hogy egy programot egy adott sorig kell végrehajtani, és meg kell vizsgálni a program állapotát ebben a pillanatban. Erre az ISE-ben van egy Debug funkció — toggle break point
Helyezzen egy töréspontot valahol a közepére, indítsa el ezt a két sort végrehajtásra, és nézze meg, hogyan néz ki a megállás.

3. Megvizsgáljuk az interakciót a Telegram bottal

Természetesen a bottal való interakcióról, az összes getpush és hasonlóról még több irodalom született, azonban a elmélet kérdését fakultatívan is meg lehet vizsgálni.

A mi esetünkben szükséges:

  • Megtanulni valamit küldeni a beszélgetésbe
  • Megtanulni valamit kapni a beszélgetésből

3.1. Megtanulunk valamit küldeni a beszélgetésbe és visszaérkezni arról

Egy kicsi kód — 3. rész

Write-output "Ez a 3. rész"
$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 = "Az élet irányított mozgás - " + $TimeNow

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

Invoke-WebRequest -Uri $URL4SEND

és Oroszországban ezen a helyen hibaüzenetet kapunk: Unable to connect to the remote server.

Vagy nem kapunk — ez a szolgáltatótól függ, és hogy a proxy be van-e állítva és működik-e.
Nos — hozzá kell adnunk a proxy-t. Vegye figyelembe — a titkosítatlan és egyáltalán nem megbízható proxy használata rendkívül veszélyes az egészségére.

A működő proxy keresésének feladata nem túl bonyolult — a közzétett http proxyk nagy része működik. Nekem a tizedik nézett proxy tűnt az ötödiknek elérhetőnek.

A proxy használatával kapcsolatos szintaxis:

Invoke-WebRequest -Uri $URL4SEND -Proxy $MyProxy

Ha üzenetet kaptál a chatbotodtól, akkor minden rendben van, lehet haladni tovább. Ha nem — folytassa a hibakeresést.

Megnézheti, hogy mi történik a $URL4SEND soroddal, és próbálja meg azt a böngészőjében lekérni, például így:

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

3.2. Megtanultuk írni "valamit" a csevegésbe, most próbáljuk meg olvasni

Adjunk hozzá még 4 sort, és nézzük meg, mi van benne a | get-member segítségével

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

A legérdekesebb tartalmat

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

Nézzük meg, mi van bennük:

Write-Host "ParsedHtml"
$MyMessageGet.ParsedHtml # itt valami érdekes
Write-Host "RawContent"
$MyMessageGet.RawContent # és itt is érdekes, de ráadásul olvasható is.
Write-Host "Content"
$MyMessageGet.Content

Ha minden működik, egy hosszú sorhoz jut, például:

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

Szerencsére a korábban megjelent cikkben a Telegram-botról rendszeradminisztrátoroknak már feldolgoztuk ezt a sort (igen, a $MyMessageGet.RawContent | get-member alapján ez System.String), már korábban is tárgyalva volt.

4. Feldolgozni a kapott adatokat (már tudunk küldeni valamit)

Ahogyan már írtuk itt, a legfontosabb a content-ben található. Nézzük meg jobban.

Először írjunk a botnak még pár mondatot a webes felületről vagy telefonról

/message1
/message2
/message3

és nézzük meg a böngészőn keresztül az URL-t, ami a $URLGET változóban keletkezett.

Valami ilyesmit fogunk látni:

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

Mi ez? Valamilyen bonyolult objektum az objektumok tömbjéből, ami tartalmazza az üzenet átfogó azonosítóját, a chat azonosítóját, a küldemény azonosítóját, és még sok más információt.

Azt azonban nem kell megértenünk, hogy "milyen objektum ez" — a munka egy része már el van végezve. Nézzük, mi van belül:

Olvassuk el a kapott üzeneteket vagy 4. rész

Write-Host "Ez a 4. rész" <# természetesen ez a sor nem szükséges az eredményes szövegben, de kényelmes keresni vele. #> 

$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. Most mit kezdjünk ezzel

Mentjük el a kapott fájlt myfirstbotBT105 néven, vagy ahogyan tetszik, megváltoztatjuk a címet, és kikommenteljük az összes eddig írt kódot

<#start comment 105 end comment 105#>

Most meg kell határoznunk, honnan szerezzük a szótárat (hát hol — a lemezen egy fájlban) és hogyan fog kinézni.

Természetesen lehet hatalmas szótárat is beleírni a szkript szövegébe, de ez nem helyénvaló.
Ezért nézzük meg, mivel tud dolgozni a powershell.
Tulajdonképpen nem számít, milyen fájllal dolgozik, nekünk viszont nem mindegy.
Van választási lehetőségünk: txt (lehet, de minek), csv, xml.
Vagy megnézhetjük az összes variációt. Nézzük az összeset.
Hozzunk létre egy MyVocabClassExample1 osztályt és egy $MyVocabExample1 változót
jegyezzük meg, hogy az osztály neve nem tartalmaz $-t

kicsit kód #5

write-host "Ez az 5. rész"
class MyVocabClassExample1 {
    [string]$Original  # szó
    [string]$Transcript
    [string]$Translate
    [string]$Example
    [int]$VocWordID # nagyon érdekes pillanat. Az int használata a korlátaival néha félelmetes következményekkel járhat, például a közelmúltban egy eset a HPE SSD-vel. Eleinte nem akartam hozzáadni ezt az elemet, aztán mégis hozzáírtam és megjegyeztem.
    }

$MyVocabExample1 = [MyVocabClassExample1]::new()
$MyVocabExample1.Original = "Apple"
$MyVocabExample1.Transcript = "[ ˈapəl ]"
$MyVocabExample1.Translate = "Alma"
$MyVocabExample1.Example = "Egy alma édes, ehető gyümölcs, amelyet egy almafa (Malus domestica) termel"
# $MyVocabExample1.$VocWordID = 1

$MyVocabExample2 = [MyVocabClassExample1]::new()
$MyVocabExample2.Original = "Pear"
$MyVocabExample2.Transcript = "[ pe(ə)r ]"
$MyVocabExample2.Translate = "Körte"
$MyVocabExample2.Example = "A körte ( /ˈpɛər/) fa és cserje a Pyrus nemzetséghez tartozik"
# $MyVocabExample1.$VocWordID = 2

Próbáljuk meg ezt fájlokba írni a mintára.

Kód #5.1

Write-Host $ScriptDir # remélem, hogy a $ScriptDir-t nem jegyezted meg
$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

— és hibaüzenetet kapunk az Out-File -FilePath $MyFilenameExample01 -InputObject -Append $MyVocabExample2 soron.

Nem hajlandó hozzáadni, jaj, milyen kár.

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

Nézzük, mi történt. Kiváló szöveges megjelenés — de hogyan exportálhatnánk vissza belőle? Be kellene vezetni valamilyen szövegelválasztót, például vesszőket?

És végül megkapni a "fájl elválasztókkal — vesszők, vesszővel elválasztott értékek (CSV)" STOP, VÁRJUNK!.
#

$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önnyen észrevehető, hogy a MS nem igazán különbözött logikában, egy hasonló eljárásnál az egyik esetben -FilePath-ot használnak, a másikban pedig -Path-ot.

Ezen kívül a harmadik fájlban eltűnt az orosz nyelv, a negyedik fájlban pedig… nos, valami lett belőle. #TYPE System.Object[] 00
# „Count“,»Length»,«LongLength»,«Rank»,«SyncRoot»,«IsReadOnly»,«IsFixedSize»,«IsSynchronized»
#
Egy kicsit átkonvertáljuk:

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

Úgy tűnik, hogy segített — de a formátum így sem tetszik.

Főleg azt nem tetszik, hogy nem tudom közvetlenül az objektum sorait a fájlba helyezni.
Egyébként, ha már fájlokról beszélünk — talán érdemes lenne naplózni a futást? Az időváltozóval rendelkezünk, a fájl nevét be tudjuk állítani.

Igaz, jelenleg nincs miről írni, de el lehet gondolkodni, hogyan lehetne jobban megoldani a naplók forgatását.
Egyelőre próbáljuk ki az xml-t.

Egy kis 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

Az xml-be történő exportálásnak számos előnye van — olvashatóság, az egész objektum exportálása, és nem kell elvégezni az uppendet.

Próbáljuk ki az xml fájl olvasását.

Egy kis olvasás az xml-ből

$MyFilenameExample06 = $ScriptDir + "Example06.xml"
$MyVocabExample4AsArray = Import-Clixml -Path $MyFilenameExample06
# $MyVocabExample4AsArray 
# $MyVocabExample4AsArray[0]
# és egy kicsit a teljesen észrevétlen finomságokról. A Powershell néha nem úgy viselkedik, ahogyan elvárnánk.
# például ezek a két kimenet eltérő 

Térjünk vissza a feladathoz. A tesztfájlt elmentettük, elolvastuk, a tárolási formátum világos, szükség esetén írhatunk egy külön kis fájlszerkesztőt a sorok hozzáadására vagy törlésére.

Emlékeztetnék arra, hogy a feladat az volt, hogy készítsünk egy kis tanuló botot.

Munkaformátum: elküldöm a botnak a „példa” parancsot, a bot küld nekem egy véletlenszerűen választott szót és a tranzkripciót, és tíz másodperc múlva elküldi a fordítást és a megjegyzést. A parancsokat tudjuk olvasni, persze még tanulnunk kellene automatikusan kiajánlani és ellenőrizni a proxykat, valamint eltüntetni az üzenetszámlálót.

Visszakommentáljuk az összes korábban kommenteltet, mint szükségtelen, kommenteljük ki a szükségtelen példákat txt és csv fájlokkal, és mentjük a fájlt mint B106 verziót.

Ja, igen. Küldjünk valamit a botnak még egyszer.

6. Küldés funkciókból és nemcsak

Mielőtt feldolgoznánk a fogadást, létre kell hozni egy „bármilyen” küldési funkciót a teszt üzeneten kívül.

Természetesen a példában csak egy küldés lesz és csak egy feldolgozásból, de mi van, ha többször is meg akarjuk csinálni ugyanazt?

Egyszerűbb egy funkciót írni. Tehát van egy objektum típusú változónk $MyVocabExample4AsArray, amelyet a fájlból olvastunk be, két elemű tömb formájában.
Kezdjük el olvasni.

Közben nézzük meg az időt, erre később szükségünk lesz (valójában ebben a példában — nem lesz szükség 🙂

Egy kis kód #6.1

Write-Output "Ez a 6. Rész"
$Timezone = (Get-TimeZone)
IF($Timezone.SupportsDaylightSavingTime -eq $True){
    $TimeAdjust =  ($Timezone.BaseUtcOffset.TotalSeconds + 3600) } # helyi idő
    ELSE{$TimeAdjust = ($Timezone.BaseUtcOffset.TotalSeconds) 
    }
    
function MyFirstFunction($SomeExampleForFunction1){
$TimeNow = Get-Date
$TimeNow.ToUniversalTime()
# $MyText02 = $TimeNow + " " + $SomeExampleForFunction1 # és itt hibát kapunk
$MyText02 = $SomeExampleForFunction1 + " " + $TimeNow # itt nem kapunk, aki kitalálja miért - az ügyes.

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

Ahogy könnyen látható, a függvényben meghívásra kerül $MyToken és $MyChatID, amelyeket korábban fixen hozzárendeltek.

Ezt nem szabad megtenni, és ha $MyToken minden bot számára azonos, akkor $MyChatID a chat függvényében változik.

Azonban, mivel ez egy példa, ezt most figyelmen kívül hagyjuk.

Mivel $MyVocabExample4AsArray nem tömb, bár nagyon hasonlít rá, nem lehet egyszerűen megkérdőjelezni a hosszát. Megint meg kell tennünk azt, amit nem szabad - lebegtetni a kódex szerint - meg kell számolni

Egy kis kód #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) # vagy egy sorban # MyFirstFunction($MyVocabExample4AsArray[Get-Random -Minimum 0 -Maximum ($MaxRandomExample -1)].Example) # Találjátok ki, melyik példa olvasható könnyebben mások számára.

Random

érdekes függvény . Tegyük fel, hogy 0-t vagy 1-et szeretnénk kapni (két elem van a tömbben). Ha a határokat 0..1-re állítjuk — kapunk „1”-et?nem — nem fogunk, itt szándékosan mutatjuk be a példát Példa 2: Képzelj el egy véletlenszerű egész számot 0 és 99 között Get-Random -Maximum 100
Ezért a 0..1 esetén a méretet 0..2-re kell beállítanunk, így a legmagasabb elem = 1.
7. Az érkező üzenetek kezelése és a maximális hosszúságú sor

Miken álltunk meg korábban? Van egy megkapott változónk $MyMessageGet

és az ebből nyert $Content4Pars01, aminek számunkra az array elemei a Content4Pars01.result
$Content4Pars01.result[0].update_id $Content4Pars01.result[0].message $Content4Pars01.result[0].message.text

Küldjük a botnak /message10, /message11, /message12, /word és ismét /word és /helló.

Nézzük meg, mit kaptunk:
$Content4Pars01.result[0].message.text $Content4Pars01.result[2].message.text

Feljárunk mindent, amit kaptunk, és válaszolunk, ha az üzenet /word volt

a case of szerkezet, amit egyesek if-elseif-ként írnak le, Powershellben a switch segítségével hívható meg.
természeténél fogva. a switch-en keresztül.. A kód alább a -wildcard kulcsot használja, ami egyáltalán nem szükséges, sőt, káros is lehet.

Kód részlet #7.1

Write-Output "Ez itt a 7. rész"
Foreach ($Result in $Content4Pars01.result) # Igen, gyorsabban is meg lehet csinálni 
 { 
    switch -wildcard ($Result.message.text) 
            {
            "\/word" {MyFirstFunction($TextForExample1)}
            }
}

Futtassuk a szkriptet párszor. Minden egyes végrehajtási kísérlet során kétszer ugyanazt a szót kapjuk, különösen, ha tévedtünk a random implementálásában.

De álljunk meg. Még nem küldtük el a \/word-ot újra, miért dolgozza fel újra az üzenetet?

Az üzenetek bothoz való küldésének sora véges hosszúságú (úgy tűnik, 100 vagy 200 üzenet), és ezt kézzel kell törölni.

A dokumentáció természetesen le van írva, de azt olvasni kell!

Ebben az esetben a ?chat_id paraméterre van szükség, míg az &timeout, &limit, &parse_mode=HTML és &disable_web_page_preview=true jelenleg nem szükséges.

A dokumentáció a telegram api itt található
Fehér angolsággal van leírva:
Az első frissítés azonosítója, amelyet vissza kell adni. Egyel nagyobbnak kell lennie, mint a korábban kapott frissítések legmagasabb azonosítója. Alapértelmezés szerint a legkorábbi frissítések
megerősítetlen frissítései kerülnek visszaadásra. A frissítést megerősítettnek tekintjük, amint a getUpdates hívásra kerül egy offset magasabb mint az update_id-ja;. A negatív offset megadható, hogy frissítéseket kérjünk a frissítések sorának végéből -offset frissítéstől kezdődően. Az összes korábbi frissítést elfelejtjük.

Nézzük meg a következőt:

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

Még át is írjuk - egy kicsit módosítjuk a funkciót. Két lehetőségünk van - az összes üzenetet átadni a funkciónak és az egészet feldolgozni a funkción belül, vagy csak az üzenet ID-t átadni és azt visszaállítani. Például a második opció egyszerűbbnek tűnik.

Korábban a "minden üzenet" lekérdezésünk így nézett ki

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

most pedig így fog kinézni

$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 

Senki sem tilthatja meg, hogy először megkapjam az összes üzenetet, feldolgozzam őket, és csak a sikeres feldolgozás után kérjem az unconfirmed -> confirmed-et.

Miért érdemes a megerősítést a feldolgozások befejezése után kérni? Lehetséges, hogy hiba lép fel a végrehajtás során, és ha például egy ingyenes chatbot esetében egy-egy üzenet elhagyása még semmi különöset nem jelent, akkor ha valaki fizetését vagy kártyával való tranzakciót dolgozol fel, az eredmény rosszabb lehet.

Még pár sor kód

$LastMessageId = ($Content4Pars01.result | select -last 1).update_id  #A hibát itt javasolt javítani. 
$URLGET1 = "https://api.telegram.org/bot$mytoken/getUpdates?offset=$LastMessageId&limit=100" 
Invoke-WebRequest -Uri $URLGET1 -Method Get -Proxy $MyProxy

8. Zárás helyett

A fő feladatok — üzenetek olvasása, a sor kiürítése, fájlból olvasás és fájlba írás megtörténtek és bemutatásra kerültek.

Csak négy dolgot kell még megtenni:

  • helyes válasz küldése a chat kérésére
  • válasz küldése BÁRMELY chatbe, amelybe a botot hozzáadták
  • kód végrehajtása ciklusban
  • a bot indítása a Windows ütemezőből.

Mind ezek a feladatok egyszerűek és könnyen megvalósíthatók a dokumentáció ilyen paramétereinek tanulmányozásával, mint például
Set-ExecutionPolicy Unrestricted és -ExecutionPolicy Bypass
a következő ciklus formája

$TimeToSleep = 3 # kérdezés 3 másodpercenként
$TimeToWork = 10 # perc
$HowManyTimes = $TimeToWork*60/$TimeToSleep # számláló a ciklushoz
$MainCounter = 0
for ($MainCounter=0; $MainCounter -le $HowManyTimes) {
sleep $TimeToSleep
$MainCounter ++

Köszönet mindenkinek, aki elolvasta.

Forrás: habr.com

Megbízható hosting vásárlása weboldalak számára, DDoS védelemmel, VPS VDS szerverek. 🔥 Megbízható webtárhely vásárlása DDoS védelemmel, VPS VDS szerverek | ProHoster