chore: added email and company form to cal.ai form (#14306)
* added email and company form * i18n * feat: add guest email and company * chore: update and format prompt * chore: hint var * chore: fix err message --------- Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com> Co-authored-by: Udit Takkar <udit222001@gmail.com>
This commit is contained in:
co-authored by
Udit Takkar
Udit Takkar
parent
99f9a121cb
commit
a8d8c992a4
@@ -190,12 +190,28 @@ const AISettings = ({ eventType }: { eventType: EventTypeSetup }) => {
|
||||
|
||||
<TextField
|
||||
type="text"
|
||||
hint="Variable: {name}"
|
||||
hint="Variable: {{name}}"
|
||||
label={t("guest_name")}
|
||||
placeholder="Jane Doe"
|
||||
{...formMethods.register("aiPhoneCallConfig.guestName")}
|
||||
/>
|
||||
|
||||
<TextField
|
||||
type="text"
|
||||
hint="Variable: {{email}}"
|
||||
label={t("guest_email")}
|
||||
placeholder="jane@acme.com"
|
||||
{...formMethods.register("aiPhoneCallConfig.guestEmail")}
|
||||
/>
|
||||
|
||||
<TextField
|
||||
type="text"
|
||||
hint="Variable: {{company}}"
|
||||
label={t("guest_company")}
|
||||
placeholder="Acme"
|
||||
{...formMethods.register("aiPhoneCallConfig.guestCompany")}
|
||||
/>
|
||||
|
||||
<TextField
|
||||
type="text"
|
||||
hint="For eg:- cal_live_0123.."
|
||||
|
||||
@@ -34,10 +34,41 @@ import { EventTypeSingleLayout } from "@components/eventtype/EventTypeSingleLayo
|
||||
|
||||
import { type PageProps } from "~/event-types/views/event-types-single-view.getServerSideProps";
|
||||
|
||||
const DEFAULT_PROMPT_VALUE =
|
||||
"## You are helping user set up a call with the support team. The appointment is 15 min long. You are a pleasant and friendly.\n\n## Style Guardrails\nBe Concise: Respond succinctly, addressing one topic at most.\nEmbrace Variety: Use diverse language and rephrasing to enhance clarity without repeating content.\nBe Conversational: Use everyday language, making the chat feel like talking to a friend.\nBe Proactive: Lead the conversation, often wrapping up with a question or next-step suggestion.\nAvoid multiple questions in a single response.\nGet clarity: If the user only partially answers a question, or if the answer is unclear, keep asking to get clarity.\nUse a colloquial way of referring to the date (like Friday, Jan 14th, or Tuesday, Jan 12th, 2024 at 8am).\nIf you are saying a time like 8:00 AM, just say 8 AM and emit the trailing zeros.\n\n## Response Guideline\nAdapt and Guess: Try to understand transcripts that may contain transcription errors. Avoid mentioning \"transcription error\" in the response.\nStay in Character: Keep conversations within your role'''s scope, guiding them back creatively without repeating.\nEnsure Fluid Dialogue: Respond in a role-appropriate, direct manner to maintain a smooth conversation flow.\n\n## Schedule Rule\nCurrent time is {{current_time}}. You only schedule time in current calendar year, you cannot schedule time that'''s in the past.\n\n## Task Steps\n1. I am here to learn more about your issue and help schedule an appointment with our support team.\n2. Ask for user name and email. Confirm the name and email with user by reading it back to user.\n3. Ask user for \"When would you want to meet with one of our representive\".\n4. Call function check_availability to check for availability in the user provided time range.\n - if availability exists, inform user about the availability range (do not repeat the detailed available slot) and ask user to choose from it. Make sure user chose a slot within detailed available slot.\n - if availability does not exist, ask user to select another time range for the appointment, repeat this step 3.\n4. Confirm the date and time selected by user: \"Just to confirm, you want to book the appointment at ...\".\n6. Once confirmed, call function book_appointment to book the appointment.\n - if booking returned booking detail, it means booking is successful, proceed to step 7.\n - if booking returned error message, let user know why the booking was not successful, and maybe start over with step 3.\n7. Inform the user booking is successful, and ask if user have any questions. Answer them if there are any.\n8. After all questions answered, call function end_call to hang up.";
|
||||
const DEFAULT_PROMPT_VALUE = `## You are helping user set up a call with the support team. The appointment is 15 min long. You are a pleasant and friendly.
|
||||
|
||||
const DEFAULT_BEGIN_MESSAGE = "Hi. How are you doing?";
|
||||
## Style Guardrails
|
||||
Be Concise: Respond succinctly, addressing one topic at most.
|
||||
Embrace Variety: Use diverse language and rephrasing to enhance clarity without repeating content.
|
||||
Be Conversational: Use everyday language, making the chat feel like talking to a friend.
|
||||
Be Proactive: Lead the conversation, often wrapping up with a question or next-step suggestion.
|
||||
Avoid multiple questions in a single response.
|
||||
Get clarity: If the user only partially answers a question, or if the answer is unclear, keep asking to get clarity.
|
||||
Use a colloquial way of referring to the date (like Friday, Jan 14th, or Tuesday, Jan 12th, 2024 at 8am).
|
||||
If you are saying a time like 8:00 AM, just say 8 AM and emit the trailing zeros.
|
||||
|
||||
## Response Guideline
|
||||
Adapt and Guess: Try to understand transcripts that may contain transcription errors. Avoid mentioning \"transcription error\" in the response.
|
||||
Stay in Character: Keep conversations within your role'''s scope, guiding them back creatively without repeating.
|
||||
Ensure Fluid Dialogue: Respond in a role-appropriate, direct manner to maintain a smooth conversation flow.
|
||||
|
||||
## Schedule Rule
|
||||
Current time is {{current_time}}. You only schedule time in current calendar year, you cannot schedule time that'''s in the past.
|
||||
|
||||
## Task Steps
|
||||
1. I am here to learn more about your issue and help schedule an appointment with our support team.
|
||||
2. Use name {{name}} and email {{email}} for creating booking.
|
||||
3. Ask user for \"When would you want to meet with one of our representive\".
|
||||
4. Call function check_availability to check for availability in the user provided time range.
|
||||
- if availability exists, inform user about the availability range (do not repeat the detailed available slot) and ask user to choose from it. Make sure user chose a slot within detailed available slot.
|
||||
- if availability does not exist, ask user to select another time range for the appointment, repeat this step 3.
|
||||
5. Confirm the date and time selected by user: \"Just to confirm, you want to book the appointment at ...\".
|
||||
6. Once confirmed, call function book_appointment to book the appointment.
|
||||
- if booking returned booking detail, it means booking is successful, proceed to step 7.
|
||||
- if booking returned error message, let user know why the booking was not successful, and maybe start over with step 3.
|
||||
7. Inform the user booking is successful, and ask if user have any questions. Answer them if there are any.
|
||||
8. After all questions answered, call function end_call to hang up.`;
|
||||
|
||||
const DEFAULT_BEGIN_MESSAGE = "Hi {{name}} from {{company}}. How are you doing?";
|
||||
|
||||
// These can't really be moved into calcom/ui due to the fact they use infered getserverside props typings;
|
||||
const EventSetupTab = dynamic(() =>
|
||||
@@ -256,6 +287,8 @@ const EventTypePage = (props: EventTypeSetupProps) => {
|
||||
enabled: eventType.aiPhoneCallConfig?.enabled,
|
||||
beginMessage: eventType.aiPhoneCallConfig?.beginMessage ?? DEFAULT_BEGIN_MESSAGE,
|
||||
guestName: eventType.aiPhoneCallConfig?.guestName,
|
||||
guestEmail: eventType.aiPhoneCallConfig?.guestEmail,
|
||||
guestCompany: eventType.aiPhoneCallConfig?.guestCompany,
|
||||
yourPhoneNumber: eventType.aiPhoneCallConfig?.yourPhoneNumber,
|
||||
numberToCall: eventType.aiPhoneCallConfig?.numberToCall,
|
||||
},
|
||||
|
||||
@@ -2256,6 +2256,8 @@
|
||||
"troubleshooter": "Troubleshooter",
|
||||
"number_to_call": "Number to Call",
|
||||
"guest_name": "Guest Name",
|
||||
"guest_email": "Guest Email",
|
||||
"guest_company": "Guest Company",
|
||||
"please_install_a_calendar": "Please install a calendar",
|
||||
"instant_tab_title": "Instant Booking",
|
||||
"instant_event_tab_description": "Let people book immediately",
|
||||
|
||||
@@ -65,6 +65,8 @@ export type FormValues = {
|
||||
yourPhoneNumber: string;
|
||||
numberToCall: string;
|
||||
guestName: string;
|
||||
guestEmail: string;
|
||||
guestCompany: string;
|
||||
};
|
||||
customInputs: CustomInputParsed[];
|
||||
schedule: number | null;
|
||||
|
||||
@@ -53,6 +53,8 @@ export type Event = {
|
||||
yourPhoneNumber: string;
|
||||
numberToCall: string;
|
||||
guestName: string;
|
||||
guestEmail: string;
|
||||
guestCompany: string;
|
||||
};
|
||||
schedulingType: string;
|
||||
length: number;
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
/*
|
||||
Warnings:
|
||||
|
||||
- Added the required column `guestCompany` to the `AIPhoneCallConfiguration` table without a default value. This is not possible if the table is not empty.
|
||||
- Added the required column `guestEmail` to the `AIPhoneCallConfiguration` table without a default value. This is not possible if the table is not empty.
|
||||
|
||||
*/
|
||||
-- AlterTable
|
||||
ALTER TABLE "AIPhoneCallConfiguration" ADD COLUMN "guestCompany" TEXT NOT NULL,
|
||||
ADD COLUMN "guestEmail" TEXT NOT NULL;
|
||||
@@ -396,7 +396,7 @@ model OrganizationSettings {
|
||||
isOrganizationVerified Boolean @default(false)
|
||||
orgAutoAcceptEmail String
|
||||
lockEventTypeCreationForUsers Boolean @default(false)
|
||||
// It decides if instance ADMIN has reviewed the organization or not.
|
||||
// It decides if instance ADMIN has reviewed the organization or not.
|
||||
// It is used to allow super sensitive operations like 'impersonation of Org members by Org admin'
|
||||
isAdminReviewed Boolean @default(false)
|
||||
dSyncData DSyncData?
|
||||
@@ -919,6 +919,8 @@ model AIPhoneCallConfiguration {
|
||||
yourPhoneNumber String
|
||||
numberToCall String
|
||||
guestName String
|
||||
guestEmail String
|
||||
guestCompany String
|
||||
enabled Boolean @default(false)
|
||||
beginMessage String?
|
||||
llmId String?
|
||||
|
||||
@@ -702,6 +702,12 @@ export const AIPhoneSettingSchema = z.object({
|
||||
guestName: z.string().trim().min(1, {
|
||||
message: "Please enter Guest Name",
|
||||
}),
|
||||
guestEmail: z.string().trim().email().min(1, {
|
||||
message: "Please enter Guest Email",
|
||||
}),
|
||||
guestCompany: z.string().trim().min(1, {
|
||||
message: "Please enter Guest Company",
|
||||
}),
|
||||
generalPrompt: z.string().trim().min(1, {
|
||||
message: "Please enter prompt",
|
||||
}),
|
||||
|
||||
@@ -16,6 +16,8 @@ export const EventTypeUpdateInput = _EventTypeModel
|
||||
yourPhoneNumber: z.string().default(""),
|
||||
numberToCall: z.string().default(""),
|
||||
guestName: z.string().default(""),
|
||||
guestEmail: z.string().default(""),
|
||||
guestCompany: z.string().default(""),
|
||||
})
|
||||
.optional(),
|
||||
calAiPhoneScript: z.string().optional(),
|
||||
|
||||
@@ -60,8 +60,17 @@ const createPhoneCallHandler = async ({ input, ctx }: CreatePhoneCallProps) => {
|
||||
identifier: `createPhoneCall:${ctx.user.id}`,
|
||||
});
|
||||
|
||||
const { yourPhoneNumber, numberToCall, guestName, eventTypeId, beginMessage, generalPrompt, calApiKey } =
|
||||
input;
|
||||
const {
|
||||
yourPhoneNumber,
|
||||
numberToCall,
|
||||
guestName,
|
||||
guestEmail,
|
||||
guestCompany,
|
||||
eventTypeId,
|
||||
beginMessage,
|
||||
generalPrompt,
|
||||
calApiKey,
|
||||
} = input;
|
||||
|
||||
const aiPhoneCallConfig = await ctx.prisma.aIPhoneCallConfiguration.upsert({
|
||||
where: {
|
||||
@@ -72,6 +81,8 @@ const createPhoneCallHandler = async ({ input, ctx }: CreatePhoneCallProps) => {
|
||||
generalPrompt,
|
||||
enabled: true,
|
||||
guestName,
|
||||
guestEmail,
|
||||
guestCompany,
|
||||
numberToCall,
|
||||
yourPhoneNumber,
|
||||
},
|
||||
@@ -81,6 +92,8 @@ const createPhoneCallHandler = async ({ input, ctx }: CreatePhoneCallProps) => {
|
||||
generalPrompt,
|
||||
enabled: true,
|
||||
guestName,
|
||||
guestEmail,
|
||||
guestCompany,
|
||||
numberToCall,
|
||||
yourPhoneNumber,
|
||||
},
|
||||
@@ -169,7 +182,7 @@ const createPhoneCallHandler = async ({ input, ctx }: CreatePhoneCallProps) => {
|
||||
body: JSON.stringify({
|
||||
from_number: yourPhoneNumber,
|
||||
to_number: numberToCall,
|
||||
retell_llm_dynamic_variables: { name: guestName },
|
||||
retell_llm_dynamic_variables: { name: guestName, company: guestCompany, email: guestEmail },
|
||||
}),
|
||||
}).then(createPhoneSchema.parse);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user