Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
nsolov committed Apr 1, 2018
1 parent 1d7b38e commit c44f246
Show file tree
Hide file tree
Showing 9 changed files with 451 additions and 0 deletions.
135 changes: 135 additions & 0 deletions Telegram/API.cls
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
/// êëàññ äëÿ ðàáîòû ñ API Telegram
Class Telegram.API Extends %RegisteredObject
{

Property Token as %String;

Parameter SERVER = "api.telegram.org";

Property SSLConfiguration as %String;

Method GetRequestObj() as %Net.HttpRequest [Private ]
{
#dim request as %Net.HttpRequest
set request = ##class(%Net.HttpRequest).%New()
set request.Server = ..#SERVER
set request.SSLConfiguration = ..SSLConfiguration
set request.Https = 1
return request
}

Method ExecuteRequest(request as %Net.HttpRequest, method as %String) as %DynamicObject [Private ]
{
set st = request.Post("bot"_..Token_"/"_method)
if ($$$ISERR(st)) {
throw ##class(%Exception.StatusException).CreateFromStatus(st)
}
return ##class(%Library.DynamicObject).%FromJSON(request.HttpResponse.Data)
}

Method %OnNew(token as %String, ssl as %String) as %Status [Private ]
{
return:(token="" || ssl="") 0
set ..Token = token
set ..SSLConfiguration = ssl
return $$$OK
}

Method GetMe() as %DynamicObject
{
return ..ExecuteRequest(..GetRequestObj(), "getMe")
}

Method GetUpdates(offset as %Integer = "", limit as %Integer = 100, timeout as %Integer = 0) as %DynamicObject
{
#dim request as %Net.HttpRequest
set request = ..GetRequestObj()
if (offset'="") {
do request.InsertFormData("offset",offset)
}
do request.InsertFormData("limit",limit)
do request.InsertFormData("timeout",timeout)
return ..ExecuteRequest(request, "getUpdates")
}

Method SendMessage(chatId as %Integer,
text as %String,
parseMode as %String = "",
disableWebPagePreview as %Boolean = 0,
disableNotification as %Boolean = 0,
replyToMessageId as %Integer = 0,
replyMarkup as %DynamicObject = 0) as %DynamicObject
{
#dim request as %Net.HttpRequest
set request = ..GetRequestObj()
do request.InsertFormData("chat_id",chatId)
do request.InsertFormData("text",text)
if (replyMarkup'=0) {
do request.InsertFormData("reply_markup",replyMarkup.%ToJSON())
}
return ..ExecuteRequest(request, "sendMessage")
}
/// First create instance of Telegram.API:
/// set api = ##class(Telegram.API).%New(token, <ssl_configuration_name)
/// Set webhook with
/// write api.SetWebhook(url,certificate_folder, certificate_filename).%ToJSON()
Method SetWebhook(url as %String, filedir as %String, filename as %String) as %DynamicObject
{
Set SentHttpRequest=..GetRequestObj()

Set RootMIMEPart = ##class(%Net.MIMEPart).%New()

Set BinaryMIMEPart = ##class(%Net.MIMEPart).%New()
Set contentdisp = "form-data; name="_$CHAR(34)_"certificate"_$CHAR(34)_"; filename="
_$CHAR(34)_""_filename_""_$CHAR(34)
Do BinaryMIMEPart.SetHeader("Content-Disposition",contentdisp)

Set stream=##class(%FileBinaryStream).%New()
Set stream.Filename=filedir_filename
Do stream.LinkToFile(filedir_filename)

Set BinaryMIMEPart.Body=stream
Do BinaryMIMEPart.SetHeader("Content-Type","text/plain")

Do RootMIMEPart.Parts.Insert(BinaryMIMEPart)

Set TextMIMEPart=##class(%Net.MIMEPart).%New()
Set TextMIMEPart.Body=##class(%GlobalCharacterStream).%New()
Do TextMIMEPart.Body.Write(url)

Set contentdisp = "form-data; name="_$CHAR(34)_"url"_$CHAR(34)_";"
Do TextMIMEPart.SetHeader("Content-Disposition",contentdisp)

Do RootMIMEPart.Parts.Insert(TextMIMEPart)

Set writer=##class(%Net.MIMEWriter).%New()

Set status=writer.OutputToStream(SentHttpRequest.EntityBody)
if $$$ISERR(status) {do $SYSTEM.Status.DisplayError(status) Quit}

Set status=writer.WriteMIMEBody(RootMIMEPart)
if $$$ISERR(status) {do $SYSTEM.Status.DisplayError(status) Quit}


//do SentHttpRequest.InsertFormData("url",url)

Set ContentType= "multipart/form-data; boundary="_RootMIMEPart.Boundary
Set SentHttpRequest.ContentType=ContentType

set st = SentHttpRequest.Post("bot"_..Token_"/setWebhook")


return ##class(%Library.DynamicObject).%FromJSON(SentHttpRequest.HttpResponse.Data)
}

Method DeleteWebhook() as %DynamicObject
{
return ..ExecuteRequest(..GetRequestObj(), "deleteWebhook")
}

Method GetWebhookInfo() as %DynamicObject
{
return ..ExecuteRequest(..GetRequestObj(), "getWebhookInfo")
}

}
41 changes: 41 additions & 0 deletions Telegram/AlertOperation.cls
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
Class Telegram.AlertOperation extends Ens.BusinessOperation {

Parameter ADAPTER = "Telegram.TelegramOutboundAdapter";

Property Adapter As Telegram.TelegramOutboundAdapter;

Parameter INVOCATION = "Queue";

Property TableName as %String;

Parameter SETTINGS = "TableName";

Method SendAlert(pInput As Ens.AlertRequest, Output pOutput As Ens.Response) As %Status
{
set tableName = ..TableName
return:(tableName="") $$$ERROR($$$GeneralError, "TableName íå îïðåäåëåíî")

// íàõîäèì âñåõ êòî ïîäïèñàí íà àëåðòû
&sql(DECLARE chats CURSOR FOR
SELECT DataValue FROM Ens_Util.LookupTable WHERE DataValue!='' AND TableName = :tableName)
&sql(OPEN chats)
while (1) {
&sql(FETCH chats INTO :chatId)
$$$TRACE(SQLCODE)
quit:(SQLCODE'=0)
do ..Adapter.SendMessage(chatId,"Alert!"_$$$NL_pInput.SourceConfigName_$$$NL_pInput.AlertText)
}
&sql(CLOSE chats)
return $$$OK
}

XData MessageMap {
<MapItems>
<MapItem MessageType="Ens.AlertRequest">
<Method>SendAlert</Method>
</MapItem>
</MapItems>
}


}
30 changes: 30 additions & 0 deletions Telegram/Broker.cls
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
Class REST.Broker Extends %CSP.REST
{
XData UrlMap
{
<Routes>
<Route Url="/update" Method="POST" Call="ProcessUpdate" />
</Routes>
}


ClassMethod ProcessUpdate() as %Status
{
set obj = ##class(%DynamicAbstractObject).%FromJSON(%request.Content)

//set ^t($h) = obj.%ToJSON() // log all updates

Set tSC=$$$OK
do {
Set tSC=##class(Ens.Director).CreateBusinessService("Telegram.TelegramService",.tService)
If ($$$ISERR(tSC)) Quit
Set tSC=tService.ProcessInput(obj,.output)
If ($$$ISERR(tSC)) Quit
} while (0)
If ($$$ISERR(tSC)) {
// Error: assume system is not running
}
return $$$OK
}

}
29 changes: 29 additions & 0 deletions Telegram/Msg/ButtonRequest.cls
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
Class Telegram.Msg.ButtonRequest Extends Ens.Request
{

Property ChatId As %Integer;
/// òåêñò ñîîáùåíèÿ
Property Text as %String (MAXLEN=5000);
/// òåêñò íà êíîïêå
Property Button as %String;


Storage Default
{
<Data name="ButtonRequestDefaultData">
<Subscript>"ButtonRequest"</Subscript>
<Value name="1">
<Value>ChatId</Value>
</Value>
<Value name="2">
<Value>Text</Value>
</Value>
<Value name="3">
<Value>Button</Value>
</Value>
</Data>
<DefaultData>ButtonRequestDefaultData</DefaultData>
<Type>%Library.CacheStorage</Type>
}

}
20 changes: 20 additions & 0 deletions Telegram/Msg/TextRequest.cls
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
Class Telegram.Msg.TextRequest Extends Ens.Request
{
Property ChatId As %Integer;
Property Text as %String (MAXLEN=5000);
Storage Default
{
<Data name="TextRequestDefaultData">
<Subscript>"TextRequest"</Subscript>
<Value name="1">
<Value>ChatId</Value>
</Value>
<Value name="2">
<Value>Text</Value>
</Value>
</Data>
<DefaultData>TextRequestDefaultData</DefaultData>
<Type>%Library.CacheStorage</Type>
}

}
58 changes: 58 additions & 0 deletions Telegram/TelegramInboundAdapter.cls
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/// ãëîáàë ^Telegram.ProcessedUpdateId èñïîëüçóåòñÿ äëÿ õðàíåíèÿ ID ïîñëåäíåãî îáðàáîòàííîãî ñîîáùåíèÿ
Class Telegram.TelegramInboundAdapter Extends Ens.InboundAdapter
{

Property TelegramToken As %String;

Property SSLConfiguration As %String;

Property API as Telegram.API [ Private ];

Property Updates as %DynamicArray [ Private ];

Parameter SETTINGS = "TelegramToken,SSLConfiguration";

Method OnInit() As %Status
{
set ..API = ##class(Telegram.API).%New(..TelegramToken, ..SSLConfiguration)
if '$isobject(..API) {
return $$$ERROR($$$GeneralError,"API object doesn't created, check Bot token and SSL configuration")
}
set ..Updates = []
return $$$OK
}

Method ProcessUpdates(pOutput) {
set updateObj = ..Updates.%Get(0)
return:(updateObj="") $$$OK

set st = ..BusinessHost.ProcessInput(updateObj,.pOutput)
if ($$$ISOK(st)) {
set ^Telegram.ProcessedUpdateId = updateObj."update_id"
do ..Updates.%Remove(0)
}
return st
}

Method OnTask() As %Status
{
try {
set updateObj = ..Updates.%Get(0)
if (updateObj="") {
set res = ..API.GetUpdates(1+$Get(^Telegram.ProcessedUpdateId))
if (res.ok) {
set ..Updates = res.result
} else {
return $$$ERROR($$$GeneralError,"No data received from API, check Bot token")
}
}

set st = ..ProcessUpdates(.pOutput)
} catch e {
return e.AsStatus()
}

return st
}

}
31 changes: 31 additions & 0 deletions Telegram/TelegramOperation.cls
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
Class Telegram.TelegramOperation extends Ens.BusinessOperation {

Parameter ADAPTER = "Telegram.TelegramOutboundAdapter";

Parameter INVOCATION = "Queue";

Property Adapter as Telegram.TelegramOutboundAdapter;

Method SendMessage(pInput As Telegram.Msg.TextRequest, Output pOutput As Ens.Response) As %Status
{
Quit ..Adapter.SendMessage(pInput.ChatId,pInput.Text,1)
}

Method SendButton(pInput As Telegram.Msg.ButtonRequest, Output pOutput As Ens.Response) As %Status
{
Quit ..Adapter.SendButton(pInput.ChatId,pInput.Text,pInput.Button,1)
}


XData MessageMap {
<MapItems>
<MapItem MessageType="Telegram.Msg.TextRequest">
<Method>SendMessage</Method>
</MapItem>
<MapItem MessageType="Telegram.Msg.ButtonRequest">
<Method>SendButton</Method>
</MapItem>
</MapItems>
}

}
Loading

0 comments on commit c44f246

Please sign in to comment.