Skip to content

Instantly share code, notes, and snippets.

@wd5gnr
Last active October 15, 2025 16:24
Show Gist options
  • Select an option

  • Save wd5gnr/75fb01e899c43d2f84375a0089d77531 to your computer and use it in GitHub Desktop.

Select an option

Save wd5gnr/75fb01e899c43d2f84375a0089d77531 to your computer and use it in GitHub Desktop.
Telegram notifier for klipper
By Al Williams ([email protected])
You need to do a few things.
1) Create a telegram bot (go to @botfather, follow instructions, get long string to put in two places inside the moonraker.conf file)
2) Get notify.cfg on the printer and make your printer.cfg include it: [include notify.cfg]
3) Add the user.moonraker.conf text to your moonraker config
(if you don't have a camera, you can take out the "attach" lines)
4) In your slicer on layer change you need to do this (or equivalent):
GNR_ON_LAYER_CHANGE LAYER={layer_num + 1} TOTAL={total_layer_count}
5) Put klip-notify somewhere (prefer on path) and modify notify.cfg to point to it. Make file executable (chmod +x klip-notify)
You'll need to restart moonraker/clipper to get all of that to take.
You can test from console:
GNR_ON_LAYER_CHANGE LAYER=10 TOTAL=100
If that works, you can slice/print and you should see progress on the telegram bot.
#!/bin/ash
/usr/bin/wget -qO- "http://127.0.0.1:7125/printer/gcode/script?script=GNR_DO_LAYER_NOTIFY%20LAYER=$1%20TOTAL=$2%20PCT=$3" &
exit 0
[gcode_shell_command GNR_LAYER_WGET]
# Use absolute path to klip-notify if possible
command: /opt/bin/klip-notify
timeout: 1.0
verbose: False
[gcode_macro ENABLE_LAYER_NOTIFY]
description: Turn layer notify on/off ENABLED=0/1
gcode:
{% set enabled = params.ENABLED|default(1)|int %}
SET_GCODE_VARIABLE MACRO=GNR_ON_LAYER_CHANGE VARIABLE=push_enabled VALUE={enabled}
[gcode_macro GNR_ON_LAYER_CHANGE]
description: Called by slicer on each layer change (e.g., timelapse, notification)
variable_lastnotify: 0
variable_push_enabled: 1
gcode:
{% set layer = params.LAYER|default(0)|int %}
{% set total = params.TOTAL|default(0)|int %}
{% if total > 0 %}
{% set pct = ((layer|float / total) * 100)|int %}
{% else %}
{% set pct = 0 %}
{% endif %}
{% if push_enabled != 0 %}
{% set last = printer["gcode_macro GNR_ON_LAYER_CHANGE"].lastnotify|int %}
# The logic here is we don't want to notify 0% or 100% (because the system does start/complete)
# But we do want to trigger every 10% but we don't know for sure we will always hit exactly
# so an 8 layer print will be 0%, 12.5%, 25%,... So by checking the top digit
# we will print once per decade and won't get multiple for any given decade
# On new print 1 != 9 so we are good to go again. The first layer should always be 0% so...
{% if pct//10 != last %}
SET_GCODE_VARIABLE MACRO=GNR_ON_LAYER_CHANGE VARIABLE=lastnotify VALUE={pct//10}
{% if pct != 100 and pct//10 != 0 %}
SET_GCODE_VARIABLE MACRO=GNR_LAYER_VAR VARIABLE=layer VALUE={layer}
SET_GCODE_VARIABLE MACRO=GNR_LAYER_VAR VARIABLE=total VALUE={total}
SET_GCODE_VARIABLE MACRO=GNR_LAYER_VAR VARIABLE=pct VALUE={pct}
UPDATE_DELAYED_GCODE ID=GNR_LAYER_DELAYED DURATION=1.0
{% endif %}
{% endif %}
{% endif %}
[gcode_macro GNR_LAYER_VAR]
description: Variables for delayed notify
variable_layer: 0
variable_total: 0
variable_pct: 0
gcode:
[delayed_gcode GNR_LAYER_DELAYED]
gcode:
{% set layer = printer['gcode_macro GNR_LAYER_VAR'].layer|int %}
{% set total = printer['gcode_macro GNR_LAYER_VAR'].total|int %}
{% set pct = printer['gcode_macro GNR_LAYER_VAR'].pct|int %}
RESPOND MSG="{ 'Firing async layer notify: %d/%d (%d%%)' % (layer,total,pct) }"
RUN_SHELL_COMMAND CMD=GNR_LAYER_WGET PARAMS="{layer} {total} {pct}"
[gcode_macro GNR_DO_LAYER_NOTIFY]
# Executes on Moonraker side, non-real-time
gcode:
{action_call_remote_method("notify",
name="gnr_progress_notify",
message="Layer %s/%s (%s%%) complete" %
(params.LAYER, params.TOTAL, params.PCT))}
# add the following to your moonraker config
[notifier gnr_status_notify]
url: tgram://{your telegram bot ID}
events: *
body: "Printer status: {event_name}"
body_format: text
title: AD5X Status
attach: http://localhost:8080/?action=snapshot
[notifier gnr_progress_notify]
url: tgram://{your telegram bot ID}
events: gcode
body: "{event_message}"
body_format: text
title: AD5X Progress
attach: http://localhost:8080/?action=snapshot
@wd5gnr
Copy link
Author

wd5gnr commented Oct 13, 2025

Oops, I changed the logic a bit and now it notifies too often... I need to fix something... will post here when it is done.

@wd5gnr
Copy link
Author

wd5gnr commented Oct 13, 2025

Ok that'll teach me to make a last minute change (worked with my short test print, fails bad on bigger print).

The only change is in notify.cfg where I was doing /10 and should have done //10. Will test in a second, but should be OK.

@wd5gnr
Copy link
Author

wd5gnr commented Oct 15, 2025

Ok probably last update... hahaha

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment