summaryrefslogtreecommitdiff
path: root/bot/src/actions/delete.cpp
blob: 5813d6318955fc0666a06a82ba47bbeecbecdc60 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#include <dpp/dpp.h>

dpp::task<bool> delete_action(const dpp::slashcommand_t &event, const nlohmann::json &action,
                              const std::unordered_map<std::string, std::string> &key_values,
                              dpp::user &user_ptr, dpp::cluster *cluster)
{
    const dpp::channel *channel_ptr = &event.command.get_channel();
    const auto &guild_ptr = event.command.get_guild();

    const auto member_it = guild_ptr.members.find(user_ptr.id);
    const auto *member_ptr = (member_it != guild_ptr.members.end()) ? &member_it->second : nullptr;

    const auto bot_member_it = guild_ptr.members.find(cluster->me.id);
    const auto *bot_member_ptr = (bot_member_it != guild_ptr.members.end()) ? &bot_member_it->second : nullptr;

    const std::unordered_map<std::string, std::string> error_messages = [&action]()
    {
        std::unordered_map<std::string, std::string> defaults = {
            {"error", "You need to wait a bit before deleting messages."},
            {"error_amount", "The amount of messages to delete must be between 1 and 100."},
            {"error_perm_channel", "You do not have permission to delete messages in this channel."}};
        if (action.contains("error_amount"))
            defaults["error_amount"] = action["error_amount"];
        if (action.contains("error_perm_channel"))
            defaults["error_perm_channel"] = action["error_perm_channel"];
        if (action.contains("error"))
            defaults["error"] = action["error"];
        return defaults;
    }();

    if (!member_ptr || !bot_member_ptr)
    {
        event.edit_response(error_messages.at("error_perm_channel"));
        co_return false;
    }

    const bool has_permissions = channel_ptr->get_user_permissions(*member_ptr).has(dpp::p_manage_messages) && channel_ptr->get_user_permissions(*bot_member_ptr).has(dpp::p_manage_messages);
    if (!has_permissions)
    {
        event.edit_response(error_messages.at("error_perm_channel"));
        co_return false;
    }

    int amount = 0;
    if (action.contains("depend_on"))
    {
        const std::string &depend_on = action["depend_on"];
        if (const auto it = key_values.find(depend_on); it != key_values.end())
        {
            try
            {
                amount = std::stoi(it->second);
                if (amount < 1 || amount > 100)
                {
                    event.edit_response(error_messages.at("error_amount"));
                    co_return false;
                }
            }
            catch (const std::exception &e)
            {
                event.edit_response(error_messages.at("error"));
                co_return false;
            }
        }
    }

    if (amount > 0)
    {
        const time_t two_weeks_ago = dpp::utility::time_f() - 1209600;

        auto callback = co_await cluster->co_messages_get(channel_ptr->id, 0, 0, 0, amount);
        if (callback.is_error())
        {
            event.edit_response(error_messages.at("error"));
            co_return false;
        }

        const auto &messages = callback.get<dpp::message_map>();
        if (messages.empty())
        {
            event.edit_response("No messages to delete.");
            co_return false;
        }

        std::vector<dpp::snowflake> msg_ids;
        msg_ids.reserve(messages.size());

        for (const auto &[id, msg] : messages)
        {
            if (msg.get_creation_time() >= two_weeks_ago)
            {
                msg_ids.emplace_back(id);
            }
        }

        if (!msg_ids.empty())
        {
            const auto delete_result = msg_ids.size() == 1
                                           ? co_await cluster->co_message_delete(msg_ids.front(), channel_ptr->id)
                                           : co_await cluster->co_message_delete_bulk(msg_ids, channel_ptr->id);

            if (delete_result.is_error())
            {
                event.edit_response(error_messages.at("error"));
                co_return false;
            }
        }
    }

    co_return true;
}