Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,10 @@ evals/results/
# Agent-specific local skills (installed via `npx skills add`)
.claude/skills/
.cursor/

# C# / .NET
bin/
obj/
*.user
*.suo
sdk/csharp/examples/Examples.csproj
85 changes: 0 additions & 85 deletions sdk/csharp/examples/Main.cs

This file was deleted.

92 changes: 92 additions & 0 deletions sdk/csharp/examples/MainExample.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/**
* Echo bot example demonstrating the Pachca C# SDK.
*
* Runs 8 steps that exercise the core API patterns:
* create, read, nested resource, idempotent POST, thread reply, pin, update, unpin.
*
* Usage:
*
* PACHCA_TOKEN=your_token PACHCA_CHAT_ID=12345 dotnet run -- main
*/

namespace Pachca.Sdk.Examples;

public static class MainExample
{
public static async Task<int> RunAsync()
{
var token = Environment.GetEnvironmentVariable("PACHCA_TOKEN")
?? throw new InvalidOperationException("Set PACHCA_TOKEN environment variable");
var chatId = int.Parse(
Environment.GetEnvironmentVariable("PACHCA_CHAT_ID")
?? throw new InvalidOperationException("Set PACHCA_CHAT_ID environment variable"));

using var client = new PachcaClient(token);

// -- Step 1: POST -- Create a message
Console.WriteLine("1. Creating message...");
var created = await client.Messages.CreateMessageAsync(new MessageCreateRequest
{
Message = new MessageCreateRequestMessage
{
EntityId = chatId,
Content = "SDK test C# \ud83d\ude80",
}
});
var msgId = created.Id;
Console.WriteLine($" Created message ID: {msgId}");

// -- Step 2: GET -- Read the message back
Console.WriteLine("2. Reading message...");
var msg = await client.Messages.GetMessageAsync(msgId);
Console.WriteLine($" Got message: \"{msg.Content}\"");

// -- Step 3: POST -- Add a reaction (nested resource)
Console.WriteLine("3. Adding reaction...");
await client.Reactions.AddReactionAsync(msgId, new ReactionRequest { Code = "\ud83d\udc40" });
Console.WriteLine(" Added reaction \ud83d\udc40");

// -- Step 4: POST -- Create a thread (idempotent)
Console.WriteLine("4. Creating thread...");
var thread = await client.Threads.CreateThreadAsync(msgId);
Console.WriteLine($" Thread ID: {thread.Id}");

// -- Step 5: POST -- Reply inside the thread
Console.WriteLine("5. Replying in thread...");
var reply = await client.Messages.CreateMessageAsync(new MessageCreateRequest
{
Message = new MessageCreateRequestMessage
{
EntityType = MessageEntityType.Thread,
EntityId = (int)thread.Id,
Content = $"Echo: {msg.Content}",
}
});
var replyId = reply.Id;
Console.WriteLine($" Reply ID: {replyId}");

// -- Step 6: POST -- Pin the original message
Console.WriteLine("6. Pinning message...");
await client.Messages.PinMessageAsync(msgId);
Console.WriteLine(" Pinned");

// -- Step 7: PUT -- Edit the reply
Console.WriteLine("7. Updating reply...");
await client.Messages.UpdateMessageAsync(replyId, new MessageUpdateRequest
{
Message = new MessageUpdateRequestMessage
{
Content = $"{reply.Content} (processed at {DateTimeOffset.UtcNow})",
}
});
Console.WriteLine(" Updated");

// -- Step 8: DELETE -- Unpin the original message
Console.WriteLine("8. Unpinning message...");
await client.Messages.UnpinMessageAsync(msgId);
Console.WriteLine(" Unpinned");

Console.WriteLine("\nDone! All 8 steps completed.");
return 0;
}
}
25 changes: 25 additions & 0 deletions sdk/csharp/examples/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using Pachca.Sdk.Examples;

var example = args.Length > 0 ? args[0].ToLowerInvariant() : "main";

return example switch
{
"main" => await MainExample.RunAsync(),
"upload" => await UploadExample.RunAsync(),
_ => PrintUsage()
};

static int PrintUsage()
{
Console.WriteLine("Usage: dotnet run -- <example>");
Console.WriteLine();
Console.WriteLine("Examples:");
Console.WriteLine(" main - Echo bot (create, read, react, thread, pin, update, unpin)");
Console.WriteLine(" upload - File upload (requires PACHCA_FILE_PATH)");
Console.WriteLine();
Console.WriteLine("Environment variables:");
Console.WriteLine(" PACHCA_TOKEN - API token (required)");
Console.WriteLine(" PACHCA_CHAT_ID - Chat ID (required)");
Console.WriteLine(" PACHCA_FILE_PATH - File path (upload only)");
return 1;
}
77 changes: 0 additions & 77 deletions sdk/csharp/examples/Upload.cs

This file was deleted.

84 changes: 84 additions & 0 deletions sdk/csharp/examples/UploadExample.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/**
* File upload example demonstrating the Pachca C# SDK.
*
* Uploads a local file and sends it as a message attachment.
*
* Usage:
*
* PACHCA_TOKEN=your_token PACHCA_CHAT_ID=12345 PACHCA_FILE_PATH=./photo.png dotnet run -- upload
*/

namespace Pachca.Sdk.Examples;

public static class UploadExample
{
public static async Task<int> RunAsync()
{
var token = Environment.GetEnvironmentVariable("PACHCA_TOKEN")
?? throw new InvalidOperationException("Set PACHCA_TOKEN environment variable");
var chatId = int.Parse(
Environment.GetEnvironmentVariable("PACHCA_CHAT_ID")
?? throw new InvalidOperationException("Set PACHCA_CHAT_ID environment variable"));
var filePath = Environment.GetEnvironmentVariable("PACHCA_FILE_PATH")
?? throw new InvalidOperationException("Set PACHCA_FILE_PATH environment variable");

var fileName = System.IO.Path.GetFileName(filePath);

using var client = new PachcaClient(token);

// -- Step 1: Read the local file
Console.WriteLine($"1. Reading file: {filePath}");
var fileBytes = await System.IO.File.ReadAllBytesAsync(filePath);
var fileSize = fileBytes.Length;
Console.WriteLine($" Size: {fileSize} bytes");

// -- Step 2: Get upload params
Console.WriteLine("2. Getting upload params...");
var uploadParams = await client.Common.GetUploadParamsAsync();
var key = uploadParams.Key.Replace("${filename}", fileName);
Console.WriteLine($" Got direct_url: {uploadParams.DirectUrl}");

// -- Step 3: Upload the file via SDK
Console.WriteLine("3. Uploading file...");
await client.Common.UploadFileAsync(
uploadParams.DirectUrl,
new FileUploadRequest
{
ContentDisposition = uploadParams.ContentDisposition,
Acl = uploadParams.Acl,
Policy = uploadParams.Policy,
XAmzCredential = uploadParams.XAmzCredential,
XAmzAlgorithm = uploadParams.XAmzAlgorithm,
XAmzDate = uploadParams.XAmzDate,
XAmzSignature = uploadParams.XAmzSignature,
Key = key,
File = fileBytes,
});
Console.WriteLine($" Uploaded, key: {key}");

// -- Step 4: Send message with the file attached
Console.WriteLine("4. Sending message with attachment...");
var msg = await client.Messages.CreateMessageAsync(new MessageCreateRequest
{
Message = new MessageCreateRequestMessage
{
EntityId = chatId,
Content = $"File upload test: {fileName} \ud83d\ude80",
Files = new List<MessageCreateRequestFile>
{
new()
{
Key = key,
Name = fileName,
FileType = FileType.File,
Size = fileSize,
}
},
}
});
Console.WriteLine($" Message ID: {msg.Id}");

Console.WriteLine("\nDone! File uploaded and sent.");
return 0;
}
}
Loading