Robin.cs is a bot framework written in C# that supports extending its functionalities through extensions. It also provides various useless extensions that demonstrate different bot capabilities.
- Automatic Extension/Implementation Discovery: Robin automatically discovers and loads extensions/implementations from
Extensions/
andImplementations/
using reflection. - Multiple Protocol Support: Theoretically, Robin can support multiple protocols by implementing the
IBackendFactory
interface. Currently, only OneBot v11 is implemented. - Fluent Middleware: A middleware system that allows you to easily create bot functions using a fluent API.
- Approve: Auto approve group invitations & friend requests.
- AtPoke: Poke someone by @ them.
- B23: Resolve original link for b23 card.
- Dice: Roll a dice using
/dice
- Gemini: Gemini chat bot in private chat.
- Gray: It's Ikuyover
- Help: List all extensions & descriptions.
- Oa: JLU OA announcement.
- Oled: Display messages on my SSD1306 OLED screen using OrangePi 5 Plus, you may need to modify the code to adapt to your own hardware.
- PokeBack: Poke back the one who poked you.
- RandReply: Random reply to the one who @ you.
- ReplyAction: Reply to a message with
/{verb} {adverb}
results in{your name} {verb} {sender name} {adverb}
. - Saucenao: Search image source using saucenao.
- Status: Get the status of the bot.
- Test: Test extension.
- UserRank: Get the rank of user in the group, based on the number of messages sent.
- Welcome: Welcome new members.
- WhoAtMe: Who @ me.
- Wife: Randomly choose a daily wife
(really random). - WordCloud: Generate word cloud image from group messages, see WordCloud, WordCloud.Server and hanlp.server for more details.
- Docker
Currently it is recommended to build and deploy robin using docker, see Dockerfile
.
-
Clone the repository:
git clone https://github.com/CrackTC/Robin.cs.git cd Robin.cs
-
Optional: opt out of some extensions by removing them from the
Extensions/
directory. -
Run the bot using Docker:
docker build -t robin . docker run \ -v /path/to/data:/app/data \ -it robin
Configuration file is located at ${cwd}/config.json
.
Here is an example configuration file:
{
"Bots": [
{
"Uin": 123456789,
"EventInvokerName": "OneBotForwardWebSocket",
"OperationProviderName": "OneBotHttpClient",
"EventInvokerConfig": {
"Url": "ws://<host>:<port>",
"ReconnectInterval": 5
},
"OperationProviderConfig": {
"Url": "http://<host>:<port>"
},
"Filters": {
"oa": {
"Group": {
"Whitelist": true,
"Ids": [
123456789,
987654321
]
}
},
"gemini": {
"Private": {
"Whitelist": false,
"Ids": [
1145141919810
]
}
}
},
"Configurations": [
"fluent": {
"Crons": {
"user_rank": {
"rank cron": "0 0 0 * * ?"
},
"word_cloud": {
"word cloud cron": "0 0 0 * * ?"
},
"oa": {
"main cron": "0 0 * * * ?"
}
}
},
"gemini": {
"Model": "gemini-1.5-flash-latest",
"ApiKey": "<your-api-key>"
},
"gray": {
"ApiAddress": "http://<host>:<port>"
},
"rand_reply": {
"Texts": [
"我喜欢你❤️",
"我讨厌你😡"
],
"ImagePaths": []
},
"user_rank": {
"TopN": 10
},
"word_cloud": {
"ApiAddress": "http://<host>:<port>/wordcloud",
"CloudOption": {
"Colors": [
"ffbf616a",
"ffd08770",
"ffebcb8b",
"ffa3be8c",
"ff88c0d0"
],
"Padding": 5,
"BackgroundImageUrl": "<image-url>",
"StrokeRatio": 0.01,
"StrokeColors": [
"ff2e3440"
]
}
},
"sauce_nao": {
"ApiKey": "<your-api-key>"
},
"welcome": {
"WelcomeTexts": {
"123456789": "Welcome {at}",
"987654321": "{at} 我讨厌你😡"
}
},
"oa": {
"TempGroup": 123456789
"UseVpn": false
}
]
}
]
}
-
Navigate to the
Extensions
directory:cd Extensions
-
Create a new directory for your extension:
mkdir Robin.Extensions.MyExtension cd Robin.Extensions.MyExtension
-
Create a new class library project:
dotnet new classlib -n Robin.Extensions.MyExtension
-
Add references to required projects:
<!-- Robin.Extensions.MyExtension.csproj --> <Project Sdk="Microsoft.NET.Sdk"> <ItemGroup> <ProjectReference Include="..\..\Middlewares\Robin.Middlewares.Fluent\Robin.Middlewares.Fluent.csproj" /> </ItemGroup> <PropertyGroup> <TargetFramework>net9.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> <!-- Enable dynamic loading for proper dependency resolution --> <EnableDynamicLoading>true</EnableDynamicLoading> </PropertyGroup> </Project>
-
Create your extension class:
// MyExtensionFunction.cs using Robin.Abstractions; using Robin.Abstractions.Context; using Robin.Abstractions.Event.Message; using Robin.Middlewares.Fluent; using Robin.Middlewares.Fluent.Event; namespace Robin.Extensions.MyExtension; [BotFunctionInfo("my_extension", "Description of my extension")] public class MyExtensionFunction(FunctionContext<MyExtensionOption> context) : BotFunction<MyExtensionOption>(context), // required IFluentFunction // optional, for Fluent API { public Task OnCreatingAsync(FunctionBuilder builder, CancellationToken token) { builder.On<MessageEvent>() .OnCommand("hello") .Where(e => e.Event.GroupId == 1145141919810L) .Do(async tuple => { var (e, t) = tuple; if (_context.Configuration.Enabled) await e.NewMessageRequest([new TextData(_context.Configuration.Text)]) .SendAsync(_context, t); }); return Task.CompletedTask; } }
-
Create your extension option class:
// MyExtensionOption.cs namespace Robin.Extensions.MyExtension; public class MyExtensionOption { public bool Enabled { get; set; } public string Text { get; set; } }
Simply run docker build -t robin .
in the root directory to build the bot with your extension.
GPL-2.0-only