Durante una conversazione con un amico, ho scoperto con sorpresa che nella loro scuola i ragazzi delle classi 8-10 non vengono affatto insegnati alla programmazione. Solo Word, Excel e... niente più. Niente Logo, né Pascal, né VBA per Excel.
Sono rimasto molto sorpreso, ho aperto internet e ho cominciato a leggere —
Uno degli obiettivi delle scuole specializzate è promuovere l'educazione di una nuova generazione che risponda, per il suo livello di sviluppo e stile di vita, alle esigenze della società dell'informazione.
Questo corso permetterà di applicare nella pratica le conoscenze degli studenti riguardo alle principali costrutti del linguaggio di programmazione Pascal. (da un programma di qualche ginnasio del 2017)
Alla fine ho deciso di spendere un paio d'ore per buttare giù un esempio di "come creare un semplice bot — per studenti".
Di seguito, come scrivere un ulteriore semplice bot in Powershell e farlo funzionare senza webhook, IP bianchi, server dedicati, macchine virtuali distribuite nel cloud e via dicendo — su un normale PC domestico con Windows comune.
TLDR: Un altro articolo noioso con errori grammaticali e fattuali, non c'è nulla da leggere, non ci sono battute, né immagini.
Non c'è nulla di nuovo nell'articolo, quasi tutto ciò che è scritto è già stato trattato su Habr, ad esempio negli articoli. e .
Inoltre, l'articolo è volutamente ridondante per evitare riferimenti costanti alla letteratura didattica. Non ci sono menzioni a Band 4, PowerShell Deep Dives o, ad esempio, The 5 Pillars of the AWS Well-Architected Framework nel testo.
Piuttosto che un'introduzione, si può saltare
Tranquillamente possiamo saltareNel 2006 Microsoft ha rilasciato PowerShell 1.0 per Windows XP, Vista e il server 2003. In un certo senso ha sostituito cose come gli script cmdbat, gli script vb, Windows Script Host e JScript.
Anche ora PowerShell può essere visto solo come il passo successivo dopo le varianti di Logo, invece di Delphi (o qualcosa di più vecchio) che sono probabilmente ancora in uso, nonostante abbia cicli, classi, funzioni e chiamate a MS GUI. e così via.
PowerShell è utilizzato relativamente raramente, lo si incontra al massimo come PowerShell Core, VMware vSphere PowerCLI, Azure PowerShell, MS Exchange, Desired State Configuration, e un'altra dozzina di programmi e funzionalità scarso utilizzo. Forse avrà una seconda vita con il rilascio , ma non è certo.
PowerShell ha anche tre grandi vantaggi:
- È relativamente semplice, ci sono molti materiali e esempi a riguardo, anche in russo, ad esempio un articolo su Foreach — dal libro — sulla differenza tra () e {}
- Viene fornito con l'editor , incluso con Windows. C'è anche un debugger integrato.
- È facile chiamare .
0. Preparazione.
Ciò che ci servirà:
- Un PC con Windows (io ho Windows 10)
- Qualche tipo di accesso a Internet (tramite NAT ad esempio)
- Per chi ha accesso limitato a Telegram — Freegate installato e configurato nel browser, in alcuni casi complessi insieme a Symple DNS Crypt
- Avere un client Telegram funzionante sul telefono
- Comprendere le basi — cosa sono le variabili, gli array, i cicli.
Articoli aperti e letti — e
1. Creiamo un altro bot di prova.
Poiché questo è già noto e già stato fatto, può essere saltato anche questo.Come indicato nell'articolo sopra — Prima di tutto, un bot per Telegram — è ancora un'applicazione eseguita dalla tua parte e che effettua richieste all'API di Telegram Bot. L'API è chiara — il bot si connette a un URL specifico con parametri, e Telegram risponde con un oggetto JSON.
Problemi correlati: se in qualche modo misterioso prendi un codice da un oggetto JSON e lo invii per l'esecuzione (non volontariamente) — il codice verrà eseguito.
Il processo di creazione è descritto in due articoli sopra, ma ripeto: apriamo i contatti su Telegram, cerchiamo @botfather, diciamo a lui /newbot, creeremo il bot Botfortest12344321, lo chiameremo Mynext1234bot e riceveremo un messaggio con una chiave unica del tipo 1234544311:AbcDefNNNNNNNNNNNNN.
Conserva la chiave e non ridistribuirla!
Dopo, puoi configurare il bot, ad esempio vietandone l'aggiunta ai gruppi, ma all'inizio non è necessario.
Chiederemo a BotFather «/mybot» e correggeremo le impostazioni se qualcosa non va.
Riapriamo i contatti, troviamo @Botfortest12344321 (iniziare la ricerca con @ è obbligatorio), premiamo «inizia» e scriviamo al bot «/GloryToRobots». Il segno / è obbligatorio, le virgolette non sono necessarie.
Il bot, ovviamente, non risponderà.
Controlliamo che il bot sia stato creato — apriamo.
:AbcDefNNNNNNNNNNNNN/getMe
dove 1234544311:AbcDefNNNNNNNNNNNNN è la chiave precedentemente ricevuta,
e riceveremo una stringa del tipo
{«ok»:true,«result»:{«»}}
Abbiamo la prima frase segreta (token). Ora dobbiamo scoprire il secondo numero segreto: l'ID della chat con il bot. Ogni chat, gruppo e così via sono unici e hanno il loro numero specifico (a volte con un segno meno — per i gruppi aperti). Per conoscere questo numero, dobbiamo richiedere al browser (in realtà non è necessario farlo nel browser, ma per una migliore comprensione, possiamo iniziare da lì) l'indirizzo (dove 1234544311:NNNNNNNNN è il tuo token)
https://api.telegram.org/bot1234544311:NNNNNNNNN/getUpdates
e ricevere una risposta del tipo
{«ok»:true,«result»:[{«update_id»:…,… chat«:{«id»:123456789
Abbiamo bisogno proprio di chat_id.
Verifichiamo che possiamo scrivere nella chat manualmente: richiamando dall'indirizzo del browser
https://api.telegram.org/botvostrotoken/sendMessage?chat_id=123456789&text="La vita è movimento diretto"Se hai ricevuto un messaggio dal bot nella tua chat — va bene, passerai al prossimo passo.
In questo modo (tramite il browser) puoi sempre verificare dove sono i problemi — se li hai durante la generazione del link, o se qualcosa è coperto e non funziona.
Cosa è necessario sapere prima di continuare a leggere
In Telegram esistono diversi tipi di chat di gruppo (aperte, chiuse). Per questi chat, alcune funzioni (ad esempio, l'id) variano, il che a volte causa alcuni problemi.
Immaginiamo che sia la fine del 2019 e che anche il nostro contemporaneo, il noto Uomo-Orchestra (amministratore, avvocato, specialista in sicurezza informatica, programmatore e praticamente MVP) Evgenij V. sappia distinguere la variabile $i da un array, abbia padroneggiato i cicli e, chissà, nei prossimi anni potrebbe anche familiarizzare con Chocolatey, e poi arriverà. e arriverà.
1. Pensiamo a cosa farà il nostro bot
Non avevo idee, quindi dovevo riflettere. Avevo già creato un bot per le note. Non mi interessava fare un bot 'che invia qualcosa da qualche parte'. Per collegarsi ad Azure è necessaria una carta di credito, ma come può averla uno studente? È importante notare che le grandi nuvole offrono un periodo di prova gratuito (ma è comunque necessaria una carta di credito — e sembra che verrà addebitato un dollaro. Non ricordo se poi è stato restituito.)
Senza AI, non è così interessante creare un bot strano e poetico.
Ho deciso di realizzare un bot che mi ricorderà (o non mi ricorderà) parole inglesi dal dizionario.
Il dizionario, per evitare di complicarmi con un database, sarà conservato in un file di testo e aggiornato manualmente.
In questo caso, l'obiettivo è mostrare le basi nel lavoro, non creare un prodotto anche solo parzialmente finito.
2. Proviamo tutto per la prima volta
Creiamo la cartella C:poshtranslate
Iniziamo a vedere che cos'è PowerShell; avviamo ISE tramite Esegui
powershell ise
oppure troviamo PowerShell ISE tra i programmi installati.
Dopo l'avvio si aprirà un normale editor familiare; se non c'è il campo di testo, puoi sempre cliccare su 'File — crea nuovo'.
Controlliamo la versione di PowerShell — scriviamo nel campo di testo:
get-host
e premiamo F5.
PowerShell suggerirà di salvare — 'Lo script che stai per eseguire verrà salvato.'; accettiamo e salviamo nella cartella C:poshtranslate il file da PowerShell con il nome myfirstbotBT100.
Dopo l'esecuzione, nella finestra di testo in basso otterremo una tabella di dati:
Nome : Windows PowerShell ISE Host
Versione : 5.1.(e così via)
Io ho 5.1 con qualche aggiornamento; va bene. Se hai Windows 7/8, non preoccuparti — anche se PowerShell deve essere aggiornato alla versione 5 — ad esempio, tramite .
Digita nella riga di comando sottostante Get-Date, premi Invio, controlla l'ora, poi vai alla cartella principale con il comando
cd
e pulisci lo schermo con il comando cls (no, non usare rm)
Ora verifichiamo cosa e come funziona — scriviamo non codice, ma solo due righe, e cerchiamo di capire cosa fanno. Commentiamo la riga con il simbolo get-host # e aggiungiamo qualche dettaglio.
# Пример шаблона бота
# get-host
<# это пример многострочного комментария #>
$TimeNow = Get-Date
$TimeNow
(Curiosamente, nella lista a discesa per il formato del codice su Habr ci sono una ventina di opzioni — ma non c'è PowerShell. C'è DOS. C'è Perl.)
E avviamo il codice premendo F5 o «>» dall'interfaccia grafica.
Otterremo l'output:
Sabato, 8 dicembre 2019 21:00:50 PM (o qualcosa del genere)
Ora analizziamo queste due righe e alcuni aspetti interessanti, per non doverci tornare sopra in seguito.
A differenza di Pascal (e non solo), PowerShell cerca di determinare autonomamente quale tipo assegnare a una variabile, ulteriori dettagli sono scritti nell'articolo
Pertanto, creando la variabile $TimeNow e assegnandole il valore della data e ora attuale (Get-Date), non dobbiamo preoccuparci eccessivamente di quale tipo di dato ci sarà.
Certo, questa ignoranza potrebbe causare problemi in seguito, ma questo è un altro discorso. Di seguito troverai un esempio.
Vediamo cosa abbiamo ottenuto. Eseguiamo (nel prompt dei comandi)
$TimeNow | Get-membere otterremo una pagina di testo misterioso.
Esempio di testo misterioso numero 1
PS C:> $TimeNow | Get-member
TypeName: System.DateTime
Name MemberType Definition
---- ---------- ----------
Aggiungi <b>Metodo </b>datetime Aggiungi(timespan valore)
..
DisplayHint NotaProprietà DisplayHintType DisplayHint=DateTime
Data <b>Proprietà </b>datetime Data {get;}
Anno Proprietà int Anno {get;}
..
DateTime ScriptProperty System.Object DateTime {get=if ((& { Set-StrictMode -Version 1; $this.DisplayHint }) -ieq "Data")...
Come vediamo, è stata creata una variabile di tipo TypeName: System.DateTime con una serie di metodi (nel senso che possiamo fare con questo oggetto variabile) e proprietà.
Chiamiamo $TimeNow.DayOfYear — otterremo il numero del giorno dell'anno.
Chiamiamo $TimeNow.DayOfYear | Get-Member — otterremo TypeName: System.Int32 e un insieme di metodi.
Chiamiamo $TimeNow.ToUniversalTime() — e otterremo l'orario in UTC.
Debugger
A volte è necessario eseguire il programma fino a una certa riga e vedere lo stato del programma in quel momento. A tal fine, in ISE c'è la funzione Debug — toggle break point.
Imposta un punto di interruzione a metà, esegui queste due righe e guarda come appare l'interruzione.
3. Approfondiamo l'interazione con il bot di Telegram.
Certo, ci sono molti più materiali scritti riguardo all'interazione con il bot, con tutte le getpush e così via, tuttavia la questione della teoria può essere considerata facoltativa.
Nel nostro caso è necessario:
- Imparare a inviare qualcosa nella chat
- Imparare a ricevere qualcosa dalla chat
3.1 Impariamo a inviare qualcosa nella chat e ricevere da essa
Un po' di codice — parte 3
Scrivi-output "Questa è la parte 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 = "La vita è un movimento diretto - " + $TimeNow
$URL4SEND = "https://api.telegram.org/bot$MyToken/sendMessage?chat_id=$MyChatID&text=$MyText01"
Invoke-WebRequest -Uri $URL4SEND
e in RF in questo punto otteniamo un errore Unable to connect to the remote server.
Oppure non lo otteniamo — dipende dall'operatore di rete e se il proxy è impostato e funziona.
Bene — rimane da aggiungere il proxy. Tieni presente che l'uso di proxy non crittografati e in generale di proxy sconosciuti è estremamente pericoloso per la tua salute.
Il compito di trovare un proxy funzionante non è molto difficile — la maggior parte dei proxy http pubblicati funziona. A me ha funzionato sembrerebbe il quinto per numero.
Sintassi utilizzando un proxy:
Invoke-WebRequest -Uri $URL4SEND -Proxy $MyProxy
Se hai ricevuto un messaggio nella tua chat con il bot — tutto è eccellente, puoi andare oltre. Se no — continua il debug.
Puoi vedere in cosa si trasforma la tua stringa $URL4SEND e provare a richiederla nel browser, ad esempio in questo modo:
$URL4SEND2 = '"'+$URL4SEND+'"'
start chrome $URL4SEND2
3.2. Abbiamo imparato a scrivere "qualcosa" in chat, ora proviamo a leggere
Aggiungiamo altre 4 righe e vediamo cosa c'è dentro tramite | get-member
$URLGET = "https://api.telegram.org/bot$MyToken/getUpdates"
$MyMessageGet = Invoke-WebRequest -Uri $URLGET -Method Get -Proxy $MyProxy
Write-Host "Get-Member"
$MyMessageGet | Get-Member
Le cose più interessanti sono fornite da
Content Property string Content {get;}
ParsedHtml Property mshtml.IHTMLDocument2 ParsedHtml {get;}
RawContent Property string RawContent {get;set;}Vediamo cosa c'è al suo interno:
Write-Host "ParsedHtml"
$MyMessageGet.ParsedHtml # qui ci sono cose interessanti
Write-Host "RawContent"
$MyMessageGet.RawContent # e qui ci sono cose interessanti, ma anche leggibili.
Write-Host "Content"
$MyMessageGet.Content
Se tutto funziona, riceverai una lunga stringa del tipo:
{"ok":true,"result":[{"update_id":12345678,
"message":{"message_id":3,"from":{"id"Fortunatamente, in un precedente articolo sul bot di Telegram per sistemisti, questa riga (sì, secondo $MyMessageGet.RawContent | get-member — è System.String), è già stata analizzata.
4. Elaborare il ricevuto (già sappiamo come inviare qualcosa)
Come già scritto , il più necessario si trova in content. Diamo un'occhiata più da vicino.
Iniziamo a scrivere al bot alcune frasi dal web interface o dal telefono
/message1
/message2
/message3e guardiamo attraverso il browser all'indirizzo formato nella variabile $URLGET.
Vedremo qualcosa del tipo:
{"ok":true,"result":[{"update_id":NNNNNNN,
"message":{"message_id":10, .. "text":"/message1"
"message":{"message_id":11, .. "text":"/message2
"message":{"message_id":12, .. "text":"/message3 Che cos'è? Un oggetto complesso composto da array di oggetti, contenente un identificatore univoco del messaggio, l'identificatore della chat, l'identificatore dell'invio e molte altre informazioni.
Tuttavia, non è necessario analizzare "che cos'è questo oggetto" — parte del lavoro è già stata svolta per noi. Diamo un'occhiata a cosa c'è dentro:
Lettura dei messaggi ricevuti o parte 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. Cosa dobbiamo fare ora con questo
Salviamo il file ricevuto con il nome myfirstbotBT105 o qualsiasi altro nome preferiate, cambiamo il titolo e commentiamo tutto il codice già scritto attraverso
<#start comment 105 end comment 105#>
Ora dobbiamo decidere dove prendere il dizionario (inteso dove — sul disco in un file) e come sarà strutturato.
Certo, si può creare un enorme dizionario direttamente nel testo dello script, ma non è affatto l'ideale.
Quindi vediamo a cosa può lavorare nativamente PowerShell.
In realtà, non gli importa quale file stia elaborando, ma importa a noi.
Le opzioni disponibili sono: txt (si può, ma perché farlo?), csv, xml.
Possiamo vedere tutti? Diamo un'occhiata a tutti.
Creiamo la classe MyVocabClassExample1 e la variabile $MyVocabExample1
Nota che la classe si scrive senza $
un po' di codice #5
write-host "Questo è il pezzo 5"
class MyVocabClassExample1 {
[string]$Original # parola
[string]$Transcript
[string]$Translate
[string]$Example
[int]$VocWordID # aspetto molto interessante. L'uso di int con le sue limitazioni può talvolta portare a conseguenze strane, come nel recente caso con SSD HPE. Inizialmente non avevo aggiunto questo elemento, poi alla fine l'ho aggiunto e commentato.
}
$MyVocabExample1 = [MyVocabClassExample1]::new()
$MyVocabExample1.Original = "Apple"
$MyVocabExample1.Transcript = "[ ˈapəl ]"
$MyVocabExample1.Translate = "Mela"
$MyVocabExample1.Example = "Una mela è un frutto dolce e commestibile prodotto da un melo (Malus domestica)"
# $MyVocabExample1.$VocWordID = 1
$MyVocabExample2 = [MyVocabClassExample1]::new()
$MyVocabExample2.Original = "Pear"
$MyVocabExample2.Transcript = "[ pe(ə)r ]"
$MyVocabExample2.Translate = "Pera"
$MyVocabExample2.Example = "Il pero (/ˈpɛər/) e l'arbusto sono una specie del genere Pyrus"
# $MyVocabExample1.$VocWordID = 2
Proviamo a scrivere questo in file. .
Un po' di codice #5.1
Write-Host $ScriptDir # spero che non abbiate commentato $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
— e avremo un errore alla riga Out-File -FilePath $MyFilenameExample01 -InputObject -Append $MyVocabExample2.
Non vuole aggiungere, che disdetta.
$MyVocabExample3AsArray = @($MyVocabExample1,$MyVocabExample2)
Out-File -FilePath $MyFilenameExample02 -InputObject $MyVocabExample3AsArray
notepad $MyFilenameExample02
Vediamo cosa è uscito. Bel formato di testo — ma come esportarlo di nuovo? Dobbiamo inserire dei separatori di testo, come le virgole?
E alla fine ottenere «un file con separatori — virgole, comma-separated values (CSV) A .
#
$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
È facile vedere, MS non si è particolarmente distinta nella logica, per una procedura simile in un caso si usa -FilePath, nell'altro -Path.
Inoltre, in questo terzo file è scomparso il russo, nel quarto file è uscito... beh, qualcosa è uscito. #TYPE System.Object[] 00
# „Count“,»Length»,«LongLength»,«Rank»,«SyncRoot»,«IsReadOnly»,«IsFixedSize»,«IsSynchronized»
#
Riorganizziamo un po':
Export-Csv -Path $MyFilenameExample03 -InputObject $MyVocabExample1 -Encoding Unicode
Export-Csv -Path $MyFilenameExample03 -InputObject $MyVocabExample2 -Append -Encoding Unicode
notepad $MyFilenameExample03
notepad $MyFilenameExample04
Sembra che funzioni — ma il formato non mi piace comunque.
Particolarmente non mi piace che non posso scrivere direttamente le righe dall'oggetto nel file.
A proposito, visto che abbiamo iniziato a scrivere nei file — perché non iniziare anche a tenere un log di avvio? Abbiamo il tempo come variabile e sappiamo come impostare il nome del file.
Non c'è molto da scrivere per ora, ma possiamo pensare a come gestire meglio la rotazione dei log.
Proviamo per ora con xml.
Un po' di 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
L'esportazione in xml ha solo vantaggi — leggibilità, esportazione dell'intero oggetto, e non c'è bisogno di effettuare l'append.
Proviamo .
Un po' di lettura da xml
$MyFilenameExample06 = $ScriptDir + "Example06.xml"
$MyVocabExample4AsArray = Import-Clixml -Path $MyFilenameExample06
# $MyVocabExample4AsArray
# $MyVocabExample4AsArray[0]
# e un po' sui particolari che non sono affatto ovvi. Powershell a volte si comporta in modo inaspettato.
# ad esempio, queste due uscite sono diverse
# Write-Output $MyVocabExample4AsArray
# write-host $MyVocabExample4AsArray
Torniamo al compito. Abbiamo registrato e letto il file di prova, il formato di archiviazione è chiaro; se necessario, possiamo scrivere un piccolo editor separato per aggiungere e rimuovere righe.
Ricordo che il compito era creare un piccolo bot educativo.
Formato di lavoro: io invio al bot il comando “esempio”, il bot mi invia una parola scelta a caso e la trascrizione e, dopo 10 secondi, invia la traduzione e un commento. Sappiamo leggere i comandi, sarebbe bello anche riuscire a selezionare e verificare automaticamente i proxy e resettare i contatori dei messaggi nell'oblio.
Decommentiamo tutto ciò che avevamo precedentemente commentato come superfluo, commentiamo gli esempi diventati inutili con txt e csv e salviamo il file come versione B106.
Ah, giusto. Inviamo qualcosa al bot di nuovo.
6. Invio da funzioni e non solo
Prima di elaborare la ricezione, è necessario creare una funzione per inviare "qualcosa", oltre al messaggio di prova.
Certo, nel nostro esempio ci sarà solo un invio e una sola elaborazione, ma se dovessimo ripetere la stessa operazione più volte?
È più semplice scrivere una funzione. Quindi, abbiamo una variabile di tipo oggetto $MyVocabExample4AsArray, letta da un file, sotto forma di array con due elementi.
Allo stesso tempo, facciamo chiarezza su come funzionano gli orari, ci servirà dopo (in realtà, in questo esempio non sarà necessario 🙂
Un po' di codice #6.1
Write-Output "This is Part 6"
$Timezone = (Get-TimeZone)
IF($Timezone.SupportsDaylightSavingTime -eq $True){
$TimeAdjust = ($Timezone.BaseUtcOffset.TotalSeconds + 3600) } # tempo corretto
ELSE{$TimeAdjust = ($Timezone.BaseUtcOffset.TotalSeconds)
}
function MyFirstFunction($SomeExampleForFunction1){
$TimeNow = Get-Date
$TimeNow.ToUniversalTime()
# $MyText02 = $TimeNow + " " + $SomeExampleForFunction1 # e qui otteniamo un errore
$MyText02 = $SomeExampleForFunction1 + " " + $TimeNow # e qui non, chi lo indovina - è bravo.
$URL4SendFromFunction = "https://api.telegram.org/bot$MyToken/sendMessage?chat_id=$MyChatID&text=$MyText02"
Invoke-WebRequest -Uri $URL4SendFromFunction -Proxy $MyProxy
}
Come è facile notare, nella funzione vengono chiamati $MyToken e $MyChatID, che sono stati assegnati in modo statico in precedenza.
Questo non dovrebbe essere fatto e, se $MyToken è uno per ogni bot, allora $MyChatID cambierà a seconda della chat.
Tuttavia, poiché questo è un esempio, per ora lo ignoreremo.
Dato che $MyVocabExample4AsArray non è un array, anche se molto somiglia a uno, non può semplicemente essere preso e richiesta la sua lunghezza.
Dovremo ancora una volta fare qualcosa che non si dovrebbe fare: atterrare non secondo il codice, prendere e contare
Un po' di codice #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)
# oppure in una sola riga
# MyFirstFunction($MyVocabExample4AsArray[Get-Random -Minimum 0 -Maximum ($MaxRandomExample -1)].Example)
# Indovinate voi stessi, quale esempio è più facile da leggere per le persone estranee.
Random . Supponiamo di voler ottenere 0 o 1 (abbiamo solo due elementi nell'array). Impostando i limiti 0..1 — otterremo "1"?
no — non lo otterremo, abbiamo specificamente fornito l'esempio Example 2: Ottieni un intero casuale tra 0 e 99 Get-Random -Maximum 100
Pertanto, per 0..1 dobbiamo impostare la dimensione su 0..2, con il numero massimo di elementi = 1.
7. Elaborazione dei messaggi ricevuti e lunghezza massima della coda
Da cosa eravamo rimasti? Abbiamo la variabile ricevuta $MyMessageGet
e quella estratta $Content4Pars01, di cui ci interessano gli elementi dell'array Content4Pars01.result
$Content4Pars01.result[0].update_id
$Content4Pars01.result[0].message
$Content4Pars01.result[0].message.text Invieremo al bot /message10, /message11, /message12, /word e di nuovo /word e /ciao.
Diamo un'occhiata a cosa abbiamo ricevuto:
$Content4Pars01.result[0].message.text
$Content4Pars01.result[2].message.text Esamineremo tutto il ricevuto e invieremo una risposta, se il messaggio era /word
la struttura case of, che alcuni descrivono come if-elseif, in PowerShell viene chiamata . Nel codice qui sotto è stata utilizzata l'opzione -wildcard, che non è affatto necessaria e può anche essere dannosa.
Un po' di codice #7.1
Write-Output "This is part 7"
Foreach ($Result in $Content4Pars01.result) # Sì, si può fare più veloce
{
switch -wildcard ($Result.message.text)
{
"/word" {MyFirstFunction($TextForExample1)}
}
}
Eseguiamo lo script un paio di volte. Otterremo la stessa parola due volte ad ogni tentativo di esecuzione, soprattutto se ci siamo sbagliati nella realizzazione del random.
Ma aspetta. Non abbiamo inviato /word di nuovo, perché il messaggio viene elaborato di nuovo?
La coda per inviare messaggi al bot ha una lunghezza massima (sembra, 100 o 200 messaggi), e deve essere svuotata manualmente.
La documentazione ne parla, ma bisogna leggerla!
In questo caso abbiamo bisogno del parametro ?chat_id, mentre &timeout, &limit, &parse_mode=HTML e &disable_web_page_preview=true non sono ancora necessari.
La documentazione su In inglese c'è scritto:
Identifier of the first update to be returned. Must be greater by one than the highest among the identifiers of previously received updates. By default, updates starting with the earliest
unconfirmed update are returned. An update is considered confirmed as soon as getUpdates is called with an offset higher than its update_id. The negative offset can be specified to retrieve updates starting from -offset update from the end of the updates queue. All previous updates will forgotten.
Guardiamo a:
$Content4Pars01.result[0].update_id
$Content4Pars01.result[1].update_id
$Content4Pars01.result | select -last 1
($Content4Pars01.result | select -last 1).update_idE riscriviamo: cambia un po' la funzione. Abbiamo due opzioni: passare all funzione l'intero messaggio e gestirlo completamente, oppure fornire solo l'ID del messaggio e resettarlo. Per esempio, la seconda opzione sembra più semplice.
In passato, la stringa di richiesta di "tutti i messaggi" era scritta come
$URLGET = "https://api.telegram.org/bot$MyToken/getUpdates"e sarà scritta come
$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
Nessuno impedisce di ricevere prima tutti i messaggi, elaborarli e solo dopo, con elaborazione avvenuta con successo, richiedere unconfirmed -> confirmed.
Perché ha senso richiamare la conferma dopo aver completato tutte le elaborazioni? Potrebbe verificarsi un errore a metà esecuzione e, se per esempio l'assenza di un singolo messaggio in un chatbot gratuito non è un grande problema, se stai elaborando uno stipendio o una transazione con carta, il risultato potrebbe essere peggiore.
Ancora un paio di righe di codice
$LastMessageId = ($Content4Pars01.result | select -last 1).update_id #l'errore in questo punto si presume debba essere corretto autonomamente.
$URLGET1 = "https://api.telegram.org/bot$mytoken/getUpdates?offset=$LastMessageId&limit=100"
Invoke-WebRequest -Uri $URLGET1 -Method Get -Proxy $MyProxy
8. Invece di una conclusione
Le funzioni principali—lettura dei messaggi, azzeramento della coda, lettura e scrittura da un file sono completate e dimostrate.
Resta da fare solo quattro cose:
- inviare la risposta corretta alla richiesta in chat
- inviare la risposta in QUALSIASI chat a cui è stato aggiunto il bot
- eseguire il codice in un ciclo
- avviare il bot dall'Utilità di pianificazione di Windows.
Tutti questi compiti sono semplici e facilmente realizzabili leggendo la documentazione su parametri come
Set-ExecutionPolicy Unrestricted e -ExecutionPolicy Bypass
ciclo di tipo
$TimeToSleep = 3 # polling ogni 3 secondi
$TimeToWork = 10 # minuti
$HowManyTimes = $TimeToWork*60/$TimeToSleep # contatore per il ciclo
$MainCounter = 0
for ($MainCounter=0; $MainCounter -le $HowManyTimes) {
sleep $TimeToSleep
$MainCounter ++
Grazie a tutti coloro che sono arrivati fin qui.
Fonte: habr.com
