Skip to content

Commit

Permalink
新增 Docker 示例
Browse files Browse the repository at this point in the history
  • Loading branch information
gehongyan committed Oct 27, 2023
1 parent f8f74a7 commit a5a2c6a
Show file tree
Hide file tree
Showing 5 changed files with 231 additions and 1 deletion.
25 changes: 25 additions & 0 deletions src/Kook.Net.Samples.Docker/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
**/.dockerignore
**/.env
**/.git
**/.gitignore
**/.project
**/.settings
**/.toolstarget
**/.vs
**/.vscode
**/.idea
**/*.*proj.user
**/*.dbmdl
**/*.jfm
**/azds.yaml
**/bin
**/charts
**/docker-compose*
**/Dockerfile*
**/node_modules
**/npm-debug.log
**/obj
**/secrets.dev.yaml
**/values.dev.yaml
LICENSE
README.md
18 changes: 18 additions & 0 deletions src/Kook.Net.Samples.Docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
FROM mcr.microsoft.com/dotnet/runtime:7.0 AS base
WORKDIR /app

FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build
WORKDIR /src
COPY ["Kook.Net.Samples.Docker/Kook.Net.Samples.Docker.csproj", "Kook.Net.Samples.Docker/"]
RUN dotnet restore "Kook.Net.Samples.Docker/Kook.Net.Samples.Docker.csproj"
COPY . .
WORKDIR "/src/Kook.Net.Samples.Docker"
RUN dotnet build "Kook.Net.Samples.Docker.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "Kook.Net.Samples.Docker.csproj" -c Release -o /app/publish /p:UseAppHost=false

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "Kook.Net.Samples.Docker.dll"]
15 changes: 15 additions & 0 deletions src/Kook.Net.Samples.Docker/Kook.Net.Samples.Docker.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Kook.Net" Version="0.5.2" />
</ItemGroup>

</Project>
165 changes: 165 additions & 0 deletions src/Kook.Net.Samples.Docker/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
// See https://aka.ms/new-console-template for more information

// KookSocketConfig 是 KookSocketClient 的配置类

using Kook;
using Kook.WebSocket;

KookSocketConfig config = new()
{
AlwaysDownloadUsers = false,
AlwaysDownloadVoiceStates = false,
AlwaysDownloadBoostSubscriptions = false,
MessageCacheSize = 100,
LogLevel = LogSeverity.Debug
};

// 在使用完 Kook.Net 的客户端后,建议在应用程序的生命周期结束时进行 Dispose 操作
KookSocketClient client = new(config);

// 此处列举了 Kook.Net 的 KookSocketClient 的所有事件

#region BaseKookClient

client.Log += LogAsync;
client.LoggedIn += () => Task.CompletedTask;
client.LoggedOut += () => Task.CompletedTask;

#endregion

#region KookSocketClient

client.Connected += () => Task.CompletedTask;
client.Disconnected += exception => Task.CompletedTask;
client.Ready += ReadyAsync;
client.LatencyUpdated += (before, after) => Task.CompletedTask;

#endregion

#region BaseSocketClient

client.ChannelCreated += channel => Task.CompletedTask;
client.ChannelDestroyed += channel => Task.CompletedTask;
client.ChannelUpdated += (before, after) => Task.CompletedTask;

client.ReactionAdded += (message, channel, user, reaction) => Task.CompletedTask;
client.ReactionRemoved += (message, channel, user, reaction) => Task.CompletedTask;
client.DirectReactionAdded += (message, channel, user, reaction) => Task.CompletedTask;
client.DirectReactionRemoved += (message, channel, user, reaction) => Task.CompletedTask;

client.MessageReceived += MessageReceivedAsync;
client.MessageDeleted += (message, channel) => Task.CompletedTask;
client.MessageUpdated += (before, after, channel) => Task.CompletedTask;
client.MessagePinned += (before, after, channel, @operator) => Task.CompletedTask;
client.MessageUnpinned += (before, after, channel, @operator) => Task.CompletedTask;

client.DirectMessageReceived += (message, author, channel) => Task.CompletedTask;
client.DirectMessageDeleted += (message, author, channel) => Task.CompletedTask;
client.DirectMessageUpdated += (before, after, author, channel) => Task.CompletedTask;

client.UserJoined += (user, time) => Task.CompletedTask;
client.UserLeft += (guild, user, time) => Task.CompletedTask;
client.UserBanned += (users, @operator, guild, reason) => Task.CompletedTask;
client.UserUnbanned += (users, @operator, guild) => Task.CompletedTask;
client.UserUpdated += (before, after) => Task.CompletedTask;
client.CurrentUserUpdated += (before, after) => Task.CompletedTask;
client.GuildMemberUpdated += (before, after) => Task.CompletedTask;
client.GuildMemberOnline += (users, time) => Task.CompletedTask;
client.GuildMemberOffline += (users, time) => Task.CompletedTask;

client.UserConnected += (user, channel, time) => Task.CompletedTask;
client.UserDisconnected += (user, channel, time) => Task.CompletedTask;

client.RoleCreated += role => Task.CompletedTask;
client.RoleDeleted += role => Task.CompletedTask;
client.RoleUpdated += (before, after) => Task.CompletedTask;

client.EmoteCreated += (emote, guild) => Task.CompletedTask;
client.EmoteDeleted += (emote, guild) => Task.CompletedTask;
client.EmoteUpdated += (before, after, guild) => Task.CompletedTask;

client.JoinedGuild += guild => Task.CompletedTask;
client.LeftGuild += guild => Task.CompletedTask;
client.GuildUpdated += (before, after) => Task.CompletedTask;
client.GuildAvailable += guild => Task.CompletedTask;
client.GuildUnavailable += guild => Task.CompletedTask;

client.MessageButtonClicked += MessageButtonClickedAsync;
client.DirectMessageButtonClicked += (value, user, message, channel) => Task.CompletedTask;

#endregion

// Log 事件,此处以直接输出到控制台为例
Task LogAsync(LogMessage log)
{
Console.WriteLine(log.ToString());
return Task.CompletedTask;
}

// Ready 事件表示客户端已经建立了连接,现在可以安全地访问缓存
Task ReadyAsync()
{
Console.WriteLine($"{client.CurrentUser} 已连接!");
return Task.CompletedTask;
}

// 并不建议以这样的方式实现 Bot 的命令交互功能
// 请参阅 Kook.Net.Samples.TextCommands 示例项目及其文档
async Task MessageReceivedAsync(SocketMessage message,
SocketGuildUser author,
SocketTextChannel channel)
{
// Bot 永远不应该响应自己的消息
if (author.Id == client.CurrentUser.Id)
return;


if (message.Content == "!ping")
{
// 创建一个 CardBuilder,卡片将会包含一个文本模块和一个按钮模块
CardBuilder builder = new CardBuilder()
.AddModule<SectionModuleBuilder>(s =>
s.WithText("pong!"))
.AddModule<ActionGroupModuleBuilder>(a => a
.AddElement(b => b
.WithClick(ButtonClickEventType.ReturnValue)
.WithText("点我!")
.WithValue("unique-id")
.WithTheme(ButtonTheme.Primary)));

// 发送一条卡片形式的消息,内容包含文本 pong!,以及一个按钮
// 在调用时,需要先调用 .Build() 方法来构建卡片
await channel.SendCardAsync(builder.Build());
}
}

// 当按钮被点击时,会触发 MessageButtonClicked 事件
async Task MessageButtonClickedAsync(string value,
Cacheable<SocketGuildUser, ulong> user,
Cacheable<IMessage, Guid> message,
SocketTextChannel channel)
{
// 检查按钮的值是否为之前的代码中设置的值
if (value == "unique-id")
{
IMessage messageEntity = await message.GetOrDownloadAsync();
if (messageEntity is IUserMessage userMessage)
await userMessage.ReplyTextAsync("按钮被点击了!", isQuote: true);
}

else
Console.WriteLine("接收到了一个没有对应处理程序的按钮值!");
}

// 令牌(Tokens)应被视为机密数据,永远不应硬编码在代码中
// 在实际开发中,为了保护令牌的安全性,建议将令牌存储在安全的环境中
// 例如本地 .json、.yaml、.xml、.txt 文件、环境变量或密钥管理系统
// 这样可以避免将敏感信息直接暴露在代码中,以防止令牌被滥用或泄露
string token = Environment.GetEnvironmentVariable("KookDebugToken")
?? throw new ArgumentNullException("KookDebugToken");

await client.LoginAsync(TokenType.Bot, token);
await client.StartAsync();

// 阻塞程序直到关闭
await Task.Delay(Timeout.Infinite);
9 changes: 8 additions & 1 deletion src/Kook.Net.sln
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Experimental", "Experimenta
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kook.Net.Experimental", "Kook.Net.Experimental\Kook.Net.Experimental.csproj", "{95881FD6-BAF5-43A6-9D75-9F9181FC9D21}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SolutionItems", "SolutionItems", "{55F21D65-BA1A-4A4B-B370-FD2CA0204EB2}"
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "SolutionItems", "{55F21D65-BA1A-4A4B-B370-FD2CA0204EB2}"
ProjectSection(SolutionItems) = preProject
Kook.Net.targets = Kook.Net.targets
EndProjectSection
Expand All @@ -41,6 +41,8 @@ Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Kook.Net.Samples.VisualBasi
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Kook.Net.Samples.FSharp", "..\samples\Kook.Net.Samples.FSharp\Kook.Net.Samples.FSharp.fsproj", "{DCD692BE-9D91-4DE1-8603-CD8923C59B6A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kook.Net.Samples.Docker", "Kook.Net.Samples.Docker\Kook.Net.Samples.Docker.csproj", "{B8A50094-A959-4807-AB36-6256A1EEEE61}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -99,6 +101,10 @@ Global
{DCD692BE-9D91-4DE1-8603-CD8923C59B6A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DCD692BE-9D91-4DE1-8603-CD8923C59B6A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DCD692BE-9D91-4DE1-8603-CD8923C59B6A}.Release|Any CPU.Build.0 = Release|Any CPU
{B8A50094-A959-4807-AB36-6256A1EEEE61}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B8A50094-A959-4807-AB36-6256A1EEEE61}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B8A50094-A959-4807-AB36-6256A1EEEE61}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B8A50094-A959-4807-AB36-6256A1EEEE61}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{57F76D67-0E55-4609-A61C-3A4C3073CA0E} = {58B166AB-82DD-472F-AC70-9318DA4F881E}
Expand All @@ -112,5 +118,6 @@ Global
{95881FD6-BAF5-43A6-9D75-9F9181FC9D21} = {BB39595B-5DCE-4B1C-8740-A013C261E317}
{43C91115-7D09-4A28-95CD-380C3B00EAE0} = {8DE556F9-829D-48D3-A41C-FA57207CAE72}
{DCD692BE-9D91-4DE1-8603-CD8923C59B6A} = {8DE556F9-829D-48D3-A41C-FA57207CAE72}
{B8A50094-A959-4807-AB36-6256A1EEEE61} = {8DE556F9-829D-48D3-A41C-FA57207CAE72}
EndGlobalSection
EndGlobal

0 comments on commit a5a2c6a

Please sign in to comment.