summaryrefslogtreecommitdiff
path: root/store.c
diff options
context:
space:
mode:
Diffstat (limited to 'store.c')
-rw-r--r--store.c125
1 files changed, 125 insertions, 0 deletions
diff --git a/store.c b/store.c
new file mode 100644
index 0000000..f49f23b
--- /dev/null
+++ b/store.c
@@ -0,0 +1,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);
+
+}
+