Telegram – Send Messages, Photos, Animated Gifs from your Raspberry Pi and RPi Web Cam

This tutorial has been created to work with RPi Web Cam Interface (for more details see: https://elinux.org/RPi-Cam-Web-Interface)

Telegram (an IM platform similar to WhatsApp) has the ability to send messages and pictures from your RPi Web Cam to your phone or desktop whenever motion is detected for instant notification. Plus it’s FREE! 🙂
 
To find out more visit: https://telegram.org
 
We will be using a Telegram Bot which is specifically designed to work with software, meaning that a message can be sent using bash scripts: https://telegram.org/blog/bot-revolution
 
Start by installing the Telegram app on your phone or desktop (this process will create your account – https://telegram.org), and then sign up for a Telegram bot using Botfather with the instructions here: https://core.telegram.org/bots#6-botfather.
 
Make a note of your API Token and bot username (the one that must end in bot)
 
We now need to obtain your bot’s chatid. To do this, enter the bot username in the Telegram search field (either in Contacts or Chats), then select the bot to initiate a chat with it, and then send a message. This process will establish a conversation (or chat) between you and the bot, identified as a chatid.
 
To find the chatid, enter the following URL in a browser (your API token goes after and right next to /bot):

https://api.telegram.org/botReplaceThisWithTheBotFatherToken/getUpdates

 
e.g, if your API is “123456789:jekcjrnekjrhteuncheiucnf”:

https://api.telegram.org/bot123456789:jekcjrnekjrhteuncheiucnf/getUpdates

 
You need the “id” number from the output it produces:

"message":{"message_id":2872,"from":{"id":987654321,

 
In the example above, this would be “987654321”
 
If you only see {“ok”:true,”result”:[]}, it means you haven’t yet sent your bot a message from your account.
 
Ok, so now that you have your API token and chatid, we can use the Pi to send you a message. Let’s send a test message to start with by entering the following from the Pi command line (substituting with your API and chatid where relevant):

curl -s -X POST https://api.telegram.org/bot123456789:jekcjrnekjrhteuncheiucnf/sendMessage -d text="A message from your bot" -d chat_id=987654321

 
Now we need to wrap this up in a script to send you notifications when motion is detected.

Create a new config file to store variables for Telegram

sudo nano /var/www/html/macros/configfile.cfg

Enter the following text into that file, replacing where necessary

#!/bin/bash
 
#Replace text within and including the arrow brackets <> with your own details
 
#Camera details
cameraName="<Mycam>"  
 
#Telegram details
tokenurl="https://api.telegram.org/bot<your API key>"
chatid="<your chat id>"
 
#Folder paths
webfolder="/var/www/html"
nomsg="/home/pi/nomsgfile.lck"
logfile="${webfolder}/scheduleLog.txt"
curlout="${webfolder}/curlout.txt"  #Keeps a log of the curl output for troubleshooting
 
 
#Logging function
logging () {
  #logging yes true "This is my error message"
  #$1 yes/no - send telegram msg
  #$2 true/false - disable audible notification or pop-up msg on receiving device
 
  ext="$1"
  notification="$2"
  msg="$3"
 
  NOW="`date +"-%Y/%m/%d %H:%M:%S-"`"
  echo "$msg"
  echo "${NOW} ${msg}" >> $logfile
  if [ $ext == "yes" ]; then
    curl -s \
      -X POST \
      ${tokenurl}/sendMessage \
      -d text="$msg" \
      -d disable_notification=${notification} \
      -d chat_id=${chatid} >> ${curlout} &
  fi
}

Create a new macro file that will be run whenever motion is detected

sudo nano /var/www/html/macros/motion_event.sh

Copy in the following text

#!/bin/bash
. /var/www/html/macros/configfile.cfg
 
#If you wish to disable notifications, create a file using "touch /home/pi/nomsgfile.lck"
if [ -f $nomsg ]; then
  logging no true "Message alerting has been disabled, exiting..."
exit
fi
 
#Copy the low res snapshot image from memory to a file
cp /dev/shm/mjpeg/cam.jpg ${webfolder}/cam_new.jpg
 
#On motion detection start (parameter is 1 for on, 0 for off)
fileparams=$1
if [ $fileparams -eq 1 ]
then
  #Send both a single text message and a photo because sometimes the photo message times out if the Telegram servers are busy
  
  logging yes false "Motion detected from ${cameraName}"
 
  curl -s -X POST \
    ${tokenurl}/sendPhoto \
    -F chat_id=${chatid} \
    -F photo="@${webfolder}/cam_new.jpg" \
    -F caption="Motion detected on ${cameraName}" >> ${curlout} &
 
fi

We now just need to make the motion_event.sh file executable and change the ownership:

sudo chmod +x /var/www/html/macros/motion_event.sh
sudo chown www-data:www-data /var/www/html/macros/motion_event.sh
sudo chown www-data:www-data /var/www/html/macros/configfile.cfg

To trigger motion detection within RPi Web Cam you need to ensure that Motion detect mode is set to Internal (or Monitor). For more details on how to configure this please see: https://elinux.org/RPi-Cam-Web-Interface#Motion_Detection

27 thoughts on “Telegram – Send Messages, Photos, Animated Gifs from your Raspberry Pi and RPi Web Cam

  1. Good job! Works like a charm. Do you also know how to make a custom button to start/stop messaging. Sometimes I get to many alerts when I’m at home triggering the motion detection myself.
    Gr. Rob

    Like

    1. Thanks Rob, glad you found it useful!

      Yes, I do have an easy way to disable monitoring from my phone using IFTTT DO buttons that I have written up here: https://quavoce.wordpress.com/2017/01/17/rpi-cam-web-interface-turn-on-and-off-motion-detection-using-ifttt-do-buttons/

      However I do need to update that tutorial because IFTTT has changed a bit since then (DO is more integrated into the main IFTTT app now for example), and I’ve made the Raspi-Runner script more secure. Another update is that the script creates the lock file that /var/www/html/macros/motion_event.sh looks for to stop triggering alerts.

      I’ll reply again to this once I’ve updated it.

      Liked by 1 person

  2. Hi

    I have copied the code but I can’t get it to work I have managed to get the bot so send me a message through the curl example
    but I now can’t get it to send a message after I have clicked motion detection start and it triggers to recored a video it then wont send a message or do i have to make some setting changes somewhere

    I’m running Debian strech with PHP 7 all other settings as default

    I’m new to this so sorry if i have missed something simple

    Like

    1. Hi David – thanks for the heads up – I’ve updated the guide at the end to include the need to enable motion detect and added a link to the wiki for further details.

      Like

  3. First, thank you for your tutorial, sending a message by using curl works fine,but for me i get an error message when i tried to manually execute “sudo /var/www/html/macros/motion_event.sh”

    /var/www/html/macros/motion_event.sh: line 15: [: -eq: unary operator expected

    do you have an idea ?

    Like

    1. Ah yes, if you are manually running motion_event.sh, you need to supply it with a 1 (on) or 0 (off), so do the following:

      /var/www/html/macros/motion_event.sh 1

      It’s also worth noting that you need to run this command as www-data, so run the following first:

      sudo su – www-data

      Like

  4. Hi Quavoce,

    i had resolved this issue, there were few steps to follow and my chat_id is not the same as API the front number, steps can be found in YouTube search for Telegram Bot Tutorial. Thanks!

    Like

  5. hi ! thanks for post! i need some help. i tried to link voice to motion start, but cant catch how macros work. i made test.sh in macros dir. put there:
    #!/bin/bash
    . /usr/bin/arecord.sh –format=S16_LE –duration=5 –rate=16000 –file-type=raw out.raw
    Then i made button in Rpi-web-interface and tried to start. But no result (
    I gave permissions to test.sh and made it executable. Everything works in command line.
    Perhaps a mistake in bash script?

    Like

    1. Have you tried running the script as www-data user? The web interface executes macros as this user so you need to make sure the file is owned by www-data and is able to run the command with the script.

      sudo su – www-data
      /var/www/html/macros/test.sh

      Liked by 1 person

  6. after exec i see :
    [sudo] password for www-data:

    i press enter (blank password i think) and return to console.
    but macros dosnt work (

    Like

    1. ok. i just repeat your project – everything works perfect. now i try to add simple command “rec temp.wav” to motion_event.sh after cp /dev/shm/mjpeg/cam.jpg ${webfolder}/cam_new.jpg.

      but no result. could you help what`s wrong and where to find temp.wav if it appears?

      Like

  7. when i try in console:

    sudo su – www-data
    rec temp.wav

    i see errors:
    ALSA lib pcm_direct.c:1605:(_snd_pcm_direct_get_slave_ipc_offset) Invalid value for card
    rec FAIL formats: can’t open input `default’: snd_pcm_open error: No such file or directory

    but with root it works.

    Like

    1. Looks like www-data doesn’t have permissions to access the devices that ALSA needs. I would add the rec command into sudoers by doing the following:

      As the Pi user (or root if you are using that account), find out where the rec binary is:

      which rec

      It may output /bin/rec

      Edit sudoers file:

      sudo visudo -f “/etc/sudoers.d/myOverrides”

      Add the following line, assuming rec is in /bin/

      www-data ALL=(ALL) NOPASSWD:/bin/rec, /bin/rec

      Save and exit, then try running rec as www-data again (with sudo this time) to see if errors have gone:

      sudo su – www-data
      sudo rec temp.wav

      If still a problem then you’ll need to look into it more as it’ll be a permissions issue.

      Like

  8. there`s no file like myOverrides.
    so, i made one and put there:
    www-data ALL=(ALL) NOPASSWD: usr/bin/rec, usr/bin/rec

    after that i cant do any command by error:
    >>> /etc/sudoers.d/myOverrides: syntax error near line 1 <<<
    sudo: parse error in /etc/sudoers.d/myOverrides near line 1
    sudo: no valid sudoers sources found, quitting
    sudo: unable to initialize policy plugin

    i found in path /etc/sudoers.d/ file – RPi-cam-web-interface with content:
    # allow 'shutdown' command via web server
    www-data ALL=/sbin/shutdown
    www-data ALL=NOPASSWD: /sbin/shutdown
    www-data ALL=/bin/date
    www-data ALL=NOPASSWD: /bin/date

    so i added there:
    www-data ALL=NOPASSWD: /usr/bin/rec

    but still no result, the same errors (

    Like

  9. i`ve added www-data as root user:
    sudo visudo
    www-data ALL=NOPASSWD:ALL

    but, the same errors (
    ALSA lib pcm_direct.c:1605:(_snd_pcm_direct_get_slave_ipc_offset) Invalid value for card
    rec FAIL formats: can’t open input `default’: snd_pcm_open error: No such file or directory

    Like

  10. I’ve gotten the bot to send a msg via the curl example, but I’m not getting anything sent from motion detector. I’ve changed the settings to Internal/monitor, still nothing. Here’s what I’m getting back –

    pi@raspberrypi:~ $ sudo su – www-data
    $ /var/www/html/macros/motion_event.sh 1
    Motion detected from
    /var/www/html/macros/motion_event.sh: 32: [: yes: unexpected operator
    $

    Liked by 1 person

    1. Looks like there’s a typo in your motion_event.sh script somewhere… paste it on here if you can’t see what the error is (just remove any details you don’t want to share such as your API key).

      Liked by 1 person

  11. Thanks for the help – new to this. Here’s the script –

    #!/bin/bash
    . /var/www/html/macros/configfile.cfg

    #If you wish to disable notifications, create a file using “touch /home/pi/nomsgfile.lck”
    if [ -f $nomsg ]; then
    logging no true “Message alerting has been disabled, exiting…”
    exit
    fi

    #Copy the low res snapshot image from memory to a file
    cp /dev/shm/mjpeg/cam.jpg ${webfolder}/cam_new.jpg

    #On motion detection start (parameter is 1 for on, 0 for off)
    fileparams=$1
    if [ $fileparams -eq 1 ]
    then

    #Send both a single text message and a photo because sometimes the photo message times out i$

    logging yes false “Motion detected from ${mycam}”

    curl -s -X POST \
    ${https://api.telegram.org/bot542******:******}/sendPhoto \
    -F chat_id=${512******} \
    -F photo=”@${webfolder}/cam_new.jpg” \
    -F caption=”Motion detected on ${mycam}” >> ${curlout} &

    logging yes false “Motion detected from ${mycam}”

    curl -s -X POST \
    ${https://api.telegram.org/bot542******:******}/sendPhoto \
    -F chat_id=${512******} \
    -F photo=”@${webfolder}/cam_new.jpg” \
    -F caption=”Motion detected on ${mycam}” >> ${curlout} &

    fi

    Like

  12. When I now run the motion_sensor.sh script the terminal replies only – “Motion detected from” but doesn’t list the camera name, nor do I get any updates from Telegram

    Like

  13. Could the problem be that I’ve forgotten what I named the camera when installing/setting up the RPI Web Cam Interface, and so the cameraName variable in the config file is botched? I’m trying to remember/find the camera name under the Web cam interface but I’m a complete noob so…. Would a fresh install of teh web cam interface be best?

    Like

    1. This is the problem:

      ${https://api.telegram.org/bot542******:******}
      -F chat_id=${512******} \

      text inside ${} indicates a previously set variable (e.g. mycam=”OutsideCam”; echo ${mycam}) and so can’t be used as you’ve done here.

      You need to use variables set in /var/www/html/macros/configfile.cfg, e.g.

      #Camera details
      cameraName=”OutsideCam”

      #Telegram details
      tokenurl=”https://api.telegram.org/bot542******:******”
      chatid=”512******”

      The main motion_event.sh imports this file and uses the variables set in there (sorry, a bit confusing, but they are then used in other scripts as well).

      Regarding the camera name, it seems you’ve changed the variable from ${cameraName} to ${mycam}. Did you also change the variable in /var/www/html/macros/configfile.cfg where it says cameraName=””? Make sure you don’t include the brackets.

      Basically, copy my scripts from fresh again, and just make sure you modify anything with , e.g.

      cameraName=””
      to
      cameraName=”OutsideCam”

      Liked by 1 person

Leave a reply to Raunchy 77 Cancel reply