use anthropic_sdk::{Anthropic, ClientConfig, MessageCreateBuilder};
use anthropic_sdk::types::ContentBlock;
use reqwest::header::{HeaderMap, HeaderValue};
use std::time::Duration;
fn extract_text_from_content(content: &[ContentBlock]) -> String {
content.iter()
.filter_map(|block| match block {
ContentBlock::Text { text } => Some(text.as_str()),
_ => None,
})
.collect::<Vec<_>>()
.join(" ")
}
struct EbayAnthropicClient {
client: reqwest::Client,
base_url: String,
api_key: String,
}
impl EbayAnthropicClient {
fn new(api_key: String, base_url: String) -> Self {
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()
.unwrap();
Self {
client,
base_url,
api_key,
}
}
async fn test_auth_formats(&self) -> Result<(), Box<dyn std::error::Error>> {
let url = format!("{}/messages", self.base_url.trim_end_matches('/'));
let payload = serde_json::json!({
"model": "hubgpt-chat-completions-sonnet-3-7",
"max_tokens": 100,
"messages": [{"role": "user", "content": "Hello! This is an auth test."}]
});
println!("🔑 Testing Bearer token authentication...");
match self.test_bearer_auth(&url, &payload).await {
Ok(response) => {
println!("✅ Bearer token works!");
println!("📝 Response: {}", response);
return Ok(());
}
Err(e) => println!("❌ Bearer token failed: {}", e),
}
println!("\n🔑 Testing custom token header...");
match self.test_token_header(&url, &payload).await {
Ok(response) => {
println!("✅ Token header works!");
println!("📝 Response: {}", response);
return Ok(());
}
Err(e) => println!("❌ Token header failed: {}", e),
}
println!("\n🔑 Testing Authorization header (direct)...");
match self.test_auth_header(&url, &payload).await {
Ok(response) => {
println!("✅ Authorization header works!");
println!("📝 Response: {}", response);
return Ok(());
}
Err(e) => println!("❌ Authorization header failed: {}", e),
}
println!("\n❌ None of the authentication methods worked.");
println!("💡 Check your eBay gateway documentation for the correct authentication format.");
Ok(())
}
async fn test_bearer_auth(&self, url: &str, payload: &serde_json::Value) -> Result<String, Box<dyn std::error::Error>> {
let response = self.client
.post(url)
.header("Authorization", format!("Bearer {}", self.api_key))
.header("Content-Type", "application/json")
.header("anthropic-version", "2023-06-01")
.json(payload)
.send()
.await?;
if response.status().is_success() {
let json: serde_json::Value = response.json().await?;
Ok(extract_response_text(&json))
} else {
Err(format!("HTTP {}: {}", response.status(), response.text().await?).into())
}
}
async fn test_token_header(&self, url: &str, payload: &serde_json::Value) -> Result<String, Box<dyn std::error::Error>> {
let response = self.client
.post(url)
.header("token", &self.api_key)
.header("Content-Type", "application/json")
.header("anthropic-version", "2023-06-01")
.json(payload)
.send()
.await?;
if response.status().is_success() {
let json: serde_json::Value = response.json().await?;
Ok(extract_response_text(&json))
} else {
Err(format!("HTTP {}: {}", response.status(), response.text().await?).into())
}
}
async fn test_auth_header(&self, url: &str, payload: &serde_json::Value) -> Result<String, Box<dyn std::error::Error>> {
let response = self.client
.post(url)
.header("Authorization", &self.api_key)
.header("Content-Type", "application/json")
.header("anthropic-version", "2023-06-01")
.json(payload)
.send()
.await?;
if response.status().is_success() {
let json: serde_json::Value = response.json().await?;
Ok(extract_response_text(&json))
} else {
Err(format!("HTTP {}: {}", response.status(), response.text().await?).into())
}
}
}
fn extract_response_text(json: &serde_json::Value) -> String {
json.get("content")
.and_then(|content| content.as_array())
.and_then(|blocks| blocks.first())
.and_then(|block| block.get("text"))
.and_then(|text| text.as_str())
.unwrap_or("No text content found")
.to_string()
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("🚀 eBay Gateway Custom Authentication Test");
println!("==========================================\n");
let api_key = std::env::var("ANTHROPIC_API_KEY")
.or_else(|_| std::env::var("EBAY_ANTHROPIC_API_KEY"))
.unwrap_or_else(|_| {
println!("⚠️ No API key found. Please set ANTHROPIC_API_KEY or EBAY_ANTHROPIC_API_KEY");
std::process::exit(1);
});
let base_url = "https://platformgateway2.vip.ebay.com/hubgptgatewaysvc/v1/anthropic";
println!("📡 Testing eBay Gateway: {}", base_url);
println!("🔑 API Key: {}...{}", &api_key[..4.min(api_key.len())], &api_key[api_key.len()-4.min(api_key.len())..]);
println!();
let ebay_client = EbayAnthropicClient::new(api_key.clone(), base_url.to_string());
ebay_client.test_auth_formats().await?;
println!("\n" + "=".repeat(50));
println!("🔧 SDK Modification Recommendations:");
println!();
println!("If Bearer token works, modify src/http/auth.rs:");
println!("```rust");
println!("// Change this line:");
println!("headers.insert(\"x-api-key\", api_key_header);");
println!("// To this:");
println!("headers.insert(\"Authorization\", HeaderValue::from_str(&format!(\"Bearer {{}}\", self.api_key))?);");
println!("```");
println!("\nIf 'token' header works, modify src/http/auth.rs:");
println!("```rust");
println!("// Change this line:");
println!("headers.insert(\"x-api-key\", api_key_header);");
println!("// To this:");
println!("headers.insert(\"token\", api_key_header);");
println!("```");
println!("\n📋 Next Steps:");
println!("1. Run this with your real API key: cargo run --example custom_auth_ebay");
println!("2. If one method works, I can modify the SDK auth handler");
println!("3. Or create a custom configuration option for eBay gateway");
Ok(())
}