feat&fix: fix build and add initial authnetication
This commit is contained in:
+2
-1
@@ -1,3 +1,5 @@
|
||||
.env
|
||||
|
||||
# ---> C
|
||||
# Prerequisites
|
||||
*.d
|
||||
@@ -51,4 +53,3 @@ modules.order
|
||||
Module.symvers
|
||||
Mkfile.old
|
||||
dkms.conf
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
# 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
|
||||
#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_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
|
||||
|
||||
@@ -5,6 +5,8 @@ typedef enum discord_error {
|
||||
DISCORD_OK,
|
||||
DISCORD_ERR,
|
||||
DISCORD_AUTH_ERR,
|
||||
DISCORD_NULL_VALUE,
|
||||
DISCORD_AUTH_FAILED,
|
||||
} 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 = []
|
||||
headers = []
|
||||
include_directories('src')
|
||||
include_directories('include')
|
||||
subdir('src')
|
||||
subdir('include')
|
||||
|
||||
incdir = include_directories('include')
|
||||
|
||||
libcurl = dependency('libcurl', required: true)
|
||||
|
||||
+48
-4
@@ -1,6 +1,50 @@
|
||||
#include "discord.h"
|
||||
#include "error.h"
|
||||
#include "request.h"
|
||||
|
||||
typedef struct discord_client {
|
||||
char *token_type;
|
||||
char *token_value;
|
||||
} discord_client;
|
||||
#include <curl/curl.h>
|
||||
#include <curl/easy.h>
|
||||
#include <stdio.h>
|
||||
|
||||
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_ERR, "ERR"},
|
||||
{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) {
|
||||
|
||||
+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>
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user