added a bunch of methods
This commit is contained in:
parent
5c3d9fe397
commit
556e2fc380
@ -10,6 +10,7 @@ pub const Sharder = @import("core.zig");
|
|||||||
const SessionOptions = Sharder.SessionOptions;
|
const SessionOptions = Sharder.SessionOptions;
|
||||||
|
|
||||||
pub const FetchReq = @import("http.zig").FetchReq;
|
pub const FetchReq = @import("http.zig").FetchReq;
|
||||||
|
pub const FileData = @import("http.zig").FileData;
|
||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const mem = std.mem;
|
const mem = std.mem;
|
||||||
|
185
src/http.zig
185
src/http.zig
@ -135,7 +135,61 @@ pub const FetchReq = struct {
|
|||||||
return try zjson.parse(T, self.allocator, try self.body.toOwnedSlice());
|
return try zjson.parse(T, self.allocator, try self.body.toOwnedSlice());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn makeRequest(self: *FetchReq, method: http.Method, path: []const u8, to_post: ?[]const u8) MakeRequestError!http.Client.FetchResult {
|
pub fn post2(self: *FetchReq, comptime T: type, path: []const u8) !zjson.Owned(T) {
|
||||||
|
const result = try self.makeRequest(.POST, path, null);
|
||||||
|
|
||||||
|
if (result.status != .ok)
|
||||||
|
return error.FailedRequest;
|
||||||
|
|
||||||
|
return try zjson.parse(T, self.allocator, try self.body.toOwnedSlice());
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn post3(
|
||||||
|
self: *FetchReq,
|
||||||
|
comptime T: type,
|
||||||
|
path: []const u8,
|
||||||
|
object: anytype,
|
||||||
|
files: []const FileData,
|
||||||
|
) !void {
|
||||||
|
var buf: [4096]u8 = undefined;
|
||||||
|
var fba = std.heap.FixedBufferAllocator.init(&buf);
|
||||||
|
var string = std.ArrayList(u8).init(fba.allocator());
|
||||||
|
errdefer string.deinit();
|
||||||
|
|
||||||
|
try json.stringify(object, .{}, string.writer());
|
||||||
|
const result = try self.makeRequestWithFiles(.POST, path, try string.toOwnedSlice(), files);
|
||||||
|
|
||||||
|
_ = T;
|
||||||
|
if (result.status != .ok)
|
||||||
|
return error.FailedRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn post4(self: *FetchReq, path: []const u8, object: anytype) !void {
|
||||||
|
var buf: [4096]u8 = undefined;
|
||||||
|
var fba = std.heap.FixedBufferAllocator.init(&buf);
|
||||||
|
var string = std.ArrayList(u8).init(fba.allocator());
|
||||||
|
errdefer string.deinit();
|
||||||
|
|
||||||
|
try json.stringify(object, .{}, string.writer());
|
||||||
|
const result = try self.makeRequest(.POST, path, try string.toOwnedSlice());
|
||||||
|
|
||||||
|
if (result.status != .no_content)
|
||||||
|
return error.FailedRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn post5(self: *FetchReq, path: []const u8) !void {
|
||||||
|
const result = try self.makeRequest(.POST, path, null);
|
||||||
|
|
||||||
|
if (result.status != .no_content)
|
||||||
|
return error.FailedRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn makeRequest(
|
||||||
|
self: *FetchReq,
|
||||||
|
method: http.Method,
|
||||||
|
path: []const u8,
|
||||||
|
to_post: ?[]const u8,
|
||||||
|
) MakeRequestError!http.Client.FetchResult {
|
||||||
var buf: [256]u8 = undefined;
|
var buf: [256]u8 = undefined;
|
||||||
const constructed = try std.fmt.bufPrint(&buf, "{s}{s}", .{ BASE_URL, path });
|
const constructed = try std.fmt.bufPrint(&buf, "{s}{s}", .{ BASE_URL, path });
|
||||||
|
|
||||||
@ -157,4 +211,133 @@ pub const FetchReq = struct {
|
|||||||
const res = try self.client.fetch(fetch_options);
|
const res = try self.client.fetch(fetch_options);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn makeRequestWithFiles(
|
||||||
|
self: *FetchReq,
|
||||||
|
method: http.Method,
|
||||||
|
path: []const u8,
|
||||||
|
to_post: []const u8,
|
||||||
|
files: []const FileData,
|
||||||
|
) !http.Client.FetchResult {
|
||||||
|
var form_fields = try std.ArrayList(FormField).initCapacity(self.allocator, files.len + 1);
|
||||||
|
errdefer form_fields.deinit();
|
||||||
|
|
||||||
|
for (files, 0..) |file, i|
|
||||||
|
form_fields.appendAssumeCapacity(.{
|
||||||
|
.name = try std.fmt.allocPrint(self.allocator, "files[{d}]", .{i}),
|
||||||
|
.filename = file.filename,
|
||||||
|
.value = file.value,
|
||||||
|
.content_type = .{ .override = try file.type.string() },
|
||||||
|
});
|
||||||
|
|
||||||
|
form_fields.appendAssumeCapacity(.{
|
||||||
|
.name = "payload_json",
|
||||||
|
.value = to_post,
|
||||||
|
.content_type = .{ .override = "application/json" },
|
||||||
|
});
|
||||||
|
|
||||||
|
var boundary: [64 + 3]u8 = undefined;
|
||||||
|
std.debug.assert((std.fmt.bufPrint(
|
||||||
|
&boundary,
|
||||||
|
"{x:0>16}-{x:0>16}-{x:0>16}-{x:0>16}",
|
||||||
|
.{ std.crypto.random.int(u64), std.crypto.random.int(u64), std.crypto.random.int(u64), std.crypto.random.int(u64) },
|
||||||
|
) catch unreachable).len == boundary.len);
|
||||||
|
|
||||||
|
const body = try createMultiPartFormDataBody(
|
||||||
|
self.allocator,
|
||||||
|
&boundary,
|
||||||
|
try form_fields.toOwnedSlice(),
|
||||||
|
);
|
||||||
|
|
||||||
|
const headers: std.http.Client.Request.Headers = .{
|
||||||
|
.content_type = .{ .override = try std.fmt.allocPrint(self.allocator, "multipart/form-data; boundary={s}", .{boundary}) },
|
||||||
|
.authorization = .{ .override = self.token },
|
||||||
|
};
|
||||||
|
|
||||||
|
var uri_buf: [256]u8 = undefined;
|
||||||
|
const uri = try std.Uri.parse(try std.fmt.bufPrint(&uri_buf, "{s}{s}", .{ BASE_URL, path }));
|
||||||
|
|
||||||
|
var server_header_buffer: [16 * 1024]u8 = undefined;
|
||||||
|
var request = try self.client.open(method, uri, .{
|
||||||
|
.keep_alive = false,
|
||||||
|
.server_header_buffer = &server_header_buffer,
|
||||||
|
.headers = headers,
|
||||||
|
});
|
||||||
|
defer request.deinit();
|
||||||
|
request.transfer_encoding = .{ .content_length = body.len };
|
||||||
|
|
||||||
|
try request.send();
|
||||||
|
try request.writeAll(body);
|
||||||
|
|
||||||
|
try request.finish();
|
||||||
|
try request.wait();
|
||||||
|
|
||||||
|
try request.reader().readAllArrayList(&self.body, 2 * 1024 * 1024);
|
||||||
|
|
||||||
|
if (request.response.status.class() == .success)
|
||||||
|
return .{ .status = request.response.status };
|
||||||
|
return error.FailedRequest; // TODO: make an Either type lol
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub const FileData = struct {
|
||||||
|
filename: []const u8,
|
||||||
|
value: []const u8,
|
||||||
|
type: union(enum) {
|
||||||
|
jpg,
|
||||||
|
jpeg,
|
||||||
|
png,
|
||||||
|
webp,
|
||||||
|
gif,
|
||||||
|
pub fn string(self: @This()) ![]const u8 {
|
||||||
|
var buf: [256]u8 = undefined;
|
||||||
|
return std.fmt.bufPrint(&buf, "image/{s}", .{@tagName(self)});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const FormField = struct {
|
||||||
|
name: []const u8,
|
||||||
|
filename: ?[]const u8 = null,
|
||||||
|
content_type: std.http.Client.Request.Headers.Value = .default,
|
||||||
|
value: []const u8,
|
||||||
|
};
|
||||||
|
|
||||||
|
fn createMultiPartFormDataBody(
|
||||||
|
allocator: std.mem.Allocator,
|
||||||
|
boundary: []const u8,
|
||||||
|
fields: []const FormField,
|
||||||
|
) error{OutOfMemory}![]const u8 {
|
||||||
|
var body: std.ArrayListUnmanaged(u8) = .{};
|
||||||
|
errdefer body.deinit(allocator);
|
||||||
|
const writer = body.writer(allocator);
|
||||||
|
|
||||||
|
for (fields) |field| {
|
||||||
|
try writer.print("--{s}\r\n", .{boundary});
|
||||||
|
|
||||||
|
if (field.filename) |filename| {
|
||||||
|
try writer.print("Content-Disposition: form-data; name=\"{s}\"; filename=\"{s}\"\r\n", .{ field.name, filename });
|
||||||
|
} else {
|
||||||
|
try writer.print("Content-Disposition: form-data; name=\"{s}\"\r\n", .{field.name});
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (field.content_type) {
|
||||||
|
.default => {
|
||||||
|
if (field.filename != null) {
|
||||||
|
try writer.writeAll("Content-Type: application/octet-stream\r\n");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
.omit => {},
|
||||||
|
.override => |content_type| {
|
||||||
|
try writer.print("Content-Type: {s}\r\n", .{content_type});
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
try writer.writeAll("\r\n");
|
||||||
|
try writer.writeAll(field.value);
|
||||||
|
try writer.writeAll("\r\n");
|
||||||
|
}
|
||||||
|
try writer.print("--{s}--\r\n", .{boundary});
|
||||||
|
|
||||||
|
return try body.toOwnedSlice(allocator);
|
||||||
|
}
|
||||||
|
1187
src/shard.zig
1187
src/shard.zig
File diff suppressed because it is too large
Load Diff
@ -5,6 +5,7 @@ const AllowedMentionsTypes = @import("shared.zig").AllowedMentionsTypes;
|
|||||||
const ChannelTypes = @import("shared.zig").ChannelTypes;
|
const ChannelTypes = @import("shared.zig").ChannelTypes;
|
||||||
const OverwriteTypes = @import("shared.zig").OverwriteTypes;
|
const OverwriteTypes = @import("shared.zig").OverwriteTypes;
|
||||||
const ChannelFlags = @import("shared.zig").ChannelFlags;
|
const ChannelFlags = @import("shared.zig").ChannelFlags;
|
||||||
|
const TargetTypes = @import("shared.zig").TargetTypes;
|
||||||
const VideoQualityModes = @import("shared.zig").VideoQualityModes;
|
const VideoQualityModes = @import("shared.zig").VideoQualityModes;
|
||||||
const SortOrderTypes = @import("shared.zig").SortOrderTypes;
|
const SortOrderTypes = @import("shared.zig").SortOrderTypes;
|
||||||
const User = @import("user.zig").User;
|
const User = @import("user.zig").User;
|
||||||
@ -198,3 +199,20 @@ pub const ModifyGuildChannelPositions = struct {
|
|||||||
/// The new parent ID for the channel that is moved
|
/// The new parent ID for the channel that is moved
|
||||||
parent_id: ?Snowflake,
|
parent_id: ?Snowflake,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub const CreateChannelInvite = struct {
|
||||||
|
/// Duration of invite in seconds before expiry, or 0 for never. Between 0 and 604800 (7 days). Default: 86400 (24 hours)
|
||||||
|
max_age: ?isize,
|
||||||
|
/// Max number of users or 0 for unlimited. Between 0 and 100. Default: 0
|
||||||
|
max_uses: ?isize,
|
||||||
|
/// Whether this invite only grants temporary membership. Default: false
|
||||||
|
temporary: ?bool,
|
||||||
|
/// If true, don't try to reuse similar invite (useful for creating many unique one time use invites). Default: false
|
||||||
|
unique: ?bool,
|
||||||
|
/// The type of target for this voice channel invite
|
||||||
|
target_type: ?TargetTypes,
|
||||||
|
/// The id of the user whose stream to display for this invite, required if `target_type` is 1, the user must be streaming in the channel
|
||||||
|
target_user_id: ?Snowflake,
|
||||||
|
/// The id of the embedded application to open for this invite, required if `target_type` is 2, the application must have the `EMBEDDED` flag
|
||||||
|
target_application_id: ?Snowflake,
|
||||||
|
};
|
||||||
|
@ -616,6 +616,7 @@ pub const CreateGuildChannel = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const CreateMessage = struct {
|
pub const CreateMessage = struct {
|
||||||
|
attachments: []Partial(Attachment),
|
||||||
/// The message contents (up to 2000 characters)
|
/// The message contents (up to 2000 characters)
|
||||||
content: ?[]const u8,
|
content: ?[]const u8,
|
||||||
/// Can be used to verify a message was sent (up to 25 characters). Value will appear in the Message Create event.
|
/// Can be used to verify a message was sent (up to 25 characters). Value will appear in the Message Create event.
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
const User = @import("user.zig").User;
|
const User = @import("user.zig").User;
|
||||||
const Snowflake = @import("snowflake.zig").Snowflake;
|
const Snowflake = @import("snowflake.zig").Snowflake;
|
||||||
const ActivityTypes = @import("shared.zig").ActivityTypes;
|
const ActivityTypes = @import("shared.zig").ActivityTypes;
|
||||||
|
const Partial = @import("partial.zig").Partial;
|
||||||
|
|
||||||
/// https://discord.com/developers/docs/topics/gateway#get-gateway-bot
|
/// https://discord.com/developers/docs/topics/gateway#get-gateway-bot
|
||||||
pub const GetGatewayBot = struct {
|
pub const GetGatewayBot = struct {
|
||||||
@ -34,7 +35,7 @@ pub const PresenceUpdate = struct {
|
|||||||
offline,
|
offline,
|
||||||
},
|
},
|
||||||
/// The user presence is being updated for
|
/// The user presence is being updated for
|
||||||
user: User,
|
user: Partial(User),
|
||||||
/// id of the guild
|
/// id of the guild
|
||||||
guild_id: Snowflake,
|
guild_id: Snowflake,
|
||||||
/// User's current activities
|
/// User's current activities
|
||||||
@ -64,7 +65,8 @@ pub const Activity = struct {
|
|||||||
/// Unix timestamps for start and/or end of the game
|
/// Unix timestamps for start and/or end of the game
|
||||||
timestamps: ?ActivityTimestamps,
|
timestamps: ?ActivityTimestamps,
|
||||||
/// Application id for the game
|
/// Application id for the game
|
||||||
application_id: ?Snowflake,
|
/// a string
|
||||||
|
application_id: ?[]const u8,
|
||||||
/// The emoji used for a custom status
|
/// The emoji used for a custom status
|
||||||
emoji: ?ActivityEmoji,
|
emoji: ?ActivityEmoji,
|
||||||
/// Information for the current party of the player
|
/// Information for the current party of the player
|
||||||
@ -80,21 +82,25 @@ pub const Activity = struct {
|
|||||||
/// https://discord.com/developers/docs/resources/application#get-application-activity-instance-activity-instance-object
|
/// https://discord.com/developers/docs/resources/application#get-application-activity-instance-activity-instance-object
|
||||||
pub const ActivityInstance = struct {
|
pub const ActivityInstance = struct {
|
||||||
/// Application ID
|
/// Application ID
|
||||||
application_id: Snowflake,
|
/// a string
|
||||||
|
application_id: []const u8,
|
||||||
/// Activity Instance ID
|
/// Activity Instance ID
|
||||||
instance_id: Snowflake,
|
/// a string
|
||||||
|
instance_id: []const u8,
|
||||||
/// Unique identifier for the launch
|
/// Unique identifier for the launch
|
||||||
launch_id: Snowflake,
|
/// a string
|
||||||
|
launch_id: []const u8,
|
||||||
/// The Location the instance is runnning in
|
/// The Location the instance is runnning in
|
||||||
location: ActivityLocation,
|
location: ActivityLocation,
|
||||||
/// The IDs of the Users currently connected to the instance
|
/// The IDs of the Users currently connected to the instance
|
||||||
users: [][]const u8,
|
users: []Snowflake,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// https://discord.com/developers/docs/resources/application#get-application-activity-instance-activity-location-object
|
/// https://discord.com/developers/docs/resources/application#get-application-activity-instance-activity-location-object
|
||||||
pub const ActivityLocation = struct {
|
pub const ActivityLocation = struct {
|
||||||
/// The unique identifier for the location
|
/// The unique identifier for the location
|
||||||
id: Snowflake,
|
/// a string
|
||||||
|
id: []const u8,
|
||||||
/// Enum describing kind of location
|
/// Enum describing kind of location
|
||||||
kind: ActivityLocationKind,
|
kind: ActivityLocationKind,
|
||||||
/// The id of the Channel
|
/// The id of the Channel
|
||||||
@ -136,7 +142,8 @@ pub const ActivityEmoji = struct {
|
|||||||
/// Whether this emoji is animated
|
/// Whether this emoji is animated
|
||||||
animated: ?bool,
|
animated: ?bool,
|
||||||
/// The id of the emoji
|
/// The id of the emoji
|
||||||
id: ?Snowflake,
|
/// a string
|
||||||
|
id: ?[]const u8,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// https://discord.com/developers/docs/topics/gateway#activity-object-activity-party
|
/// https://discord.com/developers/docs/topics/gateway#activity-object-activity-party
|
||||||
|
@ -4,6 +4,7 @@ const Member = @import("member.zig").Member;
|
|||||||
const Attachment = @import("attachment.zig").Attachment;
|
const Attachment = @import("attachment.zig").Attachment;
|
||||||
const Application = @import("application.zig").Application;
|
const Application = @import("application.zig").Application;
|
||||||
const Embed = @import("embed.zig").Embed;
|
const Embed = @import("embed.zig").Embed;
|
||||||
|
const AllowedMentionTypes = @import("shared.zig").AllowedMentionsTypes;
|
||||||
const PremiumTypes = @import("shared.zig").PremiumTypes;
|
const PremiumTypes = @import("shared.zig").PremiumTypes;
|
||||||
const InteractionTypes = @import("shared.zig").InteractionTypes;
|
const InteractionTypes = @import("shared.zig").InteractionTypes;
|
||||||
const StickerTypes = @import("shared.zig").StickerTypes;
|
const StickerTypes = @import("shared.zig").StickerTypes;
|
||||||
@ -342,3 +343,14 @@ pub const StickerPack = struct {
|
|||||||
/// id of the sticker pack's [banner image](https://discord.com/developers/docs/reference#image-formatting)
|
/// id of the sticker pack's [banner image](https://discord.com/developers/docs/reference#image-formatting)
|
||||||
banner_asset_id: ?Snowflake,
|
banner_asset_id: ?Snowflake,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub const AllowedMentions = struct {
|
||||||
|
/// An array of allowed mention types to parse from the content.
|
||||||
|
parse: []AllowedMentionTypes,
|
||||||
|
/// Array of role_ids to mention (Max size of 100)
|
||||||
|
roles: []Snowflake,
|
||||||
|
/// Array of user_ids to mention (Max size of 100)
|
||||||
|
users: []Snowflake,
|
||||||
|
/// For replies, whether to mention the author of the message being replied to (default false)
|
||||||
|
replied_user: ?bool,
|
||||||
|
};
|
||||||
|
@ -19,38 +19,82 @@ pub const PremiumTypes = enum {
|
|||||||
|
|
||||||
/// https://discord.com/developers/docs/resources/user#user-object-user-flags
|
/// https://discord.com/developers/docs/resources/user#user-object-user-flags
|
||||||
pub const UserFlags = packed struct {
|
pub const UserFlags = packed struct {
|
||||||
pub fn toRaw(self: UserFlags) u32 {
|
pub fn toRaw(self: UserFlags) u34 {
|
||||||
return @bitCast(self);
|
return @bitCast(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fromRaw(raw: u32) UserFlags {
|
pub fn fromRaw(raw: u34) UserFlags {
|
||||||
return @bitCast(raw);
|
return @bitCast(raw);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn toJson(_: std.mem.Allocator, value: zjson.JsonType) !@This() {
|
pub fn toJson(_: std.mem.Allocator, value: zjson.JsonType) !@This() {
|
||||||
return @bitCast(value.number.cast(u32));
|
return @bitCast(value.number.cast(u34));
|
||||||
}
|
}
|
||||||
|
|
||||||
DiscordEmployee: bool = false,
|
DiscordEmployee: bool = false,
|
||||||
PartneredServerOwner: bool = false,
|
PartneredServerOwner: bool = false,
|
||||||
HypeSquadEventsMember: bool = false,
|
HypeSquadEventsMember: bool = false,
|
||||||
BugHunterLevel1: bool = false,
|
BugHunterLevel1: bool = false,
|
||||||
_pad: u3 = 0,
|
MfaSms: bool = false,
|
||||||
|
PremiumPromoDismissed: bool = false,
|
||||||
HouseBravery: bool = false,
|
HouseBravery: bool = false,
|
||||||
HouseBrilliance: bool = false,
|
HouseBrilliance: bool = false,
|
||||||
HouseBalance: bool = false,
|
HouseBalance: bool = false,
|
||||||
EarlySupporter: bool = false,
|
EarlySupporter: bool = false,
|
||||||
TeamUser: bool = false,
|
TeamUser: bool = false,
|
||||||
_pad2: u4 = 0,
|
PartnerOrVerificationApplication: bool = false,
|
||||||
|
System: bool = false,
|
||||||
|
HasUnreadUrgentMessages: bool = false,
|
||||||
BugHunterLevel2: bool = false,
|
BugHunterLevel2: bool = false,
|
||||||
_pad3: u1 = 0,
|
UnderageDeleted: bool = false,
|
||||||
VerifiedBot: bool = false,
|
VerifiedBot: bool = false,
|
||||||
EarlyVerifiedBotDeveloper: bool = false,
|
EarlyVerifiedBotDeveloper: bool = false,
|
||||||
DiscordCertifiedModerator: bool = false,
|
DiscordCertifiedModerator: bool = false,
|
||||||
BotHttpInteractions: bool = false,
|
BotHttpInteractions: bool = false,
|
||||||
_pad4: u3 = 0,
|
Spammer: bool = false,
|
||||||
|
DisablePremium: bool = false,
|
||||||
ActiveDeveloper: bool = false,
|
ActiveDeveloper: bool = false,
|
||||||
_pad5: u6 = 0,
|
_pad: u10 = 0,
|
||||||
|
Quarantined: bool = false,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const PremiumUsageFlags = packed struct {
|
||||||
|
pub fn toRaw(self: PremiumUsageFlags) u8 {
|
||||||
|
return @bitCast(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn fromRaw(raw: u8) PremiumUsageFlags {
|
||||||
|
return @bitCast(raw);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn toJson(_: std.mem.Allocator, value: zjson.JsonType) !@This() {
|
||||||
|
return @bitCast(value.number.cast(u8));
|
||||||
|
}
|
||||||
|
|
||||||
|
PremiumDiscriminator: bool = false,
|
||||||
|
AnimatedAvatar: bool = false,
|
||||||
|
ProfileBanner: bool = false,
|
||||||
|
_pad: u5 = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const PurchasedFlags = packed struct {
|
||||||
|
pub fn toRaw(self: PurchasedFlags) u8 {
|
||||||
|
return @bitCast(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn fromRaw(raw: u8) PurchasedFlags {
|
||||||
|
return @bitCast(raw);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn toJson(_: std.mem.Allocator, value: zjson.JsonType) !@This() {
|
||||||
|
return @bitCast(value.number.cast(u8));
|
||||||
|
}
|
||||||
|
|
||||||
|
NitroClassic: bool = false,
|
||||||
|
Nitro: bool = false,
|
||||||
|
GuildBoost: bool = false,
|
||||||
|
NitroBasic: bool = false,
|
||||||
|
_pad: u4 = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const MemberFlags = packed struct {
|
pub const MemberFlags = packed struct {
|
||||||
|
@ -8,6 +8,10 @@ pub const Snowflake = enum(u64) {
|
|||||||
return @intFromEnum(self);
|
return @intFromEnum(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn from(int: u64) Snowflake {
|
||||||
|
return @enumFromInt(int);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn fromMaybe(raw: ?[]const u8) std.fmt.ParseIntError!?Snowflake {
|
pub fn fromMaybe(raw: ?[]const u8) std.fmt.ParseIntError!?Snowflake {
|
||||||
if (raw) |id| return @enumFromInt(try std.fmt.parseInt(u64, id, 10));
|
if (raw) |id| return @enumFromInt(try std.fmt.parseInt(u64, id, 10));
|
||||||
return null;
|
return null;
|
||||||
@ -28,7 +32,12 @@ pub const Snowflake = enum(u64) {
|
|||||||
|
|
||||||
pub fn toJson(_: std.mem.Allocator, value: zjson.JsonType) !@This() {
|
pub fn toJson(_: std.mem.Allocator, value: zjson.JsonType) !@This() {
|
||||||
if (value.is(.string))
|
if (value.is(.string))
|
||||||
return Snowflake.fromRaw(value.string) catch unreachable;
|
return Snowflake.fromRaw(value.string) catch std.debug.panic("invalid snowflake: {s}\n", .{value.string});
|
||||||
unreachable;
|
unreachable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn format(self: Snowflake) ![]const u8 {
|
||||||
|
var buf: [256]u8 = undefined;
|
||||||
|
return std.fmt.bufPrint(&buf, "{d}\n", .{self.into()});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,12 @@
|
|||||||
const Snowflake = @import("snowflake.zig").Snowflake;
|
const Snowflake = @import("snowflake.zig").Snowflake;
|
||||||
const Channel = @import("channel.zig").Channel;
|
const Channel = @import("channel.zig").Channel;
|
||||||
|
const ChannelTypes = @import("shared.zig").ChannelTypes;
|
||||||
|
const MessageFlags = @import("shared.zig").MessageFlags;
|
||||||
|
const Embed = @import("embed.zig").Embed;
|
||||||
|
const Partial = @import("partial.zig").Partial;
|
||||||
|
const Attachment = @import("attachment.zig").Attachment;
|
||||||
|
const AllowedMentions = @import("message.zig").AllowedMentions;
|
||||||
|
const MessageComponent = @import("message.zig").MessageComponent;
|
||||||
|
|
||||||
pub const ThreadMetadata = struct {
|
pub const ThreadMetadata = struct {
|
||||||
/// Whether the thread is archived
|
/// Whether the thread is archived
|
||||||
@ -53,3 +60,59 @@ pub const ThreadListSync = struct {
|
|||||||
/// All thread member objects from the synced threads for the current user, indicating which threads the current user has been added to
|
/// All thread member objects from the synced threads for the current user, indicating which threads the current user has been added to
|
||||||
members: []ThreadMember,
|
members: []ThreadMember,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// https://discord.com/developers/docs/resources/channel#start-thread-from-message
|
||||||
|
pub const StartThreadFromMessage = struct {
|
||||||
|
/// 1-100 character thread name
|
||||||
|
name: []const u8,
|
||||||
|
/// Duration in minutes to automatically archive the thread after recent activity
|
||||||
|
auto_archive_duration: ?isize,
|
||||||
|
/// Amount of seconds a user has to wait before sending another message (0-21600)
|
||||||
|
rate_limit_per_user: ?isize,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// https://discord.com/developers/docs/resources/channel#start-thread-without-message
|
||||||
|
pub const StartThreadWithoutMessage = struct {
|
||||||
|
/// 1-100 character thread name,
|
||||||
|
name: []const u8,
|
||||||
|
/// Duration in minutes to automatically archive the thread after recent activity,
|
||||||
|
auto_archive_duration: isize,
|
||||||
|
/// Amount of seconds a user has to wait before sending another message (0-21600),
|
||||||
|
rateLimitPerUser: ?isize,
|
||||||
|
/// the type of thread to create,
|
||||||
|
/// may only be AnnouncementThread, PublicThread, or PrivateThread
|
||||||
|
type: ChannelTypes,
|
||||||
|
/// whether non-moderators can add other non-moderators to a thread; only available when creating a private thread,
|
||||||
|
invitable: ?bool,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// https://discord.com/developers/docs/resources/channel#start-thread-in-forum-or-media-channel-forum-and-media-thread-message-params-object
|
||||||
|
pub const CreateForumAndMediaThreadMessage = struct {
|
||||||
|
/// Message contents (up to 2000 characters)
|
||||||
|
content: ?[]const u8,
|
||||||
|
/// Up to 10 rich embeds (up to 6000 characters)
|
||||||
|
embeds: ?[]Embed,
|
||||||
|
/// Allowed mentions for the message
|
||||||
|
allowed_mentions: ?AllowedMentions,
|
||||||
|
/// Components to include with the message
|
||||||
|
components: ?[]MessageComponent,
|
||||||
|
/// IDs of up to 3 stickers in the server to send in the message
|
||||||
|
sticker_ids: ?[]Snowflake,
|
||||||
|
/// Attachment objects with filename and description. See Uploading Files
|
||||||
|
attachments: ?[]Partial(Attachment),
|
||||||
|
/// Message flags combined as a bitfield (only SUPPRESS_EMBEDS and SUPPRESS_NOTIFICATIONS can be set)
|
||||||
|
flags: ?MessageFlags,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const StartThreadInForumOrMediaChannel = struct {
|
||||||
|
/// 1-100 character channel name
|
||||||
|
name: []const u8,
|
||||||
|
/// Duration in minutes to automatically archive the thread after recent activity, can be set to: 60, 1440, 4320, 10080
|
||||||
|
auto_archive_duration: ?isize,
|
||||||
|
/// Amount of seconds a user has to wait before sending another message (0-21600)
|
||||||
|
rate_limit_per_user: ?isize,
|
||||||
|
/// Contents of the first message in the forum/media thread
|
||||||
|
message: CreateForumAndMediaThreadMessage,
|
||||||
|
/// The IDs of the set of tags that have been applied to a thread in a GUILD_FORUM or a GUILD_MEDIA channel
|
||||||
|
applied_tags: ?[]Snowflake,
|
||||||
|
};
|
||||||
|
@ -142,3 +142,12 @@ pub const ApplicationRoleConnection = struct {
|
|||||||
/// object mapping application role connection metadata keys to their stringified value (max 100 characters) for the user on the platform a bot has connected
|
/// object mapping application role connection metadata keys to their stringified value (max 100 characters) for the user on the platform a bot has connected
|
||||||
metadata: []Record([]const u8),
|
metadata: []Record([]const u8),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub const ModifyCurrentUser = struct {
|
||||||
|
/// user's username, if changed may cause the user's discriminator to be randomized.
|
||||||
|
username: ?[]const u8,
|
||||||
|
/// if passed, modifies the user's avatar
|
||||||
|
avatar: ?[]const u8,
|
||||||
|
/// if passed, modifies the user's banner
|
||||||
|
banner: ?[]const u8,
|
||||||
|
};
|
||||||
|
@ -17,15 +17,15 @@ fn message_create(session: *Shard, message: Discord.Message) !void {
|
|||||||
std.debug.print("captured: {?s} send by {s}\n", .{ message.content, message.author.username });
|
std.debug.print("captured: {?s} send by {s}\n", .{ message.content, message.author.username });
|
||||||
|
|
||||||
if (message.content) |mc| if (std.ascii.eqlIgnoreCase(mc, "!hi")) {
|
if (message.content) |mc| if (std.ascii.eqlIgnoreCase(mc, "!hi")) {
|
||||||
const payload: Discord.Partial(Discord.CreateMessage) = .{
|
const msg = try session.sendMessage(message.channel_id, .{
|
||||||
.content = "discord.zig best library",
|
.content = "discord.zig best library",
|
||||||
};
|
});
|
||||||
_ = try session.sendMessage(message.channel_id, payload);
|
defer msg.deinit();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn main() !void {
|
pub fn main() !void {
|
||||||
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
var gpa = std.heap.GeneralPurposeAllocator(.{ .stack_trace_frames = 9999 }){};
|
||||||
var handler = Discord.init(gpa.allocator());
|
var handler = Discord.init(gpa.allocator());
|
||||||
try handler.start(.{
|
try handler.start(.{
|
||||||
.token = std.posix.getenv("DISCORD_TOKEN").?,
|
.token = std.posix.getenv("DISCORD_TOKEN").?,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user