Mẫu bot telegram đơn giản dành cho học sinh lớp 7-9 sử dụng Powershell

Trong khi trò chuyện với một người bạn, tôi chợt biết rằng trẻ em từ lớp 8-10 ở trường của họ hoàn toàn không được dạy lập trình. Word, Excel và mọi thứ. Không có logo, thậm chí không có Pascal, thậm chí không có VBA cho Excel.

Tôi rất ngạc nhiên, mở Internet và bắt đầu đọc -
Một trong những nhiệm vụ của trường chuyên là thúc đẩy việc giáo dục thế hệ mới đáp ứng các điều kiện của xã hội thông tin về trình độ phát triển và lối sống.
Khóa học này sẽ cho phép sinh viên củng cố kiến ​​thức thực tế về các cấu trúc cơ bản của ngôn ngữ lập trình Pascal. (Trích chương trình một số phòng tập năm 2017)

Cuối cùng, tôi quyết định dành vài giờ và phác thảo một ví dụ về “cách tạo một bot đơn giản cho học sinh”.

Phần dưới đây là cách viết một bot đơn giản khác trong Powershell và làm cho nó hoạt động mà không cần webhook, IP trắng, máy chủ chuyên dụng, máy ảo được triển khai trên đám mây, v.v. - trên một PC gia đình thông thường có Windows thông thường.

TLDR: Lại một bài viết nhàm chán, mắc lỗi ngữ pháp và thực tế, không có gì để đọc, không có tính hài hước, không có hình ảnh.

Bài viết không có gì mới, hầu như mọi thứ viết trước đó đều đã có trên Habré, ví dụ như trong các bài báo Hướng dẫn: Cách tạo bot trong Telegram и Telegram bot dành cho quản trị viên hệ thống.
Hơn nữa, bài viết cố tình dư thừa để không lúc nào cũng đề cập đến văn học giáo dục. Không có tài liệu tham khảo nào về Gang 4, PowerShell Deep Dives hay 5 trụ cột của Khung kiến ​​trúc tối ưu AWS trong văn bản.

Thay vì lời nói đầu, bạn có thể bỏ qua

Hãy bỏ quaNăm 2006, Microsoft phát hành PowerShell 1.0 cho Windows XP, Vista và Server 2003. Ở một khía cạnh nào đó, nó đã thay thế những thứ như tập lệnh cmdbat, tập lệnh vb, Windows Script Host và JScript.

Ngay cả bây giờ, PowerShell chỉ có thể được coi là bước tiếp theo sau các tùy chọn Logo, thay vì có thể vẫn được sử dụng Delphi (hoặc thứ gì đó cũ hơn), bất chấp sự hiện diện của các vòng lặp, lớp, hàm, lệnh gọi MS GUI, Tích hợp Git và như vậy.

Powershell được sử dụng tương đối hiếm; bạn chỉ có thể gặp nó ở dạng PowerShell Core, VMware vSphere PowerCLI, Azure PowerShell, MS Exchange, Desired State Configuration, Truy cập web PowerShell và hàng tá chương trình và chức năng hiếm khi được sử dụng. Có lẽ anh ấy sẽ có được làn gió thứ hai với việc phát hành WSL2, nhưng nó không chính xác.

Powershell cũng có ba ưu điểm lớn:

  1. Nó tương đối đơn giản, có rất nhiều tài liệu và ví dụ về nó, và thậm chí cả bằng tiếng Nga, chẳng hạn, một bài báo về Foreach - từ cuốn sách PowerShell chuyên sâu - về sự khác biệt () và {}
  2. Anh ấy đi cùng biên tập viên ISE, đi kèm với Windows. Thậm chí còn có một số loại trình gỡ lỗi ở đó.
  3. Thật dễ dàng để gọi từ nó Các thành phần xây dựng giao diện đồ họa.

0. Chuẩn bị.

Chúng ta sẽ cần:

  • PC Windows (Tôi có Windows 10)
  • Ít nhất một số loại truy cập Internet (ví dụ thông qua NAT)
  • Dành cho những người có quyền truy cập hạn chế vào telegram - freegate được cài đặt và định cấu hình trong trình duyệt, trong một số trường hợp khó khăn, cùng với Symple DNS Crypt
  • Có một ứng dụng khách telegram đang hoạt động trên điện thoại của bạn
  • Hiểu những điều cơ bản nhất - biến, mảng, vòng lặp là gì.

Đã mở và đọc bài viết - Hướng dẫn: Cách tạo bot trong Telegram и Telegram bot dành cho quản trị viên hệ thống

1. Hãy tạo một bot thử nghiệm khác.

Vì mọi người đều đã biết điều này và đã xảy ra nên bạn cũng có thể bỏ quaNhư đã nêu trong bài viết trên - Trước hết, bot cho Telegram - nó vẫn là một ứng dụng chạy bên phía bạn và đưa ra yêu cầu đối với API Telegram Bot. Hơn nữa, API rất rõ ràng - bot truy cập một URL cụ thể bằng các tham số và Telegram phản hồi bằng một đối tượng JSON.

Các vấn đề liên quan: nếu bằng cách nào đó bạn lấy một số mã từ một đối tượng JSON và bằng cách nào đó gửi nó đi để thực thi (không nhằm mục đích), thì mã đó sẽ được thực thi cho bạn.

Quá trình tạo được mô tả trong hai bài viết ở trên, nhưng tôi nhắc lại: trong một bức điện tín, chúng tôi mở danh bạ, tìm @botfather, nói với anh ấy /newbot, tạo bot Botfortest12344321, gọi nó là Mynext1234bot và nhận được tin nhắn có khóa duy nhất của mẫu 1234544311:AbcDefNNNNNNNNNNNNNN

Hãy giữ chìa khóa cẩn thận và đừng trao nó đi!

Sau đó, bạn có thể định cấu hình bot, chẳng hạn như cấm thêm nó vào nhóm, nhưng trong những bước đầu tiên, điều này là không cần thiết.

Hãy hỏi BotFather về “/mybot” và điều chỉnh cài đặt nếu chúng tôi không thích điều gì đó.

Hãy mở lại danh bạ, tìm @Botfortest12344321 ở đó (bắt buộc phải bắt đầu tìm kiếm bằng @), nhấp vào “bắt đầu” và viết thư cho bot “/Glory to the robots”. Dấu / là bắt buộc, không cần dấu ngoặc kép.
Tất nhiên, bot sẽ không trả lời bất cứ điều gì.

Hãy kiểm tra xem bot đã được tạo chưa và mở nó.

api.telegram.org/bot1234544311:AbcDefNNNNNNNNNNNNNN/getMe
trong đó 1234544311:AbcDefNNNNNNNNNNNNNN là khóa đã nhận trước đó,
và nhận được một dòng như
{"ok":true,"kết quả":{""}}

Chúng ta có cụm từ bí mật đầu tiên (mã thông báo). Bây giờ chúng ta cần tìm ra con số bí mật thứ hai - ID của cuộc trò chuyện với bot. Mỗi cuộc trò chuyện, nhóm, v.v. là riêng lẻ và có số riêng (đôi khi có dấu trừ - đối với các nhóm mở). Để tìm ra con số này, chúng tôi cần yêu cầu trong trình duyệt (trên thực tế, nó không cần thiết chút nào trong trình duyệt, nhưng để hiểu rõ hơn bạn có thể bắt đầu với nó) địa chỉ (trong đó 1234544311:NNNNNNNNNN là mã thông báo của bạn

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

và nhận được phản hồi như

{"ok":true,"result":[{"update_id":...,... trò chuyện trên mạng":{"nhận dạng":123456789

Chúng tôi cần chat_id.

Hãy kiểm tra xem chúng ta có thể viết thư vào cuộc trò chuyện theo cách thủ công hay không: gọi địa chỉ từ trình duyệt

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

Nếu bạn nhận được tin nhắn từ bot trong cuộc trò chuyện của mình, được thôi, bạn sẽ chuyển sang giai đoạn tiếp theo.

Bằng cách này (thông qua trình duyệt), bạn luôn có thể kiểm tra xem có vấn đề gì với việc tạo liên kết hay không hoặc có điều gì đó bị ẩn ở đâu đó và không hoạt động hay không.

Những điều bạn cần biết trước khi tiếp tục đọc

Telegram có một số loại trò chuyện nhóm (mở, đóng). Đối với những cuộc trò chuyện này, một số chức năng (ví dụ: id) khác nhau, điều này đôi khi gây ra một số vấn đề.

Giả sử rằng đó là cuối năm 2019 và thậm chí là người hùng của thời đại chúng ta, Man-Orchestra nổi tiếng (quản trị viên, luật sư, chuyên gia bảo mật thông tin, lập trình viên và gần như là MVP) Evgeniy V. phân biệt biến $i với một mảng, đã thành thạo các vòng lặp, dự kiến ​​trong vài năm tới sẽ thành thạo Chocolatey, và sau đó Xử lý song song với PowerShell и ForEach-Object song song nó sẽ đến.

1. Chúng tôi nghĩ về những gì bot của chúng tôi sẽ làm

Tôi không có ý tưởng nào cả, tôi phải suy nghĩ. Tôi đã viết một cuốn sổ tay bot. Tôi không muốn tạo ra một con bot “gửi thứ gì đó đi đâu đó”. Để kết nối với Azure bạn cần có thẻ tín dụng, nhưng học sinh lấy nó từ đâu? Cần lưu ý rằng mọi thứ không quá tệ: các đám mây chính cung cấp miễn phí một số loại thời gian thử nghiệm (nhưng bạn vẫn cần số thẻ tín dụng - và có vẻ như một đô la sẽ bị ghi nợ từ đó. Tôi không nhớ nếu nó đã được trả lại sau đó.)

Nếu không có AI ML, việc tạo ra một thợ dệt-nhà thơ-nghèo bot sẽ không còn thú vị nữa.

Tôi quyết định tạo ra một con bot sẽ nhắc nhở tôi (hoặc không phải tôi) về các từ tiếng Anh trong từ điển.
Để tránh xáo trộn cơ sở dữ liệu, từ điển sẽ được lưu trữ trong một tệp văn bản và được cập nhật theo cách thủ công.
Trong trường hợp này, nhiệm vụ là thể hiện những điều cơ bản của tác phẩm chứ không phải tạo ra ít nhất một sản phẩm đã hoàn thiện một phần.

2. Lần đầu tiên thử cái gì và như thế nào

Hãy tạo một thư mục C:poshtranslate
Đầu tiên, hãy xem chúng ta có loại powershell nào, hãy khởi chạy ISE thông qua start-run
powerhell ise
hoặc tìm Powershell ISE trong các chương trình đã cài đặt.
Sau khi khởi chạy, “một số loại trình soạn thảo” quen thuộc thông thường sẽ mở ra, nếu không có trường văn bản thì bạn luôn có thể nhấp vào “Tệp - tạo mới”.

Hãy xem phiên bản powershell - viết vào trường văn bản:

get-host 

và nhấn F5.

Powershell sẽ đề nghị lưu - “Script bạn sắp chạy sẽ được lưu.”, chúng tôi đồng ý và lưu file từ powershell với tên trong C: poshtranslate myfirstbotBT100.

Sau khi khởi chạy, trong cửa sổ văn bản phía dưới, chúng ta nhận được bảng dữ liệu:

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

Mình có 5.1 gì đó, thế là đủ rồi. Nếu bạn có Windows 7/8 cũ thì không có vấn đề gì lớn - mặc dù PowerShell sẽ cần được cập nhật lên phiên bản 5 - ví dụ: hướng dẫn.

Gõ Get-Date vào dòng lệnh bên dưới, nhấn Enter, nhìn giờ, vào thư mục gốc bằng lệnh
cd
và xóa màn hình bằng lệnh cls (không cần dùng rm)

Bây giờ, hãy kiểm tra xem những gì hoạt động và như thế nào - chúng ta hãy viết thậm chí không phải mã mà chỉ viết hai dòng và cố gắng hiểu chúng làm gì. Hãy nhận xét dòng get-host có ký hiệu # và thêm một chút.

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

(Điều thú vị là trong danh sách thả xuống định dạng mã trên Habré có tới hai chục tùy chọn - nhưng Powershell không có ở đó. Dos có ở đó. Perl có ở đó.)

Và hãy chạy mã bằng cách nhấn F5 hoặc ">" từ GUI.

Chúng tôi nhận được kết quả đầu ra sau:

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

Bây giờ chúng ta hãy xem xét hai dòng này và một số điểm thú vị để chúng ta không quay lại vấn đề này trong tương lai.

Không giống như Pascal (và không chỉ), bản thân PowerShell cố gắng xác định loại nào sẽ được gán cho một biến; thông tin chi tiết hơn về điều này sẽ được viết trong bài viết Chương trình giáo dục về gõ trong ngôn ngữ lập trình
Do đó, bằng cách tạo một biến $TimeNow và gán cho nó giá trị của ngày và giờ hiện tại (Get-Date), chúng ta không phải lo lắng quá nhiều về loại dữ liệu sẽ có ở đó.

Đúng, sự thiếu hiểu biết này có thể gây tổn thương sau này, nhưng đó là chuyện sau này. Dưới đây trong văn bản sẽ có một ví dụ.
Hãy xem chúng ta có gì nào. Hãy thực hiện (trên dòng lệnh)

$TimeNow | Get-member

và nhận được một trang có nội dung khó hiểu

Ví dụ văn bản khó hiểu số 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")...                                         

Như bạn có thể thấy, một biến kiểu TypeName: System.DateTime đã được tạo bằng một loạt các phương thức (theo nghĩa là những gì chúng ta có thể làm với đối tượng biến này) và các thuộc tính.

Hãy gọi $TimeNow.DayOfYear - chúng tôi nhận được số ngày trong năm.
Hãy gọi $TimeNow.DayOfYear | Get-Member - chúng tôi nhận được TypeName: System.Int32 và một nhóm phương pháp
Hãy gọi $TimeNow.ToUniversalTime() - và lấy thời gian ở UTC

Trình gỡ lỗi

Đôi khi cần phải thực thi một chương trình đến một dòng nhất định và xem trạng thái của chương trình tại thời điểm đó. Với mục đích này, ISE có chức năng Gỡ lỗi - chuyển đổi điểm ngắt
Đặt một điểm ngắt ở đâu đó ở giữa, chạy hai dòng này và xem điểm ngắt trông như thế nào.

3. Hiểu sự tương tác với bot Telegram

Tất nhiên, thậm chí còn có nhiều tài liệu được viết hơn về sự tương tác với bot, với tất cả các getpush, v.v., nhưng vấn đề lý thuyết có thể được xem xét tùy ý.

Trong trường hợp của chúng tôi, nó là cần thiết:

  • Học cách gửi một cái gì đó qua thư từ
  • Học cách nhận được điều gì đó từ thư từ

3.1 Học cách gửi thư từ và nhận từ nó

Một chút mật mã - phần 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

và tại Liên bang Nga tại thời điểm này, chúng tôi gặp lỗi Không thể kết nối với máy chủ từ xa.

Hoặc chúng tôi không nhận được - tùy thuộc vào nhà khai thác viễn thông và liệu proxy có được định cấu hình và hoạt động hay không
Chà, tất cả những gì còn lại là thêm proxy. Xin lưu ý rằng việc sử dụng proxy không được mã hóa và nói chung là lừa đảo là cực kỳ nguy hiểm cho sức khỏe của bạn.

Nhiệm vụ tìm proxy hoạt động không khó lắm - hầu hết các proxy http được xuất bản đều hoạt động. Tôi nghĩ cách thứ năm có tác dụng với tôi.

Cú pháp sử dụng proxy:

Invoke-WebRequest -Uri $URL4SEND -Proxy $MyProxy

Nếu bạn nhận được tin nhắn trong cuộc trò chuyện với bot thì mọi thứ đều ổn, bạn có thể tiếp tục. Nếu không, hãy tiếp tục gỡ lỗi.

Bạn có thể xem chuỗi $URL4SEND của mình biến thành gì và thử yêu cầu chuỗi đó trong trình duyệt, như sau:

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

3.2. Chúng ta đã học cách viết “thứ gì đó” trong trò chuyện, bây giờ hãy thử đọc nó

Hãy thêm 4 dòng nữa và xem bên trong có gì | nhận thành viên

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

Điều thú vị nhất được cung cấp cho chúng tôi

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

Hãy xem có gì trong chúng:

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

Nếu mọi thứ phù hợp với bạn, bạn sẽ nhận được một hàng dài như:

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

May mắn thay, trong bài viết Telegram bot dành cho quản trị hệ thống đã xuất bản trước đây có dòng này (vâng, theo $MyMessageGet.RawContent | lấy thành viên là System.String), đã được tháo rời.

4. Xử lý những gì bạn nhận được (chúng tôi đã biết cách gửi một cái gì đó)

Như đã viết đây, điều cần thiết nhất nằm ở nội dung. Chúng ta hãy xem xét kỹ hơn về nó.

Đầu tiên, chúng ta sẽ viết thêm một vài cụm từ cho bot từ giao diện web hoặc từ điện thoại

/message1
/message2
/message3

và xem qua trình duyệt tại địa chỉ được tạo trong biến $URLGET.

Chúng ta sẽ thấy một cái gì đó như:

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

Nó là gì? Một số đối tượng phức tạp từ mảng đối tượng chứa mã định danh tin nhắn đầu cuối, mã định danh trò chuyện, mã định danh gửi và nhiều thông tin khác.

Tuy nhiên, chúng ta không cần phải tìm hiểu “đây là loại vật thể gì” - một phần công việc đã được thực hiện cho chúng ta. Chúng ta hãy xem những gì bên trong:

Đọc tin nhắn đã nhận hoặc phần 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. Chúng ta nên làm gì bây giờ?

Hãy lưu tệp kết quả dưới tên myfirstbotBT105 hoặc bất cứ tên nào bạn thích nhất, thay đổi tiêu đề và nhận xét tất cả mã đã viết qua

<#start comment 105 end comment 105#>

Bây giờ chúng ta cần quyết định nơi lấy từ điển (à, ở đâu - trên đĩa trong một tệp) và nó sẽ trông như thế nào.

Tất nhiên, bạn có thể viết một cuốn từ điển khổng lồ ngay trong văn bản của kịch bản, nhưng điều này hoàn toàn không phù hợp.
Vậy hãy xem powershell có thể hoạt động bình thường với những gì.
Nói chung, anh ấy không quan tâm nên làm việc với tập tin nào, điều đó không quan trọng đối với chúng tôi.
Chúng tôi có lựa chọn: txt (bạn có thể, nhưng tại sao), csv, xml.
Chúng ta có thể xem mọi người được không?
Hãy tạo một lớp MyVocabClassExample1 và một biến $MyVocabExample1
Tôi lưu ý rằng lớp được viết không có $

một số mã số 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

Hãy thử viết cái này vào tập tin bằng cách sử dụng gương mẫu.

Một số mã #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à chúng tôi gặp lỗi trên dòng Out-File -FilePath $MyFilenameExample01 -InputObject -Append $MyVocabExample2.

Anh ấy không muốn thêm vào, à-ah, thật đáng tiếc.

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

Hãy xem điều gì sẽ xảy ra. Chế độ xem văn bản tuyệt vời - nhưng làm cách nào để xuất lại? Tôi có nên giới thiệu một số loại dấu phân cách văn bản, chẳng hạn như dấu phẩy không?

Và cuối cùng bạn nhận được một “tệp A có giá trị được phân tách bằng dấu phẩy (CSV) A DỪNG ĐỢI.
#

$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 

Như dễ thấy, MS không được phân biệt đặc biệt bởi logic của nó; đối với một quy trình tương tự, trong một trường hợp -FilePath được sử dụng, trong một trường hợp khác -Path.

Ngoài ra, trong tệp thứ ba, tiếng Nga đã biến mất, trong tệp thứ tư, hóa ra... à, đã có chuyện gì đó xảy ra. #TYPE System.Object[] 00
# “Đếm”,,”Độ dài”,,”Độ dài dài”,,”Xếp hạng”,,”SyncRoot”,”IsReadOnly”,,”IsFixedSize”,,”IsSynchronized”
#
Hãy viết lại nó một chút:

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

Có vẻ như nó đã giúp ích nhưng tôi vẫn không thích định dạng này.

Tôi đặc biệt không thích việc không thể đặt trực tiếp các dòng từ một đối tượng vào một tệp.
Nhân tiện, vì chúng ta đã bắt đầu ghi vào tệp, chúng ta có thể bắt đầu ghi nhật ký khởi động không? Chúng ta có thời gian như một biến, chúng ta có thể đặt tên tệp.

Đúng là chưa có gì để viết, nhưng bạn có thể nghĩ về cách tốt nhất để xoay các bản ghi.
Bây giờ hãy thử xml.

Một số 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

Xuất sang xml có nhiều ưu điểm - dễ đọc, xuất toàn bộ đối tượng và không cần thực hiện chi phí bổ sung.

Попробуем đọc tập tin xml.

Một chút đọc từ xml

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

Hãy quay trở lại nhiệm vụ. Chúng tôi đã viết một tệp thử nghiệm, đọc nó, định dạng lưu trữ rõ ràng, nếu cần, bạn có thể viết một trình chỉnh sửa tệp nhỏ riêng biệt để thêm và xóa dòng.

Hãy để tôi nhắc bạn rằng nhiệm vụ là tạo ra một robot huấn luyện nhỏ.

Hình thức làm việc: Tôi gửi lệnh “ví dụ” cho bot, bot gửi cho tôi một từ và bản phiên âm được chọn ngẫu nhiên, sau 10 giây sẽ gửi cho tôi bản dịch và nhận xét. Chúng tôi biết cách đọc lệnh, chúng tôi cũng muốn tìm hiểu cách tự động chọn và kiểm tra proxy cũng như đặt lại bộ đếm tin nhắn vào quên lãng.

Hãy bỏ ghi chú mọi thứ trước đây được nhận xét là không cần thiết, nhận xét các ví dụ hiện không cần thiết với txt và csv, đồng thời lưu tệp dưới dạng phiên bản B106

Ồ vâng. Hãy gửi lại thứ gì đó cho bot.

6. Điều phối từ các chức năng và hơn thế nữa

Trước khi xử lý việc tiếp nhận, bạn cần tạo một chức năng để gửi “ít nhất một thứ gì đó” ngoài tin nhắn kiểm tra.

Tất nhiên, trong ví dụ chúng ta sẽ chỉ có một lần gửi và một lần xử lý, nhưng nếu chúng ta cần làm điều tương tự nhiều lần thì sao?

Viết một hàm dễ dàng hơn. Vì vậy, chúng ta có một biến kiểu đối tượng $MyVocabExample4AsArray, được đọc từ tệp, ở dạng một mảng có tối đa hai phần tử.
Chúng ta hãy đi đọc.

Đồng thời, chúng ta sẽ xử lý đồng hồ; chúng ta sẽ cần nó sau này (thực tế, trong ví dụ này chúng ta sẽ không cần nó :)

Một số mã #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
}

Như bạn có thể dễ dàng thấy, hàm này gọi $MyToken và $MyChatID, đã được mã hóa cứng trước đó.

Không cần phải làm điều này và nếu $MyToken là một cho mỗi bot thì $MyChatID sẽ thay đổi tùy thuộc vào cuộc trò chuyện.

Tuy nhiên, vì đây là một ví dụ nên chúng tôi sẽ bỏ qua nó ngay bây giờ.

Vì $MyVocabExample4AsArray không phải là một mảng, mặc dù nó rất giống với một mảng, nên bạn không thể chỉ lấy nó yêu cầu độ dài của nó.

Một lần nữa chúng ta sẽ phải làm một việc không thể làm được - nhảy dù không đúng mã - cầm lấy và đếm

Một số mã #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)
# Угадайте сами, какой пример легче читается посторонними людьми.

ngẫu nhiên tính năng thú vị. Giả sử chúng ta muốn nhận 0 hoặc 1 (chúng ta chỉ có hai phần tử trong mảng). Khi đặt ranh giới 0..1, liệu chúng ta có nhận được “1” không?
không - chúng tôi sẽ không hiểu, chúng tôi có một ví dụ đặc biệt Ví dụ 2: Lấy một số nguyên ngẫu nhiên trong khoảng từ 0 đến 99 Get-Random -Maximum 100
Do đó, đối với 0..1 chúng ta cần đặt kích thước 0..2, với số phần tử tối đa = 1.

7. Xử lý tin nhắn đến và độ dài hàng đợi tối đa

Chúng ta đã dừng lại ở đâu trước đó? chúng tôi có biến nhận được $MyMessageGet
và $Content4Pars01 thu được từ nó, trong đó chúng tôi quan tâm đến các phần tử của mảng Content4Pars01.result

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

Hãy gửi bot /message10, /message11, /message12, /word và một lần nữa /word và /hello.
Hãy xem những gì chúng ta có:

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

Hãy xem qua mọi thứ đã nhận được và gửi phản hồi nếu tin nhắn là /word
trường hợp cấu trúc, cái mà một số người mô tả là if-elseif, được gọi trong powershell thông qua công tắc. Đồng thời, đoạn mã bên dưới sử dụng khóa -wildcard, điều này hoàn toàn không cần thiết và thậm chí có hại.

Một số mã #7.1

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

Hãy chạy tập lệnh một vài lần. Chúng tôi sẽ nhận được cùng một từ hai lần cho mỗi lần thực hiện, đặc biệt nếu chúng tôi mắc lỗi khi triển khai ngẫu nhiên.

Nhưng dừng lại. Chúng tôi đã không gửi lại /word, vậy tại sao tin nhắn lại được xử lý lại?

Hàng đợi gửi tin nhắn đến bot có độ dài hữu hạn (tôi nghĩ là 100 hoặc 200 tin nhắn) và phải được xóa thủ công.

Tất nhiên điều này được mô tả trong tài liệu, nhưng bạn phải đọc nó!

Trong trường hợp này, chúng tôi cần tham số ?chat_id và &timeout, &limit, &parse_mode=HTML và &disable_web_page_preview=true chưa cần thiết.

Tài liệu cho api điện tín ở đây
Nó nói bằng màu trắng và tiếng Anh:
Mã định danh của bản cập nhật đầu tiên được trả về. Phải lớn hơn một so với giá trị cao nhất trong số các giá trị nhận dạng của các bản cập nhật đã nhận trước đó. Theo mặc định, các bản cập nhật bắt đầu sớm nhất
chưa được xác nhận cập nhật được trả lại. Một bản cập nhật được coi là đã được xác nhận ngay khi getUpdates được gọi với một bù đắp cao hơn hơn update_id của nó. Giá trị bù trừ âm có thể được chỉ định để truy xuất các bản cập nhật bắt đầu từ -offset update từ cuối hàng đợi cập nhật. Tất cả các cập nhật trước đó sẽ bị lãng quên.

Chúng ta hãy nhìn vào:

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

Có, chúng tôi sẽ đặt lại và viết lại hàm một chút. Chúng tôi có hai tùy chọn - chuyển toàn bộ thông báo đến hàm và xử lý nó hoàn toàn trong hàm hoặc chỉ cung cấp ID thông báo và đặt lại. Ví dụ, cái thứ hai trông đơn giản hơn.

Trước đây, chuỗi truy vấn “tất cả tin nhắn” của chúng tôi trông giống như

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

và nó sẽ trông giống như

$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 

Không ai cấm bạn trước tiên nhận tất cả tin nhắn, xử lý chúng và chỉ sau khi xử lý thành công yêu cầu chưa được xác nhận -> được xác nhận.

Tại sao việc gọi xác nhận sau khi quá trình xử lý đã hoàn tất lại có ý nghĩa? Có thể xảy ra lỗi trong quá trình thực thi và nếu chẳng hạn như một chatbot miễn phí, việc thiếu một tin nhắn không có gì đặc biệt, thì nếu bạn đang xử lý tiền lương hoặc giao dịch thẻ của ai đó, kết quả có thể còn tồi tệ hơn.

Một vài dòng mã nữa

$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. Thay vì kết luận

Các chức năng cơ bản - đọc tin nhắn, đặt lại hàng đợi, đọc từ tệp và ghi vào tệp được thực hiện và hiển thị.

Chỉ còn bốn việc phải làm:

  • gửi câu trả lời đúng cho yêu cầu trong trò chuyện
  • gửi phản hồi tới BẤT KỲ cuộc trò chuyện nào mà bot đã được thêm vào
  • thực thi mã trong một vòng lặp
  • khởi chạy bot từ bộ lập lịch của windows.

Tất cả các tác vụ này đều đơn giản và có thể dễ dàng thực hiện bằng cách đọc tài liệu về các tham số như
Set-ExecutionPolicy Unrestricted và -ExecutionPolicy Bypass
chu kỳ của hình thức

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

Cảm ơn mọi người đã đọc.

Nguồn: www.habr.com

Thêm một lời nhận xét