Right now, if we want to update Telegram webhook url, we have to send a GET request manually. We can create a settings page for managing webhook URL easier.

We also need to implement user authentication to ensure that only administrators can access the page. It’s a simple task with Google Sign-In.

For this post, we will focus on creating settings page with admin authentication.


Add new extended routes for settings page. (Read More)

  • login: show sign in form
  • logout: log user out to home page
  • 403: show forbidden message
app = webapp2.WSGIApplication([
    webapp2.Route('/login', base.LoginHandler, name='login'),
    webapp2.Route('/logout', base.LogoutHandler, name='logout'),
    webapp2.Route('/403', base.Page403, name='403'),
    ('/', base.MainPage),
    ('/about', base.AboutPage),
    ('/settings', base.SettingsPage),
    ('/set_webhook', bot.SetWebhookHandler),
    ('/get_webhook', bot.GetWebhookHandler),
    ('/webhook', bot.WebhookHandler),
], debug=True)


Add settings, login, logout and 403 page handler classes.

We create __admin_required decorator to check for admin user when accessing settings page. It will compare login user email with a predefined list of admin emails.

from google.appengine.api import users

class SettingsPage(Handler):
    def __admin_required(func):
        def func_wrapper(self, *args, **kwargs):
            user = users.get_current_user()
            if user:
                email = user.email()
                admins = [
                if email in admins:
                    return func(self, *args, **kwargs)
                    return webapp2.redirect_to("403")
                return webapp2.redirect_to("login")
        return func_wrapper

    def get(self):
        kwargs = {
            'title': 'Settings',
        self.render_template('settings.html', **kwargs)

class LoginHandler(Handler):
    def get(self):

class LogoutHandler(Handler):
    def get(self):

class Page403(Handler):
    def get(self):
        kwargs = {
            'title': '403 Forbidden',
        self.render_template('403.html', **kwargs)


Add settings menu item to home navigation bar.

{% set navbar_menus = [
    ('/', 'home', 'Home'),
    ('/about', 'about', 'About'),
    ('/settings', 'settings', 'Settings'),
] -%}


{% extends "base.html" %}
{% set active_page = "settings" %}

{% block main_content %}
<h1 class="mt-5">Settings page for Admin only!</h1>
<a href="/logout">Logout</a>
{% endblock main_content %}


<!DOCTYPE html>
<html lang="en">
    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
    <!-- Custom styles for this template -->
    <link href="/static/css/style.css" rel="stylesheet">
	<div class="container">
		<img class="img-fluid rounded mx-auto d-block" src="https://i.imgur.com/p4kY38n.gif"/>


Settings Page