sellapp/lib.rs
1use reqwest::{
2 self,
3 header::{HeaderMap, HeaderValue},
4 Client, Error, Method, Response,
5};
6
7pub struct SellAppClient {
8 api_key: String,
9 store_slug: String,
10 http_client: Client,
11}
12
13impl SellAppClient {
14 fn generate_headers(&self, headers_vec: Vec<[&'static str; 2]>) -> HeaderMap {
15 let mut headers = HeaderMap::new();
16 headers.insert(
17 "Authorization",
18 HeaderValue::from_str(format!("Bearer {}", self.api_key).as_str()).unwrap(),
19 );
20 if !self.store_slug.is_empty() {
21 headers.insert(
22 "X-STORE",
23 HeaderValue::from_str(self.store_slug.as_str()).unwrap(),
24 );
25 }
26 for header in headers_vec {
27 let header_key = header[0];
28 let header_value = HeaderValue::from_str(header[1]).unwrap();
29 headers.insert(header_key, header_value);
30 }
31 return headers;
32 }
33
34 async fn send_request(&self, url: String, method: Method) -> Result<Response, Error> {
35 let req_headers = self.generate_headers(vec![["Accept", "application/json"]]);
36 let req_url = format!("https://sell.app/api/{}", url);
37
38 let req = self
39 .http_client
40 .request(method, req_url)
41 .headers(req_headers)
42 .send()
43 .await;
44
45 return req;
46 }
47
48 async fn send_request_data(
49 &self,
50 url: String,
51 method: Method,
52 body: String,
53 ) -> Result<Response, Error> {
54 let req_headers = self.generate_headers(vec![
55 ["Accept", "application/json"],
56 ["Content-Type", "application/json"],
57 ]);
58 let req_url = format!("https://sell.app/api/{}", url);
59
60 let req = self
61 .http_client
62 .request(method, req_url)
63 .headers(req_headers)
64 .body(body)
65 .send()
66 .await;
67
68 return req;
69 }
70
71 /// Fetch all of your blacklist rules.
72 ///
73 /// ``url_params``: Optional attributes to append to the request URL, e.g. **"?limit=50&page=1"**
74 ///
75 /// https://developer.sell.app/blacklists#list-all-blacklist-rules
76 pub async fn blacklist_list_all_rules(&self, url_params: &str) -> Result<Response, Error> {
77 return self
78 .send_request(format!("v1/blacklists{}", url_params), Method::GET)
79 .await;
80 }
81
82 /// Create a new blacklist rule.
83 ///
84 /// ``data``: JSON with the attributes of the new rule, required.
85 ///
86 /// https://developer.sell.app/blacklists#create-a-blacklist-rule
87 pub async fn blacklist_create_rule(&self, data: String) -> Result<Response, Error> {
88 return self
89 .send_request_data("v1/blacklists".to_string(), Method::POST, data)
90 .await;
91 }
92
93 /// Get a blacklist rule by ID.
94 ///
95 /// ``rule_id``: The ID of the rule you want to fetch, required.
96 ///
97 /// https://developer.sell.app/blacklists#retrieve-a-blacklist-rule
98 pub async fn blacklist_get_rule(&self, rule_id: String) -> Result<Response, Error> {
99 return self
100 .send_request(format!("v1/blacklists/{}", rule_id), Method::GET)
101 .await;
102 }
103
104 /// Update a blacklist rule by ID.
105 ///
106 /// ``rule_id``: The ID of the rule you want to update, required.
107 ///
108 /// ``data``: JSON with the updated attributes of the rule, required.
109 ///
110 /// https://developer.sell.app/blacklists#update-a-blacklist-rule
111 pub async fn blacklist_update_rule(
112 &self,
113 rule_id: String,
114 data: String,
115 ) -> Result<Response, Error> {
116 return self
117 .send_request_data(format!("v1/blacklists/{}", rule_id), Method::PATCH, data)
118 .await;
119 }
120
121 /// Delete a blacklist rule by ID.
122 ///
123 /// ``rule_id``: The ID of the rule you want to delete, required.
124 ///
125 /// https://developer.sell.app/blacklists#delete-a-blacklist-rule
126 pub async fn blacklist_delete_rule(&self, rule_id: String) -> Result<Response, Error> {
127 return self
128 .send_request(format!("v1/blacklists/{}", rule_id), Method::DELETE)
129 .await;
130 }
131
132 /// Get all existing coupons.
133 ///
134 /// ``url_params``: Optional attributes to append to the request URL, e.g. **"?limit=50&with_trashed=false"**
135 ///
136 /// https://developer.sell.app/coupons#list-all-coupons
137 pub async fn coupons_list_all(&self, url_params: &str) -> Result<Response, Error> {
138 return self
139 .send_request(format!("v1/coupons{}", url_params), Method::GET)
140 .await;
141 }
142
143 /// Create a new coupon.
144 ///
145 /// ``data``: JSON with the attributes of the new coupon, required.
146 ///
147 /// https://developer.sell.app/coupons#create-a-coupon
148 pub async fn coupons_create(&self, data: String) -> Result<Response, Error> {
149 return self
150 .send_request_data("v1/coupons".to_owned(), Method::POST, data)
151 .await;
152 }
153
154 /// Get a coupon by ID.
155 ///
156 /// ``coupon_id``: The ID of the coupon you want to fetch, required.
157 ///
158 /// https://developer.sell.app/coupons#retrieve-a-coupon
159 pub async fn coupons_get(&self, coupon_id: String) -> Result<Response, Error> {
160 return self
161 .send_request(format!("v1/coupons/{}", coupon_id), Method::GET)
162 .await;
163 }
164
165 /// Update a coupon by ID.
166 ///
167 /// ``coupon_id``: The ID of the coupon you want to update, required.
168 ///
169 /// ``data``: JSON with the updated attributes of the coupon, required.
170 ///
171 /// https://developer.sell.app/coupons#update-a-coupon
172 pub async fn coupons_update(&self, coupon_id: String, data: String) -> Result<Response, Error> {
173 return self
174 .send_request_data(format!("v1/coupons/{}", coupon_id), Method::PATCH, data)
175 .await;
176 }
177
178 /// Delete a coupon by ID.
179 ///
180 /// ``coupon_id``: The ID of the coupon you want to delete, required.
181 ///
182 /// https://developer.sell.app/coupons#delete-a-coupon
183 pub async fn coupons_delete(&self, coupon_id: String) -> Result<Response, Error> {
184 return self
185 .send_request(format!("v1/coupons/{}", coupon_id), Method::DELETE)
186 .await;
187 }
188
189 /// Get all feedback (reviews).
190 ///
191 /// ``url_params``: Optional attributes to append to the request URL, e.g. **"?limit=50&page=1"**
192 ///
193 /// https://developer.sell.app/feedback#list-all-feedback
194 pub async fn feedback_list_all(&self, url_params: &str) -> Result<Response, Error> {
195 return self
196 .send_request(format!("v1/feedback{}", url_params), Method::GET)
197 .await;
198 }
199
200 /// Get specific feedback by ID.
201 ///
202 /// ``feedback_id``: The ID of the feedback you want to fetch, required.
203 ///
204 /// https://developer.sell.app/feedback#retrieve-specific-feedback
205 pub async fn feedback_get(&self, feedback_id: String) -> Result<Response, Error> {
206 return self
207 .send_request(format!("v1/feedback/{}", feedback_id), Method::GET)
208 .await;
209 }
210
211 /// Reply to specifc feedback by ID.
212 ///
213 /// ``feedback_id``: The ID of the feedback you want to reply to, required.
214 ///
215 /// ``data``: JSON with the reply, required.
216 ///
217 /// https://developer.sell.app/feedback#reply-to-feedback
218 pub async fn feedback_reply(
219 &self,
220 feedback_id: String,
221 data: String,
222 ) -> Result<Response, Error> {
223 return self
224 .send_request_data(format!("v1/coupons/{}", feedback_id), Method::PATCH, data)
225 .await;
226 }
227
228 /// Get all existing product groups.
229 ///
230 /// ``url_params``: Optional attributes to append to the request URL, e.g. **"?limit=50&page=1"**
231 ///
232 /// https://developer.sell.app/groups#list-all-groups
233 pub async fn groups_list_all(&self, url_params: &str) -> Result<Response, Error> {
234 return self
235 .send_request(format!("v2/groups{}", url_params), Method::GET)
236 .await;
237 }
238
239 /// Create a product group.
240 ///
241 /// ``data``: JSON with the attributes of the group, required.
242 ///
243 /// https://developer.sell.app/groups#create-a-group
244 pub async fn groups_create(&self, data: String) -> Result<Response, Error> {
245 return self
246 .send_request_data("v2/groups".to_string(), Method::POST, data)
247 .await;
248 }
249
250 /// Get specific product group by ID.
251 ///
252 /// ``group_id``: The ID of the group you want to fetch, required.
253 ///
254 /// https://developer.sell.app/groups#retrieve-a-group
255 pub async fn groups_get(&self, group_id: String) -> Result<Response, Error> {
256 return self
257 .send_request(format!("v2/groups/{}", group_id), Method::GET)
258 .await;
259 }
260
261 /// Update a specific product group by ID.
262 ///
263 /// ``group_id``: The ID of the group you want to update, required.
264 ///
265 /// ``data``: JSON with the updated attributes, required.
266 ///
267 /// https://developer.sell.app/groups#update-a-group
268 pub async fn groups_update(&self, group_id: String, data: String) -> Result<Response, Error> {
269 return self
270 .send_request_data(format!("v2/groups/{}", group_id), Method::PATCH, data)
271 .await;
272 }
273
274 /// Delete a product group by ID.
275 ///
276 /// ``group_id``: The ID of the group you want to delete, required.
277 ///
278 /// https://developer.sell.app/groups#delete-a-group
279 pub async fn groups_delete(&self, group_id: String) -> Result<Response, Error> {
280 return self
281 .send_request(format!("v2/groups/{}", group_id), Method::DELETE)
282 .await;
283 }
284
285 /// Add products to an existing product group.
286 ///
287 /// ``group_id``: The ID of the group you want to add products to, required.
288 ///
289 /// ``data``: JSON with the product ID's you want to add, required.
290 ///
291 /// https://developer.sell.app/groups#add-products-to-group
292 pub async fn groups_add_products(
293 &self,
294 group_id: String,
295 data: String,
296 ) -> Result<Response, Error> {
297 return self
298 .send_request_data(
299 format!("v2/groups/{}/products/attach", group_id),
300 Method::POST,
301 data,
302 )
303 .await;
304 }
305
306 /// Remove products from an existing product group.
307 ///
308 /// ``group_id``: The ID of the group you want to remove products from, required.
309 ///
310 /// ``data``: JSON with the product ID's you want to remove, required.
311 ///
312 /// https://developer.sell.app/groups#remove-products-from-group
313 pub async fn groups_remove_products(
314 &self,
315 group_id: String,
316 data: String,
317 ) -> Result<Response, Error> {
318 return self
319 .send_request_data(
320 format!("v2/groups/{}/products/detach", group_id),
321 Method::DELETE,
322 data,
323 )
324 .await;
325 }
326
327 /// Get all products within a product group.
328 ///
329 /// ``group_id``: The ID of the group you want to list the products from, required.
330 ///
331 /// ``url_params``: Optional attributes to append to the request URL, e.g. **"?limit=50&page=1"**
332 ///
333 /// https://developer.sell.app/groups#list-all-products-within-group
334 pub async fn groups_list_products(
335 &self,
336 group_id: String,
337 url_params: &str,
338 ) -> Result<Response, Error> {
339 return self
340 .send_request(
341 format!("v2/groups/{}/products{}", group_id, url_params),
342 Method::GET,
343 )
344 .await;
345 }
346
347 /// Get a specific product within a product group.
348 ///
349 /// ``group_id``: The ID of the group you want to get the product from, required.
350 ///
351 /// ``product_id``: The ID of the product you want to fetch, required.
352 ///
353 /// https://developer.sell.app/groups#list-specific-product-within-group
354 pub async fn groups_get_product(
355 &self,
356 group_id: String,
357 product_id: String,
358 ) -> Result<Response, Error> {
359 return self
360 .send_request(
361 format!("v2/groups/{}/products/{}", group_id, product_id),
362 Method::GET,
363 )
364 .await;
365 }
366
367 /// Get all existing invoices (orders).
368 ///
369 /// ``url_params``: Optional attributes to append to the request URL, e.g. **"?limit=50&page=1"**
370 ///
371 /// https://developer.sell.app/invoices-v2#list-all-invoices
372 pub async fn invoices_list_all(&self, url_params: &str) -> Result<Response, Error> {
373 return self
374 .send_request(format!("v2/invoices{}", url_params), Method::GET)
375 .await;
376 }
377
378 /// Create a new invoice for a customer.
379 ///
380 /// ``data``: JSON with the invoice data, required.
381 ///
382 /// https://developer.sell.app/invoices-v2#create-an-invoice
383 pub async fn invoices_create(&self, data: String) -> Result<Response, Error> {
384 return self
385 .send_request_data("v2/invoices".to_string(), Method::POST, data)
386 .await;
387 }
388
389 /// Get specific invoice by ID.
390 ///
391 /// ``invoice_id``: The ID of the invoice you want to fetch, required.
392 ///
393 /// https://developer.sell.app/invoices-v2#retrieve-an-invoice
394 pub async fn invoices_get(&self, invoice_id: String) -> Result<Response, Error> {
395 return self
396 .send_request(format!("v2/invoices/{}", invoice_id), Method::GET)
397 .await;
398 }
399
400 /// Start a checkout session for a speficic invoice.
401 ///
402 /// ``invoice_id``: The ID of the invoice you want to start checkout for, required.
403 ///
404 /// https://developer.sell.app/invoices-v2#create-a-checkout-session
405 pub async fn invoices_checkout(&self, invoice_id: String) -> Result<Response, Error> {
406 return self
407 .send_request(format!("v2/invoices/{}/checkout", invoice_id), Method::POST)
408 .await;
409 }
410
411 /// Get the deliverables included in a specific invoice.
412 ///
413 /// ``invoice_id``: The ID of the invoice you want to get the items for, required.
414 ///
415 /// https://developer.sell.app/invoices-v2#view-invoice-deliverables
416 pub async fn invoices_get_items(&self, invoice_id: String) -> Result<Response, Error> {
417 return self
418 .send_request(
419 format!("v2/invoices/{}/deliverables", invoice_id),
420 Method::GET,
421 )
422 .await;
423 }
424
425 /// **Note: SellApp automatically marks payments as completed, you shouldn't need to call this.**
426 ///
427 /// Mark a specific (pending) invoice as completed.
428 ///
429 /// ``invoice_id``: The ID of the invoice you want to set as completed, required.
430 ///
431 /// https://developer.sell.app/invoices-v2#mark-pending-invoice-completed
432 pub async fn invoices_mark_completed(&self, invoice_id: String) -> Result<Response, Error> {
433 return self
434 .send_request(
435 format!("v2/invoices/{}/mark-completed", invoice_id),
436 Method::PATCH,
437 )
438 .await;
439 }
440
441 /// Mark a specific (pending) invoice as voided.
442 ///
443 /// ``invoice_id``: The ID of the invoice you want to set as voided, required.
444 ///
445 /// https://developer.sell.app/invoices-v2#mark-pending-invoice-voided
446 pub async fn invoices_mark_voided(&self, invoice_id: String) -> Result<Response, Error> {
447 return self
448 .send_request(
449 format!("v2/invoices/{}/mark-voided", invoice_id),
450 Method::PATCH,
451 )
452 .await;
453 }
454
455 /// Issue a replacement for a specific invoice.
456 ///
457 /// ``invoice_id``: The ID of the invoice you want to issue a replacement for, required.
458 ///
459 /// ``data``: JSON with the product variant ID's to get the replacements from.
460 ///
461 /// https://developer.sell.app/invoices-v2#issue-replacement-for-completed-invoice
462 pub async fn invoices_issue_replacement(
463 &self,
464 invoice_id: String,
465 data: String,
466 ) -> Result<Response, Error> {
467 return self
468 .send_request_data(
469 format!("v2/invoices/{}/issue-replacement", invoice_id),
470 Method::PATCH,
471 data,
472 )
473 .await;
474 }
475
476 /// Get all existing products.
477 ///
478 /// ``url_params``: Optional attributes to append to the request URL, e.g. **"?limit=50&page=1"**
479 ///
480 /// https://developer.sell.app/products-v2#list-all-products
481 pub async fn products_list_all(&self, url_params: &str) -> Result<Response, Error> {
482 return self
483 .send_request(format!("v2/products{}", url_params), Method::GET)
484 .await;
485 }
486
487 /// Create a new product. Support for uploading images is WIP.
488 ///
489 /// ``data``: JSON with the attributes of the product, required.
490 ///
491 /// https://developer.sell.app/products-v2#create-a-product
492 pub async fn products_create(&self, data: String) -> Result<Response, Error> {
493 return self
494 .send_request_data("v2/products".to_string(), Method::POST, data)
495 .await;
496 }
497
498 /// Get a specific product by ID.
499 ///
500 /// ``product_id``: The ID of the product you want to fetch, required.
501 ///
502 /// https://developer.sell.app/products-v2#retrieve-a-product
503 pub async fn products_get(&self, product_id: String) -> Result<Response, Error> {
504 return self
505 .send_request(format!("v2/products/{}", product_id), Method::GET)
506 .await;
507 }
508
509 /// Update a specific product.
510 ///
511 /// ``product_id``: The ID of the product you want to update, required.
512 ///
513 /// ``data``: JSON with the new product attributes, required.
514 ///
515 /// https://developer.sell.app/products-v2#update-a-product
516 pub async fn products_update(
517 &self,
518 product_id: String,
519 data: String,
520 ) -> Result<Response, Error> {
521 return self
522 .send_request_data(format!("v2/products/{}", product_id), Method::PATCH, data)
523 .await;
524 }
525
526 /// Delete a specific product.
527 ///
528 /// ``product_id``: The ID of the product you want to delete, required.
529 ///
530 /// https://developer.sell.app/products-v2#delete-a-product
531 pub async fn products_delete(&self, product_id: String) -> Result<Response, Error> {
532 return self
533 .send_request(format!("v2/products/{}", product_id), Method::DELETE)
534 .await;
535 }
536
537 /// Get all existing product variants.
538 ///
539 /// ``product_id``: The ID of the product you want to get the variants of, required.
540 ///
541 /// ``url_params``: Optional attributes to append to the request URL, e.g. **"?limit=50&page=1"**
542 ///
543 /// https://developer.sell.app/product-variants-v2#list-all-product-variants
544 pub async fn variants_list_all(
545 &self,
546 product_id: String,
547 url_params: &str,
548 ) -> Result<Response, Error> {
549 return self
550 .send_request(
551 format!("v2/products/{}/variants{}", product_id, url_params),
552 Method::GET,
553 )
554 .await;
555 }
556
557 /// Create a new product variant.
558 ///
559 /// ``product_id``: The ID of the product you want to add a new variant to, required.
560 ///
561 /// ``data``: JSON with the attributes of the variant, required.
562 ///
563 /// https://developer.sell.app/product-variants-v2#create-a-product-variant
564 pub async fn variants_create(
565 &self,
566 product_id: String,
567 data: String,
568 ) -> Result<Response, Error> {
569 return self
570 .send_request_data(
571 format!("v2/products/{}/variants", product_id),
572 Method::POST,
573 data,
574 )
575 .await;
576 }
577
578 /// Get a specific variant of a specific product.
579 ///
580 /// ``product_id``: The ID of the product, required.
581 ///
582 /// ``variant_id``: The ID of the variant you want to fetch, required.
583 ///
584 /// https://developer.sell.app/product-variants-v2#retrieve-a-product-variant
585 pub async fn variants_get(
586 &self,
587 product_id: String,
588 variant_id: String,
589 ) -> Result<Response, Error> {
590 return self
591 .send_request(
592 format!("v2/products/{}/variants/{}", product_id, variant_id),
593 Method::GET,
594 )
595 .await;
596 }
597
598 /// Update a specific variant of a specific product.
599 ///
600 /// ``product_id``: The ID of the product, required.
601 ///
602 /// ``variant_id``: The ID of the variant you want to update, required.
603 ///
604 /// ``data``: JSON with the new variant attributes, required.
605 ///
606 /// https://developer.sell.app/product-variants-v2#update-a-product-variant
607 pub async fn variants_update(
608 &self,
609 product_id: String,
610 variant_id: String,
611 data: String,
612 ) -> Result<Response, Error> {
613 return self
614 .send_request_data(
615 format!("v2/products/{}/variants/{}", product_id, variant_id),
616 Method::PATCH,
617 data,
618 )
619 .await;
620 }
621
622 /// Delete a specific product variant.
623 ///
624 /// ``product_id``: The ID of the product, required.
625 ///
626 /// ``variant_id``: The ID of the variant you want to delete, required.
627 ///
628 /// https://developer.sell.app/products-v2#delete-a-product
629 pub async fn variants_delete(
630 &self,
631 product_id: String,
632 variant_id: String,
633 ) -> Result<Response, Error> {
634 return self
635 .send_request(
636 format!("v2/products/{}/variants/{}", product_id, variant_id),
637 Method::DELETE,
638 )
639 .await;
640 }
641
642 /// Get all existing sections.
643 ///
644 /// ``url_params``: Optional attributes to append to the request URL, e.g. **"?limit=50&page=1"**
645 ///
646 /// https://developer.sell.app/sections#list-all-sections
647 pub async fn sections_list_all(&self, url_params: &str) -> Result<Response, Error> {
648 return self
649 .send_request(format!("v1/sections{}", url_params), Method::GET)
650 .await;
651 }
652
653 /// Create a new section.
654 ///
655 /// ``data``: JSON with the attributes of the secton, required.
656 ///
657 /// https://developer.sell.app/sections#create-a-section
658 pub async fn sections_create(&self, data: String) -> Result<Response, Error> {
659 return self
660 .send_request_data("v1/sections".to_string(), Method::POST, data)
661 .await;
662 }
663
664 /// Get a specific section by ID.
665 ///
666 /// ``section_id``: The ID of the section, required.
667 ///
668 /// https://developer.sell.app/sections#retrieve-a-section
669 pub async fn sections_get(&self, section_id: String) -> Result<Response, Error> {
670 return self
671 .send_request(format!("v1/sections/{}", section_id), Method::GET)
672 .await;
673 }
674
675 /// Update a specific section.
676 ///
677 /// ``section_id``: The ID of the section you want to update, required.
678 ///
679 /// ``data``: JSON with the new section attributes, required.
680 ///
681 /// https://developer.sell.app/sections#update-a-section
682 pub async fn sections_update(
683 &self,
684 section_id: String,
685 data: String,
686 ) -> Result<Response, Error> {
687 return self
688 .send_request_data(format!("v1/sections/{}", section_id), Method::PATCH, data)
689 .await;
690 }
691
692 /// Delete a specific product section.
693 ///
694 /// ``section_id``: The ID of the section you want to delete, required.
695 ///
696 /// https://developer.sell.app/sections#delete-a-section
697 pub async fn sections_delete(&self, section_id: String) -> Result<Response, Error> {
698 return self
699 .send_request(format!("v1/sections/{}", section_id), Method::DELETE)
700 .await;
701 }
702
703 /// Get all existing tickets.
704 ///
705 /// ``url_params``: Optional attributes to append to the request URL, e.g. **"?limit=50&page=1"**
706 ///
707 /// https://developer.sell.app/tickets#list-all-tickets
708 pub async fn tickets_list_all(&self, url_params: &str) -> Result<Response, Error> {
709 return self
710 .send_request(format!("v1/tickets{}", url_params), Method::GET)
711 .await;
712 }
713
714 /// Get a specific ticket.
715 ///
716 /// ``ticket_id``: The ID of the ticket you want to fetch, required.
717 ///
718 /// https://developer.sell.app/tickets#retrieve-specific-ticket
719 pub async fn tickets_get(&self, ticket_id: String) -> Result<Response, Error> {
720 return self
721 .send_request(format!("v1/tickets/{}", ticket_id), Method::GET)
722 .await;
723 }
724
725 /// Get the messages from a specific ticket.
726 ///
727 /// ``ticket_id``: The ID of the ticket you want to get the messages from, required.
728 ///
729 /// ``url_params``: Optional attributes to append to the request URL, e.g. **"?limit=50&page=1"**
730 ///
731 /// https://developer.sell.app/tickets#list-all-ticket-messages
732 pub async fn tickets_list_messages(
733 &self,
734 ticket_id: String,
735 url_params: &str,
736 ) -> Result<Response, Error> {
737 return self
738 .send_request(
739 format!("v1/tickets/{}/messages{}", ticket_id, url_params),
740 Method::GET,
741 )
742 .await;
743 }
744
745 /// Send a message to a specific ticket.
746 ///
747 /// ``ticket_id``: The ID of the ticket you want to send a messages to, required.
748 ///
749 /// ``data``: JSON with the message, required.
750 ///
751 /// https://developer.sell.app/tickets#reply-to-ticket
752 pub async fn tickets_reply(&self, ticket_id: String, data: String) -> Result<Response, Error> {
753 return self
754 .send_request_data(
755 format!("v1/tickets/{}/messages", ticket_id),
756 Method::POST,
757 data,
758 )
759 .await;
760 }
761
762 /// Get the a specific message from a specific ticket.
763 ///
764 /// ``ticket_id``: The ID of the ticket you want to get the message from, required.
765 ///
766 /// ``msg_id``: The ID of the message you want to get, required.
767 ///
768 /// https://developer.sell.app/tickets#retrieve-specific-ticket-message
769 pub async fn tickets_get_message(
770 &self,
771 ticket_id: String,
772 msg_id: String,
773 ) -> Result<Response, Error> {
774 return self
775 .send_request(
776 format!("v1/tickets/{}/messages/{}", ticket_id, msg_id),
777 Method::GET,
778 )
779 .await;
780 }
781}
782
783/// Initialize the client to make calls with your SellApp API key.
784///
785/// **Note**: ``store_slug`` is required if you are part of multiple stores, and wish to access a specific one.
786///
787/// Leave an empty &str to default to the first store from your storefront list.
788///
789/// ```
790/// let sellapp_api = sellapp::init("your_api_key", "your_store_slug");
791/// ```
792pub fn init(api_key: &str, store_slug: &str) -> SellAppClient {
793 let key = api_key.to_string();
794 let slug = store_slug.to_string();
795 let http_client = reqwest::Client::new();
796 return SellAppClient {
797 api_key: key,
798 store_slug: slug,
799 http_client,
800 };
801}