Шаблон за едноставен бот за телеграма за ученици од 7-9 одделение користејќи Powershell

За време на разговорите со еден пријател, одеднаш дознав дека децата од 8-10 одделение во нивното училиште воопшто не се учат програмирање. Word, Excel и се. Нема лого, дури ни Паскал, дури ни VBA за Excel.

Бев многу изненаден, отворив Интернет и почнав да читам -
Една од задачите на специјализираното училиште е да го промовира образованието на новата генерација која ги исполнува условите на информатичкото општество во неговото ниво на развој и начин на живот.
Овој курс ќе им овозможи на студентите во пракса да го консолидираат своето знаење за основните конструкции на програмскиот јазик Паскал. (од програмата на некоја гимназија за 2017 г.)

На крајот, решив да поминам неколку часа и да нацртам пример за „како да се создаде едноставен бот за ученици“.

Под сечењето е како да напишете уште еден едноставен бот во Powershell и да го направите да работи без веб-кука, бели IP-адреси, посветени сервери, распоредени виртуелни машини во облакот и така натаму - на обичен домашен компјутер со обичен Windows.

TLDR: Уште една досадна статија со граматички и фактички грешки, нема што да се чита, без хумор, без слики.

Нема ништо ново во статијата, скоро се што е напишано претходно веќе е на Хабре, на пример во статии Инструкции: Како да креирате ботови во Telegram и Телеграма бот за системски администратор.
Згора на тоа, написот е намерно вишок за да не се повикува секој пат на едукативна литература. Во текстот нема референци за Gang 4, PowerShell Deep Dives или, да речеме, 5-те столбови на добро архитектираната рамка AWS.

Наместо предговор, можете да прескокнете

Слободно прескокнетеВо 2006 година, Мајкрософт го објави PowerShell 1.0 за тогашните Windows XP, Vista и Server 2003 година. На некој начин, ги замени работи како cmdbat скрипти, vb скрипти, Windows Script Host и JScript.

Дури и сега, PowerShell може да се смета само како следен чекор по опциите Logo, наместо веројатно сè уште користениот Delphi (или нешто постаро), и покрај присуството на циклуси, класи, функции, повици за MS GUI, Git интеграција и така натаму.

Powershell се користи релативно ретко; можете да го сретнете само во форма на PowerShell Core, VMware vSphere PowerCLI, Azure PowerShell, MS Exchange, конфигурација на посакуваната состојба, PowerShell Web Access и десетина или повеќе ретко користени програми и функции. Можеби ќе добие втор ветер со ослободувањето WSL2, но не е баш.

Powershell исто така има три големи предности:

  1. Релативно е едноставно, има многу литература и примери за тоа, па дури и на руски, на пример, статија за Форич - од книгата PowerShell во длабочина - за разликата () и {}
  2. Тој оди со уредникот ИСЕ, вклучени со Windows. Има дури и некој вид дебагер таму.
  3. Лесно е да се јавите од него компоненти за градење на графички интерфејс.

0. Подготовка.

Ќе ни требаат:

  • Windows PC (имам Windows 10)
  • Барем некој вид на пристап до Интернет (преку NAT на пример)
  • За оние кои имаат ограничен пристап до телеграма - инсталиран и конфигуриран freegate во прелистувачот, во некои тешки случаи, заедно со Symple DNS Crypt
  • Имате работен клиент за телеграма на вашиот телефон
  • Разбирање на самите основи - што е променлива, низа, јамка.

Отворени и прочитани статии - Инструкции: Како да креирате ботови во Telegram и Телеграма бот за системски администратор

1. Ајде да создадеме уште еден тест бот.

Бидејќи сите веќе го знаат ова и веќе се случило, можете исто така да го прескокнетеКако што е наведено во написот погоре - Пред сè, бот за Телеграма - сè уште е апликација која работи на ваша страна и прави барања до Telegram Bot API. Покрај тоа, API е јасен - ботот пристапува до одредена URL адреса со параметри, а Telegram одговара со JSON објект.

Поврзани проблеми: ако на некој непознат начин земете некој код од објект JSON и некако го испратите на извршување (не намерно), кодот ќе биде извршен за вас.

Процесот на создавање е опишан во две статии погоре, но повторувам: во телеграма отвораме контакти, бараме @botfather, му кажуваме /newbot, креираме бот Botfortest12344321, го нарекуваме Mynext1234bot и добиваме порака со единствен клуч на форма 1234544311:AbcDefNNNNNNNNNNNNNN

Грижете се за клучот и не го давајте!

Потоа можете да го конфигурирате ботот, на пример, да забраните да го додавате во групи, но во првите чекори тоа не е потребно.

Ајде да побараме од BotFather „/mybot“ и да ги прилагодиме поставките ако нешто не ни се допаѓа.

Ајде повторно да ги отвориме контактите, таму да го најдеме @Botfortest12344321 (задолжително е да се започне пребарувањето со @), кликнете на „старт“ и напишете му на ботот „/Glory to the robots“. Знакот / е потребен, наводниците не се потребни.
Ботот, се разбира, нема да одговори ништо.

Ајде да провериме дали ботот е создаден и да го отвориме.

api.telegram.org/bot1234544311:AbcDefNNNNNNNNNNNNNN/getMe
каде што 1234544311:AbcDefNNNNNNNNNNNNNN е претходно примениот клуч,
и добијте линија како
{"ok":true,"result":{""}}

Ја имаме првата тајна фраза (токен). Сега треба да го дознаеме вториот таен број - ID на разговорот со ботот. Секој разговор, група и слично е индивидуален и има свој број (понекогаш со минус - за отворени групи). За да го дознаеме овој број, треба да ја побараме во прелистувачот (всушност, тоа воопшто не е потребно во прелистувачот, но за подобро разбирање можете да започнете со него) адресата (каде што 1234544311:NNNNNNNNNN е вашиот токен

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

и добијте одговор како

{"ok":true,"result":[{"update_id":...,... разговарате":{"ид":123456789

Ни треба chat_id.

Ајде да провериме дали можеме рачно да пишуваме на разговорот: јавете се на адресата од прелистувачот

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

Ако примите порака од бот во вашиот разговор, во ред, преминувате во следната фаза.

На овој начин (преку прелистувачот) секогаш можете да проверите дали има проблеми со генерирањето на врската или дали нешто е скриено некаде и не работи.

Што треба да знаете пред да продолжите да читате

Телеграма има неколку видови групни разговори (отворени, затворени). За овие разговори, некои од функциите (на пример, id) се различни, што понекогаш предизвикува некои проблеми.

Да претпоставиме дека е крајот на 2019 година, па дури и херојот на нашето време, добро познатиот Man-Orchestra (администратор, адвокат, специјалист за информациска безбедност, програмер и практично МВП) Евгениј В. ја разликува променливата $i од низа, има совладано јамки, погледнете во следните неколку години ќе го совладате Chocolatey, а потоа Паралелна обработка со PowerShell и Паралелно за секој-објект ќе дојде.

1. Размислуваме што ќе прави нашиот бот

Немав никакви идеи, морав да размислувам. Веќе напишав бот-тетратка. Не сакав да направам бот „кој испраќа нешто некаде“. За да се поврзете со Azure ви треба кредитна картичка, но од каде студентот ја добива? Треба да се напомене дека сè не е толку лошо: главните облаци даваат некаков тест период бесплатно (но сепак ви треба број на кредитна картичка - и се чини дека од него ќе се дебитира еден долар. Не се сеќавам дали подоцна беше вратено.)

Без AI ML не е толку интересно да се направи бот-сиромашен-поет-ткајач.

Решив да направам бот кој ќе ме потсетува (или не) на англиски зборови од речникот.
За да избегнете мешање со базата на податоци, речникот ќе се чува во текстуална датотека и ќе се ажурира рачно.
Во овој случај, задачата е да се прикажат основите на работата, а не да се направи барем делумно готов производ.

2. Пробување што и како за прв пат

Ајде да создадеме папка C:poshtranslate
Прво, да видиме каков вид на powershell имаме, ајде да го лансираме ISE преку start-run
powershell ise
или најдете Powershell ISE во инсталираните програми.
По лансирањето, ќе се отвори вообичаениот познат „некој вид уредувач“; ако нема поле за текст, тогаш секогаш можете да кликнете „Датотека - креирајте ново“.

Ајде да ја погледнеме верзијата на powershell - напишете во полето за текст:

get-host 

и притиснете F5.

Powershell ќе понуди зачувување - „Скриптата што ќе ја извршите ќе биде зачувана.“, се согласуваме и зачувајте ја датотеката од powershell со името во C: poshtranslate myfirstbotBT100.

По лансирањето, во долниот текстуален прозорец добиваме табела со податоци:

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

Имам 5.1 нешто, доста е. Ако имате стар Windows 7/8, тогаш нема голема работа - иако PowerShell ќе треба да се ажурира на верзијата 5 - на пр. инструкции.

Внесете Get-Date во командната линија подолу, притиснете Enter, погледнете го времето, одете во основната папка со командата
cd
и исчистете го екранот со командата cls (не, не треба да користите rm)

Сега да провериме што функционира и како - да не го напишеме дури ни кодот, туку два реда и да се обидеме да разбереме што прават. Ајде да ја коментираме линијата со get-host со симболот # и да додадеме малку.

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

(Она што е интересно е дека во паѓачката листа за форматирање на код на Habré има дваесетина опции - но Powershell го нема. Дос е таму. Перл е таму.)

Ајде да го извршиме кодот со притискање на F5 или „>“ од GUI.

Го добиваме следниот излез:

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

Сега да ги погледнеме овие две линии и некои интересни точки за да не се навраќаме на ова во иднина.

За разлика од Паскал (и не само), самиот PowerShell се обидува да одреди каков тип да додели на променлива; повеќе детали за ова се напишани во статијата Едукативна програма за пишување на програмски јазици
Затоа, со креирање на променлива $TimeNow и доделување на вредноста на тековниот датум и време (Get-Date), не мора да се грижиме премногу за тоа каков тип на податоци ќе има таму.

Навистина, ова незнаење може да боли подоцна, но тоа е за подоцна. Подолу во текстот ќе има пример.
Ајде да видиме што добивме. Ајде да извршиме (на командната линија)

$TimeNow | Get-member

и добијте страница со неразбирлив текст

Пример за неразбирлив текст број 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")...                                         

Како што можете да видите, променлива од типот TypeName: System.DateTime е создадена со еден куп методи (во смисла на тоа што можеме да направиме со оваа променлива објект) и својства.

Ајде да се јавиме $TimeNow.DayOfYear — го добиваме бројот на денот во годината.
Ајде да се јавиме $TimeNow.DayOfYear | Get-Member - добиваме TypeName: System.Int32 и група методи.
Ајде да се јавиме $TimeNow.ToUniversalTime() - и добијте време во UTC

Дебагерот

Понекогаш се случува да треба да се изврши програма до одредена линија и да се види состојбата на програмата во тој момент. За таа цел, ISE има функција Debug - префрли точка на прекин
Ставете точка на прекин некаде на средина, поминете ги овие две линии и видете како изгледа паузата.

3. Разбирање на интеракцијата со ботот Telegram

Се разбира, уште повеќе литература е напишана за интеракцијата со ботот, со сите getpush и така натаму, но прашањето на теоријата може да се разгледа опционално.

Во нашиот случај потребно е:

  • Научете да испраќате нешто во кореспонденција
  • Научете да добиете нешто од кореспонденцијата

3.1 Учење да испраќате нешто во кореспонденција и да примате од него

Мал код - дел 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

и во Руската Федерација во овој момент ја добиваме грешката Не можам да се поврзам со оддалечениот сервер.

Или не го добиваме - зависи од телекомуникацискиот оператор и дали проксито е конфигуриран и работи
Па, останува само да додадете прокси. Ве молиме имајте предвид - користењето нешифриран и генерално лажен прокси е крајно опасно за вашето здравје.

Задачата да се најде работен прокси не е многу тешка - повеќето од објавените http прокси работат. Мислам дека петтиот ми успеа.

Синтакса со помош на прокси:

Invoke-WebRequest -Uri $URL4SEND -Proxy $MyProxy

Ако примите порака во разговорот со бот, тогаш сè е во ред, можете да продолжите понатаму. Ако не, продолжете со дебагирање.

Можете да видите во што се претвора вашата низа $URL4SEND и да се обидете да ја побарате во прелистувачот, вака:

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

3.2. Научивме како да напишеме „нешто“ во разговорот, сега да се обидеме да го прочитаме

Ајде да додадеме уште 4 линии и да видиме што има внатре преку | добие-член

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

Најинтересното ни е обезбедено

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

Ајде да видиме што има во нив:

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

Ако сè работи за вас, ќе добиете долга линија како:

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

За среќа, во претходно објавената статија Телеграма бот за системски администратор оваа линија (да, според $MyMessageGet.RawContent | get-member е System.String), веќе е расклопен.

4. Обработете го она што го добивате (веќе знаеме како да испратиме нешто)

Како што е веќе напишано тука, најпотребните работи лежат во содржината. Ајде да го разгледаме подетално.

Прво, ќе напишеме уште неколку фрази на ботот од веб-интерфејсот или од телефонот

/message1
/message2
/message3

и погледнете низ прелистувачот на адресата што е формирана во променливата $URLGET.

Ќе видиме нешто како:

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

Што е тоа? Некои сложени објекти од низи објекти кои содржат идентификатор на порака од крај до крај, идентификатор за разговор, идентификатор за испраќање и многу други информации.

Сепак, не треба да откриеме „каков вид на објект е ова“ - дел од работата е веќе направена за нас. Ајде да видиме што има внатре:

Читање примени пораки или дел 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. Што треба да правиме во врска со тоа сега?

Да ја зачуваме добиената датотека под името myfirstbotBT105 или што и да ти се допаѓа најдобро, смени го насловот и коментирај го целиот веќе напишан код преку

<#start comment 105 end comment 105#>

Сега треба да одлучиме каде да го добиеме речникот (добро, каде - на диск во датотека) и како ќе изгледа.

Се разбира, можете да напишете огромен речник токму во текстот на сценариото, но ова е сосема надвор од поентата.
Значи, да видиме со што powershell може да работи нормално.
Всушност, нему не му е грижа со која датотека работи, а нам не ни е грижа.
Имаме избор: txt (можеш, но зошто), csv, xml.
Можеме ли да ги гледаме сите, да ги видиме сите.
Ајде да создадеме класа MyVocabClassExample1 и променлива $MyVocabExample1
Забележувам дека класата е напишана без $

некој код #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

Ајде да се обидеме да го напишеме ова во датотеки користејќи примерен.

Некој код #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

- и добиваме грешка на линијата Out-File -FilePath $MyFilenameExample01 -InputObject -Append $MyVocabExample2.

Тој не сака да додаде, ах-ах, каков срам.

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

Ајде да видиме што ќе се случи. Одличен приказ на текст - но како да го извезете назад? Дали треба да воведам некој вид раздвојувачи на текст, како запирки?

И на крајот добивате „датотека со вредности разделени со запирки (CSV) А СТОП ЗА ЧЕКАЊЕ.
#

$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 

Како што е лесно да се види, MS не се разликува особено по својата логика; за слична процедура, во еден случај се користи -FilePath, во друг - Path.

Дополнително, во третото досие рускиот јазик исчезна, во четвртиот досие испадна... па, нешто се случило. #TYPE систем.Објект[] 00
# „Брое“, „Должина“, „Долга должина“, „Ранг“, „Синхронизиран“, „Само за читање“, „Исфиксна големина“, „Е синхронизирано“
#
Ајде да го преработиме малку:

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

Се чини дека помогна, но сè уште не ми се допаѓа форматот.

Особено не ми се допаѓа што не можам директно да ставам линии од објект во датотека.
Патем, откако почнавме да пишуваме во датотеки, дали можеме да започнеме да водиме дневник за стартување? Имаме време како променлива, можеме да го поставиме името на датотеката.

Точно, сè уште нема што да се напише, но можете да размислите како најдобро да ги ротирате дневниците.
Ајде да пробаме xml за сега.

Некои 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 има многу предности - читливост, извоз на целиот објект и нема потреба да се врши надополнување.

Ајде да пробаме прочитајте xml датотека.

Малку читање од xml

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

Да се ​​вратиме на задачата. Напишавме тест-датотека, прочитајте ја, форматот за складирање е јасен, доколку е потребно, можете да напишете посебен мал уредувач на датотеки за додавање и бришење линии.

Да ве потсетам дека задачата беше да се направи мал тренинг бот.

Формат на работа: Ја испраќам командата „пример“ до ботот, ботот ми испраќа по случаен избор избран збор и транскрипција, а по 10 секунди ми испраќа превод и коментар. Знаеме како да читаме команди, исто така би сакале да научиме како автоматски да избираме и проверуваме прокси и да ги ресетираме бројачите на пораки во заборав.

Ајде да го декоментираме сето претходно коментирано како непотребно, да ги коментираме сега непотребните примери со txt и csv и да ја зачуваме датотеката како верзија B106

О, да. Ајде пак да испратиме нешто до ботот.

6. Испраќање од функции и многу повеќе

Пред да го обработите приемот, треба да креирате функција за испраќање „барем нешто“ освен тест порака.

Се разбира, во примерот ќе имаме само едно испраќање и само една обработка, но што ако треба да го направиме истото неколку пати?

Полесно е да се напише функција. Значи, имаме променлива од типот објект $MyVocabExample4AsArray, прочитана од датотеката, во форма на низа од дури два елементи.
Ајде да читаме.

Во исто време, ќе се справиме со часовникот; ќе ни треба подоцна (всушност, во овој пример нема да ни треба :)

Некој код #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
}

Како што можете лесно да видите, функцијата ги повикува $MyToken и $MyChatID, кои претходно беа хард-кодирани.

Нема потреба да го правите ова, и ако $MyToken е по еден за секој бот, тогаш $MyChatID ќе се промени во зависност од разговорот.

Меѓутоа, бидејќи ова е пример, засега ќе го игнорираме.

Бидејќи $MyVocabExample4AsArray не е низа, иако е многу слична на една, тогаш не можете само да го земете побарајте ја нејзината должина.

Уште еднаш ќе треба да направиме нешто што не може да се направи - падобран не според кодот - земете го и избројте

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

Случајно интересна карактеристика. Да речеме дека сакаме да добиеме 0 или 1 (имаме само два елементи во низата). Кога поставуваме граници 0..1, дали ќе добиеме „1“?
не - нема да го добиеме, имаме посебен пример Пример 2: Земете случаен цел број помеѓу 0 и 99 Земи-случаен -Максимум 100
Затоа, за 0..1 треба да ја поставиме големината 0..2, со максимален број на елемент = 1.

7. Обработка на дојдовни пораки и максимална должина на редот

Каде застанавме порано? ја имаме добиената променлива $MyMessageGet
и $Content4Pars01 добиени од него, од кои сме заинтересирани за елементите на низата Content4Pars01.result

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

Ајде да го испратиме ботот /message10, /message11, /message12, /word и повторно /word и /здраво.
Ајде да видиме што добивме:

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

Ајде да разгледаме се што е примено и да испратиме одговор ако пораката е /word
случајот на конструкција, она што некои го опишуваат како if-elseif, се нарекува во powershell преку прекинувач. Во исто време, кодот подолу го користи клучот -wildcard, кој е целосно непотребен, па дури и штетен.

Некој код #7.1

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

Ајде да го извршиме сценариото неколку пати. Ќе го добиеме истиот збор двапати за секој обид за извршување, особено ако сме направиле грешка во спроведувањето на случаен избор.

Но, застани. Повторно не испративме /word, па зошто пораката повторно се обработува?

Редот за испраќање пораки до ботот има конечна должина (мислам 100 или 200 пораки) и мора да се исчисти рачно.

Ова секако е опишано во документацијата, но мора да го прочитате!

Во овој случај, ни треба параметарот ?chat_id, а сè уште не се потребни &време, &ограничување, &parse_mode=HTML и &disable_web_page_preview=true.

Документација за api на телеграмата е тука
На бело и на англиски пишува:
Идентификатор на првото ажурирање што треба да се врати. Мора да биде поголем за еден од највисокиот меѓу идентификаторите на претходно примените ажурирања. Стандардно, ажурирањата почнуваат со најраните
непотврдено ажурирањето се враќа. Ажурирањето се смета за потврдено штом getUpdates се повика со офсет повисок од неговиот update_id. Негативното поместување може да се наведе за да се преземат ажурирања почнувајќи од -офсет ажурирање од крајот на редот за ажурирања. Сите претходни ажурирања ќе бидат заборавени.

Ајде да погледнеме во:

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

Да, и ќе го ресетираме и малку ќе ја преработиме функцијата. Имаме две опции - префрлете ја целата порака на функцијата и целосно обработете ја во функцијата или дајте само ID на пораката и ресетирајте ја. На пример, вториот изгледа поедноставен.

Претходно, нашата низа за пребарување „сите пораки“ изгледаше како

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

и ќе изгледа како

$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 

Никој не ви забранува прво да ги примате сите пораки, да ги обработувате и само по успешната обработка барањето непотврдено -> потврдено.

Зошто има смисла да се јави потврда откако ќе заврши целата обработка? Можен е неуспех во средината на извршувањето, и ако на пример на бесплатен чет-бот, пропуштањето на една порака не е ништо посебно, тогаш ако обработувате нечија плата или трансакција со картичка, резултатот може да биде полош.

Уште неколку линии код

$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. Наместо заклучок

Основни функции - читање пораки, ресетирање на редот, читање од датотека и пишување во датотека се направени и прикажани.

Остануваат само четири работи да се направат:

  • испраќање на точниот одговор на барање во разговор
  • испраќање одговор на СЕКОЈ чет на кој е додаден ботот
  • извршување на код во јамка
  • лансирање бот од распоредувачот на прозорци.

Сите овие задачи се едноставни и може лесно да се остварат со читање на документацијата за параметри како што се
Set-ExecutionPolicy Unrestricted и -ExecutionPolicy Bypass
циклус на формата

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

Ви благодариме на сите што прочитавте.

Извор: www.habr.com

Додадете коментар