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;
|
||||
|
||||
pub const FetchReq = @import("http.zig").FetchReq;
|
||||
pub const FileData = @import("http.zig").FileData;
|
||||
|
||||
const std = @import("std");
|
||||
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());
|
||||
}
|
||||
|
||||
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;
|
||||
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);
|
||||
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 OverwriteTypes = @import("shared.zig").OverwriteTypes;
|
||||
const ChannelFlags = @import("shared.zig").ChannelFlags;
|
||||
const TargetTypes = @import("shared.zig").TargetTypes;
|
||||
const VideoQualityModes = @import("shared.zig").VideoQualityModes;
|
||||
const SortOrderTypes = @import("shared.zig").SortOrderTypes;
|
||||
const User = @import("user.zig").User;
|
||||
@ -198,3 +199,20 @@ pub const ModifyGuildChannelPositions = struct {
|
||||
/// The new parent ID for the channel that is moved
|
||||
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 {
|
||||
attachments: []Partial(Attachment),
|
||||
/// The message contents (up to 2000 characters)
|
||||
content: ?[]const u8,
|
||||
/// 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 Snowflake = @import("snowflake.zig").Snowflake;
|
||||
const ActivityTypes = @import("shared.zig").ActivityTypes;
|
||||
const Partial = @import("partial.zig").Partial;
|
||||
|
||||
/// https://discord.com/developers/docs/topics/gateway#get-gateway-bot
|
||||
pub const GetGatewayBot = struct {
|
||||
@ -34,7 +35,7 @@ pub const PresenceUpdate = struct {
|
||||
offline,
|
||||
},
|
||||
/// The user presence is being updated for
|
||||
user: User,
|
||||
user: Partial(User),
|
||||
/// id of the guild
|
||||
guild_id: Snowflake,
|
||||
/// User's current activities
|
||||
@ -64,7 +65,8 @@ pub const Activity = struct {
|
||||
/// Unix timestamps for start and/or end of the game
|
||||
timestamps: ?ActivityTimestamps,
|
||||
/// Application id for the game
|
||||
application_id: ?Snowflake,
|
||||
/// a string
|
||||
application_id: ?[]const u8,
|
||||
/// The emoji used for a custom status
|
||||
emoji: ?ActivityEmoji,
|
||||
/// 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
|
||||
pub const ActivityInstance = struct {
|
||||
/// Application ID
|
||||
application_id: Snowflake,
|
||||
/// a string
|
||||
application_id: []const u8,
|
||||
/// Activity Instance ID
|
||||
instance_id: Snowflake,
|
||||
/// a string
|
||||
instance_id: []const u8,
|
||||
/// Unique identifier for the launch
|
||||
launch_id: Snowflake,
|
||||
/// a string
|
||||
launch_id: []const u8,
|
||||
/// The Location the instance is runnning in
|
||||
location: ActivityLocation,
|
||||
/// 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
|
||||
pub const ActivityLocation = struct {
|
||||
/// The unique identifier for the location
|
||||
id: Snowflake,
|
||||
/// a string
|
||||
id: []const u8,
|
||||
/// Enum describing kind of location
|
||||
kind: ActivityLocationKind,
|
||||
/// The id of the Channel
|
||||
@ -136,7 +142,8 @@ pub const ActivityEmoji = struct {
|
||||
/// Whether this emoji is animated
|
||||
animated: ?bool,
|
||||
/// The id of the emoji
|
||||
id: ?Snowflake,
|
||||
/// a string
|
||||
id: ?[]const u8,
|
||||
};
|
||||
|
||||
/// 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 Application = @import("application.zig").Application;
|
||||
const Embed = @import("embed.zig").Embed;
|
||||
const AllowedMentionTypes = @import("shared.zig").AllowedMentionsTypes;
|
||||
const PremiumTypes = @import("shared.zig").PremiumTypes;
|
||||
const InteractionTypes = @import("shared.zig").InteractionTypes;
|
||||
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)
|
||||
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
|
||||
pub const UserFlags = packed struct {
|
||||
pub fn toRaw(self: UserFlags) u32 {
|
||||
pub fn toRaw(self: UserFlags) u34 {
|
||||
return @bitCast(self);
|
||||
}
|
||||
|
||||
pub fn fromRaw(raw: u32) UserFlags {
|
||||
pub fn fromRaw(raw: u34) UserFlags {
|
||||
return @bitCast(raw);
|
||||
}
|
||||
|
||||
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,
|
||||
PartneredServerOwner: bool = false,
|
||||
HypeSquadEventsMember: bool = false,
|
||||
BugHunterLevel1: bool = false,
|
||||
_pad: u3 = 0,
|
||||
MfaSms: bool = false,
|
||||
PremiumPromoDismissed: bool = false,
|
||||
HouseBravery: bool = false,
|
||||
HouseBrilliance: bool = false,
|
||||
HouseBalance: bool = false,
|
||||
EarlySupporter: bool = false,
|
||||
TeamUser: bool = false,
|
||||
_pad2: u4 = 0,
|
||||
PartnerOrVerificationApplication: bool = false,
|
||||
System: bool = false,
|
||||
HasUnreadUrgentMessages: bool = false,
|
||||
BugHunterLevel2: bool = false,
|
||||
_pad3: u1 = 0,
|
||||
UnderageDeleted: bool = false,
|
||||
VerifiedBot: bool = false,
|
||||
EarlyVerifiedBotDeveloper: bool = false,
|
||||
DiscordCertifiedModerator: bool = false,
|
||||
BotHttpInteractions: bool = false,
|
||||
_pad4: u3 = 0,
|
||||
Spammer: bool = false,
|
||||
DisablePremium: 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 {
|
||||
|
@ -8,6 +8,10 @@ pub const Snowflake = enum(u64) {
|
||||
return @intFromEnum(self);
|
||||
}
|
||||
|
||||
pub fn from(int: u64) Snowflake {
|
||||
return @enumFromInt(int);
|
||||
}
|
||||
|
||||
pub fn fromMaybe(raw: ?[]const u8) std.fmt.ParseIntError!?Snowflake {
|
||||
if (raw) |id| return @enumFromInt(try std.fmt.parseInt(u64, id, 10));
|
||||
return null;
|
||||
@ -28,7 +32,12 @@ pub const Snowflake = enum(u64) {
|
||||
|
||||
pub fn toJson(_: std.mem.Allocator, value: zjson.JsonType) !@This() {
|
||||
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;
|
||||
}
|
||||
|
||||
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 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 {
|
||||
/// 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
|
||||
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
|
||||
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 });
|
||||
|
||||
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",
|
||||
};
|
||||
_ = try session.sendMessage(message.channel_id, payload);
|
||||
});
|
||||
defer msg.deinit();
|
||||
};
|
||||
}
|
||||
|
||||
pub fn main() !void {
|
||||
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||
var gpa = std.heap.GeneralPurposeAllocator(.{ .stack_trace_frames = 9999 }){};
|
||||
var handler = Discord.init(gpa.allocator());
|
||||
try handler.start(.{
|
||||
.token = std.posix.getenv("DISCORD_TOKEN").?,
|
||||
|
Loading…
x
Reference in New Issue
Block a user