Skip to content

Commit c44f246

Browse files
committed
initial commit
1 parent 1d7b38e commit c44f246

9 files changed

+451
-0
lines changed

Telegram/API.cls

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
/// êëàññ äëÿ ðàáîòû ñ API Telegram
2+
Class Telegram.API Extends %RegisteredObject
3+
{
4+
5+
Property Token as %String;
6+
7+
Parameter SERVER = "api.telegram.org";
8+
9+
Property SSLConfiguration as %String;
10+
11+
Method GetRequestObj() as %Net.HttpRequest [Private ]
12+
{
13+
#dim request as %Net.HttpRequest
14+
set request = ##class(%Net.HttpRequest).%New()
15+
set request.Server = ..#SERVER
16+
set request.SSLConfiguration = ..SSLConfiguration
17+
set request.Https = 1
18+
return request
19+
}
20+
21+
Method ExecuteRequest(request as %Net.HttpRequest, method as %String) as %DynamicObject [Private ]
22+
{
23+
set st = request.Post("bot"_..Token_"/"_method)
24+
if ($$$ISERR(st)) {
25+
throw ##class(%Exception.StatusException).CreateFromStatus(st)
26+
}
27+
return ##class(%Library.DynamicObject).%FromJSON(request.HttpResponse.Data)
28+
}
29+
30+
Method %OnNew(token as %String, ssl as %String) as %Status [Private ]
31+
{
32+
return:(token="" || ssl="") 0
33+
set ..Token = token
34+
set ..SSLConfiguration = ssl
35+
return $$$OK
36+
}
37+
38+
Method GetMe() as %DynamicObject
39+
{
40+
return ..ExecuteRequest(..GetRequestObj(), "getMe")
41+
}
42+
43+
Method GetUpdates(offset as %Integer = "", limit as %Integer = 100, timeout as %Integer = 0) as %DynamicObject
44+
{
45+
#dim request as %Net.HttpRequest
46+
set request = ..GetRequestObj()
47+
if (offset'="") {
48+
do request.InsertFormData("offset",offset)
49+
}
50+
do request.InsertFormData("limit",limit)
51+
do request.InsertFormData("timeout",timeout)
52+
return ..ExecuteRequest(request, "getUpdates")
53+
}
54+
55+
Method SendMessage(chatId as %Integer,
56+
text as %String,
57+
parseMode as %String = "",
58+
disableWebPagePreview as %Boolean = 0,
59+
disableNotification as %Boolean = 0,
60+
replyToMessageId as %Integer = 0,
61+
replyMarkup as %DynamicObject = 0) as %DynamicObject
62+
{
63+
#dim request as %Net.HttpRequest
64+
set request = ..GetRequestObj()
65+
do request.InsertFormData("chat_id",chatId)
66+
do request.InsertFormData("text",text)
67+
if (replyMarkup'=0) {
68+
do request.InsertFormData("reply_markup",replyMarkup.%ToJSON())
69+
}
70+
return ..ExecuteRequest(request, "sendMessage")
71+
}
72+
/// First create instance of Telegram.API:
73+
/// set api = ##class(Telegram.API).%New(token, <ssl_configuration_name)
74+
/// Set webhook with
75+
/// write api.SetWebhook(url,certificate_folder, certificate_filename).%ToJSON()
76+
Method SetWebhook(url as %String, filedir as %String, filename as %String) as %DynamicObject
77+
{
78+
Set SentHttpRequest=..GetRequestObj()
79+
80+
Set RootMIMEPart = ##class(%Net.MIMEPart).%New()
81+
82+
Set BinaryMIMEPart = ##class(%Net.MIMEPart).%New()
83+
Set contentdisp = "form-data; name="_$CHAR(34)_"certificate"_$CHAR(34)_"; filename="
84+
_$CHAR(34)_""_filename_""_$CHAR(34)
85+
Do BinaryMIMEPart.SetHeader("Content-Disposition",contentdisp)
86+
87+
Set stream=##class(%FileBinaryStream).%New()
88+
Set stream.Filename=filedir_filename
89+
Do stream.LinkToFile(filedir_filename)
90+
91+
Set BinaryMIMEPart.Body=stream
92+
Do BinaryMIMEPart.SetHeader("Content-Type","text/plain")
93+
94+
Do RootMIMEPart.Parts.Insert(BinaryMIMEPart)
95+
96+
Set TextMIMEPart=##class(%Net.MIMEPart).%New()
97+
Set TextMIMEPart.Body=##class(%GlobalCharacterStream).%New()
98+
Do TextMIMEPart.Body.Write(url)
99+
100+
Set contentdisp = "form-data; name="_$CHAR(34)_"url"_$CHAR(34)_";"
101+
Do TextMIMEPart.SetHeader("Content-Disposition",contentdisp)
102+
103+
Do RootMIMEPart.Parts.Insert(TextMIMEPart)
104+
105+
Set writer=##class(%Net.MIMEWriter).%New()
106+
107+
Set status=writer.OutputToStream(SentHttpRequest.EntityBody)
108+
if $$$ISERR(status) {do $SYSTEM.Status.DisplayError(status) Quit}
109+
110+
Set status=writer.WriteMIMEBody(RootMIMEPart)
111+
if $$$ISERR(status) {do $SYSTEM.Status.DisplayError(status) Quit}
112+
113+
114+
//do SentHttpRequest.InsertFormData("url",url)
115+
116+
Set ContentType= "multipart/form-data; boundary="_RootMIMEPart.Boundary
117+
Set SentHttpRequest.ContentType=ContentType
118+
119+
set st = SentHttpRequest.Post("bot"_..Token_"/setWebhook")
120+
121+
122+
return ##class(%Library.DynamicObject).%FromJSON(SentHttpRequest.HttpResponse.Data)
123+
}
124+
125+
Method DeleteWebhook() as %DynamicObject
126+
{
127+
return ..ExecuteRequest(..GetRequestObj(), "deleteWebhook")
128+
}
129+
130+
Method GetWebhookInfo() as %DynamicObject
131+
{
132+
return ..ExecuteRequest(..GetRequestObj(), "getWebhookInfo")
133+
}
134+
135+
}

Telegram/AlertOperation.cls

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
Class Telegram.AlertOperation extends Ens.BusinessOperation {
2+
3+
Parameter ADAPTER = "Telegram.TelegramOutboundAdapter";
4+
5+
Property Adapter As Telegram.TelegramOutboundAdapter;
6+
7+
Parameter INVOCATION = "Queue";
8+
9+
Property TableName as %String;
10+
11+
Parameter SETTINGS = "TableName";
12+
13+
Method SendAlert(pInput As Ens.AlertRequest, Output pOutput As Ens.Response) As %Status
14+
{
15+
set tableName = ..TableName
16+
return:(tableName="") $$$ERROR($$$GeneralError, "TableName íå îïðåäåëåíî")
17+
18+
// íàõîäèì âñåõ êòî ïîäïèñàí íà àëåðòû
19+
&sql(DECLARE chats CURSOR FOR
20+
SELECT DataValue FROM Ens_Util.LookupTable WHERE DataValue!='' AND TableName = :tableName)
21+
&sql(OPEN chats)
22+
while (1) {
23+
&sql(FETCH chats INTO :chatId)
24+
$$$TRACE(SQLCODE)
25+
quit:(SQLCODE'=0)
26+
do ..Adapter.SendMessage(chatId,"Alert!"_$$$NL_pInput.SourceConfigName_$$$NL_pInput.AlertText)
27+
}
28+
&sql(CLOSE chats)
29+
return $$$OK
30+
}
31+
32+
XData MessageMap {
33+
<MapItems>
34+
<MapItem MessageType="Ens.AlertRequest">
35+
<Method>SendAlert</Method>
36+
</MapItem>
37+
</MapItems>
38+
}
39+
40+
41+
}

Telegram/Broker.cls

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
Class REST.Broker Extends %CSP.REST
2+
{
3+
XData UrlMap
4+
{
5+
<Routes>
6+
<Route Url="/update" Method="POST" Call="ProcessUpdate" />
7+
</Routes>
8+
}
9+
10+
11+
ClassMethod ProcessUpdate() as %Status
12+
{
13+
set obj = ##class(%DynamicAbstractObject).%FromJSON(%request.Content)
14+
15+
//set ^t($h) = obj.%ToJSON() // log all updates
16+
17+
Set tSC=$$$OK
18+
do {
19+
Set tSC=##class(Ens.Director).CreateBusinessService("Telegram.TelegramService",.tService)
20+
If ($$$ISERR(tSC)) Quit
21+
Set tSC=tService.ProcessInput(obj,.output)
22+
If ($$$ISERR(tSC)) Quit
23+
} while (0)
24+
If ($$$ISERR(tSC)) {
25+
// Error: assume system is not running
26+
}
27+
return $$$OK
28+
}
29+
30+
}

Telegram/Msg/ButtonRequest.cls

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
Class Telegram.Msg.ButtonRequest Extends Ens.Request
2+
{
3+
4+
Property ChatId As %Integer;
5+
/// òåêñò ñîîáùåíèÿ
6+
Property Text as %String (MAXLEN=5000);
7+
/// òåêñò íà êíîïêå
8+
Property Button as %String;
9+
10+
11+
Storage Default
12+
{
13+
<Data name="ButtonRequestDefaultData">
14+
<Subscript>"ButtonRequest"</Subscript>
15+
<Value name="1">
16+
<Value>ChatId</Value>
17+
</Value>
18+
<Value name="2">
19+
<Value>Text</Value>
20+
</Value>
21+
<Value name="3">
22+
<Value>Button</Value>
23+
</Value>
24+
</Data>
25+
<DefaultData>ButtonRequestDefaultData</DefaultData>
26+
<Type>%Library.CacheStorage</Type>
27+
}
28+
29+
}

Telegram/Msg/TextRequest.cls

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
Class Telegram.Msg.TextRequest Extends Ens.Request
2+
{
3+
Property ChatId As %Integer;
4+
Property Text as %String (MAXLEN=5000);
5+
Storage Default
6+
{
7+
<Data name="TextRequestDefaultData">
8+
<Subscript>"TextRequest"</Subscript>
9+
<Value name="1">
10+
<Value>ChatId</Value>
11+
</Value>
12+
<Value name="2">
13+
<Value>Text</Value>
14+
</Value>
15+
</Data>
16+
<DefaultData>TextRequestDefaultData</DefaultData>
17+
<Type>%Library.CacheStorage</Type>
18+
}
19+
20+
}

Telegram/TelegramInboundAdapter.cls

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/// ãëîáàë ^Telegram.ProcessedUpdateId èñïîëüçóåòñÿ äëÿ õðàíåíèÿ ID ïîñëåäíåãî îáðàáîòàííîãî ñîîáùåíèÿ
2+
Class Telegram.TelegramInboundAdapter Extends Ens.InboundAdapter
3+
{
4+
5+
Property TelegramToken As %String;
6+
7+
Property SSLConfiguration As %String;
8+
9+
Property API as Telegram.API [ Private ];
10+
11+
Property Updates as %DynamicArray [ Private ];
12+
13+
Parameter SETTINGS = "TelegramToken,SSLConfiguration";
14+
15+
Method OnInit() As %Status
16+
{
17+
set ..API = ##class(Telegram.API).%New(..TelegramToken, ..SSLConfiguration)
18+
if '$isobject(..API) {
19+
return $$$ERROR($$$GeneralError,"API object doesn't created, check Bot token and SSL configuration")
20+
}
21+
set ..Updates = []
22+
return $$$OK
23+
}
24+
25+
Method ProcessUpdates(pOutput) {
26+
set updateObj = ..Updates.%Get(0)
27+
return:(updateObj="") $$$OK
28+
29+
set st = ..BusinessHost.ProcessInput(updateObj,.pOutput)
30+
if ($$$ISOK(st)) {
31+
set ^Telegram.ProcessedUpdateId = updateObj."update_id"
32+
do ..Updates.%Remove(0)
33+
}
34+
return st
35+
}
36+
37+
Method OnTask() As %Status
38+
{
39+
try {
40+
set updateObj = ..Updates.%Get(0)
41+
if (updateObj="") {
42+
set res = ..API.GetUpdates(1+$Get(^Telegram.ProcessedUpdateId))
43+
if (res.ok) {
44+
set ..Updates = res.result
45+
} else {
46+
return $$$ERROR($$$GeneralError,"No data received from API, check Bot token")
47+
}
48+
}
49+
50+
set st = ..ProcessUpdates(.pOutput)
51+
} catch e {
52+
return e.AsStatus()
53+
}
54+
55+
return st
56+
}
57+
58+
}

Telegram/TelegramOperation.cls

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
Class Telegram.TelegramOperation extends Ens.BusinessOperation {
2+
3+
Parameter ADAPTER = "Telegram.TelegramOutboundAdapter";
4+
5+
Parameter INVOCATION = "Queue";
6+
7+
Property Adapter as Telegram.TelegramOutboundAdapter;
8+
9+
Method SendMessage(pInput As Telegram.Msg.TextRequest, Output pOutput As Ens.Response) As %Status
10+
{
11+
Quit ..Adapter.SendMessage(pInput.ChatId,pInput.Text,1)
12+
}
13+
14+
Method SendButton(pInput As Telegram.Msg.ButtonRequest, Output pOutput As Ens.Response) As %Status
15+
{
16+
Quit ..Adapter.SendButton(pInput.ChatId,pInput.Text,pInput.Button,1)
17+
}
18+
19+
20+
XData MessageMap {
21+
<MapItems>
22+
<MapItem MessageType="Telegram.Msg.TextRequest">
23+
<Method>SendMessage</Method>
24+
</MapItem>
25+
<MapItem MessageType="Telegram.Msg.ButtonRequest">
26+
<Method>SendButton</Method>
27+
</MapItem>
28+
</MapItems>
29+
}
30+
31+
}

0 commit comments

Comments
 (0)