Which is the correct way to customize an existing channel?

Hi. I’m making a bot for telegram. I need the functionality to delete a message and to send local files, and since I’m not an expert on python, I have to modify the site packages directly.

So in rasa\core\channels\telegram.py I did the following changes:

  1. Added ("delete",): "delete_message", and ("local",): "send_local_document", to the send_functions dictionary in the function TelegramOutput.send_custom_json.

  2. Added message_id=msg.message_id to every call of UserMessage in the function TelegramInput.message.

In telegram\bot.py i added:

    def send_local_document(self, chat_id, document, filename=None, caption=None, disable_notification=False, reply_to_message_id=None, reply_markup=None, timeout=20, parse_mode=None, thumb=None, **kwargs):
            
            self.send_document(chat_id, open(document, 'rb'), filename, caption, disable_notification, reply_to_message_id, reply_markup, timeout, parse_mode, thumb)

With these changes I can use

attachment = {"local": path}
dispatcher.utter_custom_json(attachment)

to upload a file to telegram and send it and I can use

ldte = tracker.events_after_latest_restart()
for item in reversed(ldte):
	if item["event"] == "user":
		if "message_id" in item:
			attachment = {"delete":int(item["message_id"])}
			dispatcher.utter_custom_json(attachment)
		break

to get an user message id and delete it (the second “if” is to prevent errors in tests using shell or interactive). This works, but overwriting the packages looks like a problematic idea. So what would be the correct way to customize a channel to add this functionality?

Hi, you can write a custom channel connector using the original one as a template. Just copy-paste the contents of rasa\core\channels\telegram.py in a separate file, e.g. custom_channel.py, and do the necessary customizing as required. Give your custom channel a name, e.g. MyIo, by editing the class method name. Now in the credentials.yml file, just declare you own custom channel like so:

custom_channel.MyIo:
  access_token: "490161424:AAGlRxinBRtKGb21_rlOEMtDFZMXBl6EC0o"
  verify: "your_bot"
  webhook_url: "https://your_url.com/webhooks/MyIo/webhook"

And, that’s it! It should work fine.

You can do like @saurabh-m523 mentioned or you can do what you have done and request it maybe as a feature enhancement to that channel as well so everyone gets the benefit of the update.

That sounds like a good idea. I’ll do that.

Where shall I place this custom_channel.py? I tried to place it in the path same as my credentials.yml, but got an “unknown input channel” error.

Yes, it goes there. You must modify your credentials.yml file, instead of telegram: write <name of your custom channel py file>.<class that inherits InputChannel>:.

May I know how you customized dispatcher ?

I didn’t. I’m using the function dispatcher.utter_custom_json(attachment). The functions were already in the telegram bot api. I modified the dictionary in the connector to use them.