-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathmain.c
147 lines (123 loc) · 4.4 KB
/
main.c
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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#include <deltachat.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
void handle_message(dc_context_t *context, int chat_id, int message_id) {
dc_chat_t *chat = dc_get_chat(context, chat_id);
if (dc_chat_get_type(chat) == DC_CHAT_TYPE_SINGLE) {
dc_msg_t *msg = dc_get_msg(context, message_id);
if (!msg) {
return;
}
char *text = dc_msg_get_text(msg);
dc_send_text_msg(context, chat_id, text);
dc_str_unref(text);
dc_msg_unref(msg);
}
dc_chat_unref(chat);
}
void *event_handler(void *context) {
dc_event_emitter_t *emitter = dc_get_event_emitter(context);
dc_event_t *event;
while ((event = dc_get_next_event(emitter)) != NULL) {
// use the event as needed, e.g. dc_event_get_id() returns the type.
// once you're done, unref the event to avoid memory leakage:
int event_type = dc_event_get_id(event);
if (event_type == DC_EVENT_ERROR || event_type == DC_EVENT_INFO ||
event_type == DC_EVENT_WARNING) {
char *message = dc_event_get_data2_str(event);
switch (event_type) {
case DC_EVENT_ERROR:
printf("[Error] %s\n", message);
break;
case DC_EVENT_INFO:
printf("[Info] %s\n", message);
break;
case DC_EVENT_WARNING:
printf("[Warn] %s\n", message);
break;
}
dc_str_unref(message);
} else if (event_type == DC_EVENT_CONFIGURE_PROGRESS) {
int progress = dc_event_get_data1_int(event);
char *comment = dc_event_get_data2_str(event);
printf("[configure-progress] %d %s\n", progress, comment);
if (progress == 0) {
// Failed to configure
printf(
"[BOT] configuration failed, maybe your credentials are incorect? "
"look for error messages above and restart the bot to try again");
} else if (progress == 1000) {
printf("[BOT] confuguration sucessfull, starting io");
dc_start_io(context);
}
dc_str_unref(comment);
} else if (event_type == DC_EVENT_INCOMING_MSG) {
int chat_id = dc_event_get_data1_int(event);
int message_id = dc_event_get_data2_int(event);
printf("[incoming-msg] %d %d\n", chat_id, message_id);
handle_message(context, chat_id, message_id);
} else {
printf("[?] unhandled event of type: %d\n", event_type);
}
dc_event_unref(event);
}
dc_event_emitter_unref(emitter);
return NULL;
}
void stop_context(dc_context_t *context) {
dc_stop_io(context);
dc_stop_ongoing_process(context);
}
int main() {
// this line is just a hacky workaround to ensure we are using a recent core
// that already auto accepts contact requests, when bot config variable is set.
// basically a core version that includes https://github.com/deltachat/deltachat-core-rust/pull/3567 merged
dc_jsonrpc_instance_t* unused;
char *addr = getenv("addr");
char *mailpw = getenv("mailpw");
printf("starting bot\n");
dc_context_t *context = dc_context_new(NULL, "deltachat-db/dc.db", NULL);
static pthread_t event_thread;
if (pthread_create(&event_thread, NULL, event_handler, context) != 0) {
printf("Event Thread creation failed\n");
stop_context(context);
return 1;
}
if (!dc_is_configured(context)) {
if (!addr) {
printf("you need to specify the addr enviroment variable to the bots "
"email address\n");
}
if (!mailpw) {
printf("you need to specify the mailpw enviroment variable to the bots "
"email password\n");
}
if (!addr || !mailpw) {
stop_context(context);
printf("shutting down...\n");
int thread_join_result = pthread_join(event_thread, NULL);
if (thread_join_result != 0) {
printf("join thread failed with error code %d\n", thread_join_result);
}
return 1;
}
printf("configuring bot\n");
dc_set_config(context, "addr", addr);
dc_set_config(context, "mail_pw", mailpw);
dc_set_config(context, "bot", "1");
dc_set_config(context, "fetch_existing_msgs", "0");
dc_configure(context);
} else {
printf("already configured, wait for messages\n");
char* addr = dc_get_config (context, "addr");
printf("bot address is %s\n", addr);
dc_start_io(context);
}
// wait for event thread to complete
int thread_join_result = pthread_join(event_thread, NULL);
if (thread_join_result != 0) {
printf("join thread failed with error code %d\n", thread_join_result);
}
return 0;
}