def generate_pretty_roll(roll): pretty_roll = None victim = dao.get_bakchod_by_id(roll["victim"]) try: if roll["winrar"] is None: pretty_roll = "Roll a {} to {} {}!".format( roll["roll_number"], pretty_roll_rule(roll["rule"]), util.extract_pretty_name_from_bakchod(victim), ) else: winrar = dao.get_bakchod_by_id(roll["winrar"]) try: roll_expiry = ciso8601.parse_datetime(roll["expiry"]) except Exception as e: roll_expiry = roll["expiry"] now = datetime.datetime.now() td = roll_expiry - now if roll["rule"] == "kick_user": pretty_roll = "{} won by rolling a {}! {} has been kicked from this group!".format( util.extract_pretty_name_from_bakchod(winrar), roll["roll_number"], util.extract_pretty_name_from_bakchod(victim), ) else: pretty_roll = "{} won by rolling a {}! {} is now {} for {}".format( util.extract_pretty_name_from_bakchod(winrar), roll["roll_number"], util.extract_pretty_name_from_bakchod(victim), pretty_roll_rule(roll["rule"]), util.pretty_time_delta(td.total_seconds()), ) except Exception as e: logger.error( "Caught Error in roll.generate_pretty_roll - {} \n {}", e, traceback.format_exc(), ) return pretty_roll
def all(update, context): # Update Bakchod DB bakchod = dao.get_bakchod_by_id(update.message.from_user.id) if bakchod is None: bakchod = Bakchod.fromUpdate(update) logger.info("Looks like we have a new Bakchod! - {}", bakchod.__dict__) bakchod = update_bakchod(bakchod, update) # Update Group DB group = dao.get_group_by_id(update.message.chat.id) if group is None: group = Group.fromUpdate(update) logger.info("Looks like we have a new Group! - {}", group.__dict__) update_group(group, bakchod, update) # Log this logger.info( "[default.all] b.username='******' b.rokda={} g.title='{}'", util.extract_pretty_name_from_bakchod(bakchod), bakchod.rokda, group.title, ) handle_bakchod_modifiers(update, context, bakchod) handle_dice_rolls(update, context) handle_message_matching(update, context)
def ratelimit_user(update, ratelimit_key, fail_message, timeout_mins): limited = False # Enforce rate limiting on getting random quotes bakchod = dao.get_bakchod_by_id(update.message.from_user.id) history = bakchod.history if history is None: history = {} timeout_time = datetime.now() - timedelta(minutes=timeout_mins) if ratelimit_key in history: last_time_get = ciso8601.parse_datetime(history[ratelimit_key]) if last_time_get > timeout_time: logger.info("[ratelimit] blocked for key={}", ratelimit_key) update.message.reply_text(fail_message) limited = True return limited history[ratelimit_key] = datetime.now() bakchod.history = history dao.insert_bakchod(bakchod) return limited
def set_bakchod_rokda(rokda_to_set, bakchod_id): bakchod = dao.get_bakchod_by_id(bakchod_id) bakchod.rokda = rokda_to_set dao.insert_bakchod(bakchod) reponse = "✅ Set {}'s ₹okda to {}!".format(bakchod.username, bakchod.rokda) return reponse
def check_if_user_can_riposte(tg_id): bakchod = dao.get_bakchod_by_id(tg_id) if bakchod is not None: if bakchod.rokda <= 50: return False else: bakchod.rokda = bakchod.rokda - 50 dao.insert_bakchod(bakchod) return True else: return False
def get_random_bakchod(group, bakchod_id): if group is not None: members = group.members random_index = random.randint(0, len(members) - 1) random_bakchod_id = members[random_index] random_bakchod = dao.get_bakchod_by_id(random_bakchod_id) if random_bakchod.id == str(bakchod_id): return Bakchod(0, "cr", "cr") return random_bakchod
def get_random_bakchod(group_id): random_bakchod = None group = dao.get_group_by_id(group_id) if group is not None: members = group.members random_index = random.randint(0, len(members) - 1) random_bakchod_id = members[random_index] random_bakchod = dao.get_bakchod_by_id(random_bakchod_id) return random_bakchod
def paywall_user(tg_id, cost): bakchod = dao.get_bakchod_by_id(tg_id) if bakchod is not None: if bakchod.rokda <= cost: logger.info("[paywall] {} doesn't have enough rokda cost={}", bakchod.id, cost) return False else: bakchod.rokda = bakchod.rokda - cost dao.insert_bakchod(bakchod) return True else: return False
def handle(update, context): util.log_chat("reset", update) try: # Extract query... query = update.message.text query = query.split(" ") target = None if not util.is_admin(update.message.from_user["id"]): return # Request includes the username as a mention if update.message.entities: for entity in update.message.entities: if entity.type == "text_mention" and entity.user is not None: target = dao.get_bakchod_by_id(entity.user.id) # Last attempt... try to lookup username in DB if target is None: receiver_username = query[1] # Remove the "@" prefix if receiver_username.startswith("@"): receiver_username = receiver_username[1:] target = dao.get_bakchod_by_username(receiver_username) if target is not None: logger.info("[reset] target={}", util.extract_pretty_name_from_bakchod(target)) target.modifiers = {} dao.insert_bakchod(target) update.message.reply_text( "Reset - " + util.extract_pretty_name_from_bakchod(target)) return except Exception as e: logger.error( "Caught Error in reset.handle - {} \n {}", e, traceback.format_exc(), )
def handle(update, context): util.log_chat("about", update) if update.message.reply_to_message: query_id = update.message.reply_to_message.from_user["id"] else: query_id = update.message.from_user["id"] bakchod = dao.get_bakchod_by_id(query_id) if bakchod is None: bakchod = Bakchod.fromUpdate(update) dao.insert_bakchod(bakchod) update.message.reply_text(text=generate_about_response(bakchod), parse_mode=ParseMode.MARKDOWN)
def get_random_bakchod(group_id): random_bakchod = None group = dao.get_group_by_id(group_id) if group is not None: collected_bakchods = [] # loop through the member ids and store the bakchod objects for member_id in group.members: bakchod = dao.get_bakchod_by_id(member_id) if bakchod is not None: if bakchod.lastseen is not None: try: bakchod.lastseen = ciso8601.parse_datetime(bakchod.lastseen) collected_bakchods.append(bakchod) except Exception as e: logger.error( "Caught Error in roll.get_random_bakchod - {} \n {}", e, traceback.format_exc(), ) # sort the bakchods by lastseen collected_bakchods.sort(key=lambda r: r.lastseen, reverse=True) # only care about the x% of the lastseen relevant_section = math.ceil(0.15 * len(collected_bakchods)) # pick a random bakchod from the relevant section index = random.randint(0, relevant_section) random_bakchod = collected_bakchods[index] return random_bakchod
def reset_roll_effects(context: telegram.ext.CallbackContext): # Get group_id group_id = context.job.context # Get relevant roll based on group_id roll = dao.get_roll_by_id(group_id) # Get victim's Bakchod victim = dao.get_bakchod_by_id(roll["victim"]) logger.info( "[roll] Resetting roll effects for {} in group={}", util.extract_pretty_name_from_bakchod(victim), group_id, ) # Reset victim's modifiers if roll["rule"] == "mute_user": censored_modifiers = victim.modifiers["censored"] if censored_modifiers is not None: censored_modifiers["group_ids"].remove(group_id) victim.modifiers["censored"] = censored_modifiers elif roll["rule"] == "auto_mom": auto_mom_modifiers = victim.modifiers["auto_mom"] if auto_mom_modifiers is not None: auto_mom_modifiers["group_ids"].remove(group_id) victim.modifiers["auto_mom"] = auto_mom_modifiers dao.insert_bakchod(victim) # Post reset message response = "Roll Modifiers for {} are now removed!".format( util.extract_pretty_name_from_bakchod(victim) ) context.bot.send_message( group_id, text=response, ) return
def gamble(bakchod_id, chat_id, update): bakchod = dao.get_bakchod_by_id(bakchod_id) if bakchod is None: bakchod = Bakchod.fromUpdate(update) dao.insert_bakchod(bakchod) can_gamble, response = can_bakchod_gamble(bakchod) if can_gamble: # Get a random_bakchod from the same Group group = dao.get_group_by_id(chat_id) random_bakchod = get_random_bakchod(group, bakchod_id) response, bakchod, random_bakchod = gamble_engine( bakchod, random_bakchod) # Update History try: history = bakchod.history except: history = {} history["gamble"] = datetime.datetime.now() bakchod.history = history # Update gambler bakchod dao.insert_bakchod(bakchod) # Update random_bakchod if random_bakchod.id != 0: dao.insert_bakchod(random_bakchod) return response
def handle(update, context): util.log_chat("rokda", update) if update.message.reply_to_message: bakchod_id = update.message.reply_to_message.from_user["id"] else: bakchod_id = update.message.from_user["id"] bakchod = dao.get_bakchod_by_id(bakchod_id) if bakchod is not None: response = "💰" + util.extract_pretty_name_from_bakchod( bakchod) + " has " + str(round(bakchod.rokda, 2)) + " ₹okda!" logger.info("[rokda] Sending response " + response) update.message.reply_text(response) else: logger.info("[rokda] Couldn't find user") file_id = "CAADAwADrQADnozgCI_qxocBgD_OFgQ" sticker_to_send = file_id update.message.reply_sticker(sticker=sticker_to_send)
def handle(update, context): try: util.log_chat("daan", update) # Extract query... query = update.message.text query = query.split(" ") if len(query) < 2: update.message.reply_text( text="Haat chutiya! Syntax is `/daan @username 786`", parse_mode=ParseMode.MARKDOWN, ) return # Extract Sender by ID sender = dao.get_bakchod_by_id(update.message.from_user["id"]) if sender is None: sender = Bakchod.fromUpdate(update) dao.insert_bakchod(sender) # Extract Receiver receiver = None if update.message.reply_to_message: # Request is a reply to message... Extract receiver from ID receiver = dao.get_bakchod_by_id( update.message.reply_to_message.from_user["id"] ) # Donation can be the rest of the message donation = query[1:] else: # Request includes the username as a mention if update.message.entities: for entity in update.message.entities: if entity.type == "text_mention" and entity.user is not None: receiver = dao.get_bakchod_by_id(entity.user.id) # Last attempt... try to lookup username in DB if receiver is None: receiver_username = query[1] # Remove the "@" prefix if receiver_username.startswith("@"): receiver_username = receiver_username[1:] receiver = dao.get_bakchod_by_username(receiver_username) # Donation can be the rest of the message donation = query[2:] # Handle if receiver could be extracted if receiver is None: if receiver_username: update.message.reply_text(receiver_username + "??? Who dat???") return else: update.message.reply_text("Kisko daan do be????") return # Parse Daan amount try: daan = float("".join(donation)) daan = round(daan, 2) daan = abs(daan) except Exception as e: update.message.reply_text("Kitna ₹okda be???") return logger.info( "[daan] sender={} receiver={} daan={}", util.extract_pretty_name_from_bakchod(sender), util.extract_pretty_name_from_bakchod(receiver), daan, ) if (sender.rokda - daan) < 0: update.message.reply_text("Gareeb saale! You don't have enough ₹okda!") return if sender.id == receiver.id: file_id = "CAADAwADrQADnozgCI_qxocBgD_OFgQ" sticker_to_send = file_id update.message.reply_sticker(sticker=sticker_to_send) return # Commit Daan transaction to DB sender.rokda = sender.rokda - daan dao.insert_bakchod(sender) receiver.rokda = receiver.rokda + daan dao.insert_bakchod(receiver) daan_id = shortuuid.uuid() dao.insert_daan( daan_id, sender.id, receiver.id, daan, str(datetime.datetime.now()) ) update.message.reply_text( text="{} gave {} 🤲 a daan of {} ₹okda! 🎉 \n Daan ID - <code>{}</code>".format( util.extract_pretty_name_from_bakchod(sender), util.extract_pretty_name_from_bakchod(receiver), daan, daan_id, ), parse_mode=ParseMode.HTML, ) return except Exception as e: logger.error( "Caught Error in daan.handle - {} \n {}", e, traceback.format_exc(), )
def handle(update, context): util.log_chat("quotes", update) try: # Extract query... query = update.message.text query = query.split(" ") command = None try: command = query[1].lower() except: command = "random" if command == "add": if update.message.reply_to_message.text: response = add_quote(update) update.message.reply_text(text=response, parse_mode=ParseMode.MARKDOWN) elif command == "remove": if util.is_admin(update.message.from_user["id"]): try: id_to_remove = query[2] except: update.message.reply_text( text="Please include the Quote ID you want to remove!", parse_mode=ParseMode.MARKDOWN, ) return response = remove_quote(id_to_remove) else: response = "Chal kat re bsdk!" update.message.reply_text(text=response, parse_mode=ParseMode.MARKDOWN) elif command == "get": response = "" try: quote_id = query[2] except: update.message.reply_text( text="Please include the Quote ID you want to get!", parse_mode=ParseMode.MARKDOWN, ) return quote = get_quote_by_id(quote_id) if quote is None: group_id = util.get_group_id_from_update(update) if group_id is None: update.message.reply_text(text="Can't run this command here!") return # Return a random quote random_quote = get_random_quote(group_id) if random_quote is None: logger.info("[quotes] No quotes found! - group_id={}", group_id) update.message.reply_text( text="No quotes found for this Group! You can add quotes with `/quotes add`", parse_mode=ParseMode.MARKDOWN, ) return response = "Couldn't find quote with ID `{}`... but here's a random one - \n".format( quote_id ) pretty_quote = generate_pretty_quote(quote) response = response + pretty_quote update.message.reply_text(text=response, parse_mode=ParseMode.MARKDOWN) elif command == "join": response = "" try: quote_id = query[2] except: update.message.reply_text( text="Please include the Quote ID you want to join!", parse_mode=ParseMode.MARKDOWN, ) return quote = get_quote_by_id(quote_id) if quote is None: update.message.reply_text( text="Couldn't find quote with ID `{}`!".format(quote_id), parse_mode=ParseMode.MARKDOWN, ) return response = join_quotes(quote, update) update.message.reply_text(text=response, parse_mode=ParseMode.MARKDOWN) else: # Enforce rate limiting on getting random quotes bakchod = dao.get_bakchod_by_id(update.message.from_user.id) history = bakchod.history if history is None: history = {} two_min_ago = datetime.datetime.now() - datetime.timedelta(minutes=2) if "random_quote_get" in history: last_time_get = ciso8601.parse_datetime(history["random_quote_get"]) if last_time_get > two_min_ago: logger.info("[quotes] request random quote too soon... skipping") update.message.reply_text( "Quotes ki dukan band hai... come back later!" ) return history["random_quote_get"] = datetime.datetime.now() bakchod.history = history dao.insert_bakchod(bakchod) group_id = util.get_group_id_from_update(update) if group_id is None: update.message.reply_text(text="Can't run this command here!") return # Return a random quote random_quote = get_random_quote(group_id) if random_quote is None: logger.info("[quotes] No quotes found! - group_id={}", group_id) update.message.reply_text( text="No quotes found for this Group! You can add quotes with `/quotes add`", parse_mode=ParseMode.MARKDOWN, ) return logger.info("[quotes] Got a random quote '{}", random_quote) pretty_quote = generate_pretty_quote(random_quote) update.message.reply_text(text=pretty_quote, parse_mode=ParseMode.MARKDOWN) return except Exception as e: logger.error( "Caught Error in quotes.handle - {} \n {}", e, traceback.format_exc(), )
def handle_dice_rolls(dice_value, update, context): try: metrics.rolls_attempted.inc() logger.info("[roll] handle_dice_rolls dice_value={}", dice_value) # Extract Group ID group_id = get_group_id_from_update(update) if group_id is None: logger.info("[roll] dice roll was not in a group... skipping") return # Get current roll based on group_id current_roll = dao.get_roll_by_id(group_id) if current_roll is None: logger.info("[roll] current_roll was a None... skipping") return # Check whether roll already a winrar if current_roll["winrar"] is not None: logger.info("[roll] current_roll already has a winrar... skipping") return # Check roll expiry roll_expiry = ciso8601.parse_datetime(current_roll["expiry"]) if roll_expiry <= datetime.datetime.now(): logger.info("[roll] current_roll has expired... skipping") return # Check and update roll history roller = dao.get_bakchod_by_id(update.message.from_user.id) history = roller.history if history is None: history = {} five_min_ago = datetime.datetime.now() - datetime.timedelta(minutes=5) if not DEBUG: if "roll" in history: last_time_rolled = ciso8601.parse_datetime(history["roll"]) if last_time_rolled > five_min_ago: logger.info("[roll] rolled too soon... skipping") update.message.reply_text( "You can only roll once every 5 mins... Ignoring this roll!" ) return else: logger.debug("[roll] DEBUG is True... ignoring time check") history["roll"] = datetime.datetime.now() roller.history = history dao.insert_bakchod(roller) # Check roll outcome roll_number = int(current_roll["roll_number"]) if dice_value == roll_number: metrics.rolls_won.inc() # Handle roll winrar winrar_bakchod = dao.get_bakchod_by_id(update.message.from_user.id) logger.info( "[roll] We got a winrar! bakchod={} roll_number={} group_id={}", util.extract_pretty_name_from_bakchod(winrar_bakchod), roll_number, group_id, ) current_roll["winrar"] = winrar_bakchod.id current_roll["expiry"] = datetime.datetime.now() + datetime.timedelta( hours=1 ) # Update roll in DB dao.insert_roll( current_roll["group_id"], current_roll["rule"], current_roll["roll_number"], current_roll["victim"], current_roll["winrar"], current_roll["expiry"], ) # Add roll effect to victims modifiers victim = dao.get_bakchod_by_id(current_roll["victim"]) modifiers = victim.modifiers if current_roll["rule"] == "mute_user": if "censored" in modifiers: censored_modifier = modifiers["censored"] else: censored_modifier = {} if "group_ids" not in censored_modifier: censored_modifier["group_ids"] = [] censored_modifier["group_ids"].append(group_id) modifiers["censored"] = censored_modifier elif current_roll["rule"] == "auto_mom": if "auto_mom" in modifiers: auto_mom_modifier = modifiers["auto_mom"] else: auto_mom_modifier = {} if "group_ids" not in auto_mom_modifier: auto_mom_modifier["group_ids"] = [] auto_mom_modifier["group_ids"].append(group_id) modifiers["auto_mom"] = auto_mom_modifier elif current_roll["rule"] == "kick_user": try: logger.info( "[roll] Kicking User - group_id={} victim.id={}", group_id, victim.id, ) context.bot.send_message( chat_id=update.message.chat_id, text="BYEEEEEEEEEEEE " + util.extract_pretty_name_from_bakchod(victim), ) # refer to https://python-telegram-bot.readthedocs.io/en/stable/telegram.bot.html#telegram.Bot.kick_chat_member ban_until = datetime.datetime.now() + datetime.timedelta(seconds=31) context.bot.kick_chat_member( chat_id=group_id, user_id=victim.id, until_date=ban_until ) # remove the victim from group members list group = dao.get_group_by_id(group_id) group.members.remove(victim.id) dao.insert_group(group) except Exception as e: logger.error( "[roll] Caught Error in kick Bakchod - {} \n {}", e, traceback.format_exc(), ) context.bot.send_message( chat_id=update.message.chat_id, text="Looks like I'm not able to kick user... Please check the Group permissions!", ) return victim.modifiers = modifiers dao.insert_bakchod(victim) response = "<b>WINRAR!!!</b> {}".format(generate_pretty_roll(current_roll)) update.message.reply_text(text=response, parse_mode=telegram.ParseMode.HTML) # Schedule callback for resetting roll effects in 1 hour context.job_queue.run_once( reset_roll_effects, 3600, context=update.message.chat_id ) except Exception as e: logger.error( "Caught Error in roll.handle_dice_rolls - {} \n {}", e, traceback.format_exc(), ) return