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.

Send image form ip camera to telegram
#1
I have an IP camera working and I can view it trough my logic machine.
The next step I like to reach is to send the snapshot to my telegram.
I have already configured my telegram, I can send messages. But it's impossible to send a snapshot.
I have a DAHUA camera, and the url to view the snapshot is this:
Http: // user: password@cameraip/cgi-bin/snapshot.cgi
I can view it in chrome without problems.
I try to send it with "sendphoto" command and with the example from here, in this case send through email.
https://forum.logicmachine.net/showthread.php?tid=1061

I do not know what else to do. Can someone help me?
Thanks.
Reply
#2
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
Code:
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
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))
Reply
#3
Thanks for the answer.
I put my url snapshot on "filedata" and my CHATID and BOT_TOKEN, but it doesn't work.
The log says:


* arg: 1
* number: 1
* arg: 2
* number: 400
* 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: 79
["date"]
* string: Thu, 13 Aug 2020 15:18:09 GMT
["strict-transport-security"]
* string: max-age=31536000; includeSubDomains; preload
["access-control-allow-origin"]
* string: *
* arg: 4
* string: HTTP/1.1 400 Bad Request


* string: {"ok":false,"error_code":400,"description":"Bad Request: IMAGE_PROCESS_FAILED"}
Reply
#4
As mentioned before first you need to retrieve the image from your camera via http request. You cannot pass a url to the snapshot here because telegram server cannot access your camera.
Reply
#5
Ok.
As you can see I'm a completely noob with LUA.
I will search info about that.

Thanks again.
Reply
#6
Hello.

I have tried to retrieve the image with no results.
I have used these examples:


https://forum.logicmachine.net/showthrea...tp+request

https://forum.logicmachine.net/showthrea...64#pid9364

Can you explain me how I need to do this?
Thanks in advance.
Reply
#7
Log what you get when sending a request to the camera. Make sure that the URL is correct and it actually returns an image not a HTML page containing the image.
Code:
12
require('socket.http') log(socket.http.request('http://user:password@cameraip/cgi-bin/snapshot.cgi'))
Reply
#8
(14.08.2020, 08:08)admin Wrote: Log what you get when sending a request to the camera. Make sure that the URL is correct and it actually returns an image not a HTML page containing the image.
Code:
12
require('socket.http') log(socket.http.request('http://user:password@cameraip/cgi-bin/snapshot.cgi'))

Sure:

* arg: 1
  * string:
* arg: 2
  * number: 401
* arg: 3
  * table:
  ["content-length"]
    * string: 0
  ["www-authenticate"]
    * string: Digest realm="Login to 5L02EC8PAGC1BC0", qop="auth", nonce="762101674", opaque="e65481894c6ae41a2f1296db7e53d66882f66471"
  ["connection"]
    * string: close
* arg: 4
  * string: HTTP/1.1 401 Unauthorized
Reply
#9
This means that you need to use digest code example from here: https://forum.logicmachine.net/showthrea...64#pid9364
log what you get from the request:
Code:
123
url = 'http://user:password@cameraip/cgi-bin/snapshot.cgi' image, err, hdrs = request(url) log(image, err, hdrs)
Reply
#10
(14.08.2020, 08:47)admin Wrote: This means that you need to use digest code example from here: https://forum.logicmachine.net/showthrea...64#pid9364
log what you get from the request:
Code:
123
url = 'http://user:password@cameraip/cgi-bin/snapshot.cgi' image, err, hdrs = request(url) log(image, err, hdrs)

With the last code I have not had any records, instead that I had an error:

User script:21: attempt to call global 'request' (a nil value)
stack traceback:
User script:21: in main chunk
Reply
#11
You need to copy the whole code from here: https://forum.logicmachine.net/showthrea...64#pid9364
And change the last lines as in my previous post.
Reply
#12
(14.08.2020, 08:53)admin Wrote: You need to copy the whole code from here: https://forum.logicmachine.net/showthrea...64#pid9364
And change the last lines as in my previous post.

Ok, sorry. This is the log:

Code:
12
* arg: 1   * string: ����
Reply
#13
EDIT
It's working, I have to put on filedata, the name without ' '.

Thanks admin.

This is my whole code:
Code:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
local skthttp = require('socket.http') local skturl = require('socket.url') local ltn12 = require('ltn12') local md5sum = require('encdec').md5 local hash = function(...)   return md5sum(table.concat({...}, ':')) end local parse_header = function(header)   local result = {}   for key, value in (header .. ','):gmatch('(%w+)=(.-),') do     if value:sub(1, 1) == '"' then -- strip quotes       result[ key:lower() ] = value:sub(2, -2)     else       result[ key:lower() ] = value     end   end   return result end local make_digest_header = function(headers)   local digest = {}   for _, header in ipairs(headers) do     if not header.unquote then       header[ 2 ] = '"' .. header[ 2 ] .. '"'     end     digest[ #digest + 1 ] = header[ 1 ] .. '=' .. header[ 2 ]   end   return 'Digest ' .. table.concat(digest, ', ') end local _request = function(req)   if not req.url then     return nil, 'missing url'   end   local url = skturl.parse(req.url)   local user, password = url.user, url.password   if not user or not password then     return nil, 'missing credentials in url'   end   url.user, url.password, url.authority, url.userinfo = nil, nil, nil, nil   req.url = skturl.build(url)   local source   if req.source then     local chunks = {}     local capture = function(chunk)       if chunk then         chunks[ #chunks + 1 ] = chunk       end       return chunk     end     local chunk_id = 0     source = function()       chunk_id = chunk_id + 1       return chunks[ chunk_id ]     end     req.source = ltn12.source.chain(req.source, capture)   end   local body, code, hdrs = skthttp.request(req)   if code == 401 and hdrs['www-authenticate'] then     local ht = parse_header(hdrs['www-authenticate'])     if not ht.realm or not ht.nonce then       return nil, 'missing realm/nonce from response'     end     if ht.qop ~= 'auth' then       return nil, 'unsupported qop ' .. tostring(ht.qop)     end     if ht.algorithm and ht.algorithm:lower() ~= 'md5' then       return nil, 'unsupported algo ' .. tostring(ht.algorithm)     end     local nc = '00000001'     local cnonce = string.format('%08x', os.time())     local uri = skturl.build({ path = url.path, query = url.query })     local method = req.method or 'GET'     local response = hash(       hash(user, ht.realm, password),       ht.nonce,       nc,       cnonce,       'auth',       hash(method, uri)     )     req.headers = req.headers or {}     local auth = {       { 'username', user },       { 'realm', ht.realm },       { 'nonce', ht.nonce },       { 'uri', uri },       { 'cnonce', cnonce },       { 'nc', nc, unquote = true },       { 'qop', 'auth' },       { 'algorithm', 'MD5' },       { 'response', response },     }     if ht.opaque then       table.insert(auth, { 'opaque', ht.opaque })     end     req.headers.authorization = make_digest_header(auth)     if not req.headers.cookie and hdrs['set-cookie'] then       -- not really correct but enough for httpbin       local cookie = (hdrs['set-cookie'] .. ';'):match('(.-=.-)[;,]')       if cookie then         req.headers.cookie = '$Version: 0; ' .. cookie .. ';'       end     end     if req.source then       req.source = source     end     body, code, hdrs = skthttp.request(req)   end   return body, code, hdrs end local request = function(url)   local t = type(url)   if t == 'table' then     return _request(table.clone(url))   elseif t == 'string' then     local req = {}     local _, code, headers = _request({ url = url, sink = ltn12.sink.table(req) })     return table.concat(req), code, headers   end end url = 'http://USER:PASS@CAM IP/cgi-bin/snapshot.cgi?1&ts=123/snapshot.jpeg' image, err, hdrs = request(url) log(image, err, hdrs) require('ssl.https') boundary = os.date('%d%m%Y%H%M%S') filedata = image -- snapshot image data as a string params = {   {     name = 'chat_id',     value = 'MY CHAT ID',   },   {     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/MY BOT/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))
Reply
#14
This line is incorrect:
Code:
1
filedata = 'image'

It should be
Code:
1
filedata = image
Reply
#15
(14.08.2020, 11:08)admin Wrote: This line is incorrect:
Code:
1
filedata = 'image'

It should be
Code:
1
filedata = image

Yes, I just put it in my previous post. Thank you very much again.
Reply


Forum Jump: