Create Notes in Odoo from messages sent to Telegram bot

Here we’ll make a telegram bot, that receives your message and create a Note in Odoo with the same content. You’ll need:

Deployment

Configure OpenAPI

Using OpenAPI module, configure following access:

  • Model: Note (note.note)

  • [x] Create via API

../../_images/openapi-access.png

Create a bot

  • In telegram client open BotFather

  • Send /newbot command to create a new bot

  • Follow instruction to set bot name and get bot token

  • Keep your token secure and store safely, it can be used by anyone to control your bot

Prepare zip file

To make deployment package execute following commands:

mkdir /tmp/bot
cd /tmp/bot

pip3 install python-telegram-bot -t .
pip3 install bravado -t .
wget https://raw.githubusercontent.com/it-projects-llc/odoo-sync/master/doc-src/x2odoo/telegram2odoo-via-lambda/lambda_function.py
zip -r /tmp/bot.zip *

Create Lambda function

Runtime

Use Python 3.6

../../_images/create-lambda.png

Function code

  • Set Code entry type to Upload a .zip file

  • Select bot.zip file you made

Environment variables

  • BOT_TOKEN – the one you got from BotFather

  • LOGGING_LEVEL – Level of loger. Allowed values: DEBUG, INFO, CRITICAL, ERROR, WARNING. Default value: INFO

  • TELEGRAM_USER_ID – put here your ID. You can get one by sending any message to Get My ID bot

  • ODOO_OPENAPI_SPECIFICATION_URL – link to swagger.json file. See OpenAPI module’s documentation for details

  • ODOO_OPENAPI_TOKEN – OpenAPI Token. You can find one in Odoo user’s form. See OpenAPI module’s documentation for details

Trigger

  • API Gateway. Once you configure it and save, you will see Invoke URL under Api Gateway details section

  • Set the security mechanism for your API endpoint as Open

Register telegram webhook

Tell telegram to send notifications to lambda function when bot receives new messages

# set your values
BOT_TOKEN="PASTE_BOT_TOKEN_HERE"
INVOKE_URL="https://PASTE-YOUR-INVOKE-URL"

# execute command below without changes
curl -XPOST https://api.telegram.org/bot${BOT_TOKEN}/setWebhook --data-urlencode "url=${INVOKE_URL}"

Max execution time

At Basic settings section increase Timeout value to avoid error like Task timed out after 3.00 seconds”. Value may depend on different factors. Try to start with value 30 sec.

Try it out

  • In telegram: send some messages to the bot

    ../../_images/telegram-bot.png
  • In Odoo: open menu [[ Notes ]]

  • RESULT: the notes are created

    ../../_images/odoo-notes.png
  • If something goes wrong, check Odoo logs and CloudWatch logs

Source

Key script of the bot is presented below:

import os
import logging
import json
import urllib.parse as urlparse

# https://github.com/python-telegram-bot/python-telegram-bot
import telegram
# https://github.com/Yelp/bravado
from bravado.requests_client import RequestsClient
from bravado.client import SwaggerClient


logger = logging.getLogger()
LOGGING_LEVEL = os.environ.get('LOGGING_LEVEL')
if LOGGING_LEVEL:
    logger.setLevel(getattr(logging, LOGGING_LEVEL))


BOT_TOKEN = os.environ.get('BOT_TOKEN')
TELEGRAM_USER_ID = int(os.environ.get('TELEGRAM_USER_ID'))
ODOO_OPENAPI_SPECIFICATION_URL = os.environ.get('ODOO_OPENAPI_SPECIFICATION_URL')
ODOO_OPENAPI_TOKEN = os.environ.get('ODOO_OPENAPI_TOKEN')


RESPONSE_200 = {
    "statusCode": 200,
    "headers": {},
    "body": ""
}



def lambda_handler(event, context):
    logger.debug("Event: \n%s", json.dumps(event))

    bot = telegram.Bot(token=BOT_TOKEN)
    update_json = json.loads(event["body"])
    update = telegram.Update.de_json(update_json, bot)
    message = update.message

    chat = message.chat
    user = message.from_user
    text = message.text

    if user.id != TELEGRAM_USER_ID:
        bot.sendMessage(chat_id=chat.id, text="This is a private bot, sorry. If you want a similar bot, check documentation at website https://odoo-sync.sh")
        return RESPONSE_200

    openapi_url = urlparse.urlparse(ODOO_OPENAPI_SPECIFICATION_URL)
    host = openapi_url.hostname
    db = urlparse.parse_qs(openapi_url.query)['db'][0]

    http_client = RequestsClient()
    http_client.set_basic_auth(
        host, db, ODOO_OPENAPI_TOKEN
    )
    odoo = SwaggerClient.from_url(
        ODOO_OPENAPI_SPECIFICATION_URL,
        http_client=http_client,
    )

    res = odoo.note_note.addNoteNote(body={'memo': text}).response().result
    note_id = res['id']
    note_url = '/'.join(ODOO_OPENAPI_SPECIFICATION_URL.split('/')[:3])
    note_url = '%s/web#id=%s&view_type=form&model=note.note' % (note_url, note_id)
    bot.sendMessage(chat_id=chat.id, text="Note is created: %s" % note_url, reply_to_message_id=message.message_id)
    return RESPONSE_200

Custom integration

For any further assistance contact us by email or fill out request form: