Oh je da funktioniert im Moment einiges nicht. Willst Du Dir das wirklich antun? Das ist ein ganz schöner "Scheiß" und ich probiere mich doch daran erst seit vorgestern. Andererseits brauche ich auch Hilfe.
Ich entschuldige mich für die nicht funktionierenden Einrückungen. Das entsteht durch Copy-Paste und ist immer viel Arbeit das im Browser so zu editieren das die Einrückungen stimmen.
Code: Select all
#SingleInstance Force
#NoEnv
SetWorkingDir , % A_ScriptDir
SetBatchLines , -1
global q := Chr(0x22)
global MeinBot
; nur ein Teststring - falls man testen will bitte mit eigenen Bot-Daten befüllen!
JSON_Config:=
(LTrim Join
{"1":
{ "Name":"MeinBot_bot",
"Token":"1234567890:ABCDEFGH4gfgdhfg3uh45gfhgh_PGaz1nxW",
"LastOffset":"",
"LastMsgDate":"",
"ReplyTo":[
{ "chatID":"987654321",
"username":"TestUser",
"auth":"admin"}
]
}
}
)
settings := { "BotName" : "MeinBot_bot"
, "BotConfig" : JSON_Config
, "updateInterval" : 30
, "dialogInterval" : 5
, "DialogTimeout" : 120
, "callbackfunc" : "Telegram_Messagehandler"
, "log" : true
, "debug" : true}
MeinBot := new TelegramBot(settings)
MeinBot.StartUpdates()
;TelegramBot.BotsConfigGui(A_ScriptDir "\Telegram_Config.json")
return
Telegram_Messagehandler() {
messages:= MeinBot.GetNewMessages()
MeinBot.print("received: " (MsgMax := messages.MaxIndex()) " new messages")
; loop through message queue
Loop % MsgMax {
msg := messages[A_Index]
MeinBot.print(" " A_Index ". from: " msg.username ", msg: " q msg.text q)
; get user and check if known
user := MeinBot.GetUser(msg.ChatId)
If !IsObject(user) {
MeinBot.print("unknown user with chat_id: " msg.ChatId)
continue
}
; check if it's our admin
If RegExMatch(user.auth, "i)admin") {
; start reply service if not
;---> FUNKTIONIERT SO NICHT
;---> If !IsObject(MeinBot.Reply[user.ChatId]) {
;---> MeinBot.print("user " q user.username "(" user.ChatId ")" q " is admin. Starting reply service now.") <--- das da funktioniert ab so
;---> MeinBot.Reply[user.ChatId].Reply(user.ChatId, user.username, user.auth)
;---> If IsObject(ReplyService[user.ChatId])
;---> MeinBot.print("reply service for user " q user.username "(" user.ChatId ")" q " is established.") <--- das dann auch
}
; is started then generate a response message
;---> If IsObject(ReplyService[user.ChatId]) {
;---> ReplyService[user.ChatId].ParseMessage(msg.text)
;---> }
}
}
MeinBot.print("set new offset: " messages[MsgMax].updateID)
old := MeinBot.GetupDatesOpt.offset
MeinBot.GetupDatesOpt.offset := messages[MsgMax].updateID + 1
MeinBot.print("last offset: " old ", new: " MeinBot.GetupDatesOpt.offset)
}
class TelegramBot {
; setup/handle bots
;----------------------------------------------------------------------------------------------------------------------------------------------
__NEW(settings) { ; setup a new bot
If RegExMatch(settings.BotConfig, "i)\.json\s") && FileExist(settings.BotConfig)
BotConfig := JSON.Load(FileOpen(settings.BotConfig, "r").Read())
else
BotConfig := JSON.Load(settings.BotConfig)
For botNr, BotObj in BotConfig
{
If InStr(BotObj.Name, settings.BotName) {
this.Token := BotObj.Token
this.LastOffset := BotObj.LastOffset
this.LastMsgDate := BotObj.LastMsgDate
this.ReplyTo := BotObj.ReplyTo
}
}
this.URL := "https://api.telegram.org/bot" this.Token "/"
this.CallbackFunc := settings.CallbackFunc
this.ShortName := RegExReplace(settings.BotName, "\_*bot", "")
this.updateInterval := settings.updateInterval
this.dialogInterval := settings.dialogInterval
this.DialogTimeout := settings.DialogTimeout
; for GetUpdates() api calls
this.GetUpdatesOpt:={ "offset" : settings.offset
, "updlimit" : (settings.updlimit ? settings.updlimit : 100)
, "timeout" : (settings.timeout ? settings.timeout : 0)}
this.debug := settings.debug
this.filterReady := 0
}
__Delete() { ; remove this bot
timer := this.timer
SetTimer % timer, Delete
this := ""
}
; get/set variables in TelegramBot object
;----------------------------------------------------------------------------------------------------------------------------------------------
GetVar(ValName) {
return this[ValName]
}
SetVar(ValName, value) {
oldVal := this[ValName]
this[ValName] := value
return oldVal
}
; user settings gui's
;----------------------------------------------------------------------------------------------------------------------------------------------
BotsConfigGui(BotConfigFile) {
static T1, T2, T3, BName, BAdd, BDel, BToken, BReply, BSave, BDiscard, Bots, BotNames, botNr
Bots := JSON.Load(FileOpen(BotConfigFile, "r").Read())
For botNr, BotObj in Bots
BotNames .= A_Index ": " BotObj.Name "|"
botNr:=1
If (A_ScreenWidth > 1920)
FontSize := 12
else
FontSize := 8
FontStyle1 := "s" FontSize+4 " cBlack Bold q5"
FontStyle2 := "s" FontSize+1 " cWhite Bold q5"
FontStyle3 := "s" FontSize " cBlack Normal q5"
FontStyle4 := "s" FontSize-1 " cWhite Normal q5"
Gui, BC: -DPIScale +HWNDhBC
Gui, BC: Margin, 10, 10
Gui, BC: Color , 4EA6E0, c8FC8F2
Gui, BC: Font , % FontStyle1, Lucida Sans Unicode
Gui, BC: Add , ListBox, x90 ym r1 , % RTrim(BotNames, "|")
Gui, BC: Font , % FontStyle3
Gui, BC: Add , Button , x+20 vBAdd , % "Add a bot"
Gui, BC: Add , Button , x+20 vBDel , % "Delete this bot"
Gui, BC: Font , % FontStyle2
Gui, BC: Add , Text , xm y+25 vT1 , % "name"
GuiControlGet, p, BC: Pos, T1
Gui, BC: Font , % FontStyle3
Gui, BC: Add , Edit , % "x90 y" pY " w800 r1 vBName" , % Bots[botNr].Name
Gui, BC: Font , % FontStyle2
Gui, BC: Add , Text , xm vT2 , % "token"
GuiControlGet, p, BC: Pos, T2
Gui, BC: Font , % FontStyle3
Gui, BC: Add , Edit , % "x90 y" pY " w800 r1 vBToken" , % Bots[botNr].Token
Gui, BC: Font , % FontStyle2
Gui, BC: Add , Text , xm vT3 , % "reply to"
Gui, BC: Font , % FontStyle4
GuiControlGet, p, BC: Pos, T3
Gui, BC: Add , Text , % "xm y" pY+pH+3 " w" pW " Center" , % "(filter)"
Gui, BC: Font , % FontStyle3
Gui, BC: Add , Edit , % "x90 y" pY " w800 r20 vBReply" , % ""
Gui, BC: Add , Button , x90 vBSave , % "Save Config"
Gui, BC: Add , Button , x+20 vBDiscard , % "Discard Config"
Gui, BC: Show , AutoSize, Telegram bot configuration
return
BCGuiClose:
BCGuiEscape:
Gui, BC: Destroy
ExitApp
return
}
; timer methods
;----------------------------------------------------------------------------------------------------------------------------------------------
StartUpdates() { ; starting GetUpdates calls with a given interval
; starting onmessage callback if wanted
If (StrLen(this.CallbackFunc) > 0) && IsFunc(this.CallbackFunc) {
Gui, OnMsg: +HWNDhWnd
Gui, OnMsg: +LastFound
this.OnMsgCallbackhWnd := hWnd
OnMessage(0x5555, this.CallbackFunc)
} else {
throw Callback " is not a function.`nThis script will be terminated"
ExitApp
}
; starting the handler function
this.timer := ObjBindMethod(this, "UpdatesHandler")
timer := this.timer
SetTimer, % timer, % (this.updateInterval * 1000)
this.print("update interval is set to " this.updateInterval "s")
; get first updates before starting the timer
this.UpdatesHandler()
}
StopUpdates() { ; stop GetUpdates calls
; stop sendmessage callbacks
OnMessage(0x5555, "")
; stop timer's
timer := this.timer
SetTimer % timer, Off
RestoreTimer := this.RestoreTimer
SetTimer, % RestoreTimer, Delete
this.print("getUpdates stopped")
}
SetUpdatesInterval(new_updateInterval) { ; set update interval
If (StrLen(new_updateInterval) > 0) {
this.interval := new_updateInterval
timer := this.timer
SetTimer, % timer, % (this.interval * 1000)
this.print("update interval is changed to " this.interval "s")
}
}
UpdatesHandler() { ; timed function to get updates from telegram
static tRound
tRound++
oResponse := this.GetUpdates()
If oResponse.ok
this.FilterSenders(oResponse.result)
}
; filter methods
;----------------------------------------------------------------------------------------------------------------------------------------------
FilterSenders(chats) { ; filters by sender who is answered
messages := Object()
this.print("I am here")
For idx, body in chats
{
If body.hasKey("message") {
message := body.message
chat := message.chat
from := message.from
chat := message.chat
oTgram := Object()
oTgram := { "updateID" : body.update_id
, "fromID" : from.id
, "chatID" : chat.id
, "date" : message.date
, "type" : chat.type
, "username" : from.username
, "isbot" : (from.is_bot ? true:false)}
If message.haskey("text") {
oTgram.content := "text"
oTgram.text := message.text
}
}
else if body.haskey("channel_post") {
message := body.channel_post
chat := message.chat
oTgram := Object()
oTgram := { "updateID" : body.update_id
, "chatID" : chat.id
, "chatTitle" : chat.title
, "date" : message.date
, "type" : chat.type
, "username" : chat.username}
If message.haskey("photo") {
oTgram.content := "image"
oTgram.photo := message.photo
}
}
; build a new message object with the only needed senders to reply to
For rIdx, toReply in this.replyTo
{
If (oTgram.ChatId = toReply.ChatId) && (oTgram.username = toReply.username) {
messages.Push(oTgram)
break
}
}
}
;
If (messages.MaxIndex() > 0) {
; store the new messages here
this.messages := messages
; callback by send a message to call a user defined function
SendMessage, 0x5555, 1, 0,, % "ahk_id " this.OnMsgCallbackhWnd
; set timer interval to for faster response, set a timer to fallback to the long polling interval
this.SetUpdatesInterval(this.dialogInterval)
this.RestoreTimer := ObjBindMethod(this, "SetUpdatesInterval", this.updateInterval)
RestoreTimer := this.RestoreTimer
SetTimer, % RestoreTimer, % "-" (this.DialogTimeout * 1000)
}
this.filterReady += 1
}
GetNewMessages() { ; get prepared FilterSenders messages
return this.messages
}
GetUser(ChatId) { ; get data from user (replyTo configuration!)
For idx, sender in this.replyTo
If (sender.ChatId = ChatId)
return sender
}
; debug methods
;----------------------------------------------------------------------------------------------------------------------------------------------
print(Text:="", Clear:=0, LineBreak:=1, Exit:=0) { ; print to SciTE output pane for debugging
static LinesOut := 0
;If !this.Debug
; return
try
SciObj := ComObjActive("SciTE4AHK.Application") ;get pointer to active SciTE window
catch
return ;if not return
If InStr(Text, "ShowLinesOut") {
SciObj.Output("SciteOutput function has printed " LinesOut " lines.`n")
return
}
If Clear || ((StrLen(Text) = 0) && (LinesOut = 0))
SendMessage, SciObj.Message(0x111, 420) ;If clear=1 Clear output window
If LineBreak
Text .= "`r`n" ;If LineBreak=1 append text with `r`n
SciObj.Output("[" this.ShortName "] " Text) ;send text to SciTE output pane
LinesOut += StrSplit(Text, "`n").MaxIndex()
If (Exit=1) {
MsgBox, 36, Exit App?, Exit Application? ;If Exit=1 ask if want to exit application
IfMsgBox,Yes, ExitApp ;If Msgbox=yes then Exit the appliciation
}
}
; Telegram api calls wrapper
;----------------------------------------------------------------------------------------------------------------------------------------------
GetMe() { ;-- get information about the bot itself
query := this.URL "getMe"
Return this.HttpPost(query, "application/json")
}
GetUpdates() { ;-- get updates from bot
query := Format(this.URL "getupdates?offset={1}&limit={2}&timeout={3}", this.GetUpdatesOpt.offset, this.GetUpdatesOpt.updlimit, this.GetUpdatesOpt.timeout)
Return this.HttpPost(query, "application/json")
}
InlineButtons(msg, from_id, mtext:="") { ;-- add inline buttons
keyb= ; json string:
(
{"inline_keyboard":[ [{"text": "Command One" , "callback_data" : "Command1"}, {"text" : "Some button (Cmd3)", "callback_data" : "Command3"} ] ], "resize_keyboard" : true }
)
Format(this.URL "sendMessage?text=Keyboard added&chat_id={1}&reply_markup={2}", from_id, keyb)
Return this.HttpPost(query, "application/json")
}
RemoveKeyb(msg, from_id, mtext="") { ;-- remove custom keyboard
keyb := "{" q "remove_keyboard" q " : true }"
query := Format(this.URL "sendMessage?text=Keyboard removed&chat_id={1}&reply_markup={2}", tfrom_id, keyb)
Return this.HttpPost(query, "application/json")
}
SendPhoto(chatID, file, caption:="" ) { ;-- media send: image
;-- you could add more options; compare the Telegram API docs
return this.UploadFormData(Format(this.URL "sendPhoto?caption={1}", caption), {"chat_id" : ChatId, "photo" : [file] })
}
SendText(ChatId, textMsg) { ;-- send a text message
query := Format(this.URL "sendMessage?chat_id={1}&text={2}", ChatId, this.uriEncode(txtMsg))
Return this.HttpPost(query, "application/json")
}
SomeFunction(botToken, msg, from_id, mtext) {
if (msg.callback_query.id!="") { ; After the user presses a callback button, Telegram clients will display a progress bar until you call answerCallbackQuery
cbQuery_id := msg.callback_query.id
query := Format(this.URL "answerCallbackQuery?text=Notification&callback_query_id={1}&show_alert=true", cbQuery_id)
jsonResponse := this.HttpPost(query, "application/json")
}
text := "You chose " mtext
this.SendText(from_id, text) ; url encoding for messages : %0A = newline (\n) %2b = plus sign (+) %0D for carriage return \r single Quote ' : %27 %20 = space
Return jsonResponse
}
; Telegram api helper functions
;----------------------------------------------------------------------------------------------------------------------------------------------
DownloadFile(FilePath) {
query := this.URL . StrSplit(FilePath,"/").2
;InetGet(Query, fileName)
Return True
}
GetFilePath(FileID) { ; get the path of a file on Telegram Server by its File ID
query := this.URL "/getFile?fileid=" FileID
oResponse := this.HttpPost(query, "application/json")
Return oResponse.result.filepath
}
; HTTP Methods
;----------------------------------------------------------------------------------------------------------------------------------------------
HttpPost(query, content_Type) {
WinHTTP := ComObjCreate("WinHTTP.WinHttpRequest.5.1")
WinHTTP.Open("POST", query, 0)
WinHTTP.SetRequestHeader("Content-Type", content_Type)
WinHTTP.Send()
jsonResponse := WinHTTP.ResponseText
WinHTTP := "" ; free COM object
this.lastResponse := jsonResponse
Return JSON.Load(jsonResponse)
}
uriEncode(str) { ; v 0.3 / (w) 24.06.2008 by derRaphael / zLib-Style release
b_Format := A_FormatInteger
data := ""
SetFormat, Integer, H
Loop,Parse,str
if ((Asc(A_LoopField)>0x7f) || (Asc(A_LoopField)<0x30) || (asc(A_LoopField)=0x3d))
data .= "%" . ((StrLen(c:=SubStr(ASC(A_LoopField),3))<2) ? "0" . c : c)
Else
data .= A_LoopField
SetFormat, Integer, % b_format
return data
}
UploadFormData(url_str, objParam) { ;-- Upload multipart/form-data
CreateFormData(postData, hdr_ContentType, objParam)
WinHTTP := ComObjCreate("WinHttp.WinHttpRequest.5.1")
WinHTTP.Open("POST", url_str, true)
WinHTTP.SetRequestHeader("Content-Type", hdr_ContentType)
; WinHTTP.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko") ; ???????
WinHTTP.Option(6) := False ; No auto redirect
WinHTTP.Send(postData)
WinHTTP.WaitForResponse()
jsonResponse := WinHTTP.ResponseText
WinHTTP := "" ; free COM object
return jsonResponse ; will return a JSON string that contains, among many other things, the file_id of the uploaded file
}
;
;----------------------------------------------------------------------------------------------------------------------------------------------
class reply { ;extends TelegramBot
; setup reply services
;----------------------------------------------------------------------------------------------------------------------------------------------
;----------------------------------------------------------------------------------------------------------------------------------------------
__NEW(ChatId, username, auth) { ; setup a new reply service for a specific username
this.reply := Object()
this.reply.ChatId := ChatId
this.reply.username:= username
this.reply.auth:= auth
}
__Delete(ChatId) {
this.reply := ""
}
; message content parsers/handlers
;----------------------------------------------------------------------------------------------------------------------------------------------
;----------------------------------------------------------------------------------------------------------------------------------------------
ParseMessage(messageText) {
static escaped
If (StrLen(escaped) = 0) {
str:=StrSplit("!§$%&/()=?\/```´{}[]@*+~'-_:.,;")
Loop, % str.MaxIndex()
escaped .= "\" str[A_Index]
}
this.print("reply service receiving: " q messageText q " from user: " this.reply.username)
If RegExMatch(messageText, "i)^\s*\#(?<cmd>[a-zäöüß\s" escaped "]+)", chat_) {
this.print("receiving command (" q chat_cmd q ") from user: " this.reply.username)
this.reply.cmd := ObjBindMethod(this, chat_cmd)
fn := this.reply.cmd
If IsFunc(fn) {
SetTimer, % fn, -10
} else {
this.print("unknown command (" q chat_cmd q ") received from user: " this.reply.username)
}
} else {
this.print("no command received from user: " this.reply.username)
}
}
; commands
;----------------------------------------------------------------------------------------------------------------------------------------------
;----------------------------------------------------------------------------------------------------------------------------------------------
Cmds() { ; sends avaible commands to user
this.SendText(this.reply.ChatId, "What commands?")
}
}
}
#include %A_ScriptDir%\..\lib
#Include BinArr.ahk
#include CreateFormData.ahk
#include class_JSONFile.ahk