feat&fix: fix build and add initial authnetication
This commit is contained in:
+2
-1
@@ -1,3 +1,5 @@
|
|||||||
|
.env
|
||||||
|
|
||||||
# ---> C
|
# ---> C
|
||||||
# Prerequisites
|
# Prerequisites
|
||||||
*.d
|
*.d
|
||||||
@@ -51,4 +53,3 @@ modules.order
|
|||||||
Module.symvers
|
Module.symvers
|
||||||
Mkfile.old
|
Mkfile.old
|
||||||
dkms.conf
|
dkms.conf
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
# discord.c
|
# discord.c
|
||||||
|
|
||||||
Discord API in C
|
A simple Discord API in C, inspired by discord.py.
|
||||||
|
|||||||
+16
-1
@@ -1,9 +1,24 @@
|
|||||||
#ifndef DISCORD_DISCORD_H
|
#ifndef DISCORD_DISCORD_H
|
||||||
#define DISCORD_DISCORD_H
|
#define DISCORD_DISCORD_H
|
||||||
|
|
||||||
|
#include "error.h"
|
||||||
|
|
||||||
|
// @TODO: use opaque pointer
|
||||||
|
#include <curl/curl.h>
|
||||||
|
|
||||||
#define DISCORD_BASE_URL "https://discord.com/api"
|
#define DISCORD_BASE_URL "https://discord.com/api"
|
||||||
#define DISCORD_API_VERSION "10"
|
#define DISCORD_API_VERSION "10"
|
||||||
|
#define DISCORD_MAX_API_URL 256
|
||||||
|
#define DISCORD_MAX_TOKEN_VALUE 128
|
||||||
|
|
||||||
typedef struct discord_client discord_client;
|
typedef struct discord_client {
|
||||||
|
// char *token_type; // Bot or Bearer
|
||||||
|
char token_value[DISCORD_MAX_TOKEN_VALUE];
|
||||||
|
char api_url[DISCORD_MAX_API_URL];
|
||||||
|
CURL *curl;
|
||||||
|
} discord_client;
|
||||||
|
|
||||||
|
// remember to call curl_global_cleanup()
|
||||||
|
discord_error discord_init(discord_client *client, const char *token);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ typedef enum discord_error {
|
|||||||
DISCORD_OK,
|
DISCORD_OK,
|
||||||
DISCORD_ERR,
|
DISCORD_ERR,
|
||||||
DISCORD_AUTH_ERR,
|
DISCORD_AUTH_ERR,
|
||||||
|
DISCORD_NULL_VALUE,
|
||||||
|
DISCORD_AUTH_FAILED,
|
||||||
} discord_error;
|
} discord_error;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
headers += files(
|
||||||
|
'discord.h',
|
||||||
|
'error.h',
|
||||||
|
'request.h',
|
||||||
|
)
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
#ifndef DISCORD_REQUEST_H
|
||||||
|
#define DISCORD_REQUEST_H
|
||||||
|
|
||||||
|
#include <curl/curl.h>
|
||||||
|
|
||||||
|
int request_auth(CURL *curl, const char *token, const char *api_url);
|
||||||
|
|
||||||
|
#endif
|
||||||
+3
-2
@@ -7,8 +7,9 @@ project(
|
|||||||
|
|
||||||
sources = []
|
sources = []
|
||||||
headers = []
|
headers = []
|
||||||
include_directories('src')
|
subdir('src')
|
||||||
include_directories('include')
|
subdir('include')
|
||||||
|
|
||||||
incdir = include_directories('include')
|
incdir = include_directories('include')
|
||||||
|
|
||||||
libcurl = dependency('libcurl', required: true)
|
libcurl = dependency('libcurl', required: true)
|
||||||
|
|||||||
+48
-4
@@ -1,6 +1,50 @@
|
|||||||
#include "discord.h"
|
#include "discord.h"
|
||||||
|
#include "error.h"
|
||||||
|
#include "request.h"
|
||||||
|
|
||||||
typedef struct discord_client {
|
#include <curl/curl.h>
|
||||||
char *token_type;
|
#include <curl/easy.h>
|
||||||
char *token_value;
|
#include <stdio.h>
|
||||||
} discord_client;
|
|
||||||
|
static int authenticate(discord_client *client) {
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = request_auth(client->curl, client->token_value, client->api_url);
|
||||||
|
if (ret != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
discord_error discord_init(discord_client *client, const char *token) {
|
||||||
|
if (!client || !token) {
|
||||||
|
return DISCORD_NULL_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ret;
|
||||||
|
CURLcode result;
|
||||||
|
|
||||||
|
ret = snprintf(client->api_url, sizeof(client->api_url), "%s/v%s/users/@me", DISCORD_BASE_URL, DISCORD_API_VERSION);
|
||||||
|
if (ret > DISCORD_MAX_API_URL) {
|
||||||
|
return DISCORD_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = snprintf(client->token_value, sizeof(client->token_value), "%s", token);
|
||||||
|
if (ret > DISCORD_MAX_TOKEN_VALUE) {
|
||||||
|
return DISCORD_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = curl_global_init(CURL_GLOBAL_ALL);
|
||||||
|
if (result != CURLE_OK) {
|
||||||
|
return DISCORD_ERR;
|
||||||
|
}
|
||||||
|
client->curl = curl_easy_init();
|
||||||
|
|
||||||
|
ret = authenticate(client);
|
||||||
|
if (ret != 0) {
|
||||||
|
return DISCORD_AUTH_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return DISCORD_OK;
|
||||||
|
}
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ static discord_err errors[] = {
|
|||||||
{DISCORD_OK, "OK"},
|
{DISCORD_OK, "OK"},
|
||||||
{DISCORD_ERR, "ERR"},
|
{DISCORD_ERR, "ERR"},
|
||||||
{DISCORD_AUTH_ERR, "Authentication error, maybe wrong token"},
|
{DISCORD_AUTH_ERR, "Authentication error, maybe wrong token"},
|
||||||
|
{DISCORD_NULL_VALUE, "NULL value passed"},
|
||||||
|
{DISCORD_AUTH_FAILED, "Authentication failed"},
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *discord_err_str(discord_error err) {
|
const char *discord_err_str(discord_error err) {
|
||||||
|
|||||||
+5
-1
@@ -1 +1,5 @@
|
|||||||
sources += files('main.c')
|
sources += files(
|
||||||
|
'discord.c',
|
||||||
|
'error.c',
|
||||||
|
'request.c',
|
||||||
|
)
|
||||||
|
|||||||
@@ -0,0 +1,85 @@
|
|||||||
|
#include "request.h"
|
||||||
|
|
||||||
|
#include <curl/curl.h>
|
||||||
|
#include <curl/easy.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <yyjson.h>
|
||||||
|
|
||||||
|
#define MAX_AUTH_LEN 256
|
||||||
|
|
||||||
|
struct response_buffer {
|
||||||
|
char *data;
|
||||||
|
size_t size;
|
||||||
|
};
|
||||||
|
|
||||||
|
static size_t write_cb(char *contents, size_t size, size_t nmemb, void *userp) {
|
||||||
|
size_t realsize = size * nmemb;
|
||||||
|
struct response_buffer *mem = (struct response_buffer *)userp;
|
||||||
|
|
||||||
|
char *ptr = realloc(mem->data, mem->size + realsize + 1);
|
||||||
|
if (!ptr) {
|
||||||
|
printf("not enough memory (realloc returned NULL)\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
mem->data = ptr;
|
||||||
|
memcpy(&(mem->data[mem->size]), contents, realsize);
|
||||||
|
mem->size += realsize;
|
||||||
|
mem->data[mem->size] = 0;
|
||||||
|
|
||||||
|
return realsize;
|
||||||
|
}
|
||||||
|
|
||||||
|
int request_auth(CURL *curl, const char *token, const char *api_url) {
|
||||||
|
if (!curl || !token) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
CURLcode result;
|
||||||
|
struct response_buffer buffer;
|
||||||
|
memset(&buffer, 0, sizeof(buffer));
|
||||||
|
|
||||||
|
char auth[MAX_AUTH_LEN];
|
||||||
|
snprintf(auth, sizeof(auth), "Authorization: Bot %s", token);
|
||||||
|
|
||||||
|
struct curl_slist *headers = NULL;
|
||||||
|
headers = curl_slist_append(headers, auth);
|
||||||
|
headers = curl_slist_append(headers, "Content-Type: application/json");
|
||||||
|
|
||||||
|
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_URL, api_url);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_VERBOSE, 0L);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_cb);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&buffer);
|
||||||
|
// @TODO: change url and version
|
||||||
|
curl_easy_setopt(curl, CURLOPT_USERAGENT, "DiscordBot (https://discord.com, 0.1)");
|
||||||
|
|
||||||
|
result = curl_easy_perform(curl);
|
||||||
|
if (result != CURLE_OK) {
|
||||||
|
fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(result));
|
||||||
|
curl_slist_free_all(headers);
|
||||||
|
free(buffer.data);
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print response
|
||||||
|
fprintf(stdout, "[RESPONSE SIZE]: %ld\n", buffer.size);
|
||||||
|
fprintf(stdout, "[RESPONSE DATA]:\n%s\n", buffer.data);
|
||||||
|
|
||||||
|
// Parse json
|
||||||
|
yyjson_doc *doc = yyjson_read(buffer.data, buffer.size, 0);
|
||||||
|
yyjson_val *root = yyjson_doc_get_root(doc);
|
||||||
|
yyjson_val *username = yyjson_obj_get(root, "username");
|
||||||
|
fprintf(stdout, "[USERNAME]: %s\n", yyjson_get_str(username));
|
||||||
|
|
||||||
|
// Clear resources
|
||||||
|
yyjson_doc_free(doc);
|
||||||
|
free(buffer.data);
|
||||||
|
|
||||||
|
curl_slist_free_all(headers);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
+13
-1
@@ -1,7 +1,19 @@
|
|||||||
|
#include "discord.h"
|
||||||
|
#include "error.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
puts("discord.c");
|
puts("discord.c example");
|
||||||
|
|
||||||
|
const char token[] = "";
|
||||||
|
|
||||||
|
discord_client client;
|
||||||
|
discord_error err = discord_init(&client, token);
|
||||||
|
if (err != DISCORD_OK) {
|
||||||
|
fprintf(stderr, "discord_init(): %s\n", discord_err_str(err));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user