Powershell proqramından istifadə edən 7-9-cu sinif şagirdləri üçün sadə teleqram botu üçün şablon

Dostumla söhbət zamanı birdən öyrəndim ki, onların məktəbində 8-10-cu siniflərdə oxuyan uşaqlara ümumiyyətlə proqramlaşdırma öyrədilmir. Word, Excel və hər şey. Loqo yoxdur, hətta Paskal da, Excel üçün VBA da yoxdur.

Çox təəccübləndim, interneti açıb oxumağa başladım -
İxtisaslaşdırılmış məktəbin vəzifələrindən biri də öz inkişaf səviyyəsinə və həyat tərzinə görə informasiya cəmiyyətinin şərtlərinə cavab verən yeni nəslin təhsilinə kömək etməkdir.
Bu kurs tələbələrə Paskal proqramlaşdırma dilinin əsas konstruksiyaları haqqında biliklərini praktikada möhkəmləndirməyə imkan verəcək. (bəzi gimnaziyanın 2017-ci il üçün proqramından)

Sonda bir neçə saat sərf etmək və "məktəblilər üçün sadə bir bot yaratmaq" nümunəsini çəkmək qərarına gəldim.

Aşağıda Powershell-də başqa sadə botu necə yazmaq və onu veb-qancasız, ağ IP-lər, xüsusi serverlər, buludda yerləşdirilmiş virtual maşınlar və s. olmadan necə işləmək olar - adi Windows ilə adi ev kompüterində.

TLDR: Qrammatik və faktiki səhvləri olan, oxunacaq heç nə, yumor və şəkillər olmayan başqa bir cansıxıcı məqalə.

Məqalədə yeni heç nə yoxdur, demək olar ki, əvvəllər yazılanların hamısı Habré-də, məsələn məqalələrdə olub Təlimatlar: Telegram-da botları necə yaratmaq olar и Sistem administratoru üçün telegram botu.
Üstəlik, hər dəfə tədris ədəbiyyatına istinad edilməməsi üçün məqalə bilərəkdən artıqdır. Mətndə Gang 4, PowerShell Deep Dives və ya məsələn, AWS Yaxşı Architected Çərçivəsinin 5 Sütununa istinad yoxdur.

Ön söz əvəzinə keçə bilərsiniz

Keçirməkdən çekinmeyin2006-cı ildə Microsoft o vaxtkı Windows XP, Vista və Server 1.0 üçün PowerShell 2003-ı buraxdı. Bəzi yollarla o, cmdbat skriptləri, vb skriptləri, Windows Script Host və JScript kimi şeyləri əvəz etdi.

Hətta indi də PowerShell, loopların, siniflərin, funksiyaların, MS GUI çağırışlarının mövcudluğuna baxmayaraq, ehtimal ki, hələ də istifadə olunan Delphi (və ya daha köhnə bir şey) əvəzinə, Loqo seçimlərindən sonra növbəti addım hesab edilə bilər. Git inteqrasiyası və s.

Powershell nisbətən nadir hallarda istifadə olunur; siz onunla yalnız PowerShell Core, VMware vSphere PowerCLI, Azure PowerShell, MS Exchange, İstədiyiniz Dövlət Konfiqurasiyası, PowerShell Veb Girişi və onlarla və ya daha çox nadir hallarda istifadə olunan proqramlar və funksiyalar. Ola bilsin ki, buraxılışla ikinci bir külək alsın WSL2, amma tam olaraq deyil.

Powershell-in də üç böyük üstünlüyü var:

  1. Nisbətən sadədir, bu barədə çoxlu ədəbiyyat və nümunələr var və hətta rus dilində, məsələn, Foreach haqqında məqalə - kitabdan Dərinlikdə PowerShell - fərq haqqında () və {}
  2. O, redaktorla gedir İMKB, Windows ilə birlikdə. Orada hətta bir növ debugger var.
  3. Ondan zəng etmək asandır qrafik interfeys qurmaq üçün komponentlər.

0. Hazırlıq.

Bizə lazımdır:

  • Windows PC (məndə Windows 10 var)
  • Ən azı bir növ İnternetə çıxış (məsələn, NAT vasitəsilə)
  • Telegrama məhdud çıxışı olanlar üçün - brauzerdə quraşdırılmış və konfiqurasiya edilmiş freegate, bəzi çətin hallarda Simple DNS Crypt ilə birlikdə
  • Telefonunuzda işləyən telegram müştərisinin olması
  • Əsasları başa düşmək - dəyişən, massiv, döngə nədir.

Açılan və oxunan məqalələr - Təlimatlar: Telegram-da botları necə yaratmaq olar и Sistem administratoru üçün telegram botu

1. Gəlin başqa bir test botu yaradaq.

Hər kəs bunu artıq bildiyinə və artıq baş verdiyinə görə, siz də keçə bilərsinizYuxarıdakı məqalədə deyildiyi kimi - İlk növbədə, Telegram üçün bir bot - bu hələ də sizin tərəfinizdə çalışan və Telegram Bot API-yə sorğular göndərən bir proqramdır. Üstəlik, API aydındır - bot parametrləri olan xüsusi URL-ə daxil olur və Telegram JSON obyekti ilə cavab verir.

Əlaqədar problemlər: əgər siz JSON obyektindən hansısa naməlum şəkildə kod götürsəniz və onu hansısa şəkildə icraya göndərsəniz (məsələ ilə bağlı deyil), kod sizin üçün icra olunacaq.

Yaradılma prosesi yuxarıda iki məqalədə təsvir edilmişdir, lakin təkrar edirəm: teleqramda biz kontaktları açırıq, @botfather-ı axtarırıq, ona /newbot deyin, Botfortest12344321 bot yaradın, ona Mynext1234bot zəng edin və unikal açarı olan bir mesaj alırıq. forma 1234544311:AbcDefNNNNNNNNNNNNNNNN

Açarın qayğısına qalın və onu təhvil verməyin!

Sonra botu konfiqurasiya edə bilərsiniz, məsələn, onu qruplara əlavə etməyi qadağan edin, lakin ilk addımlarda bu lazım deyil.

Gəlin BotFather-dən “/mybot” üçün soruşaq və nəyisə bəyənməsək, parametrləri tənzimləyək.

Kontaktları yenidən açaq, orada @Botfortest12344321-i tapın (axtarmağa @ ilə başlamaq məcburidir), “başlat” düyməsini basın və bota “/Robotlara şöhrət” yazın. / işarəsi tələb olunur, sitatlara ehtiyac yoxdur.
Bot, əlbəttə ki, heç bir şeyə cavab verməyəcək.

Gəlin botun yaradıldığını yoxlayaq və onu açaq.

api.telegram.org/bot1234544311:AbcDefNNNNNNNNNNNNNNNN/getMe
burada 1234544311:AbcDefNNNNNNNNNNNNNN əvvəllər alınmış açardır,
və kimi bir xətt əldə edin
{"ok":doğru,"nəticə":{""}}

Bizdə birinci gizli ifadə (token) var. İndi ikinci gizli nömrəni - botla söhbətin identifikatorunu tapmalıyıq. Hər bir söhbət, qrup və s. fərdi və öz nömrəsinə malikdir (bəzən mənfi ilə - açıq qruplar üçün). Bu nömrəni tapmaq üçün brauzerdə (əslində bu, brauzerdə heç də lazım deyil, lakin daha yaxşı başa düşmək üçün ondan başlaya bilərsiniz) ünvanı (burada 1234544311:NNNNNNNNNN nişanınızdır) tələb etməliyik.

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

və kimi bir cavab alın

{"ok":true,"nəticə":[{"update_id":...,... söhbət":{"id":123456789

Bizə chat_id lazımdır.

Söhbətə əl ilə yaza biləcəyimizi yoxlayaq: brauzerdən ünvana zəng edin

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

Söhbətinizdə bir botdan mesaj alsanız, tamam, növbəti mərhələyə keçirsiniz.

Bu yolla (brauzer vasitəsilə) siz həmişə linkin yaradılması ilə bağlı problemlərin olub-olmadığını yoxlaya bilərsiniz və ya nəyinsə haradasa gizləndiyini və işləmədiyini yoxlaya bilərsiniz.

Oxumağa davam etməzdən əvvəl nə bilmək lazımdır

Telegram-da bir neçə növ qrup çatı var (açıq, qapalı). Bu söhbətlər üçün bəzi funksiyalar (məsələn, id) fərqlidir, bu da bəzən bəzi problemlərə səbəb olur.

Tutaq ki, 2019-cu ilin sonudur və hətta dövrümüzün qəhrəmanı, tanınmış Man-Orkestri (inzibatçı, hüquqşünas, informasiya təhlükəsizliyi üzrə mütəxəssis, proqramçı və praktiki olaraq MVP) Yevgeni V. $i dəyişənini massivdən fərqləndirir, loops mənimsəmiş, növbəti bir neçə ildə baxmaq Chocolatey master olacaq, sonra PowerShell ilə paralel emal и ForEach-Object Paralel gələcək.

1. Biz botumuzun nə edəcəyini düşünürük

Heç bir fikrim yox idi, düşünməli idim. Artıq bot-notebook yazmışam. Mən "harasa bir şey göndərən" bir bot yaratmaq istəmədim. Azure-a qoşulmaq üçün sizə kredit kartı lazımdır, amma tələbə onu haradan alır? Qeyd etmək lazımdır ki, hər şey o qədər də pis deyil: əsas buludlar bir növ sınaq müddətini pulsuz verir (lakin hələ də kredit kartı nömrəsi lazımdır - və deyəsən, ondan bir dollar çıxılacaq. Yadımda deyil. sonra geri qaytarıldı.)

AI ML olmadan bot-kasıb-şair-toxucu etmək o qədər də maraqlı deyil.

Lüğətdəki ingilis sözlərini mənə xatırladacaq (yaxud mənə yox) bot hazırlamaq qərarına gəldim.
Verilənlər bazası ilə məşğul olmamaq üçün lüğət mətn faylında saxlanılacaq və əl ilə yenilənəcək.
Bu vəziyyətdə vəzifə işin əsaslarını göstərməkdir və ən azı qismən hazır məhsul hazırlamaq deyil.

2. İlk dəfə nə və necə cəhd edin

Gəlin C:poshtranslate qovluğu yaradaq
Əvvəlcə gəlin görək hansı güc qabığımız var, start-run vasitəsilə ISE-i işə salaq
powershell isə
və ya quraşdırılmış proqramlarda Powershell ISE tapın.
Başladıqdan sonra adi tanış "bir növ redaktor" açılacaq; mətn sahəsi yoxdursa, həmişə "Fayl - yeni yarat" düyməsini vura bilərsiniz.

Powershell versiyasına baxaq - mətn sahəsinə yazın:

get-host 

və F5 düyməsini basın.

Powershell yadda saxlamağı təklif edəcək - “İşlətmək üzrə olduğunuz skript yadda saxlanılacaq.”, biz razılaşırıq və faylı C: poshtranslate adı ilə powershell-dən yadda saxlayın. myfirstbotBT100.

Başladıqdan sonra aşağı mətn pəncərəsində məlumat cədvəli alırıq:

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

Məndə 5.1 bir şey var, bu kifayətdir. Köhnə Windows 7/8-iniz varsa, o zaman böyük bir şey yoxdur - baxmayaraq ki, PowerShell-i 5-ci versiyaya yeniləmək lazımdır - məs. təlimatlar.

Aşağıdakı komanda xəttinə Get-Date yazın, Enter düyməsini basın, saata baxın, əmrlə kök qovluğa gedin
cd
və cls əmri ilə ekranı təmizləyin (xeyr, rm istifadə etmək lazım deyil)

İndi nəyin və necə işlədiyini yoxlayaq - gəlin hətta kodu deyil, iki sətir yazaq və onların nə etdiyini anlamağa çalışaq. Get-host ilə sətri # simvolu ilə şərh edək və bir az əlavə edək.

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

(Maraqlısı odur ki, Habré-də kod formatlama açılan siyahısında iki onlarla seçim var - lakin Powershell orada deyil. Dos var. Perl var.)

Və GUI-dən F5 və ya ">" düyməsini basaraq kodu işə salaq.

Aşağıdakı çıxışı alırıq:

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

Gəlin bu iki sətirə və bəzi maraqlı məqamlara nəzər salaq ki, gələcəkdə buna qayıtmayaq.

Paskaldan fərqli olaraq (yalnız deyil), PowerShell özü dəyişənə hansı növ təyin ediləcəyini müəyyən etməyə çalışır; bu barədə ətraflı məlumat məqalədə yazılmışdır. Proqramlaşdırma dillərində yazı yazmaq üzrə tədris proqramı
Buna görə də, $TimeNow dəyişəni yaratmaqla və ona cari tarix və vaxtın (Get-Date) dəyərini təyin etməklə, orada hansı növ məlumatların olacağı ilə bağlı çox narahat olmayaq.

Düzdür, bu cəhalət sonradan zərər verə bilər, amma bu daha sonradır. Aşağıda mətndə bir nümunə olacaq.
Görək nə əldə etdik. Gəlin icra edək (komanda xəttində)

$TimeNow | Get-member

və anlaşılmaz mətnin bir səhifəsini əldə edin

1 nömrəli anlaşılmaz mətn nümunəsi

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

Gördüyünüz kimi, TypeName: System.DateTime tipli dəyişən bir çox metodlar (bu dəyişən obyektlə nə edə biləcəyimiz mənasında) və xassələrlə yaradılmışdır.

zəng edək $TimeNow.DayOfYear — ilin gününün nömrəsini alırıq.
zəng edək $TimeNow.DayOfYear | Get-Member - alırıq TypeName: System.Int32 və üsullar qrupu.
zəng edək $TimeNow.ToUniversalTime() - və UTC-də vaxtı əldə edin

Ayıklayıcı

Bəzən elə olur ki, müəyyən sətrə qədər proqramı icra etmək və həmin an proqramın vəziyyətini görmək lazımdır. Bu məqsədlə ISE-də Debug funksiyası var - keçid nöqtəsi
Kəsmə nöqtəsini ortada bir yerə qoyun, bu iki xətti keçin və fasilənin necə göründüyünə baxın.

3. Telegram botu ilə qarşılıqlı əlaqənin başa düşülməsi

Əlbəttə ki, botla qarşılıqlı əlaqə, getpush və s. ilə bağlı daha çox ədəbiyyat yazılmışdır, lakin nəzəriyyə məsələsinə isteğe bağlı olaraq baxıla bilər.

Bizim vəziyyətimizdə zəruridir:

  • Yazışmalarda bir şey göndərməyi öyrənin
  • Yazışmalardan nəsə almağı öyrənin

3.1 Yazışmalarda bir şey göndərməyi və ondan almağı öyrənmək

Kiçik kod - 3-cü hissə

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

və Rusiya Federasiyasında bu nöqtədə uzaq serverə qoşulmaq mümkün deyil xətası alırıq.

Və ya biz onu almırıq - telekommunikasiya operatorundan və proksinin konfiqurasiya olunub-olmamasından asılıdır
Yaxşı, yalnız bir proxy əlavə etmək qalır. Nəzərə alın ki, şifrələnməmiş və ümumiyyətlə saxta proksidən istifadə sağlamlığınız üçün son dərəcə təhlükəlidir.

İşləyən proksi tapmaq vəzifəsi çox çətin deyil - dərc edilmiş http proksilərinin əksəriyyəti işləyir. Düşünürəm ki, beşinci mənim işimə yaradı.

Proksi istifadə edərək sintaksis:

Invoke-WebRequest -Uri $URL4SEND -Proxy $MyProxy

Bir bot ilə söhbətinizdə bir mesaj alsanız, hər şey qaydasındadır, davam edə bilərsiniz. Əgər yoxsa, sazlamağa davam edin.

Siz $URL4SEND sətirinizin nəyə çevrildiyini görə bilərsiniz və bunu brauzerdə tələb etməyə cəhd edə bilərsiniz, məsələn:

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

3.2. Çatda "bir şey" yazmağı öyrəndik, indi oxumağa çalışaq

Gəlin daha 4 sətir əlavə edək və | vasitəsilə içəridə nə olduğunu görək üzv almaq

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

Ən maraqlısı bizə təqdim olunur

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

Onların içində nə olduğuna baxaq:

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

Hər şey sizin üçün işləyirsə, uzun bir xətt alacaqsınız:

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

Xoşbəxtlikdən, əvvəllər dərc edilmiş məqalədə Telegram bot sistem administratoru üçün bu xətt (bəli, $MyMessageGet.RawContent | görə get-member System.String-dir), artıq sökülüb.

4. Aldığınızı emal edin (biz artıq nəyisə necə göndərəcəyimizi bilirik)

Artıq yazıldığı kimi burada, ən zəruri şeylər məzmundadır. Gəlin buna daha yaxından nəzər salaq.

Əvvəlcə veb interfeysindən və ya telefondan bota daha bir neçə ifadə yazacağıq

/message1
/message2
/message3

və $URLGET dəyişənində formalaşmış ünvana brauzer vasitəsilə baxın.

Belə bir şey görəcəyik:

{"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 nədir? Başdan sona mesaj identifikatoru, söhbət identifikatoru, göndərmə identifikatoru və bir çox başqa məlumatları ehtiva edən obyektlər massivlərindən bəzi mürəkkəb obyekt.

Bununla belə, "bunun nə cür obyekt olduğunu" anlamağa ehtiyac yoxdur - işin bir hissəsi bizim üçün artıq görülüb. Gəlin içəridə nə olduğuna baxaq:

Qəbul edilən mesajların və ya 4-cü hissənin oxunması

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. İndi bununla bağlı nə etməliyik?

Gəlin əldə edilən faylı myfirstbotBT105 adı altında və ya ən çox bəyəndiyiniz hər hansı bir adı altında saxlayaq, başlığı dəyişdirin və artıq yazılmış bütün kodu şərh edin.

<#start comment 105 end comment 105#>

İndi lüğəti haradan əldə edəcəyimizi (yaxşı, harada - faylda diskdə) və necə görünəcəyinə qərar verməliyik.

Əlbəttə ki, skriptin mətnində böyük bir lüğət yaza bilərsiniz, lakin bu tamamilə nöqtədən kənardır.
Beləliklə, Powershell-in normal olaraq hansı ilə işləyə biləcəyinə baxaq.
Ümumiyyətlə, hansı faylla işləmək ona əhəmiyyət vermir, bizim üçün fərqi yoxdur.
Seçimimiz var: txt (bacarsan, amma niyə), csv, xml.
Hamını izləyə bilərik?Gəlin hamını görək.
Gəlin MyVocabClassExample1 sinfi və $MyVocabExample1 dəyişəni yaradaq
Qeyd edim ki, sinif $ olmadan yazılır

bə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

Bunu istifadə edərək fayllara yazmağa çalışaq nümunə götürmək.

Bə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

- və Out-File -FilePath $MyFilenameExample01 -InputObject -Əlavə $MyVocabExample2 xəttində xəta alırıq.

Əlavə etmək istəmir, ah-ah, nə ayıbdır.

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

Gəlin görək nə baş verir. Əla mətn görünüşü - amma onu necə geri ixrac etmək olar? Vergül kimi bir növ mətn ayırıcıları təqdim etməliyəmmi?

Və sonunda "vergüllə ayrılmış dəyərlər (CSV) faylı A alırsınız GÖZLƏYİN.
#

$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 

Göründüyü kimi, MS məntiqi ilə xüsusilə seçilmir; oxşar prosedur üçün bir halda -FilePath, digərində -Path istifadə olunur.

Bundan əlavə, üçüncü faylda rus dili itdi, dördüncü faylda belə çıxdı... yaxşı, nəsə oldu. #TYPE System.Object[] 00
# "Say","Uzunluq","Uzunluq","Rank","SyncRoot","Yalnız Okunur","Sabit Ölçü","Sinxronlaşdırılıb"
#
Bir az yenidən yazaq:

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

Görünür, kömək etdi, amma formatı hələ də bəyənmirəm.

Xüsusilə obyektdən sətirləri birbaşa fayla qoya bilməməyimdən xoşum gəlmir.
Yeri gəlmişkən, biz fayllara yazmağa başladığımız üçün başlanğıc jurnalını saxlamağa başlaya bilərikmi? Dəyişən olaraq vaxtımız var, fayl adını təyin edə bilərik.

Düzdür, hələ yazmaq üçün heç bir şey yoxdur, ancaq logları necə ən yaxşı şəkildə döndərmək barədə düşünə bilərsiniz.
Hələlik xml-i sınayaq.

Bə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-ə ixracın bir çox üstünlükləri var - oxunaqlılıq, bütün obyektin ixracı və yuxarı qaldırmağa ehtiyac yoxdur.

Çalışaq xml faylını oxuyun.

xml-dən bir az oxu

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

Tapşırığa qayıdaq. Test faylı yazdıq, oxuyun, saxlama formatı aydındır, lazım gələrsə, sətirləri əlavə etmək və silmək üçün ayrıca kiçik bir fayl redaktoru yaza bilərsiniz.

Nəzərinizə çatdırım ki, tapşırıq kiçik bir təlim botu hazırlamaq idi.

İş formatı: Mən bota “nümunə” əmrini göndərirəm, bot mənə təsadüfi seçilmiş söz və transkripsiyanı göndərir, 10 saniyədən sonra isə tərcümə və şərh göndərir. Biz əmrləri necə oxumağı bilirik, həmçinin proksiləri avtomatik seçmək və yoxlamaq və mesaj sayğaclarını unudulmuş vəziyyətə qaytarmağı öyrənmək istərdik.

Gəlin əvvəllər lazımsız kimi qeyd edilən hər şeyi şərh edək, indi lazımsız nümunələri txt və csv ilə şərh edək və faylı B106 versiyası olaraq qeyd edək.

Oh bəli. Yenidən bota nəsə göndərək.

6. Funksiyalardan göndərmə və daha çox

Qəbulu emal etməzdən əvvəl, test mesajından başqa "ən azı bir şey" göndərmək üçün bir funksiya yaratmalısınız.

Əlbəttə ki, nümunədə yalnız bir göndərmə və yalnız bir emalımız olacaq, amma eyni şeyi bir neçə dəfə etmək lazımdırsa necə?

Funksiya yazmaq daha asandır. Beləliklə, fayldan oxunan, iki elementdən ibarət massiv şəklində olan $MyVocabExample4AsArray tipli obyekt dəyişənimiz var.
Gedək oxuyaq.

Eyni zamanda, biz saatla məşğul olacağıq; ona sonra ehtiyacımız olacaq (əslində, bu nümunədə ona ehtiyacımız olmayacaq :)

Bə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
}

Asanlıqla gördüyünüz kimi, funksiya əvvəllər sərt kodlaşdırılmış $MyToken və $MyChatID-ni çağırır.

Bunu etməyə ehtiyac yoxdur və əgər $MyToken hər bot üçün birdirsə, o zaman $MyChatID söhbətdən asılı olaraq dəyişəcək.

Ancaq bu bir nümunə olduğu üçün hələlik buna məhəl qoymayacağıq.

$MyVocabExample4AsArray massiv olmadığına görə birinə çox bənzəyir, onda sadəcə götürə bilməzsən uzunluğunu tələb edin.

Yenə də edə bilməyəcəyimiz bir şey etməli olacağıq - koda uyğun olmayan paraşütlə - götür və hesabla

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

təsadüfi maraqlı xüsusiyyət. Tutaq ki, biz 0 və ya 1 almaq istəyirik (massivdə yalnız iki elementimiz var). Sərhədləri 0..1 təyin edərkən "1" alacağıq?
Xeyr - biz bunu əldə etməyəcəyik, bizdə xüsusi bir nümunə var Misal 2: 0 ilə 99 arasında təsadüfi tam ədəd alın Get-Random -Maksimum 100
Buna görə də, 0..1 üçün maksimum element sayı = 0 olan 2..1 ölçüsünü təyin etməliyik.

7. Daxil olan mesajların emalı və maksimum növbə uzunluğu

Daha əvvəl harada dayandıq? biz qəbul dəyişən $MyMessageGet var
və ondan əldə edilən $Content4Pars01, bunlardan bizi Content4Pars01.result massivinin elementləri maraqlandırır.

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

/message10, /message11, /message12, /word və yenidən /word və /salam botu göndərək.
Nə əldə etdiyimizə baxaq:

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

Gəlin alınan hər şeyi nəzərdən keçirək və mesaj /word idisə cavab göndərək
Bəzilərinin if-elseif kimi təsvir etdiyi konstruksiya halı powershell-də adlanır keçid vasitəsilə. Eyni zamanda, aşağıdakı kod tamamilə lazımsız və hətta zərərli olan -wildcard açarından istifadə edir.

Bəzi kod #7.1

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

Skripti bir neçə dəfə işlədək. Hər icra cəhdi üçün eyni sözü iki dəfə alacağıq, xüsusən də təsadüfi həyata keçirərkən səhv etmişik.

Amma dayan. Yenidən /söz göndərmədik, bəs niyə mesaj yenidən işlənir?

Bota mesaj göndərmək üçün növbə sonlu uzunluğa malikdir (məncə 100 və ya 200 mesaj) və əl ilə təmizlənməlidir.

Bu, əlbəttə ki, sənədlərdə təsvir edilmişdir, lakin siz onu oxumalısınız!

Bu halda, bizə ?chat_id parametri lazımdır və &timeout, &limit, &parse_mode=HTML və &disable_web_page_preview=true hələ lazım deyil.

üçün sənədlər telegram api burada
Ağ və ingilis dilində deyilir:
Qaytarılacaq ilk yeniləmənin identifikatoru. Əvvəllər alınan yeniləmələrin identifikatorları arasında ən yüksəkdən bir böyük olmalıdır. Varsayılan olaraq, yeniləmələr ən erkəndən başlayır
təsdiqlənməmiş yeniləmə qaytarılır. GetUpdates ilə çağırılan kimi yeniləmə təsdiqlənmiş sayılır ofset ali onun update_id-dən daha çox. Mənfi ofset yenilənmə növbəsinin sonundan ofset yeniləməsindən başlayaraq yeniləmələri əldə etmək üçün təyin edilə bilər. Bütün əvvəlki yeniləmələr unudulacaq.

Gəlin baxaq:

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

Bəli və biz onu sıfırlayacağıq və funksiyanı bir az yenidən yazacağıq. Bizim iki seçimimiz var - bütün mesajı funksiyaya ötürmək və onu tamamilə funksiyada emal etmək və ya yalnız mesaj identifikatorunu vermək və onu sıfırlamaq. Məsələn, ikincisi daha sadə görünür.

Əvvəllər "bütün mesajlar" sorğu sətirimiz belə görünürdü

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

və belə görünəcək

$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 

Heç kim sizə ilk olaraq bütün mesajları qəbul etməyi, onları emal etməyi qadağan etmir və yalnız uğurlu emaldan sonra sorğu təsdiqlənmir -> təsdiqlənir.

Nə üçün bütün emal başa çatdıqdan sonra təsdiqi çağırmaq məntiqlidir? İcranın ortasında uğursuzluq mümkündür və əgər pulsuz bir chatbot məsələn, bir mesajı qaçırmaq xüsusi bir şey deyilsə, o zaman kiminsə maaşını və ya kart əməliyyatını emal edirsinizsə, nəticə daha pis ola bilər.

Daha bir neçə sətir 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. Nəticə əvəzinə

Əsas funksiyalar - mesajların oxunması, növbənin sıfırlanması, fayldan oxunması və fayla yazılması yerinə yetirilir və göstərilir.

Yalnız dörd iş qalır:

  • chatda sorğuya düzgün cavabın göndərilməsi
  • botun əlavə olunduğu HƏR söhbətə cavab göndərmək
  • kodun bir döngədə icrası
  • windows planlaşdırıcısından botun işə salınması.

Bütün bu vəzifələr sadədir və kimi parametrlər haqqında sənədləri oxumaqla asanlıqla yerinə yetirilə bilər
Set-ExecutionPolicy Unlimited və -ExecutionPolicy Bypass
formanın dövrü

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

Oxuyan hər kəsə təşəkkürlər.

Mənbə: www.habr.com

Добавить комментарий