Sablon egy egyszerű távirat-bothoz 7-9. osztályos iskolásoknak Powershell használatával

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 programozni. Word, Excel és minden. Nincs logó, még Pascal, még VBA sem Excelhez.

Nagyon meglepődtem, kinyitottam az internetet és elkezdtem olvasni -
A szakosított iskola feladatai közé tartozik, hogy elősegítse az információs társadalom feltételeinek fejlettségi és életmódjában megfelelő új nemzedék nevelését.
Ez a kurzus lehetővé teszi a hallgatóknak, hogy a gyakorlatban megszilárdítsák tudásukat a Pascal programozási nyelv alapvető konstrukcióiról. (valamelyik gimnázium 2017-es programjából)

Végül úgy döntöttem, hogy eltöltök néhány órát, és felvázolok egy példát, „hogyan készítsünk egyszerű botot iskolások számára”.

A vágás alatt bemutatjuk, hogyan írhat egy másik egyszerű botot a Powershellben, és hogyan működhet webhook, fehér IP-címek, dedikált szerverek, felhőben telepített virtuális gépek és így tovább – egy normál otthoni számítógépen, normál Windows rendszerrel.

TLDR: Újabb unalmas cikk nyelvtani és ténybeli hibákkal, semmi olvasnivaló, nincs humor, nincsenek képek.

A cikkben nincs újdonság, szinte minden, amit korábban írtak, már Habrén is szerepelt, például cikkekben Utasítások: Hogyan készítsünk botokat a Telegramban и Telegram bot rendszergazdának.
Ráadásul a cikk szándékosan redundáns, hogy ne hivatkozzon minden alkalommal oktatási irodalomra. A szövegben nincs utalás a Gang 4-re, a PowerShell Deep Divesre vagy mondjuk az AWS jól felépített keretrendszer 5 pillérére.

Előszó helyett átugorhatja

Nyugodtan kihagyhatja2006-ban a Microsoft kiadta a PowerShell 1.0-t az akkori Windows XP, Vista és Server 2003 rendszerekre. Bizonyos szempontból olyan dolgokat váltott fel, mint a cmdbat szkriptek, a vb szkriptek, a Windows Script Host és a JScript.

A PowerShell még most is csak a Logo opciók után következő lépésnek tekinthető, a valószínűleg még használt Delphi (vagy valami régebbi) helyett, hiába vannak ciklusok, osztályok, függvények, MS GUI hívások, Git integráció és így tovább.

A Powershell-t viszonylag ritkán használják, csak PowerShell Core, VMware vSphere PowerCLI, Azure PowerShell, MS Exchange, Desired State Configuration, PowerShell Web Access és egy tucatnyi ritkábban használt program és funkció. Talán második szelet kap a kiadással WSL2, de nem egészen az.

A Powershellnek három nagy előnye is van:

  1. Viszonylag egyszerű, sok irodalom és példa van róla, sőt oroszul is például egy cikk a Foreach-ről - a könyvből PowerShell mélységben - a különbségről () és {}
  2. A szerkesztővel megy ISE, a Windows része. Még valami hibakereső is van ott.
  3. Könnyű onnan hívni komponensek grafikus felület felépítéséhez.

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

Szükségünk lesz:

  • Windows PC (Windows 10-em van)
  • Legalább valamilyen internet-hozzáférés (például NAT-on keresztül)
  • Azok számára, akik korlátozott hozzáféréssel rendelkeznek a távirathoz - telepített és konfigurált freegate a böngészőben, néhány nehéz esetben a Symple DNS Crypttel együtt
  • Működő telegram kliens a telefonon
  • Az alapok megértése – mi az a változó, tömb, ciklus.

Cikkek megnyitása és elolvasása - Utasítások: Hogyan készítsünk botokat a Telegramban и Telegram bot rendszergazdának

1. Hozzon létre egy másik tesztbotot.

Mivel ezt már mindenki tudja, és már megtörtént, ki is hagyhatjaAhogy a fenti cikkben is szerepel - Először is egy bot a Telegram számára - ez még mindig az Ön oldalán futó alkalmazás, és kéréseket küld a Telegram Bot API-nak. Ezenkívül az API egyértelmű - a bot egy adott URL-hez ér el paraméterekkel, a Telegram pedig egy JSON-objektummal válaszol.

Kapcsolódó problémák: ha valamilyen ismeretlen módon kivesz egy kódot egy JSON-objektumból, és valahogy végrehajtásra küldi (nem szándékosan), akkor a kód végrehajtásra kerül.

A létrehozás folyamatát két fentebbi cikk ismerteti, de ismétlem: egy táviratban megnyitjuk a névjegyeket, megkeressük a @botfather nevet, megmondjuk neki /newbot, létrehozunk egy botot Botfortest12344321, Mynext1234bot-nak hívjuk, és üzenetet kapunk a program egyedi kulcsával. űrlap 1234544311:AbcDefNNNNNNNNNNNNNN

Vigyázz a kulcsra és ne add oda!

Ezután beállíthatja a botot, például megtilthatja a csoportokhoz való hozzáadását, de az első lépésekben ez nem szükséges.

Kérdezzük meg a BotFathertől a „/mybot”-ot, és módosítsuk a beállításokat, ha valami nem tetszik.

Nyissuk meg újra a névjegyeket, keressük meg ott a @Botfortest12344321-et (a keresést kötelező @-val indítani), kattintsunk a „start” gombra, és írjuk a botnak „/Glory to the robots”. A / jel kötelező, idézőjel nem szükséges.
A bot természetesen nem válaszol semmit.

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

api.telegram.org/bot1234544311:AbcDefNNNNNNNNNNNNNN/getMe
ahol 1234544311:AbcDefNNNNNNNNNNNNNN a korábban kapott kulcs,
és kap egy sort
{"ok":true"eredmény":{""}}

Megvan az első titkos kifejezés (token). Most meg kell találnunk a második titkos számot - a bottal folytatott csevegés azonosítóját. Minden csevegés, csoport stb. egyéni és saját számmal rendelkezik (néha mínuszjellel - nyitott csoportok esetén). Ahhoz, hogy ezt a számot megtudjuk, kérnünk kell a böngészőben (sőt, a böngészőben egyáltalán nem szükséges, de a jobb megértés kedvéért kezdhetsz vele) a címet (ahol 1234544311:NNNNNNNNNN a token

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

és kap egy hasonló választ

{"ok":true"result":[{"update_id":...,... csevegés":{"id":123456789

Szükségünk van chat_id.

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

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

Ha üzenetet kap egy bottól a csevegésben, oké, továbblép a következő szakaszba.

Így (böngészőn keresztül) mindig ellenőrizhető, hogy nincs-e probléma a linkgenerálással, vagy van-e valami elrejtve valahol és nem működik.

Amit tudnia kell, mielőtt folytatná az olvasást

A Telegram többféle csoportos csevegést kínál (nyitott, zárt). Ezeknél a csevegéseknél bizonyos funkciók (például id) eltérőek, ami néha problémákat okoz.

Tegyük fel, hogy 2019 vége van, sőt korunk hőse, a jól ismert Man-Orchestra (adminisztrátor, ügyvéd, információbiztonsági szakember, programozó és gyakorlatilag MVP) Jevgenyij V. megkülönbözteti a $i változót egy tömbtől, elsajátította a hurkok, nézd meg a következő pár évben elsajátítja Chocolatey, majd Párhuzamos feldolgozás PowerShell-lel и Minden egyes objektum párhuzamos jönni fog.

1. Átgondoljuk, mit fog tenni a robotunk

Nem voltak ötleteim, gondolkodnom kellett. Már írtam egy bot-notebookot. Nem akartam olyan botot készíteni, „ami küld valamit valahova”. Az Azure-hoz való csatlakozáshoz hitelkártyára van szüksége, de honnan szerzi be a hallgató? Meg kell jegyezni, hogy nem minden olyan rossz: a fő felhők ingyen adnak valamilyen tesztidőszakot (de még mindig kell egy hitelkártyaszám - és úgy tűnik, hogy leterhelnek egy dollárt. Arra nem emlékszem, hogy később visszaküldték.)

AI ML nélkül nem olyan érdekes bot-szegény-költő-szövőt csinálni.

Úgy döntöttem, hogy készítek egy robotot, amely emlékeztetni fog (vagy nem) a szótár angol szavaira.
Az adatbázissal való babrálás elkerülése érdekében a szótárt egy szöveges fájlban tárolja, és manuálisan frissíti.
Ebben az esetben a munka alapjainak bemutatása a feladat, nem pedig a legalább részben kész termék elkészítése.

2. Első alkalommal kipróbálni, mit és hogyan

Hozzunk létre egy C:poshtranslate mappát
Először nézzük meg, milyen powershell-ünk van, indítsuk el az ISE-t start-run keresztül
powerhell ise
vagy keresse meg a Powershell ISE-t a telepített programokban.
Indítás után megnyílik a megszokott „valamilyen szerkesztő”; ha nincs szövegmező, akkor mindig kattintson a „Fájl - új létrehozása” gombra.

Nézzük meg a powershell verzióját - írja be a szövegmezőbe:

get-host 

és nyomja meg az F5 billentyűt.

A Powershell felajánlja a mentést – „A futtatni kívánt szkript mentésre kerül.”, egyetértünk, és mentjük a fájlt a powershellből C: poshtranslate néven. myfirstbotBT100.

Indítás után az alsó szövegablakban egy adattáblázatot kapunk:

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

5.1-es valamim van, az elég. Ha régi Windows 7/8-ad van, akkor nem nagy ügy - bár a PowerShellt frissíteni kell az 5-ös verzióra - pl. utasítás.

Írja be a Get-Date parancsot az alábbi parancssorba, nyomja meg az Enter billentyűt, nézze meg az időt, lépjen a gyökérmappába a paranccsal
cd
és törölje a képernyőt a cls paranccsal (nem, nem kell rm-t használnia)

Most nézzük meg, mi működik és hogyan - ne is a kódot írjuk, hanem két sort, és próbáljuk megérteni, mit csinálnak. Tegyük megjegyzésbe a get-host sort a # szimbólummal, és adjunk hozzá egy kicsit.

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

(Az az érdekes, hogy a Habré kódformázási legördülő listájában két tucat lehetőség van – de a Powershell nincs ott. Dos ott van. A Perl ott van.)

És futtassuk le a kódot az F5 vagy a ">" gomb megnyomásával a grafikus felhasználói felületen.

A következő kimenetet kapjuk:

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

Most nézzük meg ezt a két sort és néhány érdekes pontot, hogy a jövőben ne térjünk vissza erre.

A Pascallal (és nem csak) ellentétben a PowerShell maga próbálja meghatározni, hogy milyen típust rendeljen egy változóhoz; erről a cikkben olvashat bővebben. Oktatási program programozási nyelveken való gépelésről
Ezért ha létrehozunk egy $TimeNow változót, és hozzárendeljük az aktuális dátum és idő értékét (Get-Date), nem kell túl sokat foglalkoznunk azzal, hogy milyen típusú adatok lesznek ott.

Igaz, ez a tudatlanság később fájhat, de ez későbbre vonatkozik. Alább a szövegben lesz egy példa.
Lássuk, mit kaptunk. Végrehajtjuk (a parancssorban)

$TimeNow | Get-member

és kap egy oldalnyi érthetetlen szöveget

Példa az 1. számú értelmezhetetlen szövegre

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

Mint látható, egy TypeName: System.DateTime típusú változót hoztak létre egy csomó metódussal (abban az értelemben, hogy mit tehetünk ezzel a változó objektummal) és tulajdonságokkal.

Hívjuk $TimeNow.DayOfYear — megkapjuk az év napjának számát.
Hívjuk $TimeNow.DayOfYear | Get-Member - kapunk TypeName: System.Int32 és módszerek egy csoportja.
Hívjuk $TimeNow.ToUniversalTime() - és megkapja az időt UTC-ben

Hibakereső

Néha megesik, hogy egy programot egy bizonyos sorig kell végrehajtani, és meg kell nézni a program aktuális állapotát. Erre a célra az ISE rendelkezik egy Debug funkcióval - töréspont váltása
Tegyen egy töréspontot valahol a közepére, futtassa ezt a két sort, és nézze meg, hogyan néz ki a törés.

3. A Telegram bottal való interakció megértése

Természetesen még több irodalmat írtak a bottal való interakcióról, minden getpush-ról és így tovább, de az elmélet kérdése opcionálisan szóba jöhet.

A mi esetünkben szükséges:

  • Tanulj meg levelet küldeni
  • Tanulj meg valamit a levelezésből

3.1 Megtanulni valamit levélben elküldeni és onnan fogadni

Egy kis kód – 3. rész

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

és az Orosz Föderációban ezen a ponton a Nem sikerült kapcsolódni a távoli szerverhez hibaüzenetet kapjuk.

Vagy nem kapjuk meg - a távközlési szolgáltatótól és attól függ, hogy a proxy konfigurálva van-e és működik-e
Nos, már csak egy proxy hozzáadása van hátra. Felhívjuk figyelmét, hogy a titkosítatlan és általában csalárd proxy használata rendkívül veszélyes az egészségére.

A működő proxy megtalálása nem túl nehéz - a legtöbb publikált http proxy működik. Szerintem az ötödik bevált nekem.

Szintaxis proxy használatával:

Invoke-WebRequest -Uri $URL4SEND -Proxy $MyProxy

Ha üzenetet kapsz a chatben egy bottal, akkor minden rendben van, mehetsz tovább. Ha nem, folytassa a hibakeresést.

Megnézheti, mivé alakul a $URL4SEND karakterlánc, és megpróbálhatja lekérni a böngészőben, így:

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

3.2. Megtanultuk, hogyan kell „valamit” írni a chatben, most próbáljuk meg elolvasni

Adjunk hozzá még 4 sort, és nézzük meg, mi van a | taggá válni

$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 dolog a rendelkezésünkre áll

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

Lássuk, mi van bennük:

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

Ha minden működik az Ön számára, akkor egy hosszú sort fog kapni, például:

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

Szerencsére a korábban megjelent Telegram bot a rendszergazdának című cikkben ezt a sort (igen, a $MyMessageGet.RawContent | szerint get-member a System.String), már szétszedték.

4. Feldolgozza, amit kap (már tudjuk, hogyan kell küldeni valamit)

Ahogy már írták itt, a legszükségesebb dolgok a tartalomban rejlenek. Nézzük meg közelebbről.

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

/message1
/message2
/message3

és nézze meg a böngészőben a $URLGET változóban létrehozott címet.

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 

Ami? Néhány összetett objektum objektumtömbökből, amelyek végpontok közötti üzenetazonosítót, csevegési azonosítót, küldési azonosítót és sok egyéb információt tartalmaznak.

Nem kell azonban rájönnünk, hogy „miféle tárgy ez” – a munka egy részét már elvégezték helyettünk. Lássuk, mi van belül:

Beérkezett üzenetek vagy 4. rész olvasása

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. Mit tegyünk most ez ellen?

Mentsük el az eredményül kapott fájlt myfirstbotBT105 néven, vagy ami a legjobban tetszik, változtassuk meg a címet és írjuk ki kommentbe az összes már megírt kódot.

<#start comment 105 end comment 105#>

Most el kell döntenünk, hol szerezzük be a szótárt (jó, hol - a lemezen egy fájlban), és hogyan fog kinézni.

Természetesen a forgatókönyv szövegébe bele lehet írni egy hatalmas szótárat, de ez teljesen a lényeg.
Lássuk tehát, hogy a powershell mivel tud normálisan működni.
Általában nem érdekli, hogy melyik fájllal dolgozik, nekünk mindegy.
Választhatunk: txt (lehet, de miért), csv, xml.
Mindenkit megnézhetünk?Lássunk mindenkit.
Hozzunk létre egy MyVocabClassExample1 osztályt és egy $MyVocabExample1 változót
Megjegyzem, hogy az osztály $ nélkül van írva

valami 5-ös kód

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

Próbáljuk meg ezt fájlba írni a segítségével példamutató.

Néhány kód #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

- és hibát kapunk az Out-File -FilePath $MyFilenameExample01 -InputObject -Append $MyVocabExample2 sorban.

Nem akarja hozzátenni, hogy ah-ah, micsoda szégyen.

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

Nézzük mi történik. Nagyszerű szöveges nézet – de hogyan lehet vissza exportálni? Be kellene vezetnem valamilyen szövegelválasztót, például vesszőt?

És a végén kap egy „vesszővel elválasztott értékek (CSV) fájlt A STOP VÁRJ.
#

$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 

Amint az könnyen belátható, az MS-t logikája nem különösebben különbözteti meg, egy hasonló eljáráshoz az egyik esetben a -FilePath-ot, a másikban a -Path-t használják.

Ráadásul a harmadik fájlból eltűnt az orosz nyelv, a negyedikből kiderült... na, történt valami. #TYPE System.Object[] 00
# "Count", "Length", "LongLength", "Rank", "SyncRoot", "IsReadOnly", "IsFixedSize", "IsSynchronized"
#
Írjuk át egy kicsit:

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

Úgy tűnik, segített, de még mindig nem tetszik a formátum.

Különösen nem szeretem, hogy nem tudok sorokat közvetlenül fájlba rakni egy objektumból.
Amúgy amióta elkezdtünk fájlba írni, kezdhetünk indítási naplót vezetni? Változóként időnk van, beállíthatjuk a fájl nevét.

Igaz, még nincs mit írni, de el lehet gondolkodni azon, hogyan lehet legjobban forgatni a rönköket.
Egyelőre próbáljuk meg az xml-t.

Néhány 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 exportálásnak számos előnye van – olvashatóság, a teljes objektum exportálása, és nincs szükség feltöltésre.

Próbáljuk meg xml fájl olvasása.

Egy kis olvasnivaló xml-ből

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

Térjünk vissza a feladathoz. Írtunk egy tesztfájlt, olvassa el, a tárolási formátum egyértelmű, ha kell, külön kis fájlszerkesztőt írhat a sorok hozzáadásához, törléséhez.

Hadd emlékeztesselek arra, hogy a feladat egy kis edzőbot elkészítése volt.

Munka formátuma: elküldöm a „példa” parancsot a botnak, a bot elküld egy véletlenszerűen kiválasztott szót és átírást, majd 10 másodperc múlva fordítást és megjegyzést. Ismerjük a parancsok olvasását, szeretnénk megtanulni a proxy automatikus kiválasztását és ellenőrzését, valamint az üzenetszámlálók feledésbe állítását.

Tegyük ki a kommentárt, amit korábban feleslegesnek nyilvánítottak, a most felesleges példákat txt-vel és csv-vel, és mentsük el a fájlt B106-os verzióként.

Ó, igen. Ismét küldjünk valamit a botnak.

6. Kiszállítás a funkcióktól és egyebektől

A vétel feldolgozása előtt létre kell hoznia egy funkciót, amely „legalább valamit” küld a tesztüzeneten kívül.

Természetesen a példában csak egy küldés és csak egy feldolgozás lesz, de mi van akkor, ha többször is meg kell csinálnunk ugyanazt?

Könnyebb függvényt írni. Tehát van egy $MyVocabExample4AsArray objektum típusú változónk, amelyet a fájlból olvasunk ki, akár két elemből álló tömb formájában.
Menjünk olvasni.

Ugyanakkor foglalkozunk az órával, később szükségünk lesz rá (sőt, ebben a példában nem lesz rá szükségünk :)

Néhány kód #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
}

Amint könnyen látható, a függvény meghívja a $MyToken-t és a $MyChatID-t, amelyeket korábban keményen kódoltak.

Erre nincs szükség, és ha a $MyToken minden bothoz egy, akkor a $MyChatID a chattől függően változik.

Mivel azonban ez egy példa, egyelőre figyelmen kívül hagyjuk.

Mivel a $MyVocabExample4AsArray nem tömb, bár nagyon hasonlít egyhez, akkor nem veheted csak úgy kérje a hosszát.

Megint tennünk kell valamit, amit nem lehet megcsinálni - ejtőernyőzni nem a kód szerint - fogni és számolni

Néhány 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)
# или в одну строку
# MyFirstFunction($MyVocabExample4AsArray[Get-Random -Minimum 0 -Maximum ($MaxRandomExample -1)].Example)
# Угадайте сами, какой пример легче читается посторонними людьми.

Véletlen érdekes tulajdonság. Tegyük fel, hogy 0-t vagy 1-et szeretnénk kapni (csak két elemünk van a tömbben). A 0..1 határok beállításakor „1”-et kapunk?
nem - nem fogjuk megkapni, van egy speciális példa 2. példa: Véletlenszerű egész szám 0 és 99 között Get-Random -Maximum 100
Ezért 0..1-hez 0..2-es méretet kell beállítanunk, a maximális elemszám = 1.

7. A bejövő üzenetek feldolgozása és a sor maximális hossza

Hol álltunk meg korábban? megkaptuk a $MyMessageGet változót
és az abból kapott $Content4Pars01, amelyek közül minket a Content4Pars01.result tömb elemei érdekelnek

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

Küldjük el a /message10, /message11, /message12, /word és még egyszer /word és /hello botot.
Lássuk, mit kaptunk:

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

Nézzünk végig mindent, amit kapott, és küldjünk választ, ha az üzenet a /word volt
a konstrukció esetét, amit egyesek if-elseif-ként írnak le, powershellben hívják kapcsolón keresztül. Ugyanakkor az alábbi kód a -wildcard billentyűt használja, ami teljesen felesleges, sőt káros is.

Néhány kód #7.1

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

Futtassuk le párszor a szkriptet. Minden végrehajtási kísérletnél kétszer ugyanazt a szót kapjuk, különösen akkor, ha a véletlenszerű implementációjában hibáztunk.

De állj meg. Nem küldtük el újra a /word-ot, akkor miért kerül újra feldolgozásra az üzenet?

A botnak való üzenetküldési sor véges hosszúságú (szerintem 100 vagy 200 üzenet), és manuálisan kell törölni.

Ez természetesen le van írva a dokumentációban, de el kell olvasni!

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

Dokumentáció ehhez távirat api itt van
Fehéren és angolul ezt írja:
Az első visszaküldendő frissítés azonosítója. Egygyel nagyobbnak kell lennie, mint a korábban kapott frissítések azonosítói közül a legmagasabb érték. Alapértelmezés szerint a frissítések a legkorábban kezdődnek
nem megerősített frissítés érkezik vissza. A frissítés megerősítettnek minősül, amint a getUpdates meghívásra kerül egy eltolt <p></p> mint az update_id. A negatív eltolás megadható a frissítések lekéréséhez a frissítési sor végétől -offset frissítéstől kezdve. Minden korábbi frissítés el lesz felejtve.

Nézzük:

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

Igen, és visszaállítjuk, és kicsit átírjuk a függvényt. Két lehetőségünk van - átadja a teljes üzenetet a függvénynek, és teljesen feldolgozza a függvényben, vagy csak az üzenetazonosítót adja meg és állítsa vissza. Például a második egyszerűbbnek tűnik.

Korábban az „összes üzenet” lekérdezési karakterláncunk így nézett ki

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

és ú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 tiltja, hogy először megkapja az összes üzenetet, feldolgozza azokat, és csak a sikeres feldolgozás után a kérés megerősítve -> megerősítve.

Miért van értelme megerősítést kérni az összes feldolgozás befejezése után? A végrehajtás közepén előfordulhat hiba, és ha egy ingyenes chatbot esetében egyetlen üzenet hiánya sem különösebb, akkor ha valaki fizetését vagy kártyatranzakcióját dolgozza fel, az eredmény rosszabb lehet.

Még néhány sor kód

$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. Következtetés helyett

Az alapvető funkciók - üzenetek olvasása, sor visszaállítása, fájlból olvasás és fájlba írás megtörténik és megjelenik.

Már csak négy tennivaló van hátra:

  • a helyes válasz elküldése egy kérésre a chatben
  • válasz küldése BÁRMELY csevegésre, amelyhez hozzáadták a botot
  • kód végrehajtása ciklusban
  • bot indítása a Windows ütemezőből.

Mindezek a feladatok egyszerűek, és könnyen elvégezhetők, ha elolvassa a dokumentációt olyan paraméterekről, mint pl
Set-ExecutionPolicy Unrestricted és -ExecutionPolicy Bypass
a forma ciklusa

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

Köszönöm mindenkinek, hogy elolvasta.

Forrás: will.com

Hozzászólás