This forum uses cookies
This forum makes use of cookies to store your login information if you are registered, and your last visit if you are not. Cookies are small text documents stored on your computer; the cookies set by this forum can only be used on this website and pose no security risk. Cookies on this forum also track the specific topics you have read and when you last read them. Please confirm that you accept these cookies being set.

TELEGRAM APP
#21
(04.03.2021, 17:17)admin Wrote: See this example: https://forum.logicmachine.net/showthrea...4#pid17944
Replace name/filename as needed, set ctype to text/csv and finally replace /sendPhoto with /sendDocument in the URL.

hello admin
but how to attach the CSV file in the script?
I tried mentioned code but I got this in the logs :


* arg: 1
  * number: 1
* arg: 2
  * number: 404
* arg: 3
  * table:
  ["server"]
    * string: nginx/1.16.1
  ["access-control-expose-headers"]
    * string: Content-Length,Content-Type,Date,Server,Connection
  ["content-type"]
    * string: application/json
  ["connection"]
    * string: close
  ["content-length"]
    * string: 55
  ["date"]
    * string: Mon, 08 Mar 2021 14:23:48 GMT
  ["strict-transport-security"]
    * string: max-age=31536000; includeSubDomains; preload
  ["access-control-allow-origin"]
    * string: *
* arg: 4
  * string: HTTP/1.1 404 Not Found
Best Regards,
Reply
#22
Here's a working example. Change token and chat_id. filedata is a string containing your CSV data.

Code:
require('ssl.https')

token = '9876543210:abcdefgh'
chat_id = '1234567890'

filedata = [[
col_a,col_b,col_c
1,2,3
4,5,6
]]

params = {
  {
    name = 'chat_id',
    value = chat_id,
  },
  {
    name = 'document',
    filename = 'report.csv',
    ctype = 'text/csv',
    value = filedata,
  }
}

boundary = os.date('%d%m%Y%H%M%S')

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/bot' .. token .. '/sendDocument',
    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))
Reply
#23
(09.03.2021, 07:08)admin Wrote: Here's a working example. Change token and chat_id. filedata is a string containing your CSV data.

Code:
require('ssl.https')

token = '9876543210:abcdefgh'
chat_id = '1234567890'

filedata = [[
col_a,col_b,col_c
1,2,3
4,5,6
]]

params = {
  {
    name = 'chat_id',
    value = chat_id,
  },
  {
    name = 'document',
    filename = 'report.csv',
    ctype = 'text/csv',
    value = filedata,
  }
}

boundary = os.date('%d%m%Y%H%M%S')

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/bot' .. token .. '/sendDocument',
    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))

thank you admin for your time
I want to insert the log object script such as this one
I tried but I still not tough in LUA

logtime = os.time() - 60 * 60

-- Список  объектов по id
objects = {}

-- получаем объекты по которым ведется запись действий
query = 'SELECT address, datatype, name FROM objects WHERE disablelog=0'
for _, object in ipairs(db:getall(query)) do
 objects[ tonumber(object.address) ] = {
   datatype = tonumber(object.datatype),
   name = tostring(object.name or ''),
 }
end

-- csv буфер
buffer = {'"date","address","name","value"'}

-- получаем список действий по объектам
query = 'SELECT src, address, datahex, logtime, eventtype FROM objectlog WHERE logtime >= ? ORDER BY id DESC'
for _, row in ipairs(db:getall(query, logtime)) do
 object = objects[ tonumber(row.address) ]

 -- находим соответствие между объектом и  типом события – запись по групповому адресу
 if object and row.eventtype == 'write' then
   datatype = object.datatype

   -- проверяем что тип данных установлен
   if datatype then
     -- раскодируем данные
     data = knxdatatype.decode(row.datahex, datatype)

     -- удаляем null символы из char/string типов
     if datatype == dt.char or datatype == dt.string then
       data = data:gsub('%z+', '')
     -- конвертируем date в формат DD.MM.YYYY
     elseif datatype == dt.date then
       data = string.format('%.2d.%.2d.%.2d', data.day, data.month, data.year)
     -- time в HH:MM:SS
     elseif datatype == dt.time then
       data = string.format('%.2d:%.2d:%.2d', data.hour, data.minute, data.second)
     end
   else
     data = ''
   end

   -- форматируем csv колонки
   logdate = os.date('%Y.%m.%d %H:%M:%S', row.logtime)
   csv = string.format('%q,%q,%q,%q', logdate, knxlib.decodega(row.address), object.name, tostring(data))

   -- добавляем в  buffer данные
   table.insert(buffer, csv)
 end
end
Best Regards,
Reply
#24
Add my example script code after your CSV generator code, and replace filedata = [[...]] with this:
Code:
filedata = table.concat(buffer, '\n')
Reply
#25
(09.03.2021, 08:45)admin Wrote: Add my example script code after your CSV generator code, and replace filedata = [[...]] with this:
Code:
filedata = table.concat(buffer, '\n')

Thanks, admin
Work great  Smile
Best Regards,
Reply
#26
In case you need to have several Telegram users to access your bot, use the following user library:

Code:
require('ssl.https')

local token = 'token' -- your token
local chat_id_1 = '1234567' -- your chat id 1
local chat_id_2 = '7654321' -- your chat id 2

function telegram(message)
  local url = 'https://api.telegram.org/bot' .. token .. '/sendMessage'
  local msg = socket.url.escape(message)

  ssl.https.request(url, 'chat_id=' .. chat_id_1 .. '&text=' .. msg)
  ssl.https.request(url, 'chat_id=' .. chat_id_2 .. '&text=' .. msg)
end
Reply
#27
(01.06.2020, 14:29)Daniel Wrote: It was explained here https://forum.logicmachine.net/showthrea...13#pid2513 but lets make a clear version:

1. Install Telegram app

2. Find BotFather or go here https://t.me/botfather

3. 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

4. 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


5. Create a user library called telegram. paste this code and replace your token and chat ID
Code:
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

6. Create an event based script and use this code to send message to Telegram app:
Code:
require("user.telegram")
message = 'test message'
res, err = telegram(message)
log(res, err)
Hi, Daniel
I just performed above recommendations. All stages were OK. But during attempt to send telegram message I obtained error - see attachments. Could you explain me the reason and how to resolve it. Thank you in advance. KR Oleg Razumovskyi.

Attached Files Thumbnail(s)
   
Reply
#28
Update your firmware to the latest version. Or check this: https://forum.logicmachine.net/showthread.php?tid=427
Reply
#29
(05.09.2022, 06:17)admin Wrote: Update your firmware to the latest version. Or check this: https://forum.logicmachine.net/showthread.php?tid=427

Thank you.
Reply
#30
How to send message from Telegram app to LM.

1. Fallow instruction in first post how to create bot and your TOKEN
2. Create user library tgupdates and paste this code
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
3. Create resident script with 0 interval and use this code. Change TOKEN. Write to your chat in telegram and your message will be in logs.
Code:
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 a unique as it is just name in your telegram account. It can be duplicated.
------------------------------
Ctrl+F5
Reply
#31
Hello,

I tried to use it following the example in the first page and when sending a message I got this on the log: 

* arg: 1
  * nil
* arg: 2
  * string: Try again

I'm using the last FW version 20230307. Do you know how can I solve it? Thanks.
Reply
#32
Check that you have DNS and gateway configured correctly in System config > Network > Interfaces.
Reply
#33
(26.04.2023, 07:28)admin Wrote: Check that you have DNS and gateway configured correctly in System config > Network > Interfaces.

Solved. Thank you admin!
Reply
#34
(03.06.2020, 18:40)Daniel Wrote: It will work in new FW 2.5.0 which should be available in a month time.

For older fw it will work like this

Code:
function request(url)
  local resp = {}
  local stat, code, hdrs = require('ssl.https').request({
    method = 'GET',
    url = url,
    protocol = 'tlsv12',
    sink = ltn12.sink.table(resp),
  })

  if stat then
    stat = table.concat(resp)
  end

  return stat, code, hdrs
end

local chat_id = '12345'
local token = 'wwwwwwwwwwwwwwwwwwwwwwwwww'
local telegram_url = 'https://api.telegram.org/bot' .. token .. '/sendMessage?'


message = "test"
message=require('socket.url').escape(message)
data_str = 'chat_id=' .. chat_id .. '&text=' .. message..''
stat, code, hdrs = request(telegram_url .. data_str)

Hello, Daniel!
I have LM2 upgraded to 20181002 version.
I used your code for older fw.
Unfortunately, I have reply:
------------
TGtest 06.01.2024 18:30:00
* arg: 1
  * nil
* arg: 2
  * string: Try again
* arg: 3
  * nil
TGtest 06.01.2024 18:30:04
* arg: 1
  * nil
* arg: 2
  * string: Try again
* arg: 3
  * nil
--------------
Could you advice me the right way :-)
Thank you in advance,
KR, Oleg
Reply
#35
(06.01.2024, 17:51)olegrz Wrote:
(03.06.2020, 18:40)Daniel Wrote: It will work in new FW 2.5.0 which should be available in a month time.

For older fw it will work like this

Code:
function request(url)
  local resp = {}
  local stat, code, hdrs = require('ssl.https').request({
    method = 'GET',
    url = url,
    protocol = 'tlsv12',
    sink = ltn12.sink.table(resp),
  })

  if stat then
    stat = table.concat(resp)
  end

  return stat, code, hdrs
end

local chat_id = '12345'
local token = 'wwwwwwwwwwwwwwwwwwwwwwwwww'
local telegram_url = 'https://api.telegram.org/bot' .. token .. '/sendMessage?'


message = "test"
message=require('socket.url').escape(message)
data_str = 'chat_id=' .. chat_id .. '&text=' .. message..''
stat, code, hdrs = request(telegram_url .. data_str)

Hello, Daniel!
I have LM2 upgraded to 20181002 version.
I used your code for older fw.
Unfortunately, I have reply:
------------
TGtest 06.01.2024 18:30:00
* arg: 1
  * nil
* arg: 2
  * string: Try again
* arg: 3
  * nil
TGtest 06.01.2024 18:30:04
* arg: 1
  * nil
* arg: 2
  * string: Try again
* arg: 3
  * nil
--------------
Could you advice me the right way :-)
Thank you in advance,
KR, Oleg
Hello Daniel!
I've found solution in your previous post "Check that you have DNS and gateway configured correctly in System config > Network > Interfaces. "
It works! Have a nice day! KR Oleg
Reply


Forum Jump: