def on_add(bot, update): del_update_and_message(update) api_chat = get_chat(update) chat = get_or_none(models.Chat, id=api_chat.id) chat.extra_fields['left'] = False chat.save() if chat.type != models.Chat.PRIVATE: for admin in api_chat.get_administrators(): if get_or_none(models.User, id=admin.user.id): if not chat.extra_fields['enabled']: chat.extra_fields['enabled'] = True chat.save() group_type = api_chat.type send_message( bot, admin.user.id, text= 'Hello, I was added to the {}: `{}` where you are an admin. ' 'For security purposes I only allow forwarding from groups ' 'if one of the admins approve of it. The next message contains the secret key ' 'of your {}. It will enable users to set forwarding to ' 'and from your {}. Only give this key to those you have ' 'allowed to do so. Have a nice day:)'.format( group_type, chat.title, group_type, group_type)) send_message(bot, admin.user.id, text="{}".format(chat.identifier))
def del_update_and_message(update): myupdate = get_or_none(models.Update, update_id=update.update_id) if myupdate: myupdate.delete() message = get_or_none(models.Message, message_id=get_message(update).message_id) if message: message.delete()
def register_webhooks(token, force=False): if not get_or_none(api_models.Bot, token=token): BOTS_REGISTERED = {} for bot_config in settings.TELEGRAM_BOT: if bot_config['token'] is token: bot = Bot(bot_config['token']) if 'webhook' in bot_config: url = bot_config['webhook'] % bot.token if url[-1] != '/': url += '/' else: webhook = reverse('telegram_webhook', kwargs={'token': bot.token}) from django.contrib.sites.models import Site current_site = Site.objects.get_current() url = 'https://' + current_site.domain + webhook bot.set_webhook(url) bot = Bot(bot_config['token']) dispatcher = DjangoDispatcher(bot) register = import_string(bot_config['register']) register(dispatcher) api_models.Bot.objects.create( token=token, dispatcher=bot_config['register']) logger.info('bot %s registered on url %s', bot.token, url)
def get_username(bot, update, user_data): del_update_and_message(update) chat = get_or_none(models.Chat, username=get_message(update).text) if chat and not chat.extra_fields['left']: api_chat = APIChat(chat.id, chat.type, bot=bot) if get_message(update).from_user.id in [ admin.user.id for admin in api_chat.get_administrators() ]: reply_message(update, text='The secret key for your chat is:') send_message(bot, get_message(update).chat_id, text='{}'.format(chat.identifier)) if not chat.extra_fields[enabled]: chat.extra_fields[enabled] = True return ConversationHandler.END else: reply_message( update, text='Sorry, you are not an admin in this chat so I cannot give ' 'you the chat\'s secret key. Please contact your admin to get the key.' ) return ConversationHandler.END reply_message( update, text= 'Oops! This username is not in the list of groups using my service. Are you sure you ' 'it is correct? Make sure to remove the @ symbol. You can try entering the ' 'username again or use /cancel to quit ') return CHAT_USERNAME
def start(bot, update): del_update_and_message(update) if get_chat(update).type != models.Chat.CHANNEL: if get_chat(update).type != models.Chat.PRIVATE: key = None message = 'Hi, My work is to help you forward messages from one chat to ' \ 'another, You can setup auto forwarding using /setAutoForward in a private chat with me. ' \ 'To do this you have to get the chat secret key from the chat administrators. ' \ 'Use /help if you need info about my commands and /rules to read the /rules' else: chat = get_or_none(models.Chat, id=get_chat(update).id) if not chat: return error(bot, update, "private chat not created after /start") message = 'Hi, My work is to help you forward messages from one chat'\ ' to the other. Use /help if you forget anything.\n' \ 'This is your secret key for use in forwarding messages'\ ' to my chat with you.' key = chat.identifier if not chat.extra_fields['enabled']: chat.extra_fields['enabled'] = True chat.save() send_message(bot, get_message(update).chat_id, text=message) if key: send_message(bot, get_message(update).chat_id, text="{}".format(key))
def set_receiver(bot, update, user_data): del_update_and_message(update) logger.debug('set_receiver called') reply_keyboard = [[label for label, name in lang_choices]] try: receiver = get_or_none(models.Chat, identifier=get_message(update).text) if receiver is None or not receiver.extra_fields[enabled]: reply_message( update, text="Unfortunately, the key you provided does not exist, " "please check that the key is correct and that I'm still in the chat. " "You can ask the admins of the chat") return RECEIVER if receiver.id == user_data['sender_id']: reply_message( update, text= "Oops! The receiving chat cannot be the same as the as the forwarding chat" "please enter the correct secret key") return RECEIVER forwardings = AutoForward.objects.filter(forwarder=receiver, enabled=True) if len(forwardings) > 0: reply_message( update, text="Unfortunately, this chat is already sending auto " "forwards to another chat. In order to prevent circular " "forwardings, I do not allow a chat to send and receive forwards " "simultaneously, please enter another chat's secret key or " "use /cancel to terminate the setup. Later you can use /rules to read more " "about the auto forwarding rules") return RECEIVER forwardings = AutoForward.objects.filter( receiver=receiver, forwarder__id=user_data['sender_id'], enabled=True) if len(forwardings) > 0: reply_message( update, text= "Oops! There is already an auto forwarding between these two chats. " "Another one cannot be set until the existing one is deleted. Please use " "/cancel to cancel or enter another chat's secret key to " "continue the setup") return RECEIVER user_data['receiver_id'] = receiver.id reply_message( update, text="We are almost done, now you just have to choose a language to " "translate the messages to, before forwarding. Choose None if you " "don't need translating the messages", reply_markup=ReplyKeyboardMarkup(reply_keyboard, one_time_keyboard=True)) return LANGUAGE except Exception as ex: logger.error(ex.message) reply_message(update, text="Oops! Please enter the key correctly") return RECEIVER
def on_remove(bot, update): del_update_and_message(update) chat = get_or_none(models.Chat, id=get_chat(update).id) outgoings = AutoForward.objects.filter(forwarder__id=chat.id, enabled=True) for outgoing in outgoings: outgoing.enabled = False outgoing.save() incomings = AutoForward.objects.filter(receiver__id=chat.id, enabled=True) for incoming in incomings: incoming.enabled = False incoming.save() if chat.type == models.Chat.PRIVATE: user = get_or_none(models.User, id=get_message(update).from_user.id) if user: user.delete() logger.info('{} has been removed from the {} {}'.format( fd_username, chat.type, chat.title)) disable_chat(chat.id)
def post(self, request, token): dispatcher = get_or_none(api_models.Bot, token=token) if not dispatcher: return Http404() json_string = request.body.decode('utf-8') update = Update.de_json(json.loads(json_string), Bot(token)) self.on_post(update) dispatcher.process_update(update) return HttpResponse()
def set_lang(bot, update, user_data): del_update_and_message(update) if not get_message(update).text in [label for label, name in lang_choices]: reply_message( update, text= 'Easy there my friend! Please, select only options in the keyboard' ) return LANGUAGE user_data['language'] = get_message(update).text forwarding = None try: sender = get_or_none(models.Chat, id=user_data['sender_id']) receiver = get_or_none(models.Chat, id=user_data['receiver_id']) creator = get_or_none(models.User, id=get_message(update).from_user.id) header = '`Forwarded from` @{}'.format(sender.username) if sender.username else \ '`Forwarded from {}`'.format(sender.title) forwarding, _ = AutoForward.objects.update_or_create( forwarder=sender, receiver=receiver, defaults={ 'creator': creator, 'lang': user_data['language'], 'message_header': header, 'enabled': True }) if forwarding: logger.info('Auto forwarding has been set {} to {}'.format( sender.title, receiver.title)) user_data = {} reply_message( update, text="Congratulations! Your auto forwarding has been set and" " should now be up and running!", reply_markup=ReplyKeyboardRemove()) except Exception as ex: logger.error(ex.message) if not forwarding: reply_message( update, text="Oops! Something went wrong, please try again later!") return ConversationHandler.END
def set_sender(bot, update, user_data): del_update_and_message(update) try: sender = get_or_none(models.Chat, identifier=get_message(update).text) if sender is None or not sender.extra_fields[enabled]: reply_message( update, text="The key you provided does not exist, " "please check that it is correct and I am still in the chat") return SENDER if sender.type == models.Chat.PRIVATE: reply_message( update, text= "The key you provided belongs to a private chat. Forwarding cannot " "be set from my users' private chat with me. You can only forward to them. " "please enter another chat's secret key or use /cancel to terminate " ) return SENDER forwardings = AutoForward.objects.filter(receiver=sender, enabled=True) if len(forwardings) > 0: reply_message( update, text="Unfortunately, this chat is already receiving auto " "forwards from another chat. In order to prevent circular " "forwardings, I do not allow a chat to send and receive forwards " "simultaneously, please enter another chat's secret key or " "use /cancel to terminate the setup. Later you can use /rules to read more " "about the auto forwarding rules") return SENDER user_data['sender_id'] = sender.id reply_message( update, text= "Great! now enter the secret key of the chat(user, group, supergroup or " "channel) you want me to forward the messages to.") return RECEIVER except Exception as ex: logger.error(ex.message) reply_message(update, text="Oops! Please enter the key correctly") return SENDER
def del_sender(bot, update, user_data): del_update_and_message(update) try: sender = get_or_none(models.Chat, identifier=get_message(update).text) if sender is None: reply_message(update, text="The key you provided does not exist, " "please check that it is correct") return DEL_SENDER user_data['sender_id'] = sender.id reply_message( update, text= "Great, now enter the secret key of the chat(user, group, supergroup " "or channel) which is being forwarding to ") return DEL_RECEIVER except Exception as ex: logger.error(ex.message) reply_message(update, text="Oops! Please enter the key correctly") return DEL_SENDER
def migrate_chat(old_chat_id, new_chat_id): try: new_chat = get_or_none(models.Chat, id=new_chat_id) if new_chat: new_chat.delete() models.Message.objects.filter(chat__id=new_chat.id).delete() chat = models.Chat.objects.get(id=old_chat_id) chat.id = new_chat_id logger.debug(chat.id) chat.type = chat.SUPERGROUP old_chat = models.Chat.objects.get(id=old_chat_id) AutoForward.objects.filter(forwarder__id=chat.id).update( forwarder=chat) AutoForward.objects.filter(receiver__id=chat.id).update(receiver=chat) models.Message.objects.filter(chat__id=chat.id).update(chat=chat) old_chat.delete() chat.save() # AutoForward.objects.filter(forwarder__id=chat.id).update(forwarder=chat) # AutoForward.objects.filter(receiver__id=chat.id).update(receiver=chat) # models.Message.objects.filter(chat__id=chat.id).update(chat=chat) except Exception as e: logger.error("Could not migrate chat from {} to {}. Error: {}".format( old_chat_id, new_chat_id, e))
def get_chat_type(bot, update, user_data): del_update_and_message(update) if not get_message(update).text in user_data['types_keyboard']: reply_message( update, text= 'Easy there my friend! Please, select only options in the keyboard' ) return CHAT_TYPE user_data['chat_type'] = get_message(update).text if user_data['chat_type'] == 'private chat': chat = get_or_none(models.Chat, id=get_chat(update).id) if chat: reply_message(update, text='The secret key for this chat is:', reply_markup=ReplyKeyboardRemove()) send_message(bot, get_message(update).chat_id, text='{}'.format(chat.identifier)) return ConversationHandler.END if user_data['chat_type'] == 'public supergroup or public channel': reply_message( update, text= 'Awesome! now enter the username of your public channel or supergroup ' 'without the "@" symbol') return CHAT_USERNAME reply_message( update, text= 'It is a bit tricky finding private groups, supergroups and channels ' 'because they do not have unique usernames like the public ones do. ' 'In any case, I am dedicated to bringing you my service in the best possible way ' 'so I wil try and see if I can get your secret key \n\n' 'Please give me the title of your private group, supergroup or channel', reply_markup=ReplyKeyboardRemove()) return CHAT_TITLE
def unknown(bot, update): # del_update_and_message(update) # logger.debug() try: sender = get_or_none(models.Chat, id=get_chat(update).id) forwardings_from = AutoForward.objects.filter(forwarder__id=sender.id, enabled=True) forwardings_to = AutoForward.objects.filter(receiver__id=sender.id, enabled=True) if len(forwardings_from) == 0 and len(forwardings_to) == 0: if sender.type != models.Chat.PRIVATE and sender.extra_fields[ 'message_counter'] >= timeouts[sender.type]: if sender.type == models.Chat.GROUP or sender.type == models.Chat.SUPERGROUP: send_message( bot, sender.id, text= 'You have not setup any auto forwarding since you added me, so ' 'I will leave because I\'m busy serving other chats. Just add me ' 'back again when you need me (@{}) '.format( fd_username)) bot.leave_chat(sender.id) disable_chat(sender.id) logger.info('{} has left the {} {}'.format( fd_username, sender.type, sender.title)) elif not get_message(update).left_chat_member or \ (get_message(update).left_chat_member and get_message(update).left_chat_member.username != fd_username): sender.extra_fields['message_counter'] += 1 sender.save() except Exception as ex: logger.exception( 'an error occurred while processing an unknown message from {}: {}' .format( get_chat(update).title if get_chat(update).title else get_chat(update).username, ex.message))
def del_receiver(bot, update, user_data): del_update_and_message(update) logger.debug('del_receiver called') try: sender = get_or_none(models.Chat, id=user_data['sender_id']) receiver = get_or_none(models.Chat, identifier=get_message(update).text) if receiver is None: reply_message( update, text="Unfortunately, the key you provided does not exist, " "please check that the key is correct") return DEL_RECEIVER if get_message(update).text == str(sender.identifier): reply_message( update, text= "Wow, wow, easy! The keys of the forwarder and the receiver must be different, " "please enter the correct key or use /cancel to terminate deletion" ) return DEL_RECEIVER forwarding = get_or_none(AutoForward, forwarder__id=user_data['sender_id'], receiver__id=receiver.id, enabled=True) if not forwarding: reply_message( update, text= "Oops! There is no auto forwarding set between these two chats, " "ensure that both have an active auto forwarding and " "you have entered the keys in the right order, then try again." ) return ConversationHandler.END authorized = False if forwarding.creator.id != get_message(update).from_user.id: api_sender = APIChat(sender.id, sender.type, bot=bot) api_receiver = APIChat(receiver.id, receiver.type, bot=bot) if api_sender.type != models.Chat.PRIVATE: if get_message(update).from_user.id not in [ admin.user.id for admin in api_sender.get_administrators() ]: if api_receiver.type != models.Chat.PRIVATE: if get_message(update).from_user.id in [ admin.user.id for admin in api_receiver.get_administrators() ]: authorized = True elif api_receiver.id == get_message(update).from_user.id: authorized = True else: authorized = True elif api_sender.id == get_message(update).from_user.id: authorized = True else: authorized = True if not authorized: reply_message( update, text= "Unfortunately you are neither the creator of this auto forwarding " "or an admin in one of the chats involved. Please request deactivation from " "the admin or the auto forwarding creator") return ConversationHandler.END else: forwarding.enabled = False forwarding.save() send_message(bot, get_message(update).chat_id, text="forwarding has been deleted successfully.") logger.info("forwarding from {} to {} has been deleted".format( sender.title, receiver.title)) forwardings_rec = AutoForward.objects.filter(receiver=receiver, enabled=True) forwardings_send = AutoForward.objects.filter(forwarder=sender, enabled=True) if receiver.type != models.Chat.CHANNEL and receiver.type != models.Chat.PRIVATE: text = 'The auto forwarding from {} to this {} has been deleted, ' \ 'so I will no longer forward message from there.'.format(sender.title, receiver.type) if len(forwardings_rec) == 0: text += ' Since there are no more auto forwardings involving this chat, I will now '\ 'leave. If you need me again, just holla at me (@{}) and add me '\ 'me to the chat. It was fun having you all!'.format(fd_username) send_message(bot, chat_id=receiver.id, text=text) if receiver.type != models.Chat.PRIVATE: if len(forwardings_rec) == 0: bot.leave_chat(receiver.id) disable_chat(receiver.id) logger.info('{} has left the {} {}'.format( fd_username, receiver.type, receiver.title)) # receiver.delete() if len(forwardings_send) == 0: bot.leave_chat(sender.id) disable_chat(sender.id) logger.info('{} has left the {} {}'.format( fd_username, receiver.type, receiver.title)) # sender.delete() user_data = {} return ConversationHandler.END except Exception as ex: logger.error(ex.message) reply_message( update, text="Oops! Something went wrong, please try again later!") return RECEIVER