Search code examples
pythonazure-functionstelethon

Python Azure function to send telegram messages


I have an Azure Function in python that sends a telegram message with a Time Trigger. It works like a charm in my local environment (using azure and azurite emulators in VS Code). I use the telethon client with an async function declaration. Here is my code:

import asyncio
from telethon import TelegramClient
from telethon.tl.types import InputPeerUser
import azure.functions as func

api_id = '2xxxxxxx'
api_hash = 'xxxxxxxxxxxxxxxxxx6yyyyyyy'
token = '6664444-knfdkjnxxxxx-xxxxx'

async def telegram_main(client,receiver,message,token):
                await client.start(bot_token=token)
                await client.connect()
                await client.send_message(receiver, message)
                await client.disconnect()
                
async def main(mytimer: func.TimerRequest) -> None:
    utc_timestamp = datetime.datetime.utcnow().replace(
        tzinfo=datetime.timezone.utc).isoformat()

    if mytimer.past_due:
        logging.info('The timer is past due!')

    logging.info('Python timer trigger function ran at %s', utc_timestamp)

    message = "Hello, this is a test message from Azure Function"

    receiver = InputPeerUser(1111111, 0)
    client = await TelegramClient('bot', api_id, api_hash).start(bot_token=token, max_attempts=10)
    print('client declared')
    
    try:
        print('trying to send telegram message')
        loop = asyncio.get_event_loop()
        task = loop.create_task(telegram_main(client,receiver, message, token))
        await task
        print('Telegram message sent')
    except RuntimeError as e:
        print(e)

When I deploy the function in a Function App, I get the following error message:

Exception while executing function: Functions.Send_TLGRM_MSG <--- Result: 
Failure Exception:
    OperationalError: attempt to write a readonly database 

Stack:

 File "/azure-functions-host/workers/python/3.9/LINUX/X64/azure_functions_worker/dispatcher.py", line 402, in _handle__invocation_request call_result = await self._run_async_func( 
 File "/azure-functions-host/workers/python/3.9/LINUX/X64/azure_functions_worker/dispatcher.py", line 654,
   in _run_async_func return await ExtensionManager.get_async_invocation_wrapper(
 File "/azure-functions-host/workers/python/3.9/LINUX/X64/azure_functions_worker/extension.py", line 147,
   in get_async_invocation_wrapper result = await function(**args)   
 File "/home/site/wwwroot/DB_Scan_TLGRM/__init__.py", line 281,
   in main client = await TelegramClient('bot', api_id, api_hash).start(bot_token=token, max_attempts=10)
 File "/home/site/wwwroot/.python_packages/lib/site-packages/telethon/client/auth.py", line 135,
   in _start await self.connect()
 File "/home/site/wwwroot/.python_packages/lib/site-packages/telethon/client/telegrambaseclient.py", line 549,
   in connect self.session.auth_key = self._sender.auth_key
 File "/home/site/wwwroot/.python_packages/lib/site-packages/telethon/sessions/sqlite.py", line 180,
   in auth_key self._update_session_table()
 File "/home/site/wwwroot/.python_packages/lib/site-packages/telethon/sessions/sqlite.py", line 194,
   in _update_session_table c.execute('delete from sessions')

I declare an async function with my telegram workflow. Then I call that function as a task inside Azure's own event loop (which is a requisite in this case).

As mentioned, this works well in the emulator. I know that telegram bots are possible in Azure functions. This seems to be a problem with authentication, but I've looked everywhere and can't solve it. Any suggestions are welcome.


Solution

  • Python Azure function to send telegram messages

    I have reproduced in my environment and below are my expected results:

    You don't need client to send, Alternatively you can use below simple code:

    Here I created a http trigger, you can use the code and integrate it into Timer Trigger:

    __init__.py:

    import logging
    import requests
    import azure.functions as func
    
    
    def main(req: func.HttpRequest) -> func.HttpResponse:
        logging.info('Python HTTP trigger function processed a request.')
        rith_bot_token = '662538:AAF4WslGnotZN5Fc'
        rith_chat_id = '-1002124' 
        rith_message = 'Hello Rithwik'
    
        url = f'https://api.telegram.org/bot{rith_bot_token}/sendMessage'
        data = {'chat_id': rith_chat_id, 'text': rith_message}
        response = requests.post(url, data=data)
        print(response)
        
        return func.HttpResponse(
                 "Hello Bot sent the message check it in Telegram",
                 status_code=200
            )
    

    requirements.txt:

    azure-functions
    requests
    

    local.settings.json:

    {
      "IsEncrypted": false,
      "Values": {
        "AzureWebJobsStorage": "connec",
        "FUNCTIONS_WORKER_RUNTIME": "python"
      }
    }
    

    Then deployed to Azure.

    Output:

    enter image description here

    Response from Chat bot :

    enter image description here