aboutsummaryrefslogtreecommitdiff
path: root/example.c
blob: d8b268d27c53042941df82ba594f241743ba0dd9 (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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#include "easy-tg.h"
#include <stdio.h>
#include <unistd.h>
#include <string.h>

/* In this example we are not closing TDLib properly. In a real-world program, you need to call tg_close() to make a close request to TDLib (any thread is OK), and wait for the TG_CLOSED response. */

static void read_input(const char *prompt, char *buf, unsigned int len)
{
	printf("%s", prompt);
	fflush(stdout);
	ssize_t size = read(0, buf, len + 1);
	if(size >= 1) buf[size - 1] = '\0';
	printf("Read: %s\n", buf);
}

static void run()
{
	/* In each loop, the action our application needs to take is returned via return code.
	 * Other data, such as current update type and the whole JSON response, are stored in registers.
	 * There are nine registers:
	 * int tg_errno: In case of error, it will store the error code.
	 * const char *tg_update_type: Always stores the parsed type of update.
	 * json_object *tg_update: Always stores the whole tokenized JSON update.
	 * void *tg_reg1: Optional data field.
	 * void *tg_reg2: Optional data field.
	 * void *tg_reg3: Optional data field.
	 * void *tg_reg4: Optional data field.
	 * void *tg_reg5: Optional data field.
	 * void *tg_reg6: Optional data field.
	 * Each register has the lifetime from the end of tg_loop() to the next call of tg_loop().
	 * After calling tg_loop() for the next time, all memory will be released and the registers will be reset to default values, which are 0 for int and NULL for pointers.
	 */
	printf("%s\n", tg_update_type);
}

int main(int argc, char **argv)
{
	int r = 0;
	r = tg_init();
	if(r) goto cleanup; /* Fetal errors encountered. */
	while(1)
	{
		switch(tg_loop())
		{
			case TG_IGNORE: /* Invalid response from TDLib. Just ignore it. */
				break;
			case TG_RUN: /* Non-login update received. Run our custom function. */
				run();
				break;
			case TG_CLOSED: /* TDLib is shutting down. We have nothing to do except releasing resources. */
				goto destroy;
			case TG_CLOSING: /* TDLib is closing. Currently we don't need to do nothing. */
			case TG_LOGGING_OUT: /* The account is logging out. No need for now. */
				break;
			case TG_LOGGED_IN: /* Login ready. */
				printf("You are logged in!\n");
				break;
			case TG_LOGIN_PHONE: /* We need to provide the phone number to login. */
				char phone[20];
				read_input("Phone number: ", phone, 19);
				tg_login_phone(phone);
				break;
			case TG_LOGIN_CODE: /* We need to provide the verification code. */
				char code[7];
				read_input("Verification code: ", code, 6);
				tg_login_code(code);
				break;
			case TG_LOGIN_ENC: /* During initialization, TDLib is asking us for database encryption key. */
				tg_login_enc_key(""); /* Just leave it empty for now. */
				break;
			case TG_LOGIN_QR: /* QR login. Currently not supported in the demo. */
				/* The QR link is stored in register 1. */
				/* generate_qr((char*)tg_reg1); */
				printf("QR login not supported.\n");
				break;
			case TG_LOGIN_PW: /* We need to type the password. */
				char pass[257];
				read_input("Password: ", pass, 256);
				tg_login_pass(pass);
				break;
			case TG_LOGIN_REG: /* The phone number is verified but unknown. We need fill in the registration form. In this case, we will ask the user to register in the official client instead. */
				printf("Your phone number is not known.\n");
				break;
			case TG_PARAMS: /* TDLib is not been setup and is asking you for parameters. */
				tg_set_params(
					true, /* Use test datacenter */
					"/tmp/td", /* Database directory */
					NULL, /* Files directory */
					false, /* Use files database */
					false, /* Use message database */
					false, /* Use chat info database */
					false, /* Support secret chats */
					API_ID, /* API ID */
					API_HASH, /* API Hash */
					"en", /* System language code */
					"Desktop", /* Device model */
					"Windoge 114.514", /* System version */
					"Moe Bot", /* Application version */
					false, /* Enable storage optimizer */
					true /* Ignore file names */
				);
				break;
			case TG_ERROR: /* TDLib returned an error. */
				/* Error code is stored in tg_errno;
				 * Request extra (ID) is stored in register 1;
				 * Error message is stored in register 2.
				 */
				/* Built-in request extras */
				if(!strcmp(TG_REQ_SET_PARAMS, tg_reg1))
				{
					printf("Invalid TDLib parameters! %d (%s)\n", tg_errno, tg_reg2);
				} else if(!strcmp(TG_REQ_LOGIN_PHONE, tg_reg1))
				{
					printf("Invalid phone number! %d (%s)\n", tg_errno, tg_reg2);
				} else if(!strcmp(TG_REQ_LOGIN_PASS, tg_reg1))
				{
					printf("Invalid password! %d (%s)\n", tg_errno, tg_reg2);
				} else
				{
					printf("Invalid request: %s! %d (%s)\n", tg_reg1, tg_errno, tg_reg2);
				}
				break;
			case TG_SYSERR: /* Easy-TG encountered an error. */
				/* Error code is stored in tg_errno. */
				printf("Fetal: %d\n", tg_errno);
				break;
			default:
				printf("???\n");
				break;
		}
	}
	goto destroy;
destroy:
	tg_destroy();
	goto cleanup;
cleanup:
	return r;
}