Send and receive messages using LM and Telegram #
Task #
You need to send text, image from LogicMachine to Telegram or receive text from Telegram to LogicMachine.
Send text #
-
Install Telegram app
-
Find BotFather or go here https://t.me/botfather
-
Once in BotFather type /newbot and follow instructions. As a result you will get your token and your own bot link like t.me/yourname_bot . Click on the link and type any message there.
-
Open browser (preferably Firefox as it converts JSON automatically) and go here https://api.telegram.org/bot<token>/getUpdates Replace <token> with your token. As a result you should have something like that. Save your chat ID.
- Create a user library called telegram. Paste this code and replace your token and chat ID.
require('ssl.https')
local token = 'token' -- your token
local chat_id = '1234567' -- your chat id
function telegram(message)
local url = 'https://api.telegram.org/bot' .. token .. '/sendMessage'
local data = 'chat_id=' .. chat_id .. '&text=' .. socket.url.escape(message)
return ssl.https.request(url, data)
end
- Create an event based script and use this code to send message to Telegram app:
require("user.telegram")
message = 'test message'
res, err = telegram(message)
log(res, err)
Send image #
First you need to retrieve the image using http request. Then you can send the image using this example. filedata variable must contain image data as a string, change PUT_CHAT_ID_HERE and PUT_BOT_TOKEN_HERE placeholders
require('ssl.https')
boundary = os.date('%d%m%Y%H%M%S')
filedata = '...' -- snapshot image data as a string
params = {
{
name = 'chat_id',
value = 'PUT_CHAT_ID_HERE',
},
{
name = 'photo',
filename = 'snapshot.jpg',
ctype = 'image/jpeg',
value = filedata,
}
}
body = { '--' .. boundary }
for _, param in ipairs(params) do
line = string.format('Content-Disposition: form-data; name=%q', param.name)
if param.filename then
line = string.format('%s; filename=%q', line, param.filename)
end
body[ #body + 1 ] = line
if param.ctype then
body[ #body + 1 ] = string.format('Content-Type: %s', param.ctype)
end
body[ #body + 1 ] = ''
body[ #body + 1 ] = param.value
body[ #body + 1 ] = '--' .. boundary
end
-- last boundary
body[ #body ] = body[ #body ] .. '--'
-- empty line at the end
body[ #body + 1 ] = ''
bodydata = table.concat(body, '\r\n')
resp = {}
log(
ssl.https.request({
url = 'https://api.telegram.org/PUT_BOT_TOKEN_HERE/sendPhoto',
sink = ltn12.sink.table(resp),
method = 'POST',
source = ltn12.source.string(bodydata),
headers = {
['content-length'] = #bodydata,
['content-type'] = 'multipart/form-data; boundary=' .. boundary
}
})
)
log(table.concat(resp))
Receive text #
How to send messages from the Telegram app to LogicMachine.
-
Follow instruction in first post how to create bot and your TOKEN
-
Create a user library named
tgupdates
and paste this code:
return function(token, callback)
local json = require('json')
local socket = require('socket')
local ssl = require('ssl')
local host = 'api.telegram.org'
local tgupdateid = storage.get('tg_update_id')
local uri = '/bot' .. token .. '/getUpdates'
local sock = socket.tcp()
sock:settimeout(5)
local res, err = sock:connect(host, 443)
if not res then
sock:close()
log('connect failed', err)
os.sleep(5)
return
end
sock = ssl.wrap(sock, { mode = 'client' })
sock:settimeout(60)
sock:sni(host)
res, err = sock:dohandshake()
if not res then
sock:close()
log('dohandshake failed', err)
os.sleep(5)
return
end
local function sendreq()
local args = 'timeout=50'
local crlf = '\r\n'
if tgupdateid then
args = args .. '&offset=' .. tgupdateid
end
sock:send(
'POST ' .. uri .. ' HTTP/1.1' .. crlf ..
'Host: ' .. host .. crlf ..
'Content-Type: application/x-www-form-urlencoded' .. crlf ..
'Content-Length: ' .. #args .. crlf .. crlf ..
args
)
end
local function parse(resp)
resp = json.pdecode(resp)
if type(resp) ~= 'table' or not resp.ok then
log('invalid response', resp)
end
local update_id = 0
for _, item in ipairs(resp.result) do
update_id = math.max(update_id, item.update_id)
local message = item.message
local text = message.text
local userid = message.from.id
local username = message.from.first_name
callback(text, userid, username)
end
if update_id > 0 then
tgupdateid = update_id + 1
storage.set('tg_update_id', update_id + 1)
end
end
sendreq()
local pat, len = nil, nil
while true do
res, err = sock:receive(pat)
if err then
sock:close()
log('receive error', err)
break
end
if type(pat) == 'number' then
pcall(parse, res)
sendreq()
pat, len = nil, nil
elseif #res == 0 then
pat = len
elseif not len then
len = res:match('Content%-Length: (%d+)')
len = tonumber(len)
end
end
end
- Create a resident script with 0 interval and use this code. Change TOKEN. Write to your chat in telegram and your message will be in logs.
function callback(text, userid, username)
log(text, userid, username)
end
token = 'YOUR TOKEN HERE'
require('user.tgupdates')(token, callback)
Modify the function to run your actions based on revived text. UserID is a unique number which can be used for authorization/restrictions. username is not unique as it is just a name in your Telegram account. It can be duplicated.