Skip to content

Commit 290c025

Browse files
committed
Add support tickets endpoints
1 parent 36043a3 commit 290c025

File tree

9 files changed

+413
-2
lines changed

9 files changed

+413
-2
lines changed

native/swift/Sources/wordpress-api/Exports.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,3 +149,7 @@ public typealias CreateBotConversationParams = WordPressAPIInternal.CreateBotCon
149149
public typealias AddMessageToBotConversationParams = WordPressAPIInternal.AddMessageToBotConversationParams
150150
public typealias GetBotConversationParams = WordPressAPIInternal.GetBotConversationParams
151151
public typealias CreateBotConversationFeedbackParams = WordPressAPIInternal.CreateBotConversationFeedbackParams
152+
153+
// MARK: Support Tickets
154+
public typealias CreateSupportTicketParams = WordPressAPIInternal.CreateSupportTicketParams
155+

native/swift/Sources/wordpress-api/WPComApiClient.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,8 @@ public class WPComApiClient {
2525
public var supportBots: SupportBotsRequestExecutor {
2626
internalClient.supportBots()
2727
}
28+
29+
public var supportTickets: SupportTicketsRequestExecutor {
30+
internalClient.supportTickets()
31+
}
2832
}

wp_api/src/wp_com/client.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use super::endpoint::{
55
oauth2::{Oauth2RequestBuilder, Oauth2RequestExecutor},
66
subscribers::{SubscribersRequestBuilder, SubscribersRequestExecutor},
77
support_bots_endpoint::{SupportBotsRequestBuilder, SupportBotsRequestExecutor},
8+
support_tickets_endpoint::{SupportTicketsRequestBuilder, SupportTicketsRequestExecutor},
89
};
910
use crate::{
1011
WpApiClientDelegate, api_client_generate_api_client, api_client_generate_endpoint_impl,
@@ -33,6 +34,7 @@ pub struct WpComApiRequestBuilder {
3334
oauth2: Arc<Oauth2RequestBuilder>,
3435
subscribers: Arc<SubscribersRequestBuilder>,
3536
support_bots: Arc<SupportBotsRequestBuilder>,
37+
support_tickets: Arc<SupportTicketsRequestBuilder>,
3638
}
3739

3840
impl WpComApiRequestBuilder {
@@ -45,7 +47,8 @@ impl WpComApiRequestBuilder {
4547
jetpack_connection,
4648
oauth2,
4749
subscribers,
48-
support_bots
50+
support_bots,
51+
support_tickets
4952
)
5053
}
5154
}
@@ -70,6 +73,7 @@ pub struct WpComApiClient {
7073
oauth2: Arc<Oauth2RequestExecutor>,
7174
subscribers: Arc<SubscribersRequestExecutor>,
7275
support_bots: Arc<SupportBotsRequestExecutor>,
76+
support_tickets: Arc<SupportTicketsRequestExecutor>,
7377
}
7478

7579
impl WpComApiClient {
@@ -83,11 +87,13 @@ impl WpComApiClient {
8387
jetpack_connection,
8488
oauth2,
8589
subscribers,
86-
support_bots
90+
support_bots,
91+
support_tickets
8792
)
8893
}
8994
}
9095
api_client_generate_endpoint_impl!(WpComApi, jetpack_connection);
9196
api_client_generate_endpoint_impl!(WpComApi, oauth2);
9297
api_client_generate_endpoint_impl!(WpComApi, subscribers);
9398
api_client_generate_endpoint_impl!(WpComApi, support_bots);
99+
api_client_generate_endpoint_impl!(WpComApi, support_tickets);

wp_api/src/wp_com/endpoint.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ pub mod jetpack_connection_endpoint;
1010
pub mod oauth2;
1111
pub mod subscribers;
1212
pub mod support_bots_endpoint;
13+
pub mod support_tickets_endpoint;
1314

1415
#[derive(uniffi::Object)]
1516
pub struct WpComDotOrgApiUrlResolver {
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
use crate::{
2+
request::endpoint::{AsNamespace, DerivedRequest},
3+
wp_com::{
4+
WpComNamespace,
5+
support_tickets::{
6+
AddMessageToSupportConversationParams, ConversationId, CreateSupportTicketParams,
7+
SupportConversation, SupportConversationSummary,
8+
},
9+
},
10+
};
11+
use wp_derive_request_builder::WpDerivedRequest;
12+
13+
#[derive(WpDerivedRequest)]
14+
enum SupportTicketsRequest {
15+
#[post(url = "/mobile-support/conversations", params = &CreateSupportTicketParams, output = SupportConversation)]
16+
CreateSupportTicket,
17+
#[get(url = "/mobile-support/conversations", output = Vec<SupportConversationSummary>)]
18+
GetSupportConversationList,
19+
#[get(url = "/mobile-support/conversations/<conversation_id>", output = SupportConversation)]
20+
GetSupportConversation,
21+
#[post(url = "/mobile-support/conversations/<conversation_id>", params = &AddMessageToSupportConversationParams, output = SupportConversation)]
22+
AddMessageToSupportConversation,
23+
}
24+
25+
impl DerivedRequest for SupportTicketsRequest {
26+
fn namespace() -> impl AsNamespace {
27+
WpComNamespace::V2
28+
}
29+
}

wp_api/src/wp_com/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ pub mod jetpack_connection;
88
pub mod oauth2;
99
pub mod subscribers;
1010
pub mod support_bots;
11+
pub mod support_tickets;
1112

1213
impl_as_query_value_for_new_type!(WpComSiteId);
1314
uniffi::custom_newtype!(WpComSiteId, u64);

wp_api/src/wp_com/support_tickets.rs

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
use std::collections::HashMap;
2+
3+
use serde::{Deserialize, Serialize};
4+
5+
use crate::{date::WpGmtDateTime, impl_as_query_value_for_new_type};
6+
7+
#[derive(Debug, PartialEq, Eq, Serialize, uniffi::Record)]
8+
pub struct CreateSupportTicketParams {
9+
pub subject: String,
10+
pub message: String,
11+
pub application: String,
12+
#[uniffi(default = None)]
13+
#[serde(skip_serializing_if = "Option::is_none")]
14+
pub wpcom_site_id: Option<u64>,
15+
#[uniffi(default = [])]
16+
pub tags: Vec<String>,
17+
#[uniffi(default = [])]
18+
pub attachments: Vec<String>,
19+
}
20+
21+
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, uniffi::Record)]
22+
pub struct SupportConversationSummary {
23+
pub id: ConversationId,
24+
pub title: String,
25+
pub description: String,
26+
pub status: String,
27+
pub created_at: WpGmtDateTime,
28+
pub updated_at: WpGmtDateTime,
29+
}
30+
31+
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, uniffi::Record)]
32+
pub struct SupportConversation {
33+
pub id: ConversationId,
34+
pub title: String,
35+
pub description: String,
36+
pub status: String,
37+
pub created_at: WpGmtDateTime,
38+
pub updated_at: WpGmtDateTime,
39+
pub messages: Vec<SupportMessage>,
40+
}
41+
42+
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, uniffi::Record)]
43+
pub struct SupportMessage {
44+
pub id: u64,
45+
pub content: String,
46+
pub author: SupportMessageAuthor,
47+
pub role: String,
48+
pub author_is_current_user: bool,
49+
pub created_at: WpGmtDateTime,
50+
pub attachments: Vec<SupportAttachment>,
51+
}
52+
53+
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, uniffi::Record)]
54+
pub struct SupportUserIdentity {
55+
pub id: u64,
56+
pub email: String,
57+
pub display_name: String,
58+
pub avatar_url: String,
59+
}
60+
61+
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, uniffi::Record)]
62+
pub struct SupportAttachment {
63+
pub id: u64,
64+
pub filename: String,
65+
pub content_type: String,
66+
pub size: u64,
67+
pub url: String,
68+
pub metadata: HashMap<String, AttachmentMetadataValue>,
69+
}
70+
71+
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, uniffi::Enum)]
72+
#[serde(untagged)]
73+
pub enum SupportMessageAuthor {
74+
User(SupportUserIdentity),
75+
SupportAgent(SupportAgentIdentity),
76+
}
77+
78+
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, uniffi::Enum, strum_macros::Display)]
79+
#[strum(serialize_all = "snake_case")]
80+
pub enum AttachmentMetadataKey {
81+
Width,
82+
Height,
83+
Other(String),
84+
}
85+
86+
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, uniffi::Enum)]
87+
#[serde(untagged)]
88+
pub enum AttachmentMetadataValue {
89+
String(String),
90+
Number(u64),
91+
Boolean(bool),
92+
}
93+
94+
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, uniffi::Record)]
95+
pub struct SupportAgentIdentity {
96+
pub id: u64,
97+
pub name: String,
98+
}
99+
100+
#[derive(Debug, PartialEq, Eq, Serialize, uniffi::Record)]
101+
pub struct AddMessageToSupportConversationParams {
102+
pub message: String,
103+
#[uniffi(default = [])]
104+
pub attachments: Vec<String>,
105+
}
106+
107+
impl_as_query_value_for_new_type!(ConversationId);
108+
uniffi::custom_newtype!(ConversationId, u64);
109+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
110+
pub struct ConversationId(pub u64);
111+
112+
impl std::str::FromStr for ConversationId {
113+
type Err = std::num::ParseIntError;
114+
115+
fn from_str(s: &str) -> Result<Self, Self::Err> {
116+
s.parse().map(Self)
117+
}
118+
}
119+
120+
impl std::fmt::Display for ConversationId {
121+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
122+
write!(f, "{}", self.0)
123+
}
124+
}
125+
126+
#[cfg(test)]
127+
mod tests {
128+
use super::*;
129+
130+
#[test]
131+
fn test_support_conversation_deserialization() {
132+
let json = include_str!("../../tests/wpcom/support_tickets/single-conversation.json");
133+
let conversation: SupportConversation =
134+
serde_json::from_str(json).expect("Failed to deserialize support conversation");
135+
assert_eq!(conversation.messages.len(), 7);
136+
}
137+
138+
#[test]
139+
fn test_support_conversation_list_deserialization() {
140+
let json = include_str!("../../tests/wpcom/support_tickets/conversation-list.json");
141+
let conversation_list: Vec<SupportConversationSummary> =
142+
serde_json::from_str(json).expect("Failed to deserialize support conversation list");
143+
assert_eq!(conversation_list.len(), 11);
144+
}
145+
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
[
2+
{
3+
"id": 9033503,
4+
"title": "🎨 Theme Customization Help",
5+
"description": "Hello! 👋\n\nI see you're having trouble with your theme customization. Let me help you with that!\n\nThe color picker issue you're experiencing is a known bug that we've fixed in the latest update. Please try updating your theme to version 2.3.1.\n\nIf you need any further assistance, I'm here to help!\n\nBest regards,\n\nTheme Support Team 🌟",
6+
"status": "closed",
7+
"created_at": "2024-03-15T14:30:22+00:00",
8+
"updated_at": "2024-03-18T09:45:33+00:00"
9+
},
10+
{
11+
"id": 1698812,
12+
"title": "🔒 Security Update Required",
13+
"description": "مرحباً!\n\nلقد لاحظنا أن موقعك يحتاج إلى تحديث أمني. يرجى تحديث إصدار WordPress الخاص بك إلى أحدث إصدار متاح.\n\nيمكنك القيام بذلك من لوحة التحكم الخاصة بك.\n\nمع تحياتنا،\n\nفريق الدعم الأمني",
14+
"status": "closed",
15+
"created_at": "2024-03-10T09:15:45+00:00",
16+
"updated_at": "2024-03-11T16:20:12+00:00"
17+
},
18+
{
19+
"id": 1629241,
20+
"title": "🚀 Performance Optimization",
21+
"description": "Bonjour!\n\nJe vois que vous souhaitez optimiser les performances de votre site. Voici quelques suggestions:\n\n1. Activez la mise en cache\n2. Optimisez vos images\n3. Utilisez un CDN\n\nVoulez-vous que je vous guide à travers ces étapes?\n\nCordialement,\n\nL'équipe de support",
22+
"status": "closed",
23+
"created_at": "2024-03-05T11:22:18+00:00",
24+
"updated_at": "2024-03-07T14:33:29+00:00"
25+
},
26+
{
27+
"id": 1500710,
28+
"title": "📱 Mobile App Feedback",
29+
"description": "Hi there! 👋\n\nThank you for your feedback about our mobile app. We're constantly working to improve the user experience.\n\nYour suggestion about the navigation menu has been forwarded to our development team.\n\nKeep the feedback coming! 💪\n\nBest regards,\n\nMobile Support Team",
30+
"status": "closed",
31+
"created_at": "2024-02-28T15:40:55+00:00",
32+
"updated_at": "2024-03-01T10:15:22+00:00"
33+
},
34+
{
35+
"id": 1499869,
36+
"title": "🎯 SEO Optimization Help",
37+
"description": "Hello!\n\nI'd be happy to help you with your SEO optimization. Here are some key areas we can focus on:\n\n1. Meta descriptions\n2. Image alt tags\n3. URL structure\n\nWould you like me to provide more specific guidance on any of these topics?\n\nBest regards,\n\nSEO Support Team",
38+
"status": "closed",
39+
"created_at": "2024-02-25T13:20:33+00:00",
40+
"updated_at": "2024-02-27T09:45:11+00:00"
41+
},
42+
{
43+
"id": 1500203,
44+
"title": "💰 Payment Gateway Setup",
45+
"description": "Hi!\n\nI see you're setting up a new payment gateway. Let's make sure everything is configured correctly.\n\nPlease verify these settings:\n1. API keys\n2. Webhook endpoints\n3. Test mode status\n\nNeed any clarification? 🤔\n\nBest regards,\n\nPayment Support Team",
46+
"status": "closed",
47+
"created_at": "2024-02-20T10:15:44+00:00",
48+
"updated_at": "2024-02-22T16:30:27+00:00"
49+
},
50+
{
51+
"id": 1698812,
52+
"title": "🎨 Design Consultation",
53+
"description": "Hello! 👋\n\nThank you for reaching out about your site's design. I'd be happy to help you achieve the look you're going for.\n\nWould you like to schedule a design consultation call? We can discuss:\n- Color schemes\n- Layout options\n- Typography\n\nLet me know what works best for you! ✨\n\nBest regards,\n\nDesign Support Team",
54+
"status": "closed",
55+
"created_at": "2024-02-15T09:30:22+00:00",
56+
"updated_at": "2024-02-17T14:45:33+00:00"
57+
},
58+
{
59+
"id": 1629241,
60+
"title": "📊 Analytics Integration",
61+
"description": "Hi there!\n\nI see you're having trouble with your analytics integration. Let's get that sorted out.\n\nFirst, please verify that you've added the tracking code correctly to your site's header.\n\nNeed help finding where to add it? 🧐\n\nBest regards,\n\nAnalytics Support Team",
62+
"status": "closed",
63+
"created_at": "2024-02-10T11:20:18+00:00",
64+
"updated_at": "2024-02-12T15:33:29+00:00"
65+
},
66+
{
67+
"id": 1500710,
68+
"title": "🌐 Multilingual Setup",
69+
"description": "Bonjour!\n\nJe vois que vous souhaitez configurer votre site en plusieurs langues. Voici les étapes à suivre:\n\n1. Installer le plugin de traduction\n2. Configurer les langues\n3. Traduire le contenu\n\nBesoin d'aide avec l'une de ces étapes? 🤝\n\nCordialement,\n\nL'équipe de support multilingue",
70+
"status": "closed",
71+
"created_at": "2024-02-05T13:40:55+00:00",
72+
"updated_at": "2024-02-07T10:15:22+00:00"
73+
},
74+
{
75+
"id": 1499869,
76+
"title": "🔧 Technical Support",
77+
"description": "Hello! 👋\n\nI understand you're experiencing some technical issues. Let's troubleshoot this step by step.\n\nCould you please:\n1. Clear your browser cache\n2. Try a different browser\n3. Check your internet connection\n\nLet me know if you need help with any of these steps! 🛠️\n\nBest regards,\n\nTechnical Support Team",
78+
"status": "closed",
79+
"created_at": "2024-02-01T10:20:33+00:00",
80+
"updated_at": "2024-02-03T09:45:11+00:00"
81+
},
82+
{
83+
"id": 1500203,
84+
"title": "📝 Content Migration",
85+
"description": "Hi there!\n\nI see you're planning to migrate your content. Let me help you with that process.\n\nWe can use our automated migration tool, or I can guide you through a manual migration.\n\nWhich option would you prefer? 🤔\n\nBest regards,\n\nMigration Support Team",
86+
"status": "closed",
87+
"created_at": "2024-01-28T09:15:44+00:00",
88+
"updated_at": "2024-01-30T16:30:27+00:00"
89+
}
90+
]

0 commit comments

Comments
 (0)