Malli yksinkertaiselle sähkebotille 7-9-luokkien koululaisille Powershellillä

Keskustellessani ystäväni kanssa sain yhtäkkiä tietää, että heidän koulussaan 8-10 luokaille ei opeteta ohjelmointia ollenkaan. Word, Excel ja kaikki. Ei logoa, ei edes Pascalia, ei edes VBA:ta Excelille.

Olin hyvin yllättynyt, avasin Internetin ja aloin lukemaan -
Yksi erikoiskoulun tehtävistä on edistää tietoyhteiskunnan edellytykset täyttävän uuden sukupolven koulutusta kehitystasoltaan ja elämäntapoiltaan.
Tämän kurssin avulla opiskelijat voivat vakiinnuttaa käytännössä tietonsa Pascal-ohjelmointikielen perusrakenteista. (jonkin kuntosalin ohjelmasta vuodelle 2017)

Lopulta päätin viettää muutaman tunnin ja hahmotella esimerkin "kuinka luodaan yksinkertainen botti koululaisille".

Leikkauksen alla on kuinka kirjoittaa toinen yksinkertainen botti Powershelliin ja saada se toimimaan ilman webhookia, valkoisia IP-osoitteita, omistettuja palvelimia, pilvessä olevia virtuaalikoneita ja niin edelleen - tavallisessa kotitietokoneessa tavallisella Windowsilla.

TLDR: Toinen tylsä ​​artikkeli, jossa on kielioppi- ja faktavirheitä, ei mitään luettavaa, ei huumoria, ei kuvia.

Artikkelissa ei ole mitään uutta, melkein kaikki aiemmin kirjoitettu on jo ollut Habressa, esimerkiksi artikkeleissa Ohjeet: Kuinka luoda botteja Telegramissa и Telegram-botti järjestelmänvalvojalle.
Lisäksi artikkeli on tarkoituksella tarpeeton, jotta ei viitata joka kerta opetuskirjallisuuteen. Tekstissä ei ole viittauksia Gang 4:ään, PowerShell Deep Divesiin tai vaikkapa AWS:n hyvin rakennetun kehyksen viiteen pilariin.

Esipuheen sijaan voit ohittaa

Voit vapaasti ohittaaVuonna 2006 Microsoft julkaisi PowerShell 1.0:n silloisille Windows XP:lle, Vistalle ja Server 2003:lle. Jollain tapaa se korvasi sellaiset asiat kuin cmdbat-skriptit, vb-skriptit, Windows Script Host ja JScript.

Jo nyt PowerShellia voidaan pitää vain seuraavana askeleena Logo-vaihtoehtojen jälkeen luultavasti edelleen käytetyn Delphin (tai jonkin vanhemman) sijasta huolimatta silmukoista, luokista, funktioista, MS GUI -kutsuista, Git-integraatio ja niin edelleen.

Powershelliä käytetään suhteellisen harvoin; voit kohdata sen vain PowerShell Coren, VMware vSphere PowerCLI:n, Azure PowerShellin, MS Exchangen, Desired State Configurationin, PowerShell Web Access ja kymmenkunta harvemmin käytettyä ohjelmaa ja toimintoa. Ehkä hän saa toisen tuulen julkaisun myötä WSL2, mutta se ei ole aivan.

Powershellillä on myös kolme suurta etua:

  1. Se on suhteellisen yksinkertainen, siitä on paljon kirjallisuutta ja esimerkkejä, ja jopa venäjäksi esimerkiksi artikkeli Foreachista - kirjasta PowerShell perusteellisesti - erosta () ja {}
  2. Hän menee toimittajan mukana ISE, sisältyy Windowsin mukana. Siellä on jopa jonkinlainen debuggeri.
  3. Siitä on helppo soittaa komponentit graafisen käyttöliittymän rakentamiseen.

0. Valmistelu.

Tarvitsemme:

  • Windows PC (minulla on Windows 10)
  • Ainakin jonkinlainen Internet-yhteys (esim. NAT:n kautta)
  • Niille, joilla on rajoitettu pääsy sähkeen - asennettu ja määritetty freegate selaimeen joissakin vaikeissa tapauksissa yhdessä Symple DNS Cryptin kanssa
  • Puhelimessasi on toimiva sähkeasiakas
  • Perusasioiden ymmärtäminen - mikä muuttuja, array, silmukka on.

Avannut ja lukenut artikkeleita - Ohjeet: Kuinka luoda botteja Telegramissa и Telegram-botti järjestelmänvalvojalle

1. Luodaan toinen testibotti.

Koska kaikki jo tietävät tämän ja on jo tapahtunut, voit myös ohittaa senKuten yllä olevassa artikkelissa todettiin - Ensinnäkin, botti Telegramille - se on edelleen puolellasi käynnissä oleva sovellus, joka tekee pyyntöjä Telegram Bot API:lle. Lisäksi API on selkeä - botti käyttää tiettyä URL-osoitetta parametrein, ja Telegram vastaa JSON-objektilla.

Aiheeseen liittyvät ongelmat: jos jollain tuntemattomalla tavalla otat koodia JSON-objektista ja lähetät sen jollain tavalla suoritettavaksi (ei tarkoituksella), koodi suoritetaan puolestasi.

Luontiprosessi on kuvattu kahdessa yllä olevassa artikkelissa, mutta toistan: sähkeessä avaamme yhteystiedot, etsimme @botfather, kerromme hänelle /newbot, luomme botin Botfortest12344321, kutsumme sitä Mynext1234botiksi ja vastaanotamme viestin, jossa on yksilöllinen avaimen lomake 1234544311:AbcDefNNNNNNNNNNNNNN

Huolehdi avaimesta äläkä luovuta sitä!

Sitten voit määrittää botin, esimerkiksi kieltää sen lisäämisen ryhmiin, mutta ensimmäisissä vaiheissa tämä ei ole välttämätöntä.

Kysytään BotFatheriltä "/mybot" ja säädämme asetuksia, jos emme pidä jostain.

Avataan yhteystiedot uudelleen, etsitään sieltä @Botfortest12344321 (haku on aloitettava @:lla), klikataan "aloita" ja kirjoitetaan bottiin "/Glory to the robots." /-merkki vaaditaan, lainausmerkkejä ei tarvita.
Botti ei tietenkään vastaa mitään.

Tarkistetaan, että botti on luotu ja avataan se.

api.telegram.org/bot1234544311:AbcDefNNNNNNNNNNNNNN/getMe
jossa 1234544311:AbcDefNNNNNNNNNNNNNN on aiemmin vastaanotettu avain,
ja saada rivi tykkää
{"ok":true"result":{""}}

Meillä on ensimmäinen salainen lause (token). Nyt meidän on selvitettävä toinen salainen numero - botin kanssa käytävän chatin tunnus. Jokainen chat, ryhmä jne. on yksilöllinen ja sillä on oma numeronsa (joskus miinuksella - avoimille ryhmille). Tämän numeron selvittämiseksi meidän on pyydettävä selaimeen (itse asiassa se ei ole ollenkaan välttämätöntä selaimessa, mutta paremman ymmärtämisen vuoksi voit aloittaa siitä) osoite (jossa 1234544311:NNNNNNNNNN on tunnus

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

ja saat vastauksen kuten

{"ok":true,"result":[{"update_id":...,... jutella":{"id":123456789

Tarvitsemme chat_id:n.

Tarkistetaan, että voimme kirjoittaa chatiin manuaalisesti: soita osoitteeseen selaimesta

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

Jos saat viestin botilta chatissasi, siirryt seuraavaan vaiheeseen.

Näin (selaimen kautta) voit aina tarkistaa, onko linkkien luomisessa ongelmia, tai onko jotain piilossa jossain eikä toimi.

Mitä sinun tulee tietää ennen kuin jatkat lukemista

Telegramissa on useita ryhmäkeskustelutyyppejä (avoin, suljettu). Näissä keskusteluissa jotkin toiminnot (esimerkiksi id) ovat erilaisia, mikä aiheuttaa joskus ongelmia.

Oletetaan, että on vuoden 2019 loppu ja jopa aikamme sankari, tunnettu Man-Orchestra (järjestelmänvalvoja, lakimies, tietoturva-asiantuntija, ohjelmoija ja käytännössä MVP) Evgeniy V. erottaa $i-muuttujan taulukosta, on hallinnut silmukoita, katso parin seuraavan vuoden aikana hallitsee Chocolatey, ja sitten Rinnakkaiskäsittely PowerShellin kanssa и Jokaisen esineen rinnakkain se tulee.

1. Ajattelemme, mitä bottimme tekee

Minulla ei ollut ideoita, minun piti ajatella. Olen jo kirjoittanut bot-muistikirjan. En halunnut tehdä bottia, "joka lähettää jotain jonnekin". Tarvitset luottokortin muodostaaksesi yhteyden Azureen, mutta mistä opiskelija saa sen? On huomioitava, että kaikki ei ole niin huonosti: pääpilvet antavat jonkinlaisen testijakson ilmaiseksi (mutta tarvitset silti luottokortin numeron - ja näyttää siltä, ​​​​että siitä veloitetaan dollari. En muista onko se palautettiin myöhemmin.)

Ilman AI ML:ää ei ole niin mielenkiintoista tehdä bot-köyhäksi.

Päätin tehdä botin, joka muistuttaa minua (tai ei minua) englanninkielisiä sanoja sanakirjasta.
Tietokannan selaamisen välttämiseksi sanakirja tallennetaan tekstitiedostoon ja päivitetään manuaalisesti.
Tässä tapauksessa tehtävänä on näyttää työn perusteet, eikä tehdä ainakin osittain valmiita tuotteita.

2. Kokeile mitä ja miten ensimmäistä kertaa

Luodaan kansio C:poshtranslate
Ensin katsotaan millainen powershell meillä on, käynnistetään ISE start-run kautta
powerhell ise
tai etsi Powershell ISE asennetuista ohjelmista.
Käynnistyksen jälkeen avautuu tavallinen tuttu "jonkinlainen editori", jos tekstikenttää ei ole, voit aina napsauttaa "Tiedosto - luo uusi".

Katsotaanpa powershellin versiota - kirjoita tekstikenttään:

get-host 

ja paina F5.

Powershell tarjoaa tallennuksen - "Skripti, jota aiot suorittaa, tallennetaan." Hyväksymme ja tallennamme tiedoston powershellistä nimellä C: poshtranslate myfirstbotBT100.

Käynnistyksen jälkeen alemmassa tekstiikkunassa saamme datataulukon:

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

Minulla on jotain 5.1, se riittää. Jos sinulla on vanha Windows 7/8, ei hätää - vaikka PowerShell on päivitettävä versioon 5 - esim. ohjeet.

Kirjoita alla olevalle komentoriville Get-Date, paina Enter, katso kellonaika, siirry juurikansioon komennolla
cd
ja tyhjennä näyttö cls-komennolla (ei, sinun ei tarvitse käyttää rm:ää)

Tarkastetaan nyt, mikä toimii ja miten - kirjoitetaan ei edes koodia, vaan kaksi riviä ja yritetään ymmärtää, mitä he tekevät. Kommentoidaan riviä get-host symbolilla # ja lisätään vähän.

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

(Mielenkiintoista on, että Habrén koodin muotoilun avattavassa luettelossa on kaksi tusinaa vaihtoehtoa - mutta Powershelliä ei ole. Dos on siellä. Perl on siellä.)

Ja suoritetaan koodi painamalla F5 tai ">" graafisesta käyttöliittymästä.

Saamme seuraavan tuloksen:

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

Katsotaanpa nyt näitä kahta riviä ja joitain mielenkiintoisia kohtia, jotta emme palaa tähän tulevaisuudessa.

Toisin kuin Pascal (eikä vain), PowerShell itse yrittää määrittää, minkä tyypin muuttujalle annetaan; lisätietoja tästä on kirjoitettu artikkelissa Opetusohjelma ohjelmointikielien kirjoittamiseen
Siksi luomalla $TimeNow-muuttujan ja antamalla sille nykyisen päivämäärän ja kellonajan arvon (Get-Date), meidän ei tarvitse huolehtia liikaa siitä, minkä tyyppistä dataa siellä on.

Totta, tämä tietämättömyys saattaa satuttaa myöhemmin, mutta se on myöhempää. Alla tekstissä on esimerkki.
Katsotaan mitä saamme. Suoritetaan (komentorivillä)

$TimeNow | Get-member

ja saat sivun käsittämätöntä tekstiä

Esimerkki käsittämättömästä tekstistä numero 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")...                                         

Kuten näette, TyypinNimi: System.DateTime tyyppinen muuttuja on luotu joukolla menetelmiä (sillä mielessä, mitä voimme tehdä tälle muuttujaobjektille) ja ominaisuuksilla.

Soitetaan $TimeNow.DayOfYear - saamme vuoden päivän numeron.
Soitetaan $TimeNow.DayOfYear | Get-Member - saamme TypeName: System.Int32 ja joukko menetelmiä.
Soitetaan $TimeNow.ToUniversalTime() - ja saat ajan UTC:ssä

Virheen korjaaja

Joskus käy niin, että on tarpeen suorittaa ohjelma tiettyyn riviin asti ja nähdä ohjelman tila sillä hetkellä. Tätä tarkoitusta varten ISE:ssä on Debug-toiminto - toggle breakpoint
Aseta keskeytyskohta jonnekin keskelle, suorita nämä kaksi riviä ja katso, miltä katkos näyttää.

3. Telegram-botin vuorovaikutuksen ymmärtäminen

Tietenkin vielä enemmän kirjallisuutta on kirjoitettu vuorovaikutuksesta botin kanssa, kaikesta getpushista ja niin edelleen, mutta teoriakysymystä voidaan harkita valinnaisesti.

Meidän tapauksessamme tarvitaan:

  • Opi lähettämään jotain kirjeenvaihdossa
  • Opi saamaan jotain kirjeenvaihdosta

3.1 Oppiminen lähettämään jotain kirjeenvaihdossa ja vastaanottamaan siitä

Pieni koodi - osa 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

ja Venäjän federaatiossa tässä vaiheessa saamme virheilmoituksen Ei voida muodostaa yhteyttä etäpalvelimeen.

Tai emme saa sitä - riippuu teleoperaattorista ja siitä, onko välityspalvelin määritetty ja toimiva
No, jäljellä on vain välityspalvelimen lisääminen. Huomaa, että salaamattoman ja yleisesti petollisen välityspalvelimen käyttö on erittäin vaarallista terveydelle.

Tehtävä toimivan välityspalvelimen löytäminen ei ole kovin vaikeaa - useimmat julkaistut http-välityspalvelimet toimivat. Luulen, että viides toimi minulle.

Syntaksi välityspalvelimella:

Invoke-WebRequest -Uri $URL4SEND -Proxy $MyProxy

Jos saat viestin chatissasi botin kanssa, kaikki on hyvin, voit jatkaa. Jos ei, jatka virheenkorjausta.

Voit nähdä, miksi $URL4SEND-merkkijonosi muuttuu, ja yrittää pyytää sitä selaimessa seuraavasti:

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

3.2. Opimme kirjoittamaan "jotain" chatissa, yritetään nyt lukea se

Lisätään vielä 4 riviä ja katsotaan mitä | liity jäseneksi

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

Mielenkiintoisin asia tarjotaan meille

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

Katsotaan mitä niissä on:

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

Jos kaikki toimii sinulle, saat pitkän jonon, kuten:

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

Onneksi aiemmin julkaistussa artikkelissa Telegram bot järjestelmänvalvojalle tämä rivi (kyllä, $MyMessageGet.RawContent | get-member on System.String), on jo purettu.

4. Käsittele vastaanottamasi (tiedämme jo kuinka lähettää jotain)

Kuten jo kirjoitettu täällä, tärkeimmät asiat ovat sisällössä. Katsotaanpa sitä tarkemmin.

Ensin kirjoitamme pari muuta lausetta botille verkkokäyttöliittymästä tai puhelimesta

/message1
/message2
/message3

ja katso selaimen kautta osoitetta, joka on muodostettu muuttujassa $URLGET.

Näemme jotain tällaista:

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

Mikä se on? Jokin monimutkainen objekti objektiryhmistä, jotka sisältävät päästä päähän -viestitunnisteen, chat-tunnisteen, lähetystunnisteen ja paljon muuta tietoa.

Meidän ei kuitenkaan tarvitse keksiä "mikä tämä esine on" - osa työstä on jo tehty puolestamme. Katsotaan mitä sisällä on:

Vastaanotettujen viestien tai osan 4 lukeminen

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ä meidän pitäisi tehdä asialle nyt?

Tallennetaan tuloksena oleva tiedosto nimellä myfirstbotBT105 tai millä tahansa parhaalla tavalla, vaihdataan otsikkoa ja kommentoitaan kaikki jo kirjoitettu koodi

<#start comment 105 end comment 105#>

Nyt meidän on päätettävä, mistä saada sanakirja (no, missä - levyllä tiedostossa) ja miltä se näyttää.

Tietysti voit kirjoittaa valtavan sanakirjan suoraan käsikirjoituksen tekstiin, mutta tämä on täysin asian vierestä.
Joten katsotaan, minkä kanssa powershell voi toimia normaalisti.
Yleensä hän ei välitä minkä tiedoston kanssa hän työskentelee, sillä ei ole meille väliä.
Meillä on vaihtoehto: txt (voit, mutta miksi), csv, xml.
Nähdäänkö kaikki.
Luodaan luokka MyVocabClassExample1 ja muuttuja $MyVocabExample1
Huomaan, että luokka on kirjoitettu ilman $

joku koodi #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

Yritetään kirjoittaa tämä tiedostoihin käyttämällä esimerkillinen.

Jotain koodia #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

- ja saamme virheilmoituksen rivillä Out-File -FilePath $MyFilenameExample01 -InputObject -Liitä $MyVocabExample2.

Hän ei halua lisätä, ah-ah, mikä sääli.

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

Katsotaan, mitä tapahtuu. Upea tekstinäkymä - mutta kuinka viedä se takaisin? Pitäisikö minun ottaa käyttöön jonkinlaisia ​​tekstin erottimia, kuten pilkkuja?

Ja lopulta saat "pilkuilla erotettujen arvojen (CSV) tiedoston A LOPETA ODOTA.
#

$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 

Kuten on helppo nähdä, MS ei ole logiikkaltaan erityisen erottuva, vaan samanlaisessa menettelyssä käytetään yhdessä tapauksessa -FilePathia ja toisessa -Pathia.

Lisäksi kolmannessa tiedostossa venäjän kieli katosi, neljännessä tiedostossa kävi... no, jotain tapahtui. #TYYPPI System.Object[] 00
# "Count","Length","LongLength","Rank","SyncRoot","IsReadOnly","IsFixedSize","IsSynchronized"
#
Kirjoitetaanpa hieman uudelleen:

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

Se näyttää auttavan, mutta en silti pidä muodosta.

En varsinkaan pidä siitä, että en voi laittaa rivejä kohteesta suoraan tiedostoon.
Muuten, koska aloimme kirjoittaa tiedostoihin, voimmeko alkaa pitää käynnistyslokia? Meillä on aikaa muuttujana, voimme asettaa tiedostonimen.

Totta, ei ole vielä mitään kirjoitettavaa, mutta voit miettiä, kuinka tukkeja on parasta kiertää.
Kokeillaan nyt xml:ää.

Jotain 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

Xml-muotoon viennillä on monia etuja - luettavuus, koko objektin vienti, eikä lisäystä tarvitse tehdä.

Yritetään lue xml-tiedosto.

Hieman luettavaa xml:stä

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

Palataan tehtävään. Kirjoitimme testitiedoston, lue se, tallennusmuoto on selkeä, tarvittaessa voit kirjoittaa erillisen pienen tiedostoeditorin rivien lisäämistä ja poistamista varten.

Muistutan, että tehtävänä oli tehdä pieni harjoitusbotti.

Työmuoto: Lähetän "esimerkki"-komennon botille, botti lähettää minulle satunnaisesti valitun sanan ja transkription ja 10 sekunnin kuluttua lähettää minulle käännöksen ja kommentin. Osaamme lukea komentoja, haluaisimme myös oppia valitsemaan ja tarkistamaan välityspalvelimet automaattisesti ja palauttamaan viestilaskurit unohduksiin.

Poistetaan kaikki aiemmin tarpeettomiksi kommentoidut kommentit, kommentoidaan nyt tarpeettomat esimerkit txt:llä ja csv:llä ja tallennetaan tiedosto versiona B106

Kyllä. Lähetetään taas jotain bottiin.

6. Lähetys toiminnoista ja muista

Ennen vastaanoton käsittelyä sinun on luotava toiminto "ainakin jonkin muun" kuin testiviestin lähettämiseksi.

Tietenkin esimerkissä meillä on vain yksi lähetys ja vain yksi käsittely, mutta entä jos meidän on tehtävä sama asia useita kertoja?

Funktioiden kirjoittaminen on helpompaa. Joten meillä on muuttuja, jonka tyyppi on objekti $MyVocabExample4AsArray, luettuna tiedostosta, jopa kahden elementin taulukon muodossa.
Mennään lukemaan.

Samalla käsittelemme kelloa; tarvitsemme sitä myöhemmin (itse asiassa tässä esimerkissä emme tarvitse sitä :)

Jotain koodia #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
}

Kuten näet helposti, funktio kutsuu $MyTokenia ja $MyChatID:tä, jotka oli koodattu aiemmin.

Tätä ei tarvitse tehdä, ja jos $MyToken on yksi jokaiselle botille, $MyChatID muuttuu chatin mukaan.

Koska tämä on esimerkki, jätämme sen kuitenkin huomiotta toistaiseksi.

Koska $MyVocabExample4AsArray ei ole taulukko, vaikka se on hyvin samanlainen kuin yksi, niin et voi vain ottaa sitä pyydä sen pituutta.

Jälleen kerran meidän on tehtävä jotain, mitä ei voida tehdä - laskuvarjo ei koodin mukaan - ota se ja laske

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

satunnainen mielenkiintoinen ominaisuus. Oletetaan, että haluamme vastaanottaa 0 tai 1 (meillä on vain kaksi elementtiä taulukossa). Kun asetamme rajoja 0..1, saadaanko 1?
ei - emme saa sitä, meillä on erityinen esimerkki Esimerkki 2: Hanki satunnainen kokonaisluku väliltä 0 - 99 Get-Random -Maximum 100
Siksi arvolle 0..1 meidän on asetettava koko 0..2, jolloin suurin elementtimäärä = 1.

7. Saapuvien viestien käsittely ja jonon enimmäispituus

Missä pysähdyimme aikaisemmin? meillä on vastaanotettu muuttuja $MyMessageGet
ja siitä saatu $Content4Pars01, joista olemme kiinnostuneita Content4Pars01.result-taulukon elementeistä

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

Lähetetään botti /viesti10, /viesti11, /viesti12, /sana ja vielä kerran /word ja /hello.
Katsotaan mitä saamme:

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

Käydään läpi kaikki vastaanotettu ja lähetämme vastaus, jos viesti oli /word
konstruktin tapausta, jota jotkut kuvailevat if-elseifiksi, kutsutaan powershellissä kytkimen kautta. Samanaikaisesti alla oleva koodi käyttää -wildcard-näppäintä, mikä on täysin tarpeetonta ja jopa haitallista.

Jotain koodia #7.1

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

Suoritetaan käsikirjoitus pari kertaa. Saamme saman sanan kahdesti jokaisesta suoritusyrityksestä, varsinkin jos teimme virheen satunnaisen toteutuksessa.

Mutta lopeta. Emme lähettäneet /wordia uudelleen, joten miksi viestiä käsitellään uudelleen?

Jonolla viestien lähettämiseksi bottiin on rajallinen pituus (luulen, että 100 tai 200 viestiä) ja se on tyhjennettävä manuaalisesti.

Tämä on tietysti kuvattu dokumentaatiossa, mutta sinun on luettava se!

Tässä tapauksessa ?chat_id-parametria, &timeout, &limit, &parse_mode=HTML ja &disable_web_page_preview=true ei vielä tarvita.

Asiakirjat varten telegram api on täällä
Siinä lukee valkoisella ja englanniksi:
Ensimmäisen palautettavan päivityksen tunniste. Sen on oltava yhdellä suurempi kuin korkein aiemmin vastaanotettujen päivitysten tunnisteiden joukossa. Oletuksena päivitykset alkavat aikaisintaan
vahvistamaton päivitys palautetaan. Päivitys katsotaan vahvistetuksi heti, kun getUpdates kutsutaan kanssa offset korkeampi kuin sen update_id. Negatiivinen offset voidaan määrittää hakemaan päivitykset alkaen -offset-päivityksestä päivitysjonon lopusta. Kaikki aiemmat päivitykset unohdetaan.

Katsotaanpa:

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

Kyllä, ja nollaamme sen ja kirjoitamme funktiota hieman uudelleen. Meillä on kaksi vaihtoehtoa - välitä koko viesti funktiolle ja käsittele se kokonaan funktiossa tai anna vain viestin tunnus ja nollaa se. Esimerkiksi toinen näyttää yksinkertaisemmalta.

Aikaisemmin "kaikki viestit" -kyselymerkkijono näytti tältä

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

ja se tulee näyttämään

$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 

Kukaan ei kiellä sinua ensin vastaanottamaan kaikki viestit, käsittelemään ne ja vasta onnistuneen käsittelyn jälkeen pyyntö vahvistamaton -> vahvistettu.

Miksi on järkevää soittaa vahvistukseen, kun kaikki käsittely on suoritettu? Epäonnistuminen on mahdollista kesken suorituksen, ja jos esimerkiksi ilmaisen chatbotin tapauksessa yksittäisen viestin puuttuminen ei ole mitään erityistä, niin jos käsittelet jonkun palkkaa tai korttitapahtumaa, tulos voi olla huonompi.

Pari koodiriviä lisää

$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. Päätelmän sijaan

Perustoiminnot - viestien lukeminen, jonon nollaus, tiedostosta lukeminen ja tiedostoon kirjoittaminen tehdään ja näytetään.

Tehtävänä on enää neljä asiaa:

  • lähettää oikean vastauksen pyyntöön chatissa
  • lähettämällä vastauksen KAIKKIIN chattiin, johon botti lisättiin
  • koodin suorittaminen silmukassa
  • botin käynnistäminen Windowsin ajastimesta.

Kaikki nämä tehtävät ovat yksinkertaisia, ja ne voidaan suorittaa helposti lukemalla dokumentaatio parametreista, kuten
Set-ExecutionPolicy Unrestricted ja -ExecutionPolicy Bypass
lomakkeen kierto

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

Kiitos kaikille jotka lukevat.

Lähde: will.com

Lisää kommentti