We already created Telegram webhook update handler following this post. Today we will create an UI form to show and update this value on settings page.

settings.html

{% extends "base.html" %}

{% set active_page = "settings" %}

{% block main_content %}
<h1 class="mt-5">Settings</h1>
<form action="" method="post">
    {% if message %}
    <div class="alert alert-{{ message["category"] }} alert-dismissible" role="alert">
    	<button type="button" class="close" data-dismiss="alert" aria-label="Close">
            <span aria-hidden="true">&times;</span>
    	</button>
    	<strong>{{ message["title"] }}</strong> {{ message["text"] }}
    </div>
    {% endif %}
    <div class="form-group">
    	<label for="webhook_url">Webhook URL:</label>
        <input type="url" class="form-control" name="webhook_url" id="webhook_url" value="{{ webhook_url_value }}">
    </div>
    <button type="submit" class="btn btn-primary">Update</button>
</form>
{% endblock main_content %}

base.py

[...]

from google.appengine.api import urlfetch

import app.handlers.bot as telegramBot

[...]

class SettingsPage(Handler):
  def __admin_required(func):
    [...]

  def __get_webhook_url(self):
    url = '{0}/getWebhookInfo'.format(telegramBot.BASE_URL)
    try:
      result = urlfetch.fetch(url)
      if result.status_code == 200:
        jsonstr = result.content
        jsonobj = json.loads(jsonstr)
        return jsonobj['result']['url']
      else:
        return None
    except:
      return None

  def __set_webhook_url(self, new_url):
    url = '{0}/setWebhook?url={1}'.format(telegramBot.BASE_URL, new_url)
    try:
      result = urlfetch.fetch(url)
      if result.status_code == 200:
        jsonstr = result.content
        jsonobj = json.loads(jsonstr)
        message = jsonobj['description']
        if 'error_code' in jsonobj:
            success = False
            error_code = jsonobj['error_code']
            message = 'Code({0}) {1}'.format(error_code, message)
        else:
            success = True
        return success, message
      else:
        return False, None
    except:
      return False, None

  @__admin_required
  def get(self):
    kwargs = {
      'title': 'Settings',
    }
    kwargs['webhook_url_value'] = self.__get_webhook_url()
    self.render_template('settings.html', **kwargs)

  @__admin_required
  def post(self):
    kwargs = {
      'page_name': 'Webhooks'
    }
    new_url = self.request.get('webhook_url')
    success, message = self.__set_webhook_url(new_url)
    if success:
      kwargs['message'] = {
        'category': 'success',
        'title': 'Success!',
        'text': message
      }
      kwargs['webhook_url_value'] = new_url
    else:
      kwargs['message'] = {
        'category': 'danger',
        'title': 'Error!',
        'text': message
      }
    self.render_template('settings.html', **kwargs)

Clean Up

Now we can get/update Telegram webhook directly from settings page. We should update main.py and bot.py to remove set_webhook and get_webhook routes.

main.py

import webapp2

from app.handlers import base, bot

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),
  ('/webhook', bot.WebhookHandler),
], debug=True)

bot.py

import webapp2
import json
import logging

from google.appengine.api import urlfetch

import app.models.chat as chat

TOKEN = 'xxxxxx:YOUR_TELEGRAM_BOT_TOKEN'
BASE_URL = 'https://api.telegram.org/bot' + TOKEN


class WebhookHandler(webapp2.RequestHandler):
  def post(self):
    urlfetch.set_default_fetch_deadline(60)
    body = json.loads(self.request.body)
    if body:
      logging.info('Update body: {}'.format(body))
      chat_handler = chat.Handler(body)
      chat_handler.send_reply()
    else:
      logging.info('Telegram update body is Invalid')

Result

Settings Page