Powershell-dan foydalangan holda 7-9-sinf o'quvchilari uchun oddiy telegram bot uchun shablon

Do‘stim bilan suhbat chog‘ida birdan bilib qoldimki, ularning maktabida 8-10-sinf o‘quvchilariga dasturlash umuman o‘rgatilmaydi. Word, Excel va hamma narsa. Logotip yo'q, hatto Paskal ham, Excel uchun VBA ham yo'q.

Очень удивился, открыл интернет и полез читать —
Ixtisoslashtirilgan maktabning vazifalaridan biri axborot jamiyatining rivojlanish darajasi va turmush tarziga mos keladigan yangi avlodni tarbiyalashga ko'maklashishdir.
Ushbu kurs talabalarga Paskal dasturlash tilining asosiy konstruksiyalari haqidagi bilimlarini amalda mustahkamlash imkonini beradi. (ba'zi gimnaziyaning 2017 yil uchun dasturidan)

Oxir-oqibat, men bir necha soat vaqt ajratishga qaror qildim va "maktab o'quvchilari uchun oddiy botni qanday yaratish kerak" misolini chizishga qaror qildim.

Quyida Powershell-da yana bir oddiy botni qanday yozish va uni veb-huksiz, oq IP-lar, ajratilgan serverlar, bulutda o'rnatilgan virtual mashinalar va hokazolarsiz - oddiy Windows-ga ega oddiy uy kompyuterida qanday ishlashi mumkinligi ko'rsatilgan.

TLDR: Grammatik va faktik xatolar bilan yana bir zerikarli maqola, o'qish uchun hech narsa, hazil va rasmlar yo'q.

Maqolada hech qanday yangilik yo'q, ilgari yozilgan deyarli hamma narsa Habré-da, masalan, maqolalarda bo'lgan Ko'rsatmalar: Telegramda botlarni qanday yaratish kerak и Tizim administratori uchun telegram bot.
Bundan tashqari, maqola har safar o'quv adabiyotlariga murojaat qilmaslik uchun ataylab ortiqcha. Matnda Gang 4, PowerShell Deep Dives yoki, aytaylik, AWS Well-Architected Framework ning 5 ta ustuniga havolalar mavjud emas.

Muqaddima o'rniga, o'tkazib yuborishingiz mumkin

Bemalol o'tkazib yuboring2006 yilda Microsoft o'sha paytdagi Windows XP, Vista va Server 1.0 uchun PowerShell 2003 ni chiqardi. Qaysidir ma'noda u cmdbat skriptlari, vb skriptlari, Windows Script Host va JScript kabi narsalarni almashtirdi.

Hatto hozir ham PowerShell-ni faqat logotip parametrlaridan keyingi qadam sifatida ko'rib chiqish mumkin, ehtimol hali ham ishlatilgan Delphi (yoki eskiroq narsa) o'rniga, looplar, sinflar, funktsiyalar, MS GUI qo'ng'iroqlari, Git integratsiyasi va hokazo.

Powershell nisbatan kamdan-kam qo'llaniladi; siz uni faqat PowerShell Core, VMware vSphere PowerCLI, Azure PowerShell, MS Exchange, Desired State Configuration ko'rinishida uchratishingiz mumkin, PowerShell Internetga kirish va o'nlab yoki undan ko'proq kamdan-kam ishlatiladigan dastur va funktsiyalar. Ehtimol, u ozod qilish bilan ikkinchi shamolni oladi WSL2, lekin bu aniq emas.

Powershell ham uchta katta afzalliklarga ega:

  1. Bu nisbatan sodda, bu haqda ko'plab adabiyotlar va misollar mavjud va hatto rus tilida, masalan, Foreach haqidagi maqola - kitobdan Chuqurlikdagi PowerShell - () va {} farqi haqida
  2. U muharrir bilan boradi İMKB, Windows bilan birga. U erda hatto tuzatuvchining bir turi mavjud.
  3. Undan qo'ng'iroq qilish oson grafik interfeysni yaratish uchun komponentlar.

0. Tayyorgarlik.

Biz kerak bo'ladi:

  • Windows kompyuteri (menda Windows 10 bor)
  • Hech bo'lmaganda Internetga kirish (masalan, NAT orqali)
  • Telegram-dan foydalanish imkoniyati cheklanganlar uchun - brauzerda o'rnatilgan va sozlangan freegate, ba'zi qiyin holatlarda, Symple DNS Crypt bilan birga
  • Telefoningizda ishlaydigan telegram mijozi bor
  • Asoslarni tushunish - o'zgaruvchi, massiv, tsikl nima.

Ochilgan va o'qilgan maqolalar - Ko'rsatmalar: Telegramda botlarni qanday yaratish kerak и Tizim administratori uchun telegram bot

1. Keling, boshqa test bot yarataylik.

Buni hamma allaqachon bilgan va allaqachon sodir bo'lganligi sababli, uni o'tkazib yuborishingiz mumkinYuqoridagi maqolada aytilganidek - birinchi navbatda, Telegram uchun bot - u hali ham siz tomonda ishlaydigan va Telegram Bot API-ga so'rovlar yuboradigan dastur. Bundan tashqari, API aniq - bot parametrlari bilan ma'lum bir URL manziliga kiradi va Telegram JSON ob'ekti bilan javob beradi.

Tegishli muammolar: agar siz JSON ob'ektidan biron bir kodni noma'lum tarzda olsangiz va uni qandaydir tarzda bajarish uchun yuborsangiz (maqsadda emas), kod siz uchun bajariladi.

Yaratish jarayoni yuqoridagi ikkita maqolada tasvirlangan, lekin takror aytaman: telegramda biz kontaktlarni ochamiz, @botfather ni qidiramiz, unga /newbotni aytamiz, Botfortest12344321 botini yaratamiz, uni Mynext1234bot deb nomlaymiz va noyob kalitli xabarni olamiz. shakl 1234544311:AbcDefNNNNNNNNNNNNNNNN

Kalitga g'amxo'rlik qiling va uni bermang!

Keyin siz botni sozlashingiz mumkin, masalan, uni guruhlarga qo'shishni taqiqlang, lekin birinchi bosqichlarda bu kerak emas.

Keling, BotFather’dan “/mybot” so‘raymiz va biror narsa yoqmasa, sozlamalarni o‘zgartiramiz.

Kontaktlarni yana ochamiz, u erda @Botfortest12344321 ni topamiz (qidiruvni @ bilan boshlash shart), "boshlash" tugmasini bosing va botga "/Robotlarga shon-sharaf" deb yozing. / belgisi kerak, tirnoq kerak emas.
Bot, albatta, hech narsaga javob bermaydi.

Keling, bot yaratilganligini tekshirib ko'ramiz va uni ochamiz.

api.telegram.org/bot1234544311:AbcDefNNNNNNNNNNNNNNNN/getMe
bu erda 1234544311:AbcDefNNNNNNNNNNNNNNNN oldindan olingan kalit,
kabi qatorni oling
{"ok":true,"natija":{""}}

Bizda birinchi maxfiy ibora (token) bor. Endi biz ikkinchi maxfiy raqamni - bot bilan suhbatning identifikatorini aniqlashimiz kerak. Har bir suhbat, guruh va boshqalar individualdir va o'z raqamiga ega (ba'zan minus bilan - ochiq guruhlar uchun). Ushbu raqamni bilish uchun biz brauzerda so'rashimiz kerak (aslida brauzerda bu mutlaqo kerak emas, lekin yaxshiroq tushunish uchun siz undan boshlashingiz mumkin) manzilni (bu erda 1234544311: NNNNNNNNNN sizning tokeningizdir)

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

kabi javob oling

{"ok":true,"natija":[{"update_id":...,... suhbat":{"id":123456789

Bizga chat_id kerak.

Keling, suhbatga qo'lda yozishimiz mumkinligini tekshirib ko'raylik: brauzerdan manzilga qo'ng'iroq qiling

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

Agar suhbatingizda botdan xabar olsangiz, keyingi bosqichga o'tasiz.

Shu tarzda (brauzer orqali) siz har doim havolani yaratish bilan bog'liq muammolar mavjudligini yoki biror joyda biror narsa yashiringanligini va ishlamayotganligini tekshirishingiz mumkin.

O'qishni davom ettirishdan oldin nimani bilishingiz kerak

Telegramda bir nechta guruh chatlari mavjud (ochiq, yopiq). Ushbu suhbatlar uchun ba'zi funktsiyalar (masalan, id) boshqacha bo'lib, ba'zida ba'zi muammolarni keltirib chiqaradi.

Faraz qilaylik, 2019-yilning oxiri, hatto zamonamizning qahramoni, taniqli Man-orkestri (administrator, huquqshunos, axborot xavfsizligi bo‘yicha mutaxassis, dasturchi va amalda MVP) Evgeniy V. $i o‘zgaruvchisini massivdan ajratib turadi, ilmoqlarni o'zlashtirgan bo'lsa, keyingi bir necha yil ichida Shokoladni o'zlashtirib oladi, keyin esa PowerShell bilan parallel ishlov berish и ForEach-Object Parallel keladi.

1. Biz botimiz nima qilishi haqida o'ylaymiz

Menda hech qanday fikr yo'q edi, men o'ylashim kerak edi. Men allaqachon bot-notebook yozganman. Men "biror narsa yuboradigan" bot qilishni xohlamadim. Azure-ga ulanish uchun sizga kredit karta kerak, lekin talaba uni qayerdan oladi? Shuni ta'kidlash kerakki, hamma narsa unchalik yomon emas: asosiy bulutlar qandaydir sinov muddatini bepul beradi (lekin sizga hali ham kredit karta raqami kerak - va undan bir dollar yechib olinadiganga o'xshaydi. Esimda yo'q. keyinroq qaytarildi.)

AI ML bo'lmasa, bot-kambag'al-shoir-to'quvchi qilish unchalik qiziq emas.

Men lug'atdagi inglizcha so'zlarni eslatadigan (yoki menga emas) bot yaratishga qaror qildim.
Ma'lumotlar bazasi bilan aralashmaslik uchun lug'at matnli faylda saqlanadi va qo'lda yangilanadi.
Bunday holda, vazifa ishning asoslarini ko'rsatishdir va hech bo'lmaganda qisman tayyor mahsulot ishlab chiqarmaslikdir.

2. Birinchi marta nimani va qanday qilib sinab ko'rish

Keling, C:poshtranslate papkasini yaratamiz
Birinchidan, keling, bizda qanday powershell borligini bilib olaylik, keling, start-run orqali ISE ni ishga tushiramiz
powershell esa
yoki o'rnatilgan dasturlarda Powershell ISE ni toping.
Ishga tushgandan so'ng, odatiy "qandaydir muharrir" ochiladi, agar matn maydoni bo'lmasa, siz har doim "Fayl - yangisini yaratish" tugmasini bosishingiz mumkin.

Powershell versiyasini ko'rib chiqaylik - matn maydoniga yozing:

get-host 

и нажмем F5.

Powershell saqlashni taklif qiladi - "Siz ishga tushirmoqchi bo'lgan skript saqlanadi.", biz rozilik bildiramiz va faylni C: poshtranslate nomi bilan powershell'dan saqlang. myfirstbotBT100.

Ishga tushgandan so'ng, pastki matn oynasida biz ma'lumotlar jadvalini olamiz:

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

Menda 5.1 narsa bor, bu etarli. Agar sizda eski Windows 7/8 bo'lsa, unchalik muhim emas - garchi PowerShell-ni 5-versiyaga yangilash kerak bo'lsa - masalan. ko'rsatmalar.

Quyidagi buyruq satriga Get-Date yozing, Enter tugmasini bosing, vaqtga qarang, buyruq bilan ildiz papkasiga o'ting
cd
va cls buyrug'i bilan ekranni tozalang (yo'q, siz rm dan foydalanishingiz shart emas)

Endi nima va qanday ishlashini tekshirib ko'raylik - keling, hatto kodni emas, balki ikkita qatorni yozamiz va ular nima qilishini tushunishga harakat qilamiz. Get-host bilan qatorni # belgisi bilan izohlaymiz va biroz qo'shamiz.

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

(Qizigʻi shundaki, Habré’dagi kod formatlash ochiladigan roʻyxatida ikki oʻnlab variantlar mavjud – lekin Powershell yoʻq. Dos bor. Perl ham bor.)

Va GUI-dan F5 yoki ">" tugmasini bosib kodni ishga tushiramiz.

Biz quyidagi natijani olamiz:

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

Keling, kelajakda bunga qaytmasligimiz uchun, keling, ushbu ikki qatorni va ba'zi qiziqarli fikrlarni ko'rib chiqaylik.

Paskaldan (va nafaqat) farqli o'laroq, PowerShell o'zi o'zgaruvchiga qaysi turni belgilashni aniqlashga harakat qiladi; bu haqda batafsil ma'lumot maqolada yozilgan. Dasturlash tillarida matn terish bo'yicha o'quv dasturi
Shuning uchun, $TimeNow o'zgaruvchisini yaratib, unga joriy sana va vaqt (Get-Date) qiymatini belgilash orqali biz u erda qanday turdagi ma'lumotlar bo'lishi haqida ko'p tashvishlanmasligimiz kerak.

To'g'ri, bu johillik keyinroq zarar etkazishi mumkin, ammo bu keyinroq. Quyida matnda misol bo'ladi.
Keling, nima borligini ko'rib chiqaylik. Keling, bajaramiz (buyruqlar satrida)

$TimeNow | Get-member

va tushunarsiz matn sahifasini oling

1-sonli tushunarsiz matnga misol

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")...                                         

Ko'rib turganingizdek, TypeName: System.DateTime tipidagi o'zgaruvchi ko'plab usullar (bu o'zgaruvchi ob'ekt bilan nima qilishimiz mumkinligi ma'nosida) va xususiyatlar bilan yaratilgan.

Qo'ng'iroq qilaylik $TimeNow.DayOfYear - biz yil kunining raqamini olamiz.
Qo'ng'iroq qilaylik $TimeNow.DayOfYear | Get-Member - olamiz TypeName: System.Int32 va usullar guruhi.
Qo'ng'iroq qilaylik $TimeNow.ToUniversalTime() - va vaqtni UTCda oling

Nosozliklarni tuzatuvchi

Ba'zan shunday bo'ladiki, ma'lum bir satrgacha bo'lgan dasturni bajarish va dasturning o'sha paytdagi holatini ko'rish kerak. Shu maqsadda ISEda Debug funksiyasi mavjud - uzilish nuqtasini almashtirish
To'xtash nuqtasini o'rtaga qo'ying, bu ikki qatorni bajaring va tanaffus qanday ko'rinishini ko'ring.

3. Telegram boti bilan o'zaro aloqani tushunish

Albatta, bot bilan o'zaro aloqada, getpush va boshqalar bilan ko'proq adabiyotlar yozilgan, ammo nazariya masalasini ixtiyoriy ravishda ko'rib chiqish mumkin.

Bizning holatda bu zarur:

  • Xat yozishda biror narsa yuborishni o'rganing
  • Xat yozishdan biror narsa olishni o'rganing

3.1 Biror narsani yozishmalarda yuborish va undan olishni o'rganish

Kichik kod - 3-qism

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

va Rossiya Federatsiyasida bu nuqtada biz xatoga duch kelamiz Masofaviy serverga ulanib bo'lmadi.

Yoki biz uni olmaymiz - aloqa operatoriga va proksi-server sozlangan va ishlayotganiga bog'liq
Xo'sh, faqat proksi-server qo'shish qoladi. Esda tutingki, shifrlanmagan va odatda soxta proksi-serverdan foydalanish sog'liq uchun juda xavflidir.

Ishlaydigan proksi-serverni topish vazifasi unchalik qiyin emas - chop etilgan http proksi-serverlarining aksariyati ishlaydi. Menimcha, beshinchisi men uchun ishlagan.

Proksi-server yordamida sintaksis:

Invoke-WebRequest -Uri $URL4SEND -Proxy $MyProxy

Agar siz bot bilan suhbatingizda xabar olsangiz, unda hamma narsa yaxshi, siz davom etishingiz mumkin. Agar yo'q bo'lsa, tuzatishni davom eting.

Siz $URL4SEND satri nimaga aylanishini koʻrishingiz va uni brauzerda soʻrashga urinib koʻrishingiz mumkin, masalan:

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

3.2. Biz chatda "bir narsa" yozishni o'rgandik, endi uni o'qishga harakat qilaylik

Keling, yana 4 ta qator qo'shamiz va | orqali ichida nima borligini ko'ramiz a'zo bo'lish

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

Eng qiziqarli narsa bizga taqdim etiladi

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

Keling, ularda nima borligini ko'rib chiqaylik:

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

Agar hamma narsa siz uchun ishlayotgan bo'lsa, siz quyidagi kabi uzun qatorga ega bo'lasiz:

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

Yaxshiyamki, ilgari nashr etilgan maqolada Telegram bot tizim ma'muri uchun ushbu qator (ha, $MyMessageGet.RawContent |ga ko'ra get-a'zosi - System.String), allaqachon qismlarga ajratilgan.

4. Qabul qilganingizni qayta ishlang (biz bir narsani qanday yuborishni allaqachon bilamiz)

Allaqachon yozilganidek shu yerda, eng kerakli narsalar tarkibda yotadi. Keling, buni batafsil ko'rib chiqaylik.

Birinchidan, biz veb-interfeysdan yoki telefondan botga yana bir nechta iboralarni yozamiz

/message1
/message2
/message3

va brauzer orqali $URLGET o'zgaruvchisida yaratilgan manzilga qarang.

Biz shunga o'xshash narsani ko'ramiz:

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

Bu nima? Oxirgi xabar identifikatori, chat identifikatori, jo'natuvchi identifikator va boshqa ko'plab ma'lumotlarni o'z ichiga olgan ob'ektlar massivlaridan ba'zi murakkab ob'ektlar.

Biroq, biz "bu qanday ob'ekt" ni aniqlashimiz shart emas - ishning bir qismi biz uchun allaqachon qilingan. Keling, ichkarida nima borligini ko'rib chiqaylik:

Qabul qilingan xabarlarni yoki 4-qismni o'qish

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. Endi bu haqda nima qilishimiz kerak?

Olingan faylni myfirstbotBT105 nomi ostida yoki sizga yoqadigan narsa ostida saqlaymiz, sarlavhani o'zgartiramiz va allaqachon yozilgan barcha kodni sharhlaymiz.

<#start comment 105 end comment 105#>

Endi biz lug'atni qayerdan olishni (yaxshi, qaerda - fayldagi diskda) va qanday ko'rinishini hal qilishimiz kerak.

Albatta, siz skript matnida juda katta lug'at yozishingiz mumkin, ammo bu mutlaqo kerak emas.
Shunday qilib, keling, qanday powershell bilan normal ishlashi mumkinligini ko'rib chiqaylik.
Umuman olganda, u qaysi fayl bilan ishlashni qiziqtirmaydi, biz uchun bu muhim emas.
Bizda tanlov bor: txt (siz mumkin, lekin nima uchun), csv, xml.
Hammani kuzata olamizmi? Hammani ko'ramiz.
Keling, MyVocabClassExample1 sinfini va $MyVocabExample1 o‘zgaruvchisini yarataylik
Men sinf $ holda yozilganligini ta'kidlayman

Ba'zi kod # 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

Keling, buni fayllarga yozishga harakat qilaylik namuna olish uchun.

Ba'zi kod # 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

- va Out-File -FilePath $MyFilenameExample01 -InputObject -Append $MyVocabExample2 qatorida xatoga duch kelamiz.

U qo'shishni xohlamaydi, a-a, qanday uyat.

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

Keling, nima bo'lishini ko'rib chiqaylik. Ajoyib matn ko'rinishi - lekin uni qanday qilib qayta eksport qilish mumkin? Vergul kabi matn ajratgichlarni kiritishim kerakmi?

Va oxirida siz "vergul bilan ajratilgan qiymatlar (CSV) A faylini olasiz KUTING.
#

$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 

Ko'rinib turibdiki, MS o'zining mantiqiyligi bilan unchalik ajralib turmaydi; shunga o'xshash protsedura uchun bir holatda -FilePath, boshqa holatda -Path ishlatiladi.

Qolaversa, uchinchi faylda rus tili yo‘qolib qoldi, to‘rtinchi faylda... ma’lum bo‘ldiki, nimadir bo‘ldi. #TYPE System.Object[] 00
# “Hisob”, “Uzunlik”, “Uzunlik”, “Rank”, “SyncRoot”, “Faqat o'qiladi”, “IsFixedSize”, “Sinxronlashtirilgan”
#
Keling, uni biroz qayta yozamiz:

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

Bu yordam berganga o'xshaydi, lekin men hali ham formatni yoqtirmayman.

Menga, ayniqsa, obyektdan satrlarni to‘g‘ridan-to‘g‘ri faylga qo‘ya olmasligim yoqmaydi.
Aytgancha, biz fayllarga yozishni boshlaganimizdan beri, ishga tushirish jurnalini yuritishni boshlay olamizmi? Bizda o'zgaruvchi sifatida vaqt bor, biz fayl nomini o'rnatishimiz mumkin.

To'g'ri, hali yozish uchun hech narsa yo'q, lekin siz jurnallarni qanday qilib eng yaxshi aylantirish haqida o'ylashingiz mumkin.
Hozircha xml ni sinab ko'raylik.

Ba'zi 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 ga eksport qilish juda ko'p afzalliklarga ega - o'qilishi, butun ob'ektni eksport qilish va yuqoriga ko'tarilishning hojati yo'q.

Keling, sinab ko'raylik xml faylini o'qing.

Xml dan bir oz o'qish

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

Keling, vazifaga qaytaylik. Biz sinov faylini yozdik, uni o'qib chiqdik, saqlash formati aniq, agar kerak bo'lsa, qatorlarni qo'shish va o'chirish uchun alohida kichik fayl muharriri yozishingiz mumkin.

Eslatib o'taman, vazifa kichik trening botini yaratish edi.

Ish formati: Men botga "misol" buyrug'ini yuboraman, bot menga tasodifiy tanlangan so'z va transkripsiyani yuboradi va 10 soniyadan so'ng menga tarjima va izoh yuboradi. Biz buyruqlarni qanday o'qishni bilamiz, shuningdek, proksi-serverlarni avtomatik tanlash va tekshirishni, xabar hisoblagichlarini unutish holatiga qaytarishni ham o'rganmoqchimiz.

Oldin keraksiz deb ko'rsatilgan hamma narsani izohdan olib tashlaymiz, endi keraksiz misollarni txt va csv bilan izohlaymiz va faylni B106 versiyasi sifatida saqlaymiz.

Oh Ha. Keling, yana botga biror narsa yuboraylik.

6. Funksiyalardan jo‘natish va boshqalar

Qabulni qayta ishlashdan oldin siz test xabaridan tashqari "hech bo'lmaganda biror narsa" yuborish funksiyasini yaratishingiz kerak.

Albatta, misolda bizda faqat bitta jo'natish va faqat bitta ishlov berish bo'ladi, lekin bir xil ishni bir necha marta qilish kerak bo'lsa-chi?

Funktsiyani yozish osonroq. Shunday qilib, bizda fayldan o'qiladigan $MyVocabExample4AsArray tipidagi o'zgaruvchi mavjud bo'lib, u ikki elementdan iborat massiv ko'rinishida bo'ladi.
Keling, o'qiymiz.

Shu bilan birga, biz soat bilan shug'ullanamiz; bizga keyinroq kerak bo'ladi (aslida, bu misolda bizga kerak bo'lmaydi :)

Ba'zi kod # 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
}

Ko'rib turganingizdek, funktsiya ilgari qattiq kodlangan $MyToken va $MyChatID ni chaqiradi.

Buni qilishning hojati yo'q va agar $MyToken har bir bot uchun bitta bo'lsa, u holda $MyChatID chatga qarab o'zgaradi.

Biroq, bu misol bo'lgani uchun, biz buni hozircha e'tiborsiz qoldiramiz.

$MyVocabExample4AsArray massiv emasligi sababli, garchi u massivga juda o'xshash bo'lsa ham, u holda shunchaki qabul qila olmaysiz uning uzunligini so'rang.

Biz yana bir bor bajarib bo'lmaydigan narsani qilishimiz kerak - kod bo'yicha emas, balki parashyut - uni oling va hisoblang

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

tasodifiy qiziqarli xususiyat. Aytaylik, biz 0 yoki 1 ni olishni xohlaymiz (massivda faqat ikkita element mavjud). 0..1 chegaralarini o'rnatishda biz "1" olamizmi?
yo'q - biz buni olmaymiz, bizda maxsus misol bor 2-misol: 0 dan 99 gacha bo'lgan tasodifiy butun sonni oling Get-Random -Maksimum 100
Shuning uchun, 0..1 uchun biz maksimal element raqami = 0 bilan 2..1 o'lchamini belgilashimiz kerak.

7. Kiruvchi xabarlarni qayta ishlash va maksimal navbat uzunligi

Ilgari qaerda to'xtadik? bizda qabul qilingan $MyMessageGet o'zgaruvchisi bor
va undan olingan $Content4Pars01, ulardan biz Content4Pars01.result massivining elementlari bilan qiziqamiz.

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

Keling, /message10, /message11, /message12, /word va yana /word va /salom botlarini yuboramiz.
Keling, nima borligini ko'rib chiqaylik:

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

Qabul qilingan hamma narsani ko'rib chiqamiz va agar xabar /word bo'lsa, javob yuboramiz
Ba'zilar if-elseif deb ta'riflagan konstruksiya holati powershellda deyiladi kalit orqali. Shu bilan birga, quyida keltirilgan kodda -wildcard kaliti ishlatiladi, bu mutlaqo keraksiz va hatto zararli.

Ba'zi kod # 7.1

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

Skriptni bir necha marta ishga tushiramiz. Har bir ijroga urinish uchun biz bir xil so'zni ikki marta olamiz, ayniqsa tasodifiy amalga oshirishda xato qilgan bo'lsak.

Lekin to'xtang. Biz yana /so'z yubormadik, nega xabar qayta ishlanmoqda?

Botga xabarlarni jo‘natish navbati cheklangan uzunlikka ega (100 yoki 200 ta xabar, menimcha) va uni qo‘lda tozalash kerak.

Bu, albatta, hujjatlarda tasvirlangan, lekin siz uni o'qishingiz kerak!

Bunday holda, bizga ?chat_id parametri kerak va &timeout, &limit, &parse_mode=HTML va &disable_web_page_preview=true hali kerak emas.

uchun hujjatlar telegram api shu yerda
U oq va ingliz tillarida:
Qaytariladigan birinchi yangilanish identifikatori. Oldin qabul qilingan yangilanishlar identifikatorlari orasidagi eng kattasidan bir kattaroq bo'lishi kerak. Odatiy bo'lib, yangilanishlar eng ertasidan boshlanadi
tasdiqlanmagan yangilanish qaytariladi. getUpdates chaqirilishi bilan yangilanish tasdiqlangan hisoblanadi ofset oliy yangilanish_idiga qaraganda. Salbiy ofset yangilanishlar navbatining oxiridan boshlab ofset yangilanishidan boshlab yangilanishlarni olish uchun belgilanishi mumkin. Oldingi barcha yangilanishlar unutiladi.

Keling, ko'rib chiqaylik:

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

Ha, va biz uni qayta tiklaymiz va funksiyani biroz qayta yozamiz. Bizda ikkita variant bor - butun xabarni funksiyaga o'tkazing va uni to'liq funksiyada qayta ishlang yoki faqat xabar identifikatorini bering va uni qayta o'rnating. Masalan, ikkinchisi oddiyroq ko'rinadi.

Ilgari bizning "barcha xabarlar" so'rovlari qatori o'xshash edi

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

va shunga o'xshash bo'ladi

$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 

Hech kim sizga birinchi navbatda barcha xabarlarni qabul qilishni, ularni qayta ishlashni taqiqlamaydi va so'rov muvaffaqiyatli bajarilgandan keyingina tasdiqlanmagan -> tasdiqlanadi.

Nima uchun barcha ishlov berish tugagandan so'ng tasdiqlashni chaqirish mantiqiy? Amalga oshirishning o'rtasida muvaffaqiyatsizlik bo'lishi mumkin va agar bepul chatbot misolida bitta xabarni o'tkazib yuborish alohida narsa bo'lmasa, unda siz kimningdir maoshi yoki karta tranzaksiyasini qayta ishlayotgan bo'lsangiz, natija yomonroq bo'lishi mumkin.

Yana bir necha qator kod

$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. Xulosa o‘rniga

Asosiy funktsiyalar - xabarlarni o'qish, navbatni tiklash, fayldan o'qish va faylga yozish amalga oshiriladi va ko'rsatiladi.

Faqat to'rtta ish qoldi:

  • chatdagi so'rovga to'g'ri javobni yuborish
  • bot qo'shilgan HAR QANDAY chatga javob yuborish
  • kodni tsiklda bajarish
  • windows rejalashtiruvchisidan botni ishga tushirish.

Bu vazifalarning barchasi oddiy va parametrlar haqidagi hujjatlarni o'qish orqali osongina bajarilishi mumkin
Set-ExecutionPolicy Cheklanmagan va -ExecutionPolicy aylanib o'tish
shakl sikli

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

O'qigan barchaga rahmat.

Manba: www.habr.com

a Izoh qo'shish