Powershell көмегімен 7-9 сынып оқушыларына арналған қарапайым телеграмма ботының үлгісі

Құрбыммен әңгімелесу барысында мен кенеттен олардың мектебінде 8-10 сыныптардағы балаларға бағдарламалауды мүлде оқытпайтынын білдім. Word, Excel және барлығы. Ешқандай логотип жоқ, тіпті Паскаль да, тіпті Excel үшін VBA да.

Мен қатты таң қалдым, интернетті ашып, оқи бастадым -
Мамандандырылған мектептің міндеттерінің бірі – даму деңгейі мен өмір салтына сәйкес ақпараттық қоғам шарттарына сай жаңа ұрпақты тәрбиелеуге ықпал ету.
Бұл курс студенттерге Паскаль программалау тілінің негізгі құрылымдары туралы білімдерін практикада бекітуге мүмкіндік береді. (кейбір гимназияның 2017 жылға арналған бағдарламасынан)

Соңында мен бір-екі сағатымды бөліп, «мектеп оқушыларына арналған қарапайым бот жасаудың» мысалын жасауды шештім.

Төменде Powershell-де тағы бір қарапайым ботты қалай жазу және оны веб-хуксыз, ақ IP-сіз, арнайы серверлерсіз, бұлтта орналастырылған виртуалды машиналарсыз және т.б. - кәдімгі Windows жүйесі бар кәдімгі үй компьютерінде қалай жұмыс істеуге болатындығы көрсетілген.

TLDR: Грамматикалық және фактологиялық қателері бар тағы бір қызықсыз мақала, оқылатын ештеңе жоқ, әзіл-оспақ, суреттер жоқ.

Мақалада жаңа ештеңе жоқ, бұрын жазылғандардың барлығы дерлік Хабреде болды, мысалы мақалаларда Нұсқаулар: Telegram-да боттарды қалай жасауға болады и Жүйе әкімшісіне арналған Telegram боты.
Оның үстіне мақала әр кезде оқу әдебиетіне сілтеме жасамас үшін әдейі артық. Мәтінде Gang 4, PowerShell Deep Dives немесе айталық, AWS Well-Architected Framework 5 тіректеріне сілтемелер жоқ.

Алғы сөздің орнына өткізіп жіберуге болады

Өткізіп жіберуге болады2006 жылы Microsoft корпорациясы сол кездегі Windows XP, Vista және Server 1.0 үшін PowerShell 2003 шығарды. Кейбір жолдармен ол cmdbat сценарийлері, vb сценарийлері, Windows Script Host және JScript сияқты нәрселерді ауыстырды.

Тіпті қазірдің өзінде PowerShell ілмектер, сыныптар, функциялар, MS GUI қоңыраулары, Git интеграциясы тағыда басқа.

Powershell салыстырмалы түрде сирек пайдаланылады; сіз оны тек PowerShell Core, VMware vSphere PowerCLI, Azure PowerShell, MS Exchange, қалаған күй конфигурациясы түрінде кездестіре аласыз, PowerShell веб қатынасы және ондаған немесе одан да көп сирек қолданылатын бағдарламалар мен функциялар. Мүмкін ол шығарылыммен екінші жел алады WSL2, бірақ бұл дәл емес.

Powershell-тің үш үлкен артықшылығы бар:

  1. Бұл салыстырмалы түрде қарапайым, бұл туралы көптеген әдебиеттер мен мысалдар бар, тіпті орыс тілінде, мысалы, Foreach туралы мақала - кітаптан PowerShell тереңдігі - () және {} айырмашылығы туралы
  2. Ол редактормен бірге жүреді ISE, Windows жүйесіне кіреді. Онда тіпті жөндеудің қандай да бір түрі бар.
  3. Одан қоңырау шалу оңай графикалық интерфейсті құруға арналған компоненттер.

0. Дайындық.

Бізге қажет:

  • Windows компьютері (менде Windows 10 бар)
  • Кем дегенде Интернетке кірудің қандай да бір түрі (мысалы, NAT арқылы)
  • Telegram-ға қолжетімділігі шектеулі адамдар үшін - браузерде орнатылған және конфигурацияланған фригейт, кейбір қиын жағдайларда, Symple DNS Crypt-пен бірге
  • Телефоныңызда жұмыс істейтін Telegram клиенті бар
  • Негіздерді түсіну - айнымалы, массив, цикл дегеніміз не.

Ашылған және оқылған мақалалар - Нұсқаулар: Telegram-да боттарды қалай жасауға болады и Жүйе әкімшісіне арналған Telegram боты

1. Басқа сынақ ботын жасайық.

Мұны бәрі бұрыннан білетін және бұрыннан болғандықтан, оны өткізіп жіберуге де боладыЖоғарыдағы мақалада айтылғандай - Біріншіден, Telegram-ға арналған бот - бұл әлі де сіздің тарапыңызда жұмыс істейтін және Telegram Bot API-ге сұраныс жасайтын қолданба. Сонымен қатар, API анық - бот параметрлері бар белгілі бір URL мекенжайына қол жеткізеді, ал Telegram JSON нысанымен жауап береді.

Қатысты мәселелер: егер сіз JSON нысанынан қандай да бір белгісіз жолмен кодты алып, оны орындауға жіберсеңіз (әдейі емес), код сіз үшін орындалады.

Жасау процесі жоғарыда екі мақалада сипатталған, бірақ мен қайталаймын: жеделхатта біз контактілерді ашамыз, @botfather іздейміз, оған /newbot айтамыз, Botfortest12344321 ботын жасаймыз, оны Mynext1234bot деп атаймыз және бірегей кілті бар хабарлама аламыз. пішін 1234544311:AbcDefNNNNNNNNNNNNNNNN

Кілтке қамқорлық жасаңыз және оны бермеңіз!

Содан кейін сіз ботты конфигурациялай аласыз, мысалы, оны топтарға қосуға тыйым саласыз, бірақ алғашқы қадамдарда бұл қажет емес.

BotFather-тен «/mybot» сұрап, бірдеңе ұнамаса, параметрлерді реттейік.

Контактілерді қайта ашайық, сол жерден @Botfortest12344321 табыңыз (іздеу @ арқылы бастау керек), «бастау» түймесін басып, ботқа «/Роботтарға даңқ» деп жазыңыз. / белгісі қажет, тырнақша қажет емес.
Бот, әрине, ештеңеге жауап бермейді.

Боттың жасалғанын тексеріп, оны ашайық.

api.telegram.org/bot1234544311:AbcDefNNNNNNNNNNNNNNNN/getMe
мұндағы 1234544311:AbcDefNNNNNNNNNNNNNN — бұрын алынған кілт,
сияқты жолды алыңыз
{"жарайды":шын,"нәтиже":{""}}

Бізде бірінші құпия сөз тіркесі (жетон). Енді біз екінші құпия нөмірді - ботпен сөйлесудің идентификаторын табуымыз керек. Әрбір чат, топ және т.б. жеке және өз нөмірі бар (кейде минуспен - ашық топтар үшін). Бұл нөмірді білу үшін браузерде (шын мәнінде бұл браузерде қажет емес, бірақ жақсырақ түсіну үшін одан бастауға болады) мекенжайды (мұндағы 1234544311:NNNNNNNNNN сіздің таңбалауышыңыз) сұрауымыз керек.

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

сияқты жауап алыңыз

{"жарайды":true,"нәтиже":[{"update_id":...,... сұхбат":{"id":123456789

Бізге chat_id керек.

Чатқа қолмен жаза алатынымызды тексерейік: браузерден мекенжайға қоңырау шалыңыз

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

Егер чатта боттан хабарлама алсаңыз, келесі кезеңге өтесіз.

Осылайша (браузер арқылы) сіз әрқашан сілтеме жасауда ақаулардың бар-жоғын тексере аласыз немесе бір жерде бір нәрсе жасырынып, жұмыс істемейтінін тексере аласыз.

Оқуды жалғастырмас бұрын нені білу керек

Telegram-да топтық чаттардың бірнеше түрі бар (ашық, жабық). Бұл чаттар үшін кейбір функциялар (мысалы, идентификатор) әртүрлі болады, бұл кейде кейбір қиындықтарды тудырады.

2019 жылдың соңы деп есептейік, тіпті біздің заманымыздың қаһарманы, белгілі Ман-Оркестр (әкімші, заңгер, ақпараттық қауіпсіздік бойынша маман, бағдарламашы және іс жүзінде MVP) Евгений В. $i айнымалысын массивтен ажыратады, ілмектерді игерді, келесі екі жылда шоколадты игереді, содан кейін қараңыз PowerShell көмегімен параллельді өңдеу и ForEach-Object Parallel келеді.

1. Біздің бот не істейтінін ойлаймыз

Менде ешқандай идея болмады, мен ойлануым керек еді. Мен бот-блокнот жазып қойғанмын. Мен «бірдеңе жіберетін» бот жасағым келмеді. Azure-ге қосылу үшін сізге несие картасы қажет, бірақ студент оны қайдан алады? Айта кету керек, бәрі соншалықты жаман емес: негізгі бұлттар қандай да бір сынақ мерзімін тегін береді (бірақ сізге әлі де несие картасының нөмірі қажет - және одан доллар дебеттелетін сияқты. Мен есімде жоқ. кейін қайтарылды.)

AI ML болмаса, бот-кедей-ақын-тоқымашы жасау соншалықты қызық емес.

Мен сөздіктегі ағылшын сөздерін есіме түсіретін (немесе маған емес) бот жасауды шештім.
Дерекқормен араласпау үшін сөздік мәтіндік файлда сақталады және қолмен жаңартылады.
Бұл жағдайда ең болмағанда ішінара дайын өнімді жасамай, жұмыстың негізін көрсету міндеті тұр.

2. Нені және қалай екенін бірінші рет сынап көру

C:poshtranslate қалтасын жасайық
Алдымен, бізде қандай Powershell бар екенін көрейік, ISE-ді start-run арқылы іске қосайық
powershell болса
немесе орнатылған бағдарламалардан Powershell ISE табыңыз.
Іске қосылғаннан кейін әдеттегі «редактордың қандай да бір түрі» ашылады, егер мәтіндік өріс болмаса, сіз әрқашан «Файл - жаңасын жасау» түймесін басуға болады.

Powershell нұсқасын қарастырайық - мәтіндік өріске жазыңыз:

get-host 

және F5 пернесін басыңыз.

Powershell сақтауды ұсынады - «Сіз іске қосылатын сценарий сақталады.», біз келісеміз және файлды C: poshtranslate атауымен powershell-дан сақтаймыз. 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 жоқ. Dos бар. Perl бар.)

Және GUI ішінен F5 немесе «>» пернесін басу арқылы кодты іске қосамыз.

Біз келесі нәтижені аламыз:

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"

Бақытымызға орай, бұрын жарияланған мақалада Telegram боты жүйелік әкімшіге арналған бұл жол (иә, $MyMessageGet.RawContent | сәйкес get-мүшесі 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) 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 

Көру оңай болғандай, MS өзінің логикасы бойынша ерекше ерекшеленбейді; ұқсас процедура үшін бір жағдайда -FilePath, екіншісінде -Path пайдаланылады.

Оған қоса, үшінші файлда орыс тілі жоғалып кетті, төртінші файлда ол шықты... жарайды, бірдеңе болды. #TYPE System.Object[] 00
# "Санау","Ұзындық","Ұзындық","Ранк","SyncRoot","Текоқу","FixedSize","Synchronized"
#
Оны аздап қайта жазайық:

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 арасындағы кездейсоқ бүтін санды алыңыз Get-Random -Maximum 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 және /hello боттарын жіберейік.
Бізде не бар екенін көрейік:

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

Алынғанның бәрін қарап шығып, хабарлама /сөз болса, жауап жіберейік
Кейбіреулер 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)}
            }
}

Сценарийді бірнеше рет іске қосайық. Әрбір орындау әрекеті үшін біз бір сөзді екі рет аламыз, әсіресе кездейсоқ әрекетті орындауда қателессек.

Бірақ тоқта. Біз /сөзді қайта жіберген жоқпыз, сондықтан хабар неге қайта өңделуде?

Ботқа хабарлама жіберу кезегі шекті ұзындыққа ие (менің ойымша, 100 немесе 200 хабарлама) және оны қолмен тазалау керек.

Бұл, әрине, құжаттамада сипатталған, бірақ сіз оны оқуыңыз керек!

Бұл жағдайда бізге ?chat_id параметрі қажет және &timeout, &limit, &parse_mode=HTML және &disable_web_page_preview=true әлі қажет емес.

үшін құжаттама telegram api осында
Ол ақ және ағылшын тілінде былай делінген:
Қайтарылатын бірінші жаңартудың идентификаторы. Бұрын алынған жаңартулардың идентификаторларының ішіндегі ең үлкенінен бір артық болуы керек. Әдепкі бойынша, жаңартулар ең ертеден басталады
расталмаған жаңарту қайтарылады. Жаңарту getUpdates арқылы шақырылғаннан кейін расталды деп саналады офсет жоғары оның update_id қарағанда. Теріс ығысуды жаңартулар кезегінің соңынан -offset жаңартуынан бастап жаңартуларды шығарып алу үшін көрсетуге болады. Барлық алдыңғы жаңартулар ұмытылады.

Қарап көрейік:

$Content4Pars01.result[0].update_id
$Content4Pars01.result[1].update_id 
$Content4Pars01.result | select -last 1
($Content4Pars01.result | select -last 1).update_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. Қорытындының орнына

Негізгі функциялар – хабарламаларды оқу, кезекті қалпына келтіру, файлдан оқу және файлға жазу орындалады және көрсетіледі.

Тек төрт нәрсе қалды:

  • чатта сұрауға дұрыс жауапты жіберу
  • бот қосылған кез келген чатқа жауап жіберу
  • циклде кодты орындау
  • windows жоспарлаушысынан ботты іске қосу.

Бұл тапсырмалардың барлығы қарапайым және сияқты параметрлер туралы құжаттаманы оқу арқылы оңай орындалады
Set-ExecutionPolicy шектеусіз және -ExecutionPolicy айналып өту
пішін циклі

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

Оқығандардың барлығына рахмет.

Ақпарат көзі: www.habr.com

пікір қалдыру