Modelo para un robot de telegrama sinxelo para escolares de 7º a 9º curso usando Powershell

Durante conversas cun amigo, de súpeto aprendín que aos nenos de 8º a 10º da escola non se lles ensina nada a programar. Word, Excel e todo. Sen logotipo, nin sequera Pascal, nin sequera VBA para Excel.

Sorprendeume moito, abrín Internet e comecei a ler...
Unha das tarefas dunha escola especializada é promover a educación dunha nova xeración que reúna as condicións da sociedade da información no seu nivel de desenvolvemento e estilo de vida.
Este curso permitirá aos estudantes consolidar na práctica os seus coñecementos sobre os construtos básicos da linguaxe de programación Pascal. (do programa dalgún ximnasio para 2017)

Ao final, decidín pasar un par de horas e esbozar un exemplo de "como crear un bot sinxelo para escolares".

Debaixo do corte está como escribir outro bot sinxelo en Powershell e facelo funcionar sen un webhook, IP brancas, servidores dedicados, máquinas virtuais despregadas na nube, etc., nun PC doméstico normal con Windows normal.

TLDR: Outro artigo aburrido con erros gramaticais e feitos, nada que ler, sen humor, sen imaxes.

Non hai nada novo no artigo, case todo o escrito antes xa estivo en Habré, por exemplo en artigos Instrucións: Como crear bots en Telegram и Bot de telegram para administrador de sistemas.
Ademais, o artigo é deliberadamente redundante para non referirse cada vez á literatura educativa. Non hai referencias a Gang 4, PowerShell Deep Dives ou, por exemplo, Os 5 alicerces do AWS Well-Architected Framework no texto.

En lugar dun prefacio, podes saltar

Non dubides en saltarEn 2006, Microsoft lanzou PowerShell 1.0 para os entón Windows XP, Vista e Server 2003. Dalgunha maneira, substituíu cousas como scripts cmdbat, scripts vb, Windows Script Host e JScript.

Aínda agora, PowerShell só pode considerarse como o seguinte paso despois das opcións do logotipo, en lugar do probablemente aínda usado Delphi (ou algo máis antigo), a pesar da presenza de bucles, clases, funcións, chamadas MS GUI, Integración Git e así por diante.

Powershell úsase relativamente raramente; só podes atopalo en forma de PowerShell Core, VMware vSphere PowerCLI, Azure PowerShell, MS Exchange, Desired State Configuration, Acceso web de PowerShell e unha ducia de programas e funcións pouco utilizados. Quizais teña un segundo vento co lanzamento WSL2, pero non é exactamente.

Powershell tamén ten tres grandes vantaxes:

  1. É relativamente sinxelo, hai moita literatura e exemplos sobre iso, e mesmo en ruso, por exemplo, un artigo sobre Foreach - do libro PowerShell en profundidade - sobre a diferenza () e {}
  2. Vai co editor ISE, incluído con Windows. Incluso hai algún tipo de depurador alí.
  3. É doado chamar desde el compoñentes para construír unha interface gráfica.

0. Preparación.

Necesitaremos:

  • PC con Windows (teño Windows 10)
  • Polo menos algún tipo de acceso a Internet (a través de NAT, por exemplo)
  • Para aqueles que teñan acceso limitado a Telegram - Freegate instalado e configurado no navegador, nalgúns casos difíciles, xunto con Symple DNS Crypt
  • Ter un cliente de Telegram funcionando no teu teléfono
  • Comprender os conceptos básicos: que é unha variable, unha matriz, un loop.

Artigos abertos e lidos - Instrucións: Como crear bots en Telegram и Bot de telegram para administrador de sistemas

1. Imos crear outro bot de proba.

Xa que todo o mundo xa o sabe, e xa pasou, tamén podes omitiloComo se indica no artigo anterior - En primeiro lugar, un bot para Telegram - aínda é unha aplicación que se executa ao teu lado e fai solicitudes á API de Telegram Bot. Ademais, a API é clara: o bot accede a un URL específico con parámetros e Telegram responde cun obxecto JSON.

Problemas relacionados: se dalgún xeito descoñecido tomas algún código dun obxecto JSON e envíao dalgún xeito para a súa execución (non a propósito), o código executarase por ti.

O proceso de creación descríbese en dous artigos anteriores, pero repito: nun telegrama abrimos contactos, buscamos @botfather, dicímoslle /newbot, creamos un bot Botfortest12344321, chamámoslle Mynext1234bot e recibimos unha mensaxe cunha clave única do formulario 1234544311:AbcDefNNNNNNNNNNNNNN

Coida a chave e non a regales!

Entón pode configurar o bot, por exemplo, prohibir engadilo a grupos, pero nos primeiros pasos isto non é necesario.

Pedímoslle a BotFather "/mybot" e axustemos a configuración se algo non nos gusta.

Abramos os contactos de novo, busque alí @Botfortest12344321 (é obrigatorio comezar a busca con @), prema en "iniciar" e escriba ao bot "/Gloria aos robots". O signo / é necesario, non se necesitan comiñas.
O bot, por suposto, non responderá nada.

Comprobamos que o bot foi creado e ábrémolo.

api.telegram.org/bot1234544311:AbcDefNNNNNNNNNNNNNN/getMe
onde 1234544311:AbcDefNNNNNNNNNNNNNN é a clave recibida anteriormente,
e obter unha liña como
{"ok":true,"result":{""}}

Temos a primeira frase secreta (token). Agora necesitamos descubrir o segundo número secreto: o ID do chat co bot. Cada chat, grupo, etc. é individual e ten o seu propio número (ás veces cun menos - para grupos abertos). Para coñecer este número, necesitamos solicitar no navegador (de feito, non é para nada necesario no navegador, pero para unha mellor comprensión pode comezar por el) o enderezo (onde 1234544311:NNNNNNNNNN é o seu token).

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

e obter unha resposta como

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

Necesitamos chat_id.

Comprobamos que podemos escribir ao chat manualmente: chamar ao enderezo desde o navegador

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

Se recibes unha mensaxe dun bot no teu chat, vale, pasas á seguinte fase.

Deste xeito (a través do navegador) sempre pode comprobar se hai problemas coa xeración de ligazóns, ou se algo está oculto nalgún lugar e non funciona.

O que debes saber antes de seguir lendo

Telegram ten varios tipos de chats grupais (abertos, pechados). Para estes chats, algunhas das funcións (por exemplo, id) son diferentes, o que ás veces provoca algúns problemas.

Supoñamos que é finais de 2019, e mesmo o heroe do noso tempo, o coñecido Man-Orchestra (administrador, avogado, especialista en seguridade da información, programador e practicamente MVP) Evgeniy V. distingue a variable $i dunha matriz, ten dominado loops, mira nos próximos dous anos vai dominar Chocolatey, e despois Procesamento paralelo con PowerShell и Paralelo de cada obxecto virá.

1. Pensamos no que fará o noso bot

Non tiña ideas, tiña que pensar. Xa escribín un bot-caderno. Non quería facer un bot "que envía algo a algún lugar". Para conectarse a Azure necesitas unha tarxeta de crédito, pero de onde a obtén o estudante? Cómpre sinalar que non todo está tan mal: as nubes principais dan algún tipo de período de proba de balde (pero aínda necesitas un número de tarxeta de crédito, e parece que se cargará un dólar. Non recordo se foi devolto máis tarde.)

Sen AI ML non é tan interesante facer un bot-pobre-poeta-tecedor.

Decidín facer un bot que me lembrará (ou non a min) palabras en inglés do dicionario.
Para evitar xogar coa base de datos, o dicionario almacenarase nun ficheiro de texto e actualizarase manualmente.
Neste caso, a tarefa é mostrar os fundamentos do traballo, e non facer polo menos un produto parcialmente acabado.

2. Probando que e como por primeira vez

Imos crear un cartafol C:poshtranslate
Primeiro, vexamos que tipo de powershell temos, imos lanzar ISE a través de start-run
powershell ise
ou busque Powershell ISE nos programas instalados.
Despois do lanzamento, abrirase o habitual "algún tipo de editor"; se non hai un campo de texto, sempre podes facer clic en "Ficheiro - crear novo".

Vexamos a versión de powershell - escriba no campo de texto:

get-host 

e prema F5.

Powershell ofrecerá gardar: "O script que está a piques de executar será gardado.", estamos de acordo e gardamos o ficheiro de powershell co nome en C: poshtranslate myfirstbotBT100.

Despois do lanzamento, na xanela de texto inferior obtemos unha táboa de datos:

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

Teño 5.1 algo, é suficiente. Se tes un Windows 7/8 antigo, non hai gran cousa, aínda que PowerShell terá que actualizarse á versión 5, por exemplo. instrucións.

Escriba Get-Date na liña de comandos a continuación, prema Intro, mire a hora, vai ao cartafol raíz co comando
cd
e limpar a pantalla co comando cls (non, non necesitas usar rm)

Agora imos comprobar o que funciona e como - imos escribir nin o código, pero dúas liñas, e tentar entender o que fan. Comentemos a liña con get-host co símbolo # e engademos un pouco.

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

(O interesante é que na lista despregable de formato de código de Habré hai dúas ducias de opcións, pero Powershell non está. Dos está aí. Perl está aí).

E imos executar o código premendo F5 ou ">" desde a GUI.

Obtemos a saída:

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

Agora vexamos estas dúas liñas e algúns puntos interesantes para non volver sobre isto no futuro.

A diferenza de Pascal (e non só), o propio PowerShell tenta determinar que tipo asignar a unha variable; máis detalles sobre isto están escritos no artigo Programa educativo sobre mecanografía en linguaxes de programación
Polo tanto, ao crear unha variable $TimeNow e asignándolle o valor da data e hora actual (Get-Date), non temos que preocuparnos demasiado polo tipo de datos que haberá.

É certo que esta ignorancia pode doer despois, pero iso é para máis tarde. Abaixo no texto haberá un exemplo.
A ver que conseguimos. Imos executar (na liña de comandos)

$TimeNow | Get-member

e obter unha páxina de texto incomprensible

Exemplo de texto incomprensible número 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")...                                         

Como podes ver, creouse unha variable do tipo TypeName: System.DateTime cunha chea de métodos (no sentido do que podemos facer con este obxecto variable) e propiedades.

Imos chamar $TimeNow.DayOfYear - obtemos o número do día do ano.
Imos chamar $TimeNow.DayOfYear | Get-Member - obtemos TypeName: System.Int32 e un grupo de métodos.
Imos chamar $TimeNow.ToUniversalTime() - e obtén a hora en UTC

Depurador

Ás veces ocorre que é necesario executar un programa ata unha determinada liña e ver o estado do programa nese momento. Para este fin, ISE ten unha función Depuración: alternar o punto de interrupción
Pon un punto de interrupción nalgún lugar do medio, executa estas dúas liñas e mira como se ve a interrupción.

3. Comprensión da interacción co bot de Telegram

Por suposto, aínda se escribiu máis literatura sobre a interacción co bot, con todo getpush e así por diante, pero o tema da teoría pódese considerar opcionalmente.

No noso caso é necesario:

  • Aprende a enviar algo por correspondencia
  • Aprende a obter algo da correspondencia

3.1 Aprender a enviar algo por correspondencia e recibir dela

Un pequeno código - parte 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

e na Federación Rusa neste momento aparece o erro Non se pode conectar ao servidor remoto.

Ou non o recibimos - depende do operador de telecomunicacións e de se o proxy está configurado e funciona
Ben, só queda engadir un proxy. Teña en conta que usar un proxy non cifrado e xeralmente fraudulento é extremadamente perigoso para a súa saúde.

A tarefa de atopar un proxy que funcione non é moi difícil: a maioría dos proxies http publicados funcionan. Creo que o quinto funcionou para min.

Sintaxe usando proxy:

Invoke-WebRequest -Uri $URL4SEND -Proxy $MyProxy

Se recibes unha mensaxe no teu chat cun bot, entón todo está ben, podes seguir adiante. Se non, continúa coa depuración.

Podes ver en que se converte a túa cadea $URL4SEND e tentar solicitala no navegador, así:

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

3.2. Aprendemos a escribir "algo" no chat, agora imos tentar lelo

Engadimos 4 liñas máis e vexamos o que hai dentro a través de | obter-membro

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

O máis interesante proporciónanos

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

A ver que hai neles:

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

Se todo funciona para ti, recibirás unha longa fila como:

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

Afortunadamente, no artigo publicado anteriormente Telegram bot para administrador do sistema esta liña (si, segundo $MyMessageGet.RawContent | get-member é System.String), xa foi desmantelada.

4. Procesa o que recibes (xa sabemos como enviar algo)

Como xa está escrito aquí, o máis necesario está no contido. Botámoslle unha ollada máis de cerca.

En primeiro lugar, escribiremos un par de frases máis para o bot desde a interface web ou desde o teléfono

/message1
/message2
/message3

e busque a través do navegador o enderezo que se formou na variable $URLGET.

Veremos algo así como:

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

Que é? Algúns obxectos complexos de matrices de obxectos que conteñen un identificador de mensaxe de extremo a extremo, identificador de chat, identificador de envío e moita outra información.

Non obstante, non necesitamos descubrir "que tipo de obxecto é este": parte do traballo xa se fixo por nós. A ver que hai dentro:

Lectura das mensaxes recibidas ou 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. Que debemos facer agora?

Imos gardar o ficheiro resultante co nome myfirstbotBT105 ou o que máis lle guste, cambie o título e comente todo o código xa escrito mediante

<#start comment 105 end comment 105#>

Agora necesitamos decidir onde obter o dicionario (ben, onde - no disco nun ficheiro) e como será.

Por suposto, podes escribir un dicionario enorme directamente no texto do guión, pero isto está completamente fóra do punto.
Entón, imos ver con que Powershell pode funcionar normalmente.
En xeral, non lle importa con que ficheiro traballar, non nos importa.
Temos unha opción: txt (podes, pero por que), csv, xml.
Podemos ver a todos? Vémonos a todos.
Imos crear unha clase MyVocabClassExample1 e unha variable $MyVocabExample1
Observo que a clase está escrita sen $

algún código #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

Imos tentar escribir isto en ficheiros usando mostra.

Algún código #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

- e obtemos un erro na liña Out-File -FilePath $MyFilenameExample01 -InputObject -Append $MyVocabExample2.

Non quere engadir, ah-ah, que mágoa.

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

A ver que pasa. Excelente vista de texto, pero como devolvelo? Debo introducir algún tipo de separadores de texto, como as comas?

E ao final obtén un "ficheiro de valores separados por comas (CSV) A PARA ESPERAR.
#

$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 

Como é fácil de ver, MS non se distingue especialmente pola súa lóxica; para un procedemento semellante, nun caso utilízase -FilePath, noutro -Path.

Ademais, no terceiro arquivo desapareceu a lingua rusa, no cuarto arquivo resultou... bueno, algo pasou. #TYPE Sistema.Obxecto[] 00
# "Count", "Lonxitude", "LongLength", "Rank", "SyncRoot", "IsReadOnly", "IsFixedSize", "IsSynchronized"
#
Imos reescribilo un pouco:

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

Parece que axudou, pero aínda non me gusta o formato.

Non me gusta especialmente que non podo poñer liñas dun obxecto nun ficheiro directamente.
Por certo, dende que comezamos a escribir en ficheiros, podemos comezar a manter un rexistro de inicio? Temos o tempo como variable, podemos establecer o nome do ficheiro.

É certo, aínda non hai nada que escribir, pero podes pensar na mellor forma de rotar os rexistros.
Imos probar xml por agora.

Algúns 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

Exportar a xml ten moitas vantaxes: lexibilidade, exportación de todo o obxecto e non é necesario realizar un cambio.

Imos probar ler ficheiro xml.

Unha pequena lectura de xml

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

Volvamos á tarefa. Escribimos un ficheiro de proba, lemos, o formato de almacenamento é claro, se é necesario, pode escribir un pequeno editor de ficheiros separado para engadir e eliminar liñas.

Permíteme lembrarche que a tarefa era facer un pequeno bot de adestramento.

Formato de traballo: mando o comando "exemplo" ao bot, o bot envíame unha palabra e unha transcrición seleccionadas ao azar, e despois de 10 segundos envíame unha tradución e un comentario. Sabemos ler comandos, tamén nos gustaría aprender a seleccionar e comprobar automaticamente os proxies e restablecer os contadores de mensaxes ao esquecemento.

Deixemos de comentar todo o comentado anteriormente como innecesario, comentemos os exemplos agora innecesarios con txt e csv e garde o ficheiro como versión B106

Ah si. Imos enviar algo ao bot de novo.

6. Envío desde funcións e moito máis

Antes de procesar a recepción, cómpre crear unha función para enviar "polo menos algo" que non sexa unha mensaxe de proba.

Por suposto, no exemplo só teremos un envío e só un procesamento, pero e se necesitamos facer o mesmo varias veces?

É máis doado escribir unha función. Entón, temos unha variable de tipo obxecto $MyVocabExample4AsArray, lida desde o ficheiro, en forma dunha matriz de ata dous elementos.
Imos ler.

Ao mesmo tempo, ocuparémonos do reloxo; necesitarémolo máis tarde (de feito, neste exemplo non o necesitaremos :)

Algún código #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
}

Como podes ver facilmente, a función chama $MyToken e $MyChatID, que foron codificados anteriormente.

Non é necesario facelo, e se $MyToken é un para cada bot, entón $MyChatID cambiará dependendo do chat.

Non obstante, dado que este é un exemplo, ignorarémolo por agora.

Dado que $MyVocabExample4AsArray non é unha matriz, aínda que é moi semellante a unha, entón non podes simplemente tomalo solicitar a súa duración.

Unha vez máis teremos que facer algo que non se pode facer -paracaídas non segundo o código- collelo e conta

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

acaso característica interesante. Digamos que queremos recibir 0 ou 1 (só temos dous elementos na matriz). Ao establecer límites 0..1, obteremos "1"?
non - non o conseguiremos, temos un exemplo especial. Exemplo 2: Obter un enteiro aleatorio entre 0 e 99 Get-Random -Máximo 100
Polo tanto, para 0..1 necesitamos establecer o tamaño 0..2, co número máximo de elementos = 1.

7. Procesamento de mensaxes entrantes e lonxitude máxima da fila

Onde paramos antes? temos a variable recibida $MyMessageGet
e $Content4Pars01 obtidos del, dos que nos interesan os elementos da matriz Content4Pars01.result

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

Imos enviar o bot /message10, /message11, /message12, /word e de novo /word e /hello.
A ver que temos:

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

Imos repasar todo o recibido e enviar unha resposta se a mensaxe era /word
o caso de construción, o que algúns describen como if-elseif, chámase en powershell mediante interruptor. Ao mesmo tempo, o seguinte código usa a clave -comodín, que é completamente innecesaria e mesmo prexudicial.

Algún código #7.1

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

Imos executar o guión un par de veces. Recibiremos a mesma palabra dúas veces para cada intento de execución, especialmente se cometemos un erro na implementación de aleatoria.

Pero para. Non volvemos a enviar /word, entón por que se está procesando de novo a mensaxe?

A cola para enviar mensaxes ao bot ten unha lonxitude finita (100 ou 200 mensaxes, creo) e hai que borrarse manualmente.

Isto, por suposto, descríbese na documentación, pero tes que lelo!

Neste caso, necesitamos o parámetro ?chat_id, e aínda non son necesarios &timeout, &limit, &parse_mode=HTML e &disable_web_page_preview=true.

Documentación para Telegram api está aquí
Di en branco e inglés:
Identificador da primeira actualización que se devolverá. Debe ser maior en un que o máis alto entre os identificadores das actualizacións recibidas anteriormente. Por defecto, as actualizacións comezan pola máis antiga
sen confirmar actualización son devoltos. Unha actualización considérase confirmada en canto se chame a getUpdates cun compensar máis alto que o seu update_id. A compensación negativa pódese especificar para recuperar actualizacións a partir de -offset update desde o final da cola de actualizacións. Todas as actualizacións anteriores serán esquecidas.

Vexamos:

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

Si, e restablecerémolo e reescribirémolo un pouco a función. Temos dúas opcións: pasar a mensaxe completa á función e procesala completamente na función, ou dar só o ID da mensaxe e restablecela. Por exemplo, o segundo parece máis sinxelo.

Anteriormente, parecía a nosa cadea de consulta "todas as mensaxes".

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

e parecerá

$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 

Ninguén che prohibe recibir primeiro todas as mensaxes, procesalas e só despois de procesar correctamente a solicitude sen confirmar -> confirmada.

Por que ten sentido confirmar a chamada despois de que se complete todo o procesamento? É posible un fallo no medio da execución, e se, por exemplo, un chatbot gratuíto, perder unha única mensaxe non é nada especial, entón se está a procesar o salario ou a transacción con tarxeta de alguén, o resultado pode ser peor.

Un par de liñas máis de código

$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. No canto dunha conclusión

As funcións básicas: ler mensaxes, restablecer a cola, ler desde o ficheiro e escribir nun ficheiro fanse e móstranse.

Só quedan catro cousas por facer:

  • enviando a resposta correcta a unha solicitude no chat
  • enviando unha resposta a CALQUERA chat ao que se engadiu o bot
  • executando código nun bucle
  • iniciar un bot desde o planificador de Windows.

Todas estas tarefas son sinxelas e pódense realizar facilmente lendo a documentación sobre parámetros como
Set-ExecutionPolicy Unrestricted e -ExecutionPolicy Bypass
ciclo da forma

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

Grazas a todos os que ledes.

Fonte: www.habr.com

Engadir un comentario