Šablona jednoduchého telegramového robota pro školáky ve třídách 7-9 pomocí Powershell

Při rozhovorech s kamarádem jsem se najednou dozvěděl, že děti v 8.-10. ročníku na jejich škole programování vůbec neučí. Word, Excel a všechno. Žádné logo, dokonce ani Pascal, dokonce ani VBA pro Excel.

Byl jsem velmi překvapen, otevřel jsem internet a začal číst -
Jedním z úkolů specializované školy je podporovat výchovu nové generace, která svou úrovní rozvoje a životního stylu odpovídá podmínkám informační společnosti.
Tento kurz umožní studentům v praxi upevnit své znalosti základních konstrukcí programovacího jazyka Pascal. (z programu některého gymnázia na rok 2017)

Nakonec jsem se rozhodl strávit pár hodin a načrtnout příklad „jak vytvořit jednoduchého bota pro školáky“.

Níže je uvedeno, jak napsat dalšího jednoduchého robota v Powershell a zajistit, aby fungoval bez webhooku, bílých IP adres, dedikovaných serverů, nasazených virtuálních strojů v cloudu a tak dále – na běžném domácím PC s běžnými Windows.

TLDR: Další nudný článek s gramatickými a faktickými chybami, nic ke čtení, žádný humor, žádné obrázky.

V článku není nic nového, skoro vše co bylo dříve napsáno už na Habré bylo, třeba v článcích Návod: Jak vytvořit roboty v Telegramu и Telegram bot pro správce systému.
Článek je navíc záměrně nadbytečný, aby pokaždé neodkazoval na naučnou literaturu. V textu nejsou žádné odkazy na Gang 4, PowerShell Deep Dives nebo řekněme The 5 Pillars of AWS Well-Architected Framework.

Místo předmluvy můžete přeskočit

Klidně přeskočteV roce 2006 společnost Microsoft vydala PowerShell 1.0 pro tehdejší Windows XP, Vista a Server 2003. V některých ohledech nahradil takové věci, jako jsou skripty cmdbat, skripty vb, Windows Script Host a JScript.

PowerShell lze i nyní považovat za další krok po možnostech Logo, namísto pravděpodobně stále používaného Delphi (nebo něčeho staršího), a to i přes přítomnost smyček, tříd, funkcí, volání MS GUI, Integrace Git a tak dále.

Powershell se používá poměrně zřídka, můžete se s ním setkat pouze v podobě PowerShell Core, VMware vSphere PowerCLI, Azure PowerShell, MS Exchange, Desired State Configuration, Webový přístup PowerShell a asi tucet méně používaných programů a funkcí. Možná dostane druhý dech s vydáním WSL2, ale není to přesně tak.

Powershell má také tři velké výhody:

  1. Je to poměrně jednoduché, je o tom spousta literatury a ukázek a i v ruštině třeba článek o Foreach - z knihy PowerShell do hloubky - o rozdílu () a {}
  2. Jde s redaktorem ISE, součástí systému Windows. Dokonce je tam i nějaký debugger.
  3. Dá se z něj snadno volat komponenty pro tvorbu grafického rozhraní.

0. Příprava.

Budeme potřebovat:

  • Windows PC (mám Windows 10)
  • Alespoň nějaký druh přístupu k internetu (například přes NAT)
  • Pro ty, kteří mají omezený přístup k telegramu - nainstalovaná a nakonfigurovaná freegate v prohlížeči, v některých obtížných případech spolu se Symple DNS Crypt
  • Mít v telefonu funkčního telegramového klienta
  • Pochopení úplných základů – co je to proměnná, pole, smyčka.

Otevřené a přečtené články - Návod: Jak vytvořit roboty v Telegramu и Telegram bot pro správce systému

1. Vytvořme dalšího testovacího robota.

Protože to už všichni vědí a už se to stalo, můžete to také přeskočitJak je uvedeno v článku výše - Za prvé, robot pro Telegram - je to stále aplikace běžící na vaší straně a odesílání požadavků na Telegram Bot API. Navíc je API přehledné – bot přistupuje na konkrétní URL s parametry a Telegram odpoví objektem JSON.

Související problémy: pokud nějakým neznámým způsobem vezmete nějaký kód z objektu JSON a nějak ho pošlete ke spuštění (ne schválně), kód se spustí za vás.

Proces vytvoření je popsán ve dvou článcích výše, ale opakuji: v telegramu otevřeme kontakty, vyhledáme @botfather, řekneme mu /newbot, vytvoříme bota Botfortest12344321, nazveme ho Mynext1234bot a obdržíme zprávu s jedinečným klíčem formulář 1234544311:AbcDefNNNNNNNNNNNNNN

Postarejte se o klíč a nedávejte ho pryč!

Poté můžete robota nakonfigurovat, například zakázat jeho přidávání do skupin, ale v prvních krocích to není nutné.

Požádejme BotFathera o „/mybot“ a upravme nastavení, pokud se nám něco nelíbí.

Znovu otevřeme kontakty, najdeme tam @Botfortest12344321 (je povinné začít hledání pomocí @), klikneme na „start“ a napíšeme robotovi „/Sláva robotům“. Znak / je povinný, uvozovky nejsou potřeba.
Robot samozřejmě na nic neodpoví.

Zkontrolujeme, že byl robot vytvořen, a otevřete jej.

api.telegram.org/bot1234544311:AbcDefNNNNNNNNNNNNNN/getMe
kde 1234544311:AbcDefNNNNNNNNNNNNNN je dříve přijatý klíč,
a získat řádek jako
{"ok":true,"result":{""}}

Máme první tajnou frázi (token). Nyní musíme zjistit druhé tajné číslo – ID chatu s botem. Každý chat, skupina atd. je individuální a má své číslo (někdy s mínusem - u otevřených skupin). Abychom toto číslo zjistili, musíme si v prohlížeči vyžádat (ve skutečnosti to v prohlížeči není vůbec nutné, ale pro lepší pochopení s ním můžete začít) adresu (kde 1234544311:NNNNNNNNNN je váš token

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

a dostat odpověď jako

{"ok":true,"result":[{"update_id":...,... povídání":{"id":123456789

Potřebujeme chat_id.

Zkontrolujeme, že můžeme psát do chatu ručně: zavolejte na adresu z prohlížeče

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

Pokud obdržíte zprávu od robota ve vašem chatu, dobře, přejdete k další fázi.

Takto (přes prohlížeč) můžete vždy zkontrolovat, zda nejsou problémy s generováním odkazu, nebo zda se někde něco neskrývá a nefunguje.

Co potřebujete vědět, než budete pokračovat ve čtení

Telegram má několik typů skupinových chatů (otevřené, uzavřené). U těchto chatů jsou některé funkce (například id) odlišné, což někdy způsobuje určité problémy.

Předpokládejme, že je konec roku 2019 a i hrdina naší doby, známý Man-Orchestra (administrátor, právník, specialista na informační bezpečnost, programátor a prakticky MVP) Evgeniy V. rozlišuje proměnnou $i od pole, má zvládnuté smyčky, podívejte se v příštích pár letech zvládne Chocolatey, a pak Paralelní zpracování s PowerShell и Paralelní pro každý objekt přijde to.

1. Přemýšlíme o tom, co náš bot udělá

Neměl jsem žádné nápady, musel jsem přemýšlet. Už jsem napsal bot-notebook. Nechtěl jsem dělat robota, „který někam něco posílá“. K připojení k Azure potřebujete kreditní kartu, ale odkud ji student získá? Je třeba poznamenat, že všechno není tak špatné: hlavní mraky dávají nějakou zkušební dobu zdarma (ale stále potřebujete číslo kreditní karty - a zdá se, že z toho bude stržen dolar. Nevzpomínám si, jestli bylo vráceno později.)

Bez AI ML není tak zajímavé dělat z bot-chudého básníka-tkadlena.

Rozhodl jsem se vyrobit bota, který mi bude připomínat (nebo ne) anglická slova ze slovníku.
Abyste se vyhnuli manipulaci s databází, bude slovník uložen v textovém souboru a aktualizován ručně.
V tomto případě je úkolem ukázat základy práce, a ne vyrobit alespoň částečně hotový výrobek.

2. Poprvé si vyzkoušet co a jak

Vytvořme složku C:poshtranslate
Nejprve se podívejme, jaký druh powershell máme, pojďme spustit ISE přes start-run
powershell ise
nebo v nainstalovaných programech najděte Powershell ISE.
Po spuštění se otevře obvyklý známý „nějaký editor“; pokud neexistuje žádné textové pole, můžete vždy kliknout na „Soubor - vytvořit nový“.

Podívejme se na verzi powershell - do textového pole napište:

get-host 

a stiskněte F5.

Powershell nabídne uložení - “Skript, který se chystáte spustit, bude uložen.”, souhlasíme a uložíme soubor z powershell s názvem v C: poshtranslate myfirstbotBT100.

Po spuštění ve spodním textovém okně získáme datovou tabulku:

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

Mám něco 5.1, to stačí. Pokud máte starý Windows 7/8, pak není problém - ačkoli PowerShell bude muset být aktualizován na verzi 5 - např. instrukce.

Do příkazového řádku níže zadejte Get-Date, stiskněte Enter, podívejte se na čas a přejděte do kořenové složky s příkazem
cd
a vymažte obrazovku příkazem cls (ne, nemusíte používat rm)

Nyní se podívejme, co funguje a jak - napišme ani ne kód, ale dva řádky a pokusme se pochopit, co dělají. Řádek s get-host okomentujeme symbolem # a trochu přidáme.

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

(Zajímavé je, že v rozevíracím seznamu formátování kódu na Habré jsou dva tucty možností - ale Powershell tam není. Je tam Dos. Je tam Perl.)

A spusťte kód stisknutím F5 nebo ">" z GUI.

Získáme následující výstup:

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

Nyní se podívejme na tyto dva řádky a některé zajímavé body, abychom se k tomu v budoucnu nevraceli.

Na rozdíl od Pascalu (a nejen) se PowerShell sám snaží určit, jaký typ proměnné přiřadit, více podrobností o tom je napsáno v článku Vzdělávací program o psaní v programovacích jazycích
Vytvořením proměnné $TimeNow a přiřazením hodnoty aktuálního data a času (Get-Date) se tedy nemusíme příliš starat o to, jaký typ dat tam bude.

Je pravda, že tato nevědomost může později bolet, ale to až později. Níže v textu bude uveden příklad.
Podívejme se, co máme. Proveďme (na příkazovém řádku)

$TimeNow | Get-member

a získat stránku nesrozumitelného textu

Příklad nesrozumitelného textu číslo 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")...                                         

Jak vidíte, byla vytvořena proměnná typu TypeName: System.DateTime se spoustou metod (ve smyslu toho, co můžeme dělat s tímto objektem proměnné) a vlastností.

Zavolejme $TimeNow.DayOfYear — dostaneme číslo dne v roce.
Zavolejme $TimeNow.DayOfYear | Get-Member - dostaneme TypeName: System.Int32 a skupina metod.
Zavolejme $TimeNow.ToUniversalTime() - a získat čas v UTC

Debugger

Občas se stane, že je potřeba spustit program až na určitý řádek a podívat se, v jakém okamžiku se program nachází. Pro tento účel má ISE funkci Debug - přepínání bodu přerušení
Umístěte bod přerušení někam doprostřed, spusťte tyto dva řádky a podívejte se, jak vypadá přerušení.

3. Pochopení interakce s robotem Telegram

Samozřejmě bylo napsáno ještě více literatury o interakci s robotem, se všemi getpush a tak dále, ale otázka teorie může být zvážena volitelně.

V našem případě je nutné:

  • Naučte se něco posílat v korespondenci
  • Naučte se z korespondence něco získat

3.1 Naučit se něco odesílat v korespondenci a přijímat z toho

Malý kód - část 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

a v Ruské federaci v tomto okamžiku dostaneme chybu Nelze se připojit ke vzdálenému serveru.

Nebo jej neobdržíme – záleží na telekomunikačním operátorovi a na tom, zda je proxy nakonfigurováno a funguje
No, zbývá jen přidat proxy. Vezměte prosím na vědomí, že používání nešifrovaného a obecně podvodného proxy je extrémně nebezpečné pro vaše zdraví.

Úkol najít fungující proxy není příliš obtížný - většina publikovaných http proxy funguje. Myslím, že ten pátý se mi osvědčil.

Syntaxe pomocí proxy:

Invoke-WebRequest -Uri $URL4SEND -Proxy $MyProxy

Pokud dostanete zprávu do vašeho chatu s botem, pak je vše v pořádku, můžete pokračovat. Pokud ne, pokračujte v ladění.

Můžete vidět, v co se změní váš řetězec $URL4SEND, a zkuste si to v prohlížeči vyžádat takto:

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

3.2. Naučili jsme se, jak napsat „něco“ do chatu, teď si to zkusme přečíst

Přidejme další 4 řádky a podívejme se, co je uvnitř přes | získat-člen

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

To nejzajímavější je nám poskytnuto

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

Podívejme se, co v nich je:

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

Pokud vše funguje pro vás, dostanete dlouhou řadu jako:

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

Naštěstí v dříve publikovaném článku Telegram bot pro správce systému tento řádek (ano, podle $MyMessageGet.RawContent | get-member je System.String), byl již rozebrán.

4. Zpracujte, co obdržíte (my už víme, jak něco poslat)

Jak již bylo napsáno zde, to nejnutnější spočívá v obsahu. Pojďme se na to podívat blíže.

Nejprve napíšeme robotovi několik dalších frází z webového rozhraní nebo z telefonu

/message1
/message2
/message3

a podívejte se v prohlížeči na adresu, která byla vytvořena v proměnné $URLGET.

Uvidíme něco jako:

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

co to je? Nějaký složitý objekt z polí objektů obsahujících koncový identifikátor zprávy, identifikátor chatu, identifikátor odesílání a spoustu dalších informací.

Nemusíme však zjišťovat, „co je to za objekt“ – část práce už byla za nás udělána. Podívejme se, co je uvnitř:

Čtení přijatých zpráv nebo část 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. Co s tím teď máme dělat?

Uložme výsledný soubor pod názvem myfirstbotBT105 nebo jakkoli se vám líbí nejvíce, změňte název a okomentujte veškerý již napsaný kód přes

<#start comment 105 end comment 105#>

Nyní se musíme rozhodnout, kde slovník získat (no, kde - na disku v souboru) a jak bude vypadat.

Samozřejmě můžete napsat obrovský slovník přímo do textu skriptu, ale to je úplně vedle.
Pojďme se tedy podívat, s čím powershell může normálně pracovat.
Obecně je mu jedno, se kterým souborem bude pracovat, na nás nezáleží.
Máme na výběr: txt (můžete, ale proč), csv, xml.
Můžeme se dívat na všechny? Podívejme se na všechny.
Vytvořme třídu MyVocabClassExample1 a proměnnou $MyVocabExample1
Podotýkám, že třída je zapsána bez $

nějaký kód #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

Zkusme to zapsat do souborů pomocí vzorek.

Nějaký 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

- a dostaneme chybu na řádku Out-File -FilePath $MyFilenameExample01 -InputObject -Append $MyVocabExample2.

Nechce dodat, ach, jaká ostuda.

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

Pojďme se podívat, co se stane. Skvělé zobrazení textu – ale jak jej exportovat zpět? Měl bych zavést nějaké oddělovače textu, jako jsou čárky?

A nakonec získáte soubor „hodnoty oddělené čárkami (CSV) A STOP ČEKEJTE.
#

$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 

Jak je dobře vidět, MS se svou logikou nijak zvlášť nerozlišuje, pro podobný postup se v jednom případě používá -FilePath, v jiném -Path.

Navíc ve třetím souboru zmizela ruština, ve čtvrtém souboru se ukázalo... no, něco se stalo. #TYPE System.Object[] 00
# “Count”, “Length”,”LongLength”,”Rank”, “SyncRoot”,”IsReadOnly”,”IsFixedSize”,”Issynchroned”
#
Pojďme to trochu přepsat:

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

Zdá se, že to pomohlo, ale stále se mi nelíbí formát.

Hlavně se mi nelíbí, že nemůžu dát řádky z objektu do souboru přímo.
Mimochodem, od té doby, co jsme začali zapisovat do souborů, můžeme začít vést spouštěcí protokol? Jako proměnnou máme čas, můžeme nastavit název souboru.

Pravda, zatím není co psát, ale můžete popřemýšlet, jak nejlépe klády otočit.
Zkusme zatím xml.

Nějaký 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

Export do xml má mnoho výhod – čitelnost, export celého objektu a není potřeba provádět uppend.

Zkusme to číst xml soubor.

Trochu čtení z xml

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

Vraťme se k úkolu. Napsali jsme testovací soubor, přečtěte si ho, formát úložiště je jasný, v případě potřeby můžete napsat samostatný editor malých souborů pro přidávání a odstraňování řádků.

Připomínám, že úkolem bylo vyrobit malého cvičného bota.

Pracovní formát: Pošlu robotovi příkaz „example“, bot mi pošle náhodně vybrané slovo a přepis a po 10 sekundách mi pošle překlad a komentář. Umíme číst příkazy, rádi bychom se také naučili automaticky vybírat a kontrolovat proxy a resetovat počítadla zpráv do zapomnění.

Odkomentujme vše, co bylo dříve okomentováno jako nepotřebné, zakomentujme nyní nepotřebné příklady pomocí txt a csv a uložme soubor jako verzi B106

Ach ano. Zase něco pošleme robotovi.

6. Odeslání z funkcí a další

Před zpracováním příjmu je potřeba vytvořit funkci pro odeslání „alespoň něčeho“ jiného než testovací zprávy.

Samozřejmě, že v příkladu budeme mít pouze jedno odeslání a pouze jedno zpracování, ale co když potřebujeme totéž udělat několikrát?

Je jednodušší napsat funkci. Máme tedy proměnnou typu object $MyVocabExample4AsArray načtenou ze souboru ve formě pole až dvou prvků.
Pojďme číst.

Zároveň se budeme zabývat hodinami; budeme je potřebovat později (ve skutečnosti je v tomto příkladu potřebovat nebudeme :)

Nějaký 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
}

Jak můžete snadno vidět, funkce volá $MyToken a $MyChatID, které byly dříve pevně zakódovány.

Není to nutné, a pokud je $MyToken jeden pro každého robota, pak se $MyChatID změní v závislosti na chatu.

Protože se však jedná o příklad, budeme jej prozatím ignorovat.

Protože $MyVocabExample4AsArray není pole, ačkoli je jednomu velmi podobné, pak nemůžeš to jen tak vzít požadovat jeho délku.

Opět budeme muset udělat něco, co nelze - padák ne podle kódu - vezměte a počítejte

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

Náhodný zajímavá vlastnost. Řekněme, že chceme přijmout 0 nebo 1 (v poli máme pouze dva prvky). Při nastavení hranic 0..1 dostaneme „1“?
ne - nezískáme to, máme speciální příklad Příklad 2: Získejte náhodné celé číslo mezi 0 a 99 Get-Random -Maximum 100
Proto pro 0..1 musíme nastavit velikost 0..2 s maximálním počtem prvků = 1.

7. Zpracování příchozích zpráv a maximální délka fronty

Kde jsme se zastavili dříve? máme přijatou proměnnou $MyMessageGet
a z něj získané $Content4Pars01, z nichž nás zajímají prvky pole Content4Pars01.result

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

Pošleme robotovi /message10, /message11, /message12, /word a znovu /word a /hello.
Podívejme se, co máme:

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

Projdeme si vše, co jsme obdrželi, a pošleme odpověď, pokud byla zpráva /word
případ konstruktu, který někteří popisují jako if-elseif, se nazývá v powershell přes spínač. Zároveň níže uvedený kód používá klíč -wildcard, což je zcela zbytečné a dokonce škodlivé.

Nějaký kód #7.1

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

Spusťte skript několikrát. Za každý pokus o provedení dostaneme stejné slovo dvakrát, zvláště pokud jsme udělali chybu v implementaci random.

Ale přestaň. Znovu jsme neposlali /word, tak proč se zpráva zpracovává znovu?

Fronta pro odesílání zpráv botovi má konečnou délku (100 nebo 200 zpráv, myslím) a musí být ručně vymazána.

To je samozřejmě popsáno v dokumentaci, ale musíte si ji přečíst!

V tomto případě potřebujeme parametr ?chat_id a &timeout, &limit, &parse_mode=HTML a &disable_web_page_preview=true zatím nejsou potřeba.

Dokumentace pro telegram api je zde
Píše se tam bíle a anglicky:
Identifikátor první aktualizace, která má být vrácena. Musí být o jednu větší než nejvyšší mezi identifikátory dříve přijatých aktualizací. Ve výchozím nastavení začínají aktualizace nejdříve
nepotvrzený aktualizace jsou vráceny. Aktualizace je považována za potvrzenou, jakmile je getUpdates zavolána pomocí a ofset vyšší než jeho update_id. Záporný offset lze zadat pro načítání aktualizací počínaje -offset update od konce fronty aktualizací. Všechny předchozí aktualizace budou zapomenuty.

Pojďme se podívat:

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

Ano, resetujeme to a trochu přepíšeme funkci. Máme dvě možnosti – předat funkci celou zprávu a celou ji zpracovat ve funkci, nebo zadat pouze ID zprávy a resetovat ji. Například ten druhý vypadá jednodušeji.

Dříve vypadal náš řetězec dotazu „všechny zprávy“.

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

a bude to vypadat

$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 

Nikdo vám nezakazuje nejprve všechny zprávy přijímat, zpracovávat a teprve po úspěšném zpracování požadavek nepotvrzený -> potvrzený.

Proč má smysl volat potvrzení po dokončení veškerého zpracování? Selhání je možné uprostřed provádění, a pokud například u bezplatného chatbota není vynechání jediné zprávy nic zvláštního, pak pokud zpracováváte něčí plat nebo transakci kartou, může být výsledek horší.

Ještě pár řádků kódu

$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. Místo závěru

Základní funkce - čtení zpráv, resetování fronty, čtení ze souboru a zápis do souboru jsou provedeny a zobrazeny.

Zbývají už jen čtyři věci:

  • odeslání správné odpovědi na žádost v chatu
  • odeslání odpovědi na JAKÝKOLI chat, do kterého byl bot přidán
  • provádění kódu ve smyčce
  • spuštění robota z plánovače systému Windows.

Všechny tyto úkoly jsou jednoduché a lze je snadno provést přečtením dokumentace o parametrech jako např
Set-ExecutionPolicy Unrestricted a -ExecutionPolicy Bypass
cyklus formuláře

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

Díky všem, kdo čtou.

Zdroj: www.habr.com

Přidat komentář