Exemplo n.º 1
0
def process_auth(update: Update):
    user = None
    if update.message and update.message.text:
        user = User.objects.filter(
            secret_hash=str(update.message.text).strip()).first()

    if not user:
        send_telegram_message(
            chat=Chat(id=update.effective_chat.id),
            text=
            "Привет. Мы пока не знакомы. Привяжи меня на сайте или пришли мне секретный код 👇"
        )
        return

    user.telegram_id = update.effective_user.id
    user.telegram_data = {
        "id": update.effective_user.id,
        "username": update.effective_user.username,
        "first_name": update.effective_user.first_name,
        "last_name": update.effective_user.last_name,
        "language_code": update.effective_user.language_code,
    }
    user.save()

    send_telegram_message(chat=Chat(id=update.effective_chat.id),
                          text=f"Отлично! Приятно познакомиться, {user.slug}")
    cache.delete("bot:telegram_user_ids")
Exemplo n.º 2
0
def async_create_or_update_post(post, is_created):
    if not post.is_approved_by_moderator:
        send_telegram_message(
            chat=ADMIN_CHAT,
            text=render_html_message("moderator_post.html", post=post),
            reply_markup=telegram.InlineKeyboardMarkup(
                [[
                    telegram.InlineKeyboardButton(
                        "👍 Одобрить", callback_data=f"approve_post:{post.id}"),
                    telegram.InlineKeyboardButton(
                        "😕 Так себе", callback_data=f"forgive_post:{post.id}"),
                ],
                 [
                     telegram.InlineKeyboardButton(
                         "❌ В черновики",
                         callback_data=f"delete_post:{post.id}"),
                 ]]))

    # post to online channel
    send_telegram_message(
        chat=CLUB_ONLINE,
        text=render_html_message("channel_post_announce.html", post=post),
        parse_mode=telegram.ParseMode.HTML,
        disable_preview=True,
    )
Exemplo n.º 3
0
def announce_in_club_chat(post):
    send_telegram_message(
        chat=CLUB_CHAT,
        text=render_html_message("channel_post_announce.html", post=post),
        parse_mode=telegram.ParseMode.HTML,
        disable_preview=True,
    )
Exemplo n.º 4
0
def notify_post_author_rejected(post):
    if post.author.telegram_id:
        send_telegram_message(
            chat=Chat(id=post.author.telegram_id),
            text=render_html_message("post_rejected.html", post=post),
            parse_mode=telegram.ParseMode.HTML,
        )
Exemplo n.º 5
0
def async_create_or_update_user(user, created):
    user_profile_url = settings.APP_HOST + reverse("profile", kwargs={"user_slug": user.slug})

    if created:
        # new user registered
        send_telegram_message(
            chat=ADMIN_CHAT,
            text=f"👶 <b>Зарегался новенький:</b> <a href=\"{user_profile_url}\">{user.slug}</a>"
        )
Exemplo n.º 6
0
def notify_user_profile_approved(user):
    user_profile_url = settings.APP_HOST + reverse(
        "profile", kwargs={"user_slug": user.slug})

    if user.telegram_id:
        send_telegram_message(
            chat=Chat(id=user.telegram_id),
            text=f"🚀 Подравляем, вы прошли модерацию. Добро пожаловать в Клуб!"
            f"\n\nМожно пойти заполнить другие смешные поля в профиле:"
            f"\n\n{user_profile_url}")
Exemplo n.º 7
0
def async_create_or_update_user(user, created):
    user_profile_url = settings.APP_HOST + reverse(
        "profile", kwargs={"user_slug": user.slug})

    if created:
        # new user registered
        send_telegram_message(
            chat=ADMIN_CHAT,
            text=
            f"👶 *Зарегался новенький:* [{user.full_name}]({user_profile_url}) ({user.slug})\n"
        )
Exemplo n.º 8
0
def notify_user_profile_rejected(user: User, reason: RejectReason):
    try:
        text = render_html_message(f"rejected/{reason.value}.html", user=user)
    except TemplateDoesNotExist:
        text = render_html_message(f"rejected/intro.html", user=user)

    if user.telegram_id:
        send_telegram_message(
            chat=Chat(id=user.telegram_id),
            text=text,
        )
Exemplo n.º 9
0
def parse_forwarded_messages(update: Update):
    started_post = {
        "title": None,
        "type": Post.TYPE_POST,
        "text": update.message.text or update.message.caption,
        "url": None,
        "is_visible": True,
        "is_public": True,
    }
    for entity, text in update.message.parse_entities().items():
        if entity.type == "url":
            started_post["url"] = text
        elif entity.type == "bold":
            started_post["title"] = text

    # save it to user cache
    cached_post_set(update.effective_user.id, started_post)

    if started_post["url"]:
        # looks like a link
        send_telegram_message(
            chat=Chat(id=update.effective_chat.id),
            text=
            f"Выглядит как ссылка. Хотите поделиться ей в Клубе? Как будем постить?",
            reply_markup=telegram.InlineKeyboardMarkup(
                [[
                    telegram.InlineKeyboardButton("🔗 Ссылкой",
                                                  callback_data=f"link"),
                    telegram.InlineKeyboardButton("📝 Как пост",
                                                  callback_data=f"post"),
                ],
                 [
                     telegram.InlineKeyboardButton("❌ Отмена",
                                                   callback_data=f"nope"),
                 ]]))
    else:
        # looks like a text post
        if len(started_post["text"] or "") < 120:
            return "Напиши или форвардни мне нормальный пост или ссылку!"

        send_telegram_message(
            chat=Chat(id=update.effective_chat.id),
            text=f"Хотите поделиться этим в Клубе? Как будем постить?",
            reply_markup=telegram.InlineKeyboardMarkup(
                [[
                    telegram.InlineKeyboardButton("📝 Как пост",
                                                  callback_data=f"post"),
                    telegram.InlineKeyboardButton("❔ Вопросом",
                                                  callback_data=f"question"),
                ],
                 [
                     telegram.InlineKeyboardButton("❌ Отмена",
                                                   callback_data=f"nope"),
                 ]]))
Exemplo n.º 10
0
def notify_user_profile_rejected(user):
    user_profile_url = settings.APP_HOST + reverse("profile", kwargs={"user_slug": user.slug})

    if user.telegram_id:
        send_telegram_message(
            chat=Chat(id=user.telegram_id),
            text=f"😐 К сожалению, ваш профиль не прошел модерацию. Но это не конец света и всё можно исправить."
                 f"Вот популярные причины почему так бывает:\n"
                 f"- Плохо написано #intro. Одного предложения обычно мало, нам же надо как-то познакомиться\n"
                 f"- Вымышленное имя или профессия\n"
                 f"- Много незаполненных полей\n"
                 f"\n\nВот ссылка чтобы податься на ревью еще раз: {user_profile_url}"
        )
Exemplo n.º 11
0
def process_personal_chat_updates(update: Update):
    user = User.objects.filter(telegram_id=update.effective_user.id).first()
    if not user:
        send_telegram_message(
            chat=Chat(id=update.effective_chat.id),
            text=
            f"😐 Извините, мы не знакомы. Привяжите свой аккаунт в профиле на https://vas3k.club"
        )
        return

    # check for unfinished posts
    unfinished_post = cached_post_get(update.effective_user.id)

    # found an unfinished post
    if unfinished_post:
        reply = continue_posting(update, unfinished_post, user)
        if reply:
            send_telegram_message(chat=Chat(id=update.effective_chat.id),
                                  text=reply)
        return

    # parse forwarded posts and links
    if update.message:
        reply = parse_forwarded_messages(update)
        if reply:
            send_telegram_message(chat=Chat(id=update.effective_chat.id),
                                  text=reply)
        return

    send_telegram_message(chat=Chat(id=update.effective_chat.id),
                          text="Чот непонятна 🤔")
Exemplo n.º 12
0
    def handle(self, *args, **options):
        new_posts = Post.visible_objects()\
            .filter(
                is_approved_by_moderator=True,
                published_at__gte=datetime.utcnow() - timedelta(hours=24),
            )\
            .exclude(type=Post.TYPE_INTRO)\
            .order_by("-upvotes")[:6]

        send_telegram_message(
            chat=ADMIN_CHAT,
            text=render_html_message("good_morning.html", posts=new_posts, greetings=random.choice(DUMB_GREETINGS)),
        )

        self.stdout.write("Done 🥙")
Exemplo n.º 13
0
def notify_profile_needs_review(user, intro):
    user_profile_url = settings.APP_HOST + reverse("profile", kwargs={"user_slug": user.slug})
    send_telegram_message(
        chat=ADMIN_CHAT,
        text=render_html_message("moderator_new_member_review.html", user=user, intro=intro),
        reply_markup=telegram.InlineKeyboardMarkup([
            [
                telegram.InlineKeyboardButton("👍 Впустить", callback_data=f"approve_user:{user.id}"),
                telegram.InlineKeyboardButton("❌️ Отказать", callback_data=f"reject_user:{user.id}"),
            ],
            [
                telegram.InlineKeyboardButton("😏 Посмотреть", url=user_profile_url),
            ]
        ])
    )
Exemplo n.º 14
0
def process_comment_reply(update: Update):
    if not update.message.reply_to_message:
        return

    user = get_bot_user(update)
    if not user:
        return

    comment_url_entity = [
        entity["url"] for entity in update.message.reply_to_message.entities if
        entity["type"] == "text_link" and COMMENT_URL_RE.match(entity["url"])
    ]
    if not comment_url_entity:
        log.info(
            f"Comment url not found in: {update.message.reply_to_message.entities}"
        )
        return

    reply_to_id = COMMENT_URL_RE.match(comment_url_entity[0]).group(1)
    reply = Comment.objects.filter(id=reply_to_id).first()
    if not reply:
        log.info(f"Reply not found: {reply_to_id}")
        return

    is_ok = Comment.check_rate_limits(user)
    if not is_ok:
        send_telegram_message(
            chat=Chat(id=update.effective_chat.id),
            text=
            f"🙅‍♂️ Извините, вы комментировали слишком часто и достигли дневного лимита"
        )
        return

    comment = Comment.objects.create(author=user,
                                     post=reply.post,
                                     reply_to=Comment.find_top_comment(reply),
                                     text=update.message.text,
                                     useragent="TelegramBot (like TwitterBot)",
                                     metadata={"telegram": update.to_dict()})
    new_comment_url = settings.APP_HOST + reverse("show_comment",
                                                  kwargs={
                                                      "post_slug":
                                                      comment.post.slug,
                                                      "comment_id": comment.id
                                                  })
    send_telegram_message(chat=Chat(id=update.effective_chat.id),
                          text=f"➜ [Отвечено]({new_comment_url}) 👍")
Exemplo n.º 15
0
def async_create_or_update_post(post, is_created):
    if not post.is_approved_by_moderator:
        send_telegram_message(
            chat=ADMIN_CHAT,
            text=render_html_message("moderator_post.html", post=post),
            reply_markup=telegram.InlineKeyboardMarkup(
                [[
                    telegram.InlineKeyboardButton(
                        "👍 Одобрить", callback_data=f"approve_post:{post.id}"),
                    telegram.InlineKeyboardButton(
                        "😕 Так себе", callback_data=f"forgive_post:{post.id}"),
                ],
                 [
                     telegram.InlineKeyboardButton(
                         "❌ В черновики",
                         callback_data=f"delete_post:{post.id}"),
                 ]]))
Exemplo n.º 16
0
def announce_in_club_chats(post):
    if post.topic and post.topic.chat_id:
        # announce to the topic chat
        send_telegram_message(
            chat=Chat(id=post.topic.chat_id),
            text=render_html_message("channel_post_announce.html", post=post),
            parse_mode=telegram.ParseMode.HTML,
            disable_preview=True,
        )
    else:
        # announce to public chat
        send_telegram_message(
            chat=CLUB_CHAT,
            text=render_html_message("channel_post_announce.html", post=post),
            parse_mode=telegram.ParseMode.HTML,
            disable_preview=True,
        )
Exemplo n.º 17
0
def notify_user_profile_rejected(user):
    user_profile_url = settings.APP_HOST + reverse("profile", kwargs={"user_slug": user.slug})

    if user.telegram_id:
        send_telegram_message(
            chat=Chat(id=user.telegram_id),
            text=f"😐 К сожалению, ваш профиль не прошел модерацию. Вот популярные причины почему так бывает:\n\n"
                 f"- 📝 Маленькое #intro. Допишите еще хотя бы пару абзацев. Для примера посмотрите чужие, "
                 f"там есть ссылочки. <a href=\"https://vas3k.club/docs/about/#rules\">Наши правила</a>, "
                 f"с которыми вы согласились, запрещают анонимусов в Клубе.\n"
                 f"- 🤔 Много незаполненных полей. Мы не поняли кто вы. Профиль без фамилии или компании вряд "
                 f"ли пройдет модерацию.\n"
                 f"- 🤪 Вымышленное имя или профессия (например, Олег).\n"
                 f"- 🙅‍♀️ Наличие фраз типа «не скажу», «не люблю писать о себе», «потом заполню». "
                 f"Потом так потом, мы не торопимся :)\n"
                 f"- 💨 Душность, глупость или желание обмануть модераторов.\n\n"
                 f"\n\nВот ссылка чтобы исправить недочёты и податься на ревью еще раз: {user_profile_url}"
        )
Exemplo n.º 18
0
def announce_in_club_channel(post, announce_text=None, image=None):
    if not announce_text:
        announce_text = render_html_message("channel_post_announce.html",
                                            post=post)

    if image:
        send_telegram_image(
            chat=CLUB_CHANNEL,
            image_url=image,
            text=announce_text,
        )
    else:
        send_telegram_message(
            chat=CLUB_CHANNEL,
            text=announce_text,
            disable_preview=False,
            parse_mode=telegram.ParseMode.HTML,
        )
Exemplo n.º 19
0
def get_bot_user(update):
    user = User.objects.filter(telegram_id=update.effective_user.id).first()
    if not user:
        send_telegram_message(
            chat=Chat(id=update.effective_chat.id),
            text=
            f"😐 Извините, мы не знакомы. Привяжите свой аккаунт в профиле на https://vas3k.club"
        )
        return None

    if user.is_banned:
        send_telegram_message(
            chat=Chat(id=update.effective_user.id),
            text=
            f"😐 Извините, вы забанены до {user.is_banned_until.strftime('%d %B %Y')} и пока не можете писать"
        )
        return None

    return user
Exemplo n.º 20
0
def process_comment_reply(update: Update):
    if not update.message.reply_to_message:
        return

    user = get_bot_user(update)
    if not user:
        return

    comment_url_entity = [
        entity["url"] for entity in update.message.reply_to_message.entities if
        entity["type"] == "text_link" and COMMENT_URL_RE.match(entity["url"])
    ]
    if not comment_url_entity:
        log.info(
            f"Comment url not found in: {update.message.reply_to_message.entities}"
        )
        return

    comment_id = COMMENT_URL_RE.match(comment_url_entity[0]).group(1)
    comment = Comment.objects.filter(id=comment_id).first()
    if not comment:
        log.info(f"Comment not found: {comment_id}")
        return

    is_ok = Comment.check_rate_limits(user)
    if not is_ok:
        send_telegram_message(
            chat=Chat(id=update.effective_chat.id),
            text=
            f"🙅‍♂️ Извините, вы комментировали слишком часто и достигли дневного лимита"
        )
        return

    text = update.message.text or update.message.caption
    if not text:
        send_telegram_message(
            chat=Chat(id=update.effective_chat.id),
            text=f"😣 Сорян, я пока умею только в текстовые ответы")
        return

    # max 3 levels of comments are allowed
    reply_to_id = comment.id
    if comment.reply_to_id and comment.reply_to.reply_to_id:
        reply_to_id = comment.reply_to_id

    reply = Comment.objects.create(author=user,
                                   post=comment.post,
                                   reply_to_id=reply_to_id,
                                   text=f"@{comment.author.slug}, {text}",
                                   useragent="TelegramBot (like TwitterBot)",
                                   metadata={"telegram": update.to_dict()})
    new_comment_url = settings.APP_HOST + reverse("show_comment",
                                                  kwargs={
                                                      "post_slug":
                                                      reply.post.slug,
                                                      "comment_id": reply.id
                                                  })
    send_telegram_message(
        chat=Chat(id=update.effective_chat.id),
        text=f"➜ <a href=\"{new_comment_url}\">Отвечено</a> 👍")
Exemplo n.º 21
0
def process_personal_chat_updates(update: Update):
    user = get_bot_user(update)
    if not user:
        return

    # check for unfinished posts
    unfinished_post = cached_post_get(update.effective_user.id)

    # found an unfinished post
    if unfinished_post:
        reply = continue_posting(update, unfinished_post, user)
        if reply:
            send_telegram_message(chat=Chat(id=update.effective_chat.id),
                                  text=reply)
        return

    # parse forwarded posts and links
    if update.message:
        reply = parse_forwarded_messages(update)
        if reply:
            send_telegram_message(chat=Chat(id=update.effective_chat.id),
                                  text=reply)
        return

    send_telegram_message(chat=Chat(id=update.effective_chat.id),
                          text="Чот непонятна 🤔")
Exemplo n.º 22
0
def notify_profile_needs_review(user, intro):
    admin_profile_url = settings.APP_HOST + reverse(
        "admin_profile", kwargs={"user_slug": user.slug})

    send_telegram_message(
        chat=ADMIN_CHAT,
        text=render_html_message("moderator_new_member_review.html",
                                 user=user,
                                 intro=intro),
        reply_markup=telegram.InlineKeyboardMarkup(
            [[
                telegram.InlineKeyboardButton(
                    "👍 Впустить", callback_data=f"approve_user:{user.id}")
            ],
             [
                 telegram.InlineKeyboardButton(
                     "❌️ Плохое интро",
                     callback_data=f"reject_user_intro:{user.id}"),
             ],
             [
                 telegram.InlineKeyboardButton(
                     "❌️ Недостаточно данных",
                     callback_data=f"reject_user_data:{user.id}"),
             ],
             [
                 telegram.InlineKeyboardButton(
                     "❌️ Агрессия",
                     callback_data=f"reject_user_aggression:{user.id}"),
             ],
             [
                 telegram.InlineKeyboardButton(
                     "❌️ Слишком общее",
                     callback_data=f"reject_user_general:{user.id}"),
             ],
             [
                 telegram.InlineKeyboardButton("✏️ Написать юзеру",
                                               url=admin_profile_url),
             ]]))
Exemplo n.º 23
0
def async_create_or_update_comment(comment, is_created):
    # notify admins
    send_telegram_message(
        chat=ADMIN_CHAT,
        text=render_html_message("moderator_comment.html", comment=comment),
        parse_mode=telegram.ParseMode.HTML,
    )

    # notify post author
    post_author = comment.post.author
    if post_author.telegram_id and comment.author != post_author:
        send_telegram_message(
            chat=Chat(id=comment.post.author.telegram_id),
            text=render_html_message("comment_to_post.html", comment=comment),
            parse_mode=telegram.ParseMode.HTML,
        )

    # on reply — notify thread author (do not notify yourself)
    thread_author = None
    if comment.reply_to:
        thread_author = comment.reply_to.author
        if comment.reply_to_id and thread_author.telegram_id and comment.author != thread_author:
            send_telegram_message(
                chat=Chat(id=comment.reply_to.author.telegram_id),
                text=render_html_message("comment_to_thread.html",
                                         comment=comment),
                parse_mode=telegram.ParseMode.HTML,
            )

    # post first level comments to club chat
    # if not comment.reply_to:
    #     send_telegram_message(
    #         chat=CLUB_CHAT,
    #         text=render_html_message("comment_to_post_announce.html", comment=comment),
    #         parse_mode=telegram.ParseMode.HTML,
    #     )

    # parse @nicknames and notify their users
    for username in USERNAME_RE.findall(comment.text):
        user = User.objects.filter(slug=username).first()
        if user and user.telegram_id and user != post_author and user != thread_author:
            send_telegram_message(
                chat=Chat(id=user.telegram_id),
                text=render_html_message("comment_mention.html",
                                         comment=comment),
                parse_mode=telegram.ParseMode.HTML,
            )
Exemplo n.º 24
0
def process_moderator_actions(update):
    # find an action processor
    action_name, entity_id = update.callback_query.data.split(":", 1)
    action = ACTIONS.get(action_name)

    moderator = User.objects.filter(telegram_id=update.effective_user.id).first()
    if not moderator or not moderator.is_moderator:
        send_telegram_message(
            chat=ADMIN_CHAT,
            text=f"⚠️ '{update.effective_user.full_name}' не модератор или не привязал бота к аккаунту"
        )
        return

    if not action:
        send_telegram_message(
            chat=ADMIN_CHAT,
            text=f"😱 Неизвестная команда '{update.callback_query.data}'"
        )
        return

    # run run run
    try:
        result, is_final = action(entity_id, update)
    except Exception as ex:
        send_telegram_message(
            chat=ADMIN_CHAT,
            text=f"❌ Экшен наебнулся '{update.callback_query.data}': {ex}"
        )
        return

    # send results back to the chat
    send_telegram_message(
        chat=ADMIN_CHAT,
        text=result
    )

    # hide admin buttons (to not allow people do the same thing twice)
    if is_final:
        remove_action_buttons(
            chat=ADMIN_CHAT,
            message_id=update.effective_message.message_id,
        )

    return result
Exemplo n.º 25
0
def async_create_or_update_comment(comment):
    notified_user_ids = set()

    # notify post subscribers
    post_subscribers = PostSubscription.post_subscribers(comment.post)
    for post_subscriber in post_subscribers:
        if post_subscriber.user.telegram_id and comment.author != post_subscriber.user:
            template = "comment_to_post.html" if post_subscriber.user == comment.post.author else "comment_to_post_announce.html"
            send_telegram_message(
                chat=Chat(id=post_subscriber.user.telegram_id),
                text=render_html_message(template, comment=comment),
            )
            notified_user_ids.add(post_subscriber.user.id)

    # on reply — notify thread author (do not notify yourself)
    if comment.reply_to:
        thread_author = comment.reply_to.author
        if thread_author.telegram_id and comment.author != thread_author and thread_author.id not in notified_user_ids:
            send_telegram_message(
                chat=Chat(id=thread_author.telegram_id),
                text=render_html_message("comment_to_thread.html",
                                         comment=comment),
            )
            notified_user_ids.add(thread_author.id)

    # post top level comments to online channel
    if not comment.reply_to:
        send_telegram_message(
            chat=CLUB_ONLINE,
            text=render_html_message("comment_to_post_announce.html",
                                     comment=comment),
        )

    # parse @nicknames and notify their users
    for username in USERNAME_RE.findall(comment.text):
        user = User.objects.filter(slug=username).first()
        if user and user.telegram_id and user.id not in notified_user_ids:
            send_telegram_message(
                chat=Chat(id=user.telegram_id),
                text=render_html_message("comment_mention.html",
                                         comment=comment),
            )
            notified_user_ids.add(user.id)
Exemplo n.º 26
0
def async_create_or_update_comment(comment, is_created):
    # notify post author
    post_author = comment.post.author
    if post_author.telegram_id and comment.author != post_author:
        send_telegram_message(
            chat=Chat(id=comment.post.author.telegram_id),
            text=render_html_message("comment_to_post.html", comment=comment),
        )

    # on reply — notify thread author (do not notify yourself)
    thread_author = None
    if comment.reply_to:
        thread_author = comment.reply_to.author
        if comment.reply_to_id and thread_author.telegram_id and comment.author != thread_author:
            send_telegram_message(
                chat=Chat(id=comment.reply_to.author.telegram_id),
                text=render_html_message("comment_to_thread.html",
                                         comment=comment),
            )

    # post top level comments to online channel
    if not comment.reply_to:
        send_telegram_message(
            chat=CLUB_ONLINE,
            text=render_html_message("comment_to_post_announce.html",
                                     comment=comment),
        )

    # parse @nicknames and notify their users
    for username in USERNAME_RE.findall(comment.text):
        user = User.objects.filter(slug=username).first()
        if user and user.telegram_id and user != post_author and user != thread_author:
            send_telegram_message(
                chat=Chat(id=user.telegram_id),
                text=render_html_message("comment_mention.html",
                                         comment=comment),
            )
Exemplo n.º 27
0
def async_create_or_update_post(post, is_created):
    if not post.is_approved_by_moderator:
        send_telegram_message(
            chat=ADMIN_CHAT,
            text=render_html_message("moderator_new_post_review.html",
                                     post=post),
            reply_markup=telegram.InlineKeyboardMarkup(
                [[
                    telegram.InlineKeyboardButton(
                        "👍 Одобрить", callback_data=f"approve_post:{post.id}"),
                    telegram.InlineKeyboardButton(
                        "😕 Так себе", callback_data=f"forgive_post:{post.id}"),
                ],
                 [
                     telegram.InlineKeyboardButton(
                         "❌ В черновики",
                         callback_data=f"delete_post:{post.id}"),
                 ]]))

    # post to online channel
    send_telegram_message(
        chat=CLUB_ONLINE,
        text=render_html_message("channel_post_announce.html", post=post),
        parse_mode=telegram.ParseMode.HTML,
        disable_preview=True,
    )

    # parse @nicknames and notify mentioned users (only if post is visible)
    if post.is_visible and (is_created or "is_visible" in post.changed_fields):
        notified_user_ids = set()
        for username in USERNAME_RE.findall(post.text):
            user = User.objects.filter(slug=username).first()
            if user and user.telegram_id and user.id not in notified_user_ids:
                send_telegram_message(
                    chat=Chat(id=user.telegram_id),
                    text=render_html_message("post_mention.html", post=post),
                )
                notified_user_ids.add(user.id)
Exemplo n.º 28
0
def notify_user_auth(user, code):
    if user.telegram_id:
        send_telegram_message(
            chat=Chat(id=user.telegram_id),
            text=f"<b>{code.code}</b> — ваш одноразовый код для входа в Клуб")
Exemplo n.º 29
0
def notify_user_ping(user, message):
    if user.telegram_id:
        send_telegram_message(
            chat=Chat(id=user.telegram_id),
            text=f"👋 <b>Вам письмо от модераторов Клуба:</b> {message}")
Exemplo n.º 30
0
    def handle(self, *args, **options):
        # render digest using a special html endpoint
        digest_url = "https://vas3k.club" + reverse("render_weekly_digest")
        self.stdout.write(f"Generating digest: {digest_url}")

        digest_html_response = requests.get(digest_url)
        if digest_html_response.status_code > 400:
            log.error("Weekly digest error: bad status code", extra={"html": digest_html_response.text})
            return

        digest_html = digest_html_response.text

        # save digest as a post
        issue = (datetime.utcnow() - settings.LAUNCH_DATE).days // 7
        year, week, _ = (datetime.utcnow() - timedelta(days=7)).isocalendar()
        post, _ = Post.objects.update_or_create(
            slug=f"{year}_{week}",
            type=Post.TYPE_WEEKLY_DIGEST,
            defaults=dict(
                author=User.objects.filter(slug="vas3k").first(),
                title=f"Клубный журнал. Итоги недели. Выпуск #{issue}",
                html=digest_html,
                text=digest_html,
                is_pinned_until=datetime.utcnow() + timedelta(days=1),
                is_visible=True,
                is_public=False,
            )
        )

        SearchIndex.update_post_index(post)

        # sending emails
        subscribed_users = User.objects\
            .filter(
                is_email_verified=True,
                membership_expires_at__gte=datetime.utcnow() - timedelta(days=14)
            )\
            .exclude(email_digest_type=User.EMAIL_DIGEST_TYPE_NOPE)\
            .exclude(is_profile_rejected=True)\
            .exclude(is_email_unsubscribed=True)

        for user in subscribed_users:
            self.stdout.write(f"Sending to {user.email}...")

            if not options.get("production") and user.email != "*****@*****.**":
                self.stdout.write("Test mode. Use --production to send the digest to all users")
                continue

            try:
                user_digest_html = str(digest_html)
                user_digest_html = user_digest_html\
                    .replace("%username%", user.slug)\
                    .replace("%user_id%", str(user.id))\
                    .replace("%secret_code%", user.secret_hash)

                send_club_email(
                    recipient=user.email,
                    subject=f"🤘 Клубный журнал. Итоги недели. Выпуск #{issue}",
                    html=user_digest_html,
                    tags=["weekly_digest", f"weekly_digest_{issue}"]
                )
            except Exception as ex:
                self.stdout.write(f"Sending to {user.email} failed: {ex}")
                log.exception(f"Error while sending an email to {user.email}")
                continue

        if options.get("production"):
            # flush digest intro for next time
            GodSettings.objects.update(digest_intro=None)

        send_telegram_message(
            chat=CLUB_CHANNEL,
            text=render_html_message("weekly_digest_announce.html", post=post),
            disable_preview=False,
            parse_mode=telegram.ParseMode.HTML,
        )

        self.stdout.write("Done 🥙")