summaryrefslogtreecommitdiff
path: root/store.c
blob: f49f23ba54994020da19cc3706af9b7ebf646cb2 (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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
/*
 * Created by yuuta on 4/1/22.
 */

#include "log.h"
#include "logic.h"
#include "db.h"
#include "botd.h"

#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

/* Temp object between message callback and link callback */
struct say {
    long long msg_id;
    long long chat_id;
    char *text;
};

static void cb_link(bool successful, struct TdObject *result, struct TdError *error, void *cb_arg) {
    struct say *s = cb_arg;
    if (!successful) {
        LOGEV("Cannot get link for %lld/%lld: %s (%d).",
              s->chat_id, s->msg_id,
              error ? error->message_ : "NULL",
              error ? error->code_ : 0);
        goto cleanup;
    }
    LOGDV("%s", s->text);
    struct TdMessageLink *link = (struct TdMessageLink *) result;
    int r;
    sqlite3_stmt *stmt;
    if ((r = sqlite3_prepare_v2(db,
                                "INSERT INTO says(t, url, msg) VALUES(?, ?, ?)",
                                -1,
                                &stmt,
                                NULL))) {
        goto sql_err;
        sql_err:
        LOGEV("Cannot insert: %s.", sqlite3_errstr(r));
        goto cleanup;
    }
    if ((r = sqlite3_bind_text(stmt, 1, s->text, (int) strlen(s->text), NULL))) {
        goto sql_err;
    }
    if ((r = sqlite3_bind_text(stmt, 2, link->link_, (int) strlen(link->link_), NULL))) {
        goto sql_err;
    }
    if ((r = sqlite3_bind_int64(stmt, 3, s->msg_id))) {
        goto sql_err;
    }
    r = sqlite3_step(stmt);
    sqlite3_finalize(stmt);
    if (r != SQLITE_DONE && r != SQLITE_CONSTRAINT) {
        goto sql_err;
    }
    goto cleanup;
    cleanup:
    free(s->text);
    free(s);
}

static bool filter(struct TdMessage *msg) {
    if (msg->chat_id_ != CHANNEL)
        return false;
    if (!msg->forward_info_ || !msg->forward_info_->origin_) {
        return false;
    }
    struct TdMessageForwardOrigin *origin = msg->forward_info_->origin_;
    switch (origin->ID) {
        case CODE_MessageForwardOriginChannel: {
            struct TdMessageForwardOriginChannel *chan =
                    (struct TdMessageForwardOriginChannel *) origin;
            if (chan->chat_id_ != -1001304761546 &&
                chan->chat_id_ != -1001565681839)
                return false;
            break;
        }
        case CODE_MessageForwardOriginHiddenUser: {
            struct TdMessageForwardOriginHiddenUser *hid_user =
                    (struct TdMessageForwardOriginHiddenUser *) origin;
            if (strcmp("ksyx", hid_user->sender_name_) != 0) return false;
            break;
        }
        default: {
            return false;
        }
    }

    if (msg->content_->ID != CODE_MessageText) {
        return false;
    }
    return true;
}

void store(struct TdMessage *msg) {
    if (!filter(msg)) return;
    struct TdMessageText *text = (struct TdMessageText *) msg->content_;
    const char *t = text->text_->text_;
    struct say *s;
    if (!(s = malloc(sizeof(struct say)))) {
        LOGEV("Cannot allocate memory: %s.", strerror(errno));
        return;
    }
    memset(s, 0, sizeof(struct say));
    s->chat_id = msg->chat_id_;
    s->msg_id = msg->id_;
    /* I'm just too lazy to manually free in each callback, so just strdup. */
    if (!(s->text = strdup(t))) {
        LOGEV("Cannot allocate memory: %s.", strerror(errno));
        free(s);
        return;
    }
    td_send(TdCreateObjectGetMessageLink(msg->chat_id_,
                                         msg->id_,
                                         0,
                                         false,
                                         false),
            &cb_link,
            s);

}