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:
Peer Richelsen
2024-04-04 11:57:43 +00:00
committed by GitHub
co-authored by Udit Takkar Udit Takkar
parent 99f9a121cb
commit a8d8c992a4
10 changed files with 96 additions and 8 deletions
@@ -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;
+3 -1
View File
@@ -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?
+6
View File
@@ -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);