7-9-րդ դասարանների դպրոցականների համար պարզ հեռագրային բոտի ձևանմուշ՝ օգտագործելով Powershell

Ընկերոջս հետ զրույցի ժամանակ հանկարծ իմացա, որ իրենց դպրոցի 8-10-րդ դասարանների երեխաներին ընդհանրապես ծրագրավորում չեն սովորեցնում։ Word, Excel և ամեն ինչ: Ոչ մի լոգո, նույնիսկ Պասկալ, նույնիսկ VBA Excel-ի համար:

Ես շատ զարմացա, բացեցի ինտերնետը և սկսեցի կարդալ.
Մասնագիտացված դպրոցի խնդիրներից է տեղեկատվական հասարակության պայմաններին համապատասխանող նոր սերնդի կրթությունը նպաստել իր զարգացման մակարդակով և ապրելակերպով:
Այս դասընթացը ուսանողներին թույլ կտա գործնականում համախմբել իրենց գիտելիքները Pascal ծրագրավորման լեզվի հիմնական կառուցվածքների վերաբերյալ: (Որոշ գիմնազիայի 2017 թվականի ծրագրից)

Ի վերջո, ես որոշեցի ծախսել մի քանի ժամ և ուրվագծել «ինչպես ստեղծել պարզ բոտ դպրոցականների համար» օրինակ:

Ստորև բերված է, թե ինչպես կարելի է գրել ևս մեկ պարզ բոտ Powershell-ում և այն աշխատեցնել առանց վեբ-կապիկի, սպիտակ IP-ների, հատուկ սերվերների, ամպի մեջ տեղակայված վիրտուալ մեքենաների և այլն՝ սովորական տնային համակարգչի վրա՝ սովորական Windows-ով:

TLDR. Եվս մեկ ձանձրալի հոդված՝ քերականական և փաստական ​​սխալներով, կարդալու ոչինչ չկա, հումոր չկա, նկարներ չկան:

Հոդվածում ոչ մի նոր բան չկա, գրեթե ամեն ինչ նախկինում գրված է արդեն Habré-ում, օրինակ հոդվածներում Հրահանգներ. Ինչպես ստեղծել բոտեր Telegram-ում и Telegram բոտը համակարգի ադմինիստրատորի համար.
Ավելին, հոդվածը միտումնավոր ավելորդ է, որպեսզի ամեն անգամ չանդրադառնանք ուսումնական գրականությանը։ Տեքստում հղումներ չկան Gang 4-ի, PowerShell Deep Dives-ի կամ, ասենք, AWS Well-Architected Framework-ի 5 սյուների մասին:

Նախաբանի փոխարեն կարող եք բաց թողնել

Ազատ զգալ բաց թողնել2006 թվականին Microsoft-ը թողարկեց PowerShell 1.0-ն այն ժամանակվա Windows XP-ի, Vista-ի և Server 2003-ի համար: Որոշ առումներով այն փոխարինեց այնպիսի բաներ, ինչպիսիք են cmdbat scripts, vb scripts, Windows Script Host-ը և JScript-ը:

Նույնիսկ հիմա, PowerShell-ը կարելի է համարել միայն որպես հաջորդ քայլ Logo տարբերակներից հետո, հավանաբար դեռ օգտագործված Delphi-ի (կամ ավելի հին որևէ այլ բանի փոխարեն), չնայած հանգույցների, դասերի, գործառույթների, MS GUI զանգերի առկայությանը, Git ինտեգրում եւ այլն:

Powershell-ը օգտագործվում է համեմատաբար հազվադեպ, այն կարող եք հանդիպել միայն PowerShell Core, VMware vSphere PowerCLI, Azure PowerShell, MS Exchange, Desired State Configuration, PowerShell վեբ մուտք և մեկ տասնյակից ավելի հազվադեպ օգտագործվող ծրագրեր և գործառույթներ: Թերևս նա երկրորդ քամի կստանա ազատ արձակմամբ WSL2, բայց դա հենց այնպես չէ։

Powershell-ն ունի նաև երեք մեծ առավելություն.

  1. Դա համեմատաբար պարզ է, դրա մասին շատ գրականություն և օրինակներ կան, և նույնիսկ ռուսերեն, օրինակ, հոդված Foreach-ի մասին - գրքից: PowerShell-ը խորությամբ - տարբերության մասին () և {}
  2. Նա գնում է խմբագրի հետ Ise, ներառված է Windows-ի հետ։ Այնտեղ նույնիսկ ինչ-որ կարգաբերիչ կա:
  3. Դրանից հեշտ է զանգահարել բաղադրիչներ գրաֆիկական ինտերֆեյս կառուցելու համար.

0. Պատրաստում.

Մեզ անհրաժեշտ կլինի.

  • Windows PC (ես ունեմ Windows 10)
  • Առնվազն մի տեսակ ինտերնետ հասանելիություն (օրինակ՝ NAT-ի միջոցով)
  • Նրանց համար, ովքեր ունեն սահմանափակ մուտք դեպի telegram - զննարկիչում տեղադրված և կազմաձևված freegate, որոշ դժվար դեպքերում, Symple DNS Crypt-ի հետ միասին
  • Ձեր հեռախոսում աշխատող հեռագրային հաճախորդ ունենալը
  • Հասկանալով հենց հիմունքները՝ ինչ է փոփոխականը, զանգվածը, հանգույցը:

Բացել և կարդալ հոդվածներ - Հրահանգներ. Ինչպես ստեղծել բոտեր Telegram-ում и Telegram բոտը համակարգի ադմինիստրատորի համար

1. Եկեք ստեղծենք ևս մեկ թեստային բոտ:

Քանի որ բոլորն արդեն գիտեն դա, և արդեն տեղի է ունեցել, կարող եք նաև բաց թողնելԻնչպես նշված է վերը նշված հոդվածում - Առաջին հերթին, բոտ Telegram-ի համար. այն դեռևս ձեր կողմից աշխատող հավելված է և հարցումներ է կատարում 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":{""}}

Մենք ունենք առաջին գաղտնի արտահայտությունը (token). Այժմ մենք պետք է պարզենք երկրորդ գաղտնի համարը՝ բոտի հետ զրույցի ID-ն։ Յուրաքանչյուր չաթ, խումբ և այլն անհատական ​​է և ունի իր համարը (երբեմն մինուսով` բաց խմբերի համար): Այս համարը պարզելու համար անհրաժեշտ է բրաուզերում (իրականում, բրաուզերում դա ամենևին էլ անհրաժեշտ չէ, բայց ավելի լավ հասկանալու համար կարող եք սկսել դրանից) հասցեն (որտեղ 1234544311:NNNNNNNNNN-ը ձեր նշանն է).

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

և ստացեք նման պատասխան

{"ok":true,"result":[{"update_id":...,... զրուցել":{"id":123456789

Մեզ պետք է chat_id:

Եկեք ստուգենք, որ մենք կարող ենք գրել չաթում ձեռքով. զանգահարեք հասցեն բրաուզերից

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

Եթե ​​ձեր չաթում հաղորդագրություն եք ստանում բոտից, լավ, դուք անցնում եք հաջորդ փուլ:

Այս կերպ (բրաուզերի միջոցով) դուք միշտ կարող եք ստուգել, ​​թե արդյոք կապի ստեղծման հետ կապված խնդիրներ կան, կամ ինչ-որ բան ինչ-որ տեղ թաքնված է և չի աշխատում:

Այն, ինչ դուք պետք է իմանաք նախքան կարդալը շարունակելը

Telegram-ն ունի մի քանի տեսակի խմբակային չաթեր (բաց, փակ): Այս չաթերի համար որոշ գործառույթներ (օրինակ՝ id) տարբեր են, ինչը երբեմն որոշակի խնդիրներ է առաջացնում։

Ենթադրենք, որ 2019-ի վերջն է, և նույնիսկ մեր ժամանակների հերոս, հայտնի Man-Orchestra (ադմինիստրատոր, իրավաբան, տեղեկատվական անվտանգության մասնագետ, ծրագրավորող և գործնականում MVP) Եվգենի Վ.-ն առանձնացնում է $i փոփոխականը զանգվածից, յուրացրել է loops, նայեք առաջիկա մի քանի տարիների ընթացքում կտիրապետի Chocolatey, ապա Զուգահեռ մշակում PowerShell-ով и ForEach-Object զուգահեռ այն կգա:

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-ը չկա: Dos-ն այնտեղ է: Perl-ն այնտեղ է:)

Եվ եկեք գործարկենք կոդը՝ սեղմելով F5 կամ «>» GUI-ից:

Մենք ստանում ենք հետևյալ արդյունքը.

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

Հիմա եկեք նայենք այս երկու տողերին և մի քանի հետաքրքիր կետերին, որպեսզի ապագայում չանդրադառնանք դրան:

Ի տարբերություն Pascal-ի (և ոչ միայն), 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 bot համակարգի ադմինիստրատորի համար այս տողը (այո, ըստ $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) ֆայլ 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
# «Count», «Length», «LongLength», «Rank», «SyncRoot», «IsReadOnly», «IsFixedSize», «IsSynchronized»
#
Եկեք մի փոքր վերաշարադրենք.

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

Թվում է, թե դա օգնեց, բայց ես դեռ չեմ սիրում ձևաչափը:

Ինձ հատկապես դուր չի գալիս, որ ես չեմ կարող օբյեկտից տողեր ուղղակիորեն ֆայլի մեջ դնել:
Ի դեպ, քանի որ սկսել ենք ֆայլեր գրել, կարո՞ղ ենք սկսել startup log պահել: Մենք ժամանակ ունենք որպես փոփոխական, մենք կարող ենք սահմանել ֆայլի անունը։

Ճիշտ է, դեռ գրելու բան չկա, բայց կարելի է մտածել, թե ինչպես լավագույնս պտտել տեղեկամատյանները։
Եկեք փորձենք 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 - Առավելագույնը 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 պարամետրը, և դեռ անհրաժեշտ չեն &timeout, &limit, &parse_mode=HTML և &disable_web_page_preview=true:

Փաստաթղթեր համար telegram api-ն այստեղ է
Սպիտակ և անգլերենով ասվում է.
Առաջին թարմացման նույնացուցիչը, որը պետք է վերադարձվի: Պետք է լինի մեկով ավելի, քան նախկինում ստացված թարմացումների նույնացուցիչների մեջ ամենաբարձրը: Լռելյայն, թարմացումները սկսվում են ամենավաղից
չհաստատված թարմացումները վերադարձվում են: Թարմացումը համարվում է հաստատված, հենց որ getUpdates-ը կանչվի an-ով փոխհատուցել ավելի բարձր քան դրա 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

Այո, և մենք կզրոյացնենք այն և մի փոքր կվերագրենք գործառույթը: Մենք ունենք երկու տարբերակ՝ փոխանցել ամբողջ հաղորդագրությունը ֆունկցիային և այն ամբողջությամբ մշակել ֆունկցիայի մեջ, կամ տալ միայն հաղորդագրության 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 ++

Շնորհակալություն բոլորին, ովքեր կարդացել են:

Source: www.habr.com

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