@cstar.help/js 0.11.0 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +58 -6
- package/dist/chat/index.cjs +243 -10
- package/dist/chat/index.d.cts +188 -6
- package/dist/chat/index.d.ts +188 -6
- package/dist/chat/index.js +237 -9
- package/dist/index.d.cts +399 -15
- package/dist/index.d.ts +399 -15
- package/dist/quickhelp/index.cjs +102 -0
- package/dist/quickhelp/index.d.cts +97 -0
- package/dist/quickhelp/index.d.ts +97 -0
- package/dist/quickhelp/index.js +76 -0
- package/dist/webhook/index.d.cts +390 -102
- package/dist/webhook/index.d.ts +390 -102
- package/package.json +11 -1
package/dist/index.d.ts
CHANGED
|
@@ -499,8 +499,401 @@ declare class ArticlesResource extends BaseResource<Article, ArticleListParams,
|
|
|
499
499
|
constructor(client: HttpClient);
|
|
500
500
|
}
|
|
501
501
|
|
|
502
|
-
/**
|
|
503
|
-
type WebhookEventType = '
|
|
502
|
+
/** Every webhook event type cStar can dispatch. */
|
|
503
|
+
type WebhookEventType = 'article.created' | 'article.deleted' | 'article.published' | 'article.updated' | 'boss.damaged' | 'boss.defeated' | 'boss.spawned' | 'community_post.commented' | 'community_post.created' | 'community_post.deleted' | 'community_post.status_changed' | 'community_post.updated' | 'community_post.voted' | 'customer.created' | 'customer.deleted' | 'customer.updated' | 'customer_group.created' | 'customer_group.deleted' | 'customer_group.updated' | 'player.achievement_unlocked' | 'player.level_up' | 'player.quest_completed' | 'player.streak_milestone' | 'player.xp_gained' | 'social.high_five_sent' | 'social.one_up_sent' | 'survey.submitted' | 'ticket.assigned' | 'ticket.closed' | 'ticket.created' | 'ticket.deleted' | 'ticket.message_added' | 'ticket.updated';
|
|
504
|
+
/** Payload for `article.created` events. */
|
|
505
|
+
interface ArticleCreatedPayload {
|
|
506
|
+
article: {
|
|
507
|
+
id: string;
|
|
508
|
+
title: string;
|
|
509
|
+
slug: string;
|
|
510
|
+
is_public: boolean;
|
|
511
|
+
created_at: string;
|
|
512
|
+
};
|
|
513
|
+
}
|
|
514
|
+
/** Payload for `article.deleted` events. */
|
|
515
|
+
interface ArticleDeletedPayload {
|
|
516
|
+
id: string;
|
|
517
|
+
}
|
|
518
|
+
/** Payload for `article.published` events. */
|
|
519
|
+
interface ArticlePublishedPayload {
|
|
520
|
+
article: {
|
|
521
|
+
id: string;
|
|
522
|
+
title: string;
|
|
523
|
+
slug: string;
|
|
524
|
+
is_public: boolean;
|
|
525
|
+
published_at: string;
|
|
526
|
+
};
|
|
527
|
+
}
|
|
528
|
+
/** Payload for `article.updated` events. */
|
|
529
|
+
interface ArticleUpdatedPayload {
|
|
530
|
+
article: {
|
|
531
|
+
id: string;
|
|
532
|
+
title: string;
|
|
533
|
+
slug: string;
|
|
534
|
+
is_public: boolean;
|
|
535
|
+
};
|
|
536
|
+
}
|
|
537
|
+
/** Payload for `boss.damaged` events. */
|
|
538
|
+
interface BossDamagedPayload {
|
|
539
|
+
boss: {
|
|
540
|
+
id: string;
|
|
541
|
+
current_hp: number;
|
|
542
|
+
};
|
|
543
|
+
damage: number;
|
|
544
|
+
by: {
|
|
545
|
+
agent_id: string;
|
|
546
|
+
name: string;
|
|
547
|
+
};
|
|
548
|
+
}
|
|
549
|
+
/** Payload for `boss.defeated` events. */
|
|
550
|
+
interface BossDefeatedPayload {
|
|
551
|
+
boss: {
|
|
552
|
+
id: string;
|
|
553
|
+
name: string;
|
|
554
|
+
};
|
|
555
|
+
final_blow_by: {
|
|
556
|
+
agent_id: string;
|
|
557
|
+
name: string;
|
|
558
|
+
};
|
|
559
|
+
team_xp_awarded: number;
|
|
560
|
+
}
|
|
561
|
+
/** Payload for `boss.spawned` events. */
|
|
562
|
+
interface BossSpawnedPayload {
|
|
563
|
+
boss: {
|
|
564
|
+
id: string;
|
|
565
|
+
name: string;
|
|
566
|
+
level: number;
|
|
567
|
+
max_hp: number;
|
|
568
|
+
};
|
|
569
|
+
}
|
|
570
|
+
/** Payload for `community_post.commented` events. */
|
|
571
|
+
interface CommunityPostCommentedPayload {
|
|
572
|
+
comment: {
|
|
573
|
+
id: string;
|
|
574
|
+
post_id: string;
|
|
575
|
+
content: string;
|
|
576
|
+
author_id: string;
|
|
577
|
+
created_at: string;
|
|
578
|
+
};
|
|
579
|
+
}
|
|
580
|
+
/** Payload for `community_post.created` events. */
|
|
581
|
+
interface CommunityPostCreatedPayload {
|
|
582
|
+
post: {
|
|
583
|
+
id: string;
|
|
584
|
+
prefixed_id: string;
|
|
585
|
+
title: string;
|
|
586
|
+
status: string;
|
|
587
|
+
visibility: string;
|
|
588
|
+
topic: string;
|
|
589
|
+
created_at: string;
|
|
590
|
+
};
|
|
591
|
+
}
|
|
592
|
+
/** Payload for `community_post.deleted` events. */
|
|
593
|
+
interface CommunityPostDeletedPayload {
|
|
594
|
+
post: {
|
|
595
|
+
id: string;
|
|
596
|
+
prefixed_id?: string;
|
|
597
|
+
title?: string;
|
|
598
|
+
};
|
|
599
|
+
}
|
|
600
|
+
/** Payload for `community_post.status_changed` events. */
|
|
601
|
+
interface CommunityPostStatusChangedPayload {
|
|
602
|
+
post: {
|
|
603
|
+
id: string;
|
|
604
|
+
title: string;
|
|
605
|
+
status: string;
|
|
606
|
+
visibility: string;
|
|
607
|
+
};
|
|
608
|
+
}
|
|
609
|
+
/** Payload for `community_post.updated` events. */
|
|
610
|
+
interface CommunityPostUpdatedPayload {
|
|
611
|
+
post: {
|
|
612
|
+
id: string;
|
|
613
|
+
title: string;
|
|
614
|
+
status: string;
|
|
615
|
+
visibility: string;
|
|
616
|
+
};
|
|
617
|
+
}
|
|
618
|
+
/** Payload for `community_post.voted` events. */
|
|
619
|
+
interface CommunityPostVotedPayload {
|
|
620
|
+
post: {
|
|
621
|
+
id: string;
|
|
622
|
+
vote_count: number;
|
|
623
|
+
};
|
|
624
|
+
voter: {
|
|
625
|
+
id: string;
|
|
626
|
+
};
|
|
627
|
+
direction: string;
|
|
628
|
+
}
|
|
629
|
+
/** Payload for `customer.created` events. */
|
|
630
|
+
interface CustomerCreatedPayload {
|
|
631
|
+
customer: {
|
|
632
|
+
id: string;
|
|
633
|
+
name: string;
|
|
634
|
+
email: string;
|
|
635
|
+
status: string;
|
|
636
|
+
tags: Array<string>;
|
|
637
|
+
created_at: string;
|
|
638
|
+
};
|
|
639
|
+
}
|
|
640
|
+
/** Payload for `customer.deleted` events. */
|
|
641
|
+
interface CustomerDeletedPayload {
|
|
642
|
+
id: string;
|
|
643
|
+
}
|
|
644
|
+
/** Payload for `customer.updated` events. */
|
|
645
|
+
interface CustomerUpdatedPayload {
|
|
646
|
+
customer: {
|
|
647
|
+
id: string;
|
|
648
|
+
name: string;
|
|
649
|
+
email: string;
|
|
650
|
+
status: string;
|
|
651
|
+
tags: Array<string>;
|
|
652
|
+
};
|
|
653
|
+
changes: {
|
|
654
|
+
tags: {
|
|
655
|
+
from: Array<string>;
|
|
656
|
+
to: Array<string>;
|
|
657
|
+
};
|
|
658
|
+
};
|
|
659
|
+
}
|
|
660
|
+
/** Payload for `customer_group.created` events. */
|
|
661
|
+
interface CustomerGroupCreatedPayload {
|
|
662
|
+
group: {
|
|
663
|
+
id: string;
|
|
664
|
+
name: string;
|
|
665
|
+
color: string;
|
|
666
|
+
member_count: number;
|
|
667
|
+
};
|
|
668
|
+
}
|
|
669
|
+
/** Payload for `customer_group.deleted` events. */
|
|
670
|
+
interface CustomerGroupDeletedPayload {
|
|
671
|
+
customer_group: {
|
|
672
|
+
id: string;
|
|
673
|
+
};
|
|
674
|
+
}
|
|
675
|
+
/** Payload for `customer_group.updated` events. */
|
|
676
|
+
interface CustomerGroupUpdatedPayload {
|
|
677
|
+
group: {
|
|
678
|
+
id: string;
|
|
679
|
+
name: string;
|
|
680
|
+
color: string;
|
|
681
|
+
member_count: number;
|
|
682
|
+
};
|
|
683
|
+
}
|
|
684
|
+
/** Payload for `player.achievement_unlocked` events. */
|
|
685
|
+
interface PlayerAchievementUnlockedPayload {
|
|
686
|
+
player: {
|
|
687
|
+
agent_id: string;
|
|
688
|
+
name: string;
|
|
689
|
+
};
|
|
690
|
+
achievement: {
|
|
691
|
+
id: string;
|
|
692
|
+
name: string;
|
|
693
|
+
xp: number;
|
|
694
|
+
};
|
|
695
|
+
}
|
|
696
|
+
/** Payload for `player.level_up` events. */
|
|
697
|
+
interface PlayerLevelUpPayload {
|
|
698
|
+
player: {
|
|
699
|
+
agent_id: string;
|
|
700
|
+
name: string;
|
|
701
|
+
};
|
|
702
|
+
level: {
|
|
703
|
+
from: number;
|
|
704
|
+
to: number;
|
|
705
|
+
};
|
|
706
|
+
title_unlocked: string;
|
|
707
|
+
}
|
|
708
|
+
/** Payload for `player.quest_completed` events. */
|
|
709
|
+
interface PlayerQuestCompletedPayload {
|
|
710
|
+
player: {
|
|
711
|
+
agent_id: string;
|
|
712
|
+
name: string;
|
|
713
|
+
};
|
|
714
|
+
quest: {
|
|
715
|
+
id: string;
|
|
716
|
+
name: string;
|
|
717
|
+
xp: number;
|
|
718
|
+
};
|
|
719
|
+
}
|
|
720
|
+
/** Payload for `player.streak_milestone` events. */
|
|
721
|
+
interface PlayerStreakMilestonePayload {
|
|
722
|
+
player: {
|
|
723
|
+
agent_id: string;
|
|
724
|
+
name: string;
|
|
725
|
+
};
|
|
726
|
+
streak_days: number;
|
|
727
|
+
milestone: number;
|
|
728
|
+
}
|
|
729
|
+
/** Payload for `player.xp_gained` events. */
|
|
730
|
+
interface PlayerXpGainedPayload {
|
|
731
|
+
player: {
|
|
732
|
+
agent_id: string;
|
|
733
|
+
name: string;
|
|
734
|
+
};
|
|
735
|
+
amount: number;
|
|
736
|
+
reason: string;
|
|
737
|
+
ticket_id: string;
|
|
738
|
+
}
|
|
739
|
+
/** Payload for `social.high_five_sent` events. */
|
|
740
|
+
interface SocialHighFiveSentPayload {
|
|
741
|
+
from_team: {
|
|
742
|
+
id: string;
|
|
743
|
+
name: string;
|
|
744
|
+
};
|
|
745
|
+
to_team: {
|
|
746
|
+
id: string;
|
|
747
|
+
name: string;
|
|
748
|
+
};
|
|
749
|
+
message: string;
|
|
750
|
+
}
|
|
751
|
+
/** Payload for `social.one_up_sent` events. */
|
|
752
|
+
interface SocialOneUpSentPayload {
|
|
753
|
+
from: {
|
|
754
|
+
agent_id: string;
|
|
755
|
+
name: string;
|
|
756
|
+
};
|
|
757
|
+
to: {
|
|
758
|
+
agent_id: string;
|
|
759
|
+
name: string;
|
|
760
|
+
};
|
|
761
|
+
ticket_id: string;
|
|
762
|
+
message: string;
|
|
763
|
+
}
|
|
764
|
+
/** Payload for `survey.submitted` events. */
|
|
765
|
+
interface SurveySubmittedPayload {
|
|
766
|
+
survey: {
|
|
767
|
+
id: string;
|
|
768
|
+
ticket_id: string;
|
|
769
|
+
score: number;
|
|
770
|
+
comment: string;
|
|
771
|
+
submitted_at: string;
|
|
772
|
+
};
|
|
773
|
+
customer: {
|
|
774
|
+
id: string;
|
|
775
|
+
email: string;
|
|
776
|
+
};
|
|
777
|
+
}
|
|
778
|
+
/** Payload for `ticket.assigned` events. */
|
|
779
|
+
interface TicketAssignedPayload {
|
|
780
|
+
ticket: {
|
|
781
|
+
id: string;
|
|
782
|
+
prefixed_id: string;
|
|
783
|
+
};
|
|
784
|
+
assignee: {
|
|
785
|
+
id: string;
|
|
786
|
+
name: string;
|
|
787
|
+
email: string;
|
|
788
|
+
};
|
|
789
|
+
previous_assignee: null;
|
|
790
|
+
}
|
|
791
|
+
/** Payload for `ticket.closed` events. */
|
|
792
|
+
interface TicketClosedPayload {
|
|
793
|
+
ticket: {
|
|
794
|
+
id: string;
|
|
795
|
+
prefixed_id: string;
|
|
796
|
+
title: string;
|
|
797
|
+
status: string;
|
|
798
|
+
priority: string;
|
|
799
|
+
channel: string;
|
|
800
|
+
resolved_at: string;
|
|
801
|
+
};
|
|
802
|
+
}
|
|
803
|
+
/** Payload for `ticket.created` events. */
|
|
804
|
+
interface TicketCreatedPayload {
|
|
805
|
+
ticket: {
|
|
806
|
+
id: string;
|
|
807
|
+
prefixed_id: string;
|
|
808
|
+
title: string;
|
|
809
|
+
status: string;
|
|
810
|
+
priority: string;
|
|
811
|
+
channel: string;
|
|
812
|
+
customer_id: string;
|
|
813
|
+
created_at: string;
|
|
814
|
+
};
|
|
815
|
+
customer: {
|
|
816
|
+
id: string;
|
|
817
|
+
name: string;
|
|
818
|
+
email: string;
|
|
819
|
+
};
|
|
820
|
+
}
|
|
821
|
+
/** Payload for `ticket.deleted` events. */
|
|
822
|
+
interface TicketDeletedPayload {
|
|
823
|
+
id: string;
|
|
824
|
+
}
|
|
825
|
+
/** Payload for `ticket.message_added` events. */
|
|
826
|
+
interface TicketMessageAddedPayload {
|
|
827
|
+
ticket: {
|
|
828
|
+
id: string;
|
|
829
|
+
dashboard_url: string | null;
|
|
830
|
+
};
|
|
831
|
+
message: {
|
|
832
|
+
id: string;
|
|
833
|
+
sender: string;
|
|
834
|
+
sender_name: string | null;
|
|
835
|
+
content: string;
|
|
836
|
+
created_at: string;
|
|
837
|
+
};
|
|
838
|
+
customer?: {
|
|
839
|
+
id: string;
|
|
840
|
+
name: string | null;
|
|
841
|
+
email: string | null;
|
|
842
|
+
};
|
|
843
|
+
}
|
|
844
|
+
/** Payload for `ticket.updated` events. */
|
|
845
|
+
interface TicketUpdatedPayload {
|
|
846
|
+
ticket: {
|
|
847
|
+
id: string;
|
|
848
|
+
prefixed_id: string;
|
|
849
|
+
title: string;
|
|
850
|
+
status: string;
|
|
851
|
+
priority: string;
|
|
852
|
+
channel: string;
|
|
853
|
+
};
|
|
854
|
+
changes: {
|
|
855
|
+
priority: {
|
|
856
|
+
from: string;
|
|
857
|
+
to: string;
|
|
858
|
+
};
|
|
859
|
+
};
|
|
860
|
+
}
|
|
861
|
+
/** Maps each event type to its payload interface — used internally for the discriminated union. */
|
|
862
|
+
interface WebhookEventDataMap {
|
|
863
|
+
'article.created': ArticleCreatedPayload;
|
|
864
|
+
'article.deleted': ArticleDeletedPayload;
|
|
865
|
+
'article.published': ArticlePublishedPayload;
|
|
866
|
+
'article.updated': ArticleUpdatedPayload;
|
|
867
|
+
'boss.damaged': BossDamagedPayload;
|
|
868
|
+
'boss.defeated': BossDefeatedPayload;
|
|
869
|
+
'boss.spawned': BossSpawnedPayload;
|
|
870
|
+
'community_post.commented': CommunityPostCommentedPayload;
|
|
871
|
+
'community_post.created': CommunityPostCreatedPayload;
|
|
872
|
+
'community_post.deleted': CommunityPostDeletedPayload;
|
|
873
|
+
'community_post.status_changed': CommunityPostStatusChangedPayload;
|
|
874
|
+
'community_post.updated': CommunityPostUpdatedPayload;
|
|
875
|
+
'community_post.voted': CommunityPostVotedPayload;
|
|
876
|
+
'customer.created': CustomerCreatedPayload;
|
|
877
|
+
'customer.deleted': CustomerDeletedPayload;
|
|
878
|
+
'customer.updated': CustomerUpdatedPayload;
|
|
879
|
+
'customer_group.created': CustomerGroupCreatedPayload;
|
|
880
|
+
'customer_group.deleted': CustomerGroupDeletedPayload;
|
|
881
|
+
'customer_group.updated': CustomerGroupUpdatedPayload;
|
|
882
|
+
'player.achievement_unlocked': PlayerAchievementUnlockedPayload;
|
|
883
|
+
'player.level_up': PlayerLevelUpPayload;
|
|
884
|
+
'player.quest_completed': PlayerQuestCompletedPayload;
|
|
885
|
+
'player.streak_milestone': PlayerStreakMilestonePayload;
|
|
886
|
+
'player.xp_gained': PlayerXpGainedPayload;
|
|
887
|
+
'social.high_five_sent': SocialHighFiveSentPayload;
|
|
888
|
+
'social.one_up_sent': SocialOneUpSentPayload;
|
|
889
|
+
'survey.submitted': SurveySubmittedPayload;
|
|
890
|
+
'ticket.assigned': TicketAssignedPayload;
|
|
891
|
+
'ticket.closed': TicketClosedPayload;
|
|
892
|
+
'ticket.created': TicketCreatedPayload;
|
|
893
|
+
'ticket.deleted': TicketDeletedPayload;
|
|
894
|
+
'ticket.message_added': TicketMessageAddedPayload;
|
|
895
|
+
'ticket.updated': TicketUpdatedPayload;
|
|
896
|
+
}
|
|
504
897
|
/** A webhook event delivered to your endpoint. */
|
|
505
898
|
interface WebhookEvent<T extends WebhookEventType = WebhookEventType> {
|
|
506
899
|
/** Unique event ID (idempotency key). */
|
|
@@ -512,19 +905,10 @@ interface WebhookEvent<T extends WebhookEventType = WebhookEventType> {
|
|
|
512
905
|
/** Team that owns this event. */
|
|
513
906
|
team_id: string;
|
|
514
907
|
/** Event-specific payload. */
|
|
515
|
-
data:
|
|
516
|
-
}
|
|
517
|
-
|
|
518
|
-
type WebhookEventData<T extends WebhookEventType> = T
|
|
519
|
-
ticket: Ticket;
|
|
520
|
-
} : T extends 'ticket.message_added' ? {
|
|
521
|
-
ticket: Ticket;
|
|
522
|
-
message: Message;
|
|
523
|
-
} : T extends 'customer.created' | 'customer.updated' ? {
|
|
524
|
-
customer: Customer;
|
|
525
|
-
} : T extends 'article.created' | 'article.published' | 'article.updated' ? {
|
|
526
|
-
article: Article;
|
|
527
|
-
} : Record<string, unknown>;
|
|
908
|
+
data: WebhookEventDataMap[T];
|
|
909
|
+
}
|
|
910
|
+
|
|
911
|
+
type WebhookEventData<T extends WebhookEventType> = WebhookEventDataMap[T];
|
|
528
912
|
|
|
529
913
|
/** A cStar webhook endpoint. */
|
|
530
914
|
interface Webhook {
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/quickhelp/index.ts
|
|
21
|
+
var quickhelp_exports = {};
|
|
22
|
+
__export(quickhelp_exports, {
|
|
23
|
+
QuickHelpClient: () => QuickHelpClient,
|
|
24
|
+
QuickHelpError: () => QuickHelpError
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(quickhelp_exports);
|
|
27
|
+
var DEFAULT_BASE_URL = "https://www.cstar.help";
|
|
28
|
+
var QuickHelpClient = class {
|
|
29
|
+
constructor(config) {
|
|
30
|
+
if (!config?.teamId) {
|
|
31
|
+
throw new Error("QuickHelpClient: teamId is required");
|
|
32
|
+
}
|
|
33
|
+
this.baseUrl = (config.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
|
|
34
|
+
this.teamId = config.teamId;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Fetch the sanitized public config (title, subtitle, placeholder,
|
|
38
|
+
* theme overrides). Never includes agent id or escalation contact
|
|
39
|
+
* info — those leak only through the agent's own replies.
|
|
40
|
+
*
|
|
41
|
+
* Returns `null` if Quick Help is disabled on the team (404).
|
|
42
|
+
*/
|
|
43
|
+
async config() {
|
|
44
|
+
const url = `${this.baseUrl}/api/quickhelp/config/${encodeURIComponent(this.teamId)}`;
|
|
45
|
+
const res = await globalThis.fetch(url, { method: "GET" });
|
|
46
|
+
if (res.status === 404) return null;
|
|
47
|
+
if (!res.ok) {
|
|
48
|
+
const body2 = await res.json().catch(() => null);
|
|
49
|
+
throw new Error(body2?.error?.message ?? `Quick Help config failed: ${res.status}`);
|
|
50
|
+
}
|
|
51
|
+
const body = await res.json();
|
|
52
|
+
return body.data;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Ask a question and get an answer. On first turn, omit `sessionId`;
|
|
56
|
+
* the server mints one and you MUST pass it back on follow-ups. On
|
|
57
|
+
* rate-limit (429) the returned Error has a `retryAfterSeconds`
|
|
58
|
+
* property set from the response body.
|
|
59
|
+
*/
|
|
60
|
+
async ask(params) {
|
|
61
|
+
const url = `${this.baseUrl}/api/quickhelp/ask`;
|
|
62
|
+
const res = await globalThis.fetch(url, {
|
|
63
|
+
method: "POST",
|
|
64
|
+
headers: { "Content-Type": "application/json" },
|
|
65
|
+
body: JSON.stringify({
|
|
66
|
+
team_id: this.teamId,
|
|
67
|
+
session_id: params.sessionId ?? null,
|
|
68
|
+
question: params.question
|
|
69
|
+
})
|
|
70
|
+
});
|
|
71
|
+
const body = await res.json().catch(() => null);
|
|
72
|
+
if (!res.ok || !body?.success || !body.data) {
|
|
73
|
+
const message = body?.error?.message ?? `Quick Help ask failed: ${res.status}`;
|
|
74
|
+
const err = new QuickHelpError(message, {
|
|
75
|
+
status: res.status,
|
|
76
|
+
code: body?.error?.code,
|
|
77
|
+
retryAfterSeconds: parseRetryAfter(res.headers.get("retry-after"))
|
|
78
|
+
});
|
|
79
|
+
throw err;
|
|
80
|
+
}
|
|
81
|
+
return body.data;
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
var QuickHelpError = class extends Error {
|
|
85
|
+
constructor(message, opts) {
|
|
86
|
+
super(message);
|
|
87
|
+
this.name = "QuickHelpError";
|
|
88
|
+
this.status = opts.status;
|
|
89
|
+
this.code = opts.code;
|
|
90
|
+
this.retryAfterSeconds = opts.retryAfterSeconds;
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
function parseRetryAfter(header) {
|
|
94
|
+
if (!header) return void 0;
|
|
95
|
+
const n = Number(header);
|
|
96
|
+
return Number.isFinite(n) && n > 0 ? n : void 0;
|
|
97
|
+
}
|
|
98
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
99
|
+
0 && (module.exports = {
|
|
100
|
+
QuickHelpClient,
|
|
101
|
+
QuickHelpError
|
|
102
|
+
});
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/** Options for the QuickHelpClient. No auth — Quick Help is anonymous by design. */
|
|
2
|
+
interface QuickHelpConfig {
|
|
3
|
+
/** Your team's UUID. Required. */
|
|
4
|
+
teamId: string;
|
|
5
|
+
/** Override the base URL (defaults to https://www.cstar.help). */
|
|
6
|
+
baseUrl?: string;
|
|
7
|
+
}
|
|
8
|
+
/** Sanitized config the server returns to anonymous visitors. */
|
|
9
|
+
interface QuickHelpPublicConfig {
|
|
10
|
+
headerTitle: string;
|
|
11
|
+
headerSubtitle: string;
|
|
12
|
+
placeholderText: string;
|
|
13
|
+
theme: 'light' | 'dark' | null;
|
|
14
|
+
primaryColor: string | null;
|
|
15
|
+
fontHeading: string | null;
|
|
16
|
+
fontBody: string | null;
|
|
17
|
+
borderRadius: string | null;
|
|
18
|
+
}
|
|
19
|
+
type QuickHelpTurnOutcome = 'answered' | 'escalated' | 'needs_clarification';
|
|
20
|
+
interface QuickHelpAskParams {
|
|
21
|
+
/** The visitor's question. Max 2000 chars. */
|
|
22
|
+
question: string;
|
|
23
|
+
/**
|
|
24
|
+
* The session id from a previous `ask()` call, if this is a follow-up
|
|
25
|
+
* turn. Omit or pass null on the first turn; the server mints a new
|
|
26
|
+
* id and returns it in `sessionId`.
|
|
27
|
+
*/
|
|
28
|
+
sessionId?: string | null;
|
|
29
|
+
}
|
|
30
|
+
interface QuickHelpAskResult {
|
|
31
|
+
sessionId: string;
|
|
32
|
+
answer: string;
|
|
33
|
+
turnOutcome: QuickHelpTurnOutcome;
|
|
34
|
+
turnNumber: number;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Quick Help — anonymous AI Q&A client.
|
|
39
|
+
*
|
|
40
|
+
* No API key. No login. The Quick Help widget is the exact same product
|
|
41
|
+
* cStar's marketing site dogfoods on its homepage, just driven
|
|
42
|
+
* programmatically. Sessions live entirely in memory on the caller side;
|
|
43
|
+
* the server hands back a `sessionId` on the first turn and expects you
|
|
44
|
+
* to pass it back on follow-ups so the orchestrator can see prior
|
|
45
|
+
* transcript.
|
|
46
|
+
*
|
|
47
|
+
* ```typescript
|
|
48
|
+
* import { QuickHelpClient } from '@cstar.help/js/quickhelp';
|
|
49
|
+
*
|
|
50
|
+
* const qh = new QuickHelpClient({ teamId: 'your-team-uuid' });
|
|
51
|
+
*
|
|
52
|
+
* const turn1 = await qh.ask({ question: 'How do I reset my password?' });
|
|
53
|
+
* console.log(turn1.answer);
|
|
54
|
+
*
|
|
55
|
+
* const turn2 = await qh.ask({
|
|
56
|
+
* question: 'Can you walk me through that?',
|
|
57
|
+
* sessionId: turn1.sessionId
|
|
58
|
+
* });
|
|
59
|
+
* ```
|
|
60
|
+
*/
|
|
61
|
+
declare class QuickHelpClient {
|
|
62
|
+
private readonly baseUrl;
|
|
63
|
+
private readonly teamId;
|
|
64
|
+
constructor(config: QuickHelpConfig);
|
|
65
|
+
/**
|
|
66
|
+
* Fetch the sanitized public config (title, subtitle, placeholder,
|
|
67
|
+
* theme overrides). Never includes agent id or escalation contact
|
|
68
|
+
* info — those leak only through the agent's own replies.
|
|
69
|
+
*
|
|
70
|
+
* Returns `null` if Quick Help is disabled on the team (404).
|
|
71
|
+
*/
|
|
72
|
+
config(): Promise<QuickHelpPublicConfig | null>;
|
|
73
|
+
/**
|
|
74
|
+
* Ask a question and get an answer. On first turn, omit `sessionId`;
|
|
75
|
+
* the server mints one and you MUST pass it back on follow-ups. On
|
|
76
|
+
* rate-limit (429) the returned Error has a `retryAfterSeconds`
|
|
77
|
+
* property set from the response body.
|
|
78
|
+
*/
|
|
79
|
+
ask(params: QuickHelpAskParams): Promise<QuickHelpAskResult>;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Thrown by `QuickHelpClient.ask` when the request fails. Carries the
|
|
83
|
+
* HTTP status + error code + Retry-After (on 429) so callers can back
|
|
84
|
+
* off intelligently.
|
|
85
|
+
*/
|
|
86
|
+
declare class QuickHelpError extends Error {
|
|
87
|
+
readonly status: number;
|
|
88
|
+
readonly code?: string;
|
|
89
|
+
readonly retryAfterSeconds?: number;
|
|
90
|
+
constructor(message: string, opts: {
|
|
91
|
+
status: number;
|
|
92
|
+
code?: string;
|
|
93
|
+
retryAfterSeconds?: number;
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export { type QuickHelpAskParams, type QuickHelpAskResult, QuickHelpClient, type QuickHelpConfig, QuickHelpError, type QuickHelpPublicConfig, type QuickHelpTurnOutcome };
|