Customization guides

Actions

Use actions to add custom behavior to the Inkeep widgets.

Actions configuration allows you to define interactive elements in your chat interface, such as help buttons, links, and forms. These actions can be triggered by users or the AI assistant.

Action Types

Open URL Action

Opens a URL in a new tab or the current window:

const urlAction: OpenUrlAction = {
  type: "open_link",
  url: "https://example.com/docs",
};

Invoke Callback Action

Executes a callback function with optional modal control:

const callbackAction: InvokeCallbackAction = {
  type: "invoke_callback",
  callback: ({ conversation }) => {
    console.log("Chat conversation:", conversation);
    // Handle callback
  },
  shouldCloseModal: true, // Optional: controls whether to close the modal after callback
};

Open Form Action

Opens a form dialog with configurable fields and success view:

const formAction: OpenFormAction = {
  type: "open_form",
  formSettings: {
    heading: "Contact Support",
    description: "Please fill out the form below",
    fields: [
      {
        name: "email",
        label: "Email Address",
        inputType: "email",
        isRequired: true,
        placeholder: "Enter your email",
      },
      {
        name: "description",
        label: "Issue Description",
        inputType: "textarea",
        isRequired: true,
        placeholder: "Describe your issue",
      },
      {
        name: "priority",
        label: "Priority Level",
        inputType: "select",
        items: [
          { label: "Low", value: "low" },
          { label: "Medium", value: "medium" },
          { label: "High", value: "high" },
        ],
        isRequired: true,
      },
    ],
    buttons: {
      submit: {
        label: "Submit Ticket",
        onSubmit: async ({ values, conversation }) => {
          // Handle form submission
          await submitTicket(values);
        },
      },
      close: {
        action: "return_to_chat",
      },
    },
    successView: {
      heading: "Ticket Submitted",
      message: "We will get back to you shortly",
      doneButton: {
        label: "Back to Chat",
        action: "return_to_chat",
      },
    },
  },
};

Help Actions

Configure help actions in the chat interface:

const helpActions: GetHelpOption[] = [
  {
    icon: { builtIn: "FaEnvelope" },
    name: "Contact Support",
    isPinnedToToolbar: true,
    action: {
      type: "open_form",
      formSettings: {
        heading: "Contact Support",
        description: "How can we help you today?",
        fields: [
          {
            name: "email",
            label: "Email",
            inputType: "email",
            isRequired: true,
          },
          {
            name: "message",
            label: "Message",
            inputType: "textarea",
            isRequired: true,
          },
          {
            _type: "include_chat_session",
            label: "Include chat history",
            defaultValue: true,
          },
        ],
        buttons: {
          submit: {
            label: "Send Message",
            onSubmit: async ({ values, conversation }) => {
              await sendSupportRequest(values);
            },
          },
        },
        successView: {
          heading: "Message Sent",
          message: "We will respond to your email shortly",
          doneButton: {
            label: "Continue Chatting",
            action: "return_to_chat",
          },
        },
      },
    },
  },
  {
    icon: { builtIn: "FaDiscord" },
    name: "Join Discord",
    action: {
      type: "open_link",
      url: "https://discord.gg/example",
    },
  },
];

FormSettings Reference

The FormSettings interface provides a comprehensive way to configure forms in your chat interface, through the open_form action type. Here's a detailed breakdown of all available options:

Basic Properties

PropertyTypeRequiredDescription
headingstringNoThe form's title displayed at the top
descriptionstringNoExplanatory text shown below the heading
fieldsFormField[]YesArray of form field configurations
buttonsFormButtonsYesConfiguration for form action buttons
successViewSuccessViewYesConfiguration for the success confirmation page

Field Types

Forms support various field types through the FormField union type:

Base Field Properties

All field types inherit these base properties:

PropertyTypeRequiredDescription
namestringYesUnique identifier for the field
labelstringYesDisplay label for the field
isRequiredbooleanNoWhether the field is required
isHiddenbooleanNoWhether to hide the field
descriptionstringNoHelp text shown below the field

Text Field

{
  name: 'name',
  label: 'Full Name',
  inputType: 'text',
  defaultValue?: string,
  placeholder?: string
}

Email Field

{
  name: 'email',
  label: 'Email Address',
  inputType: 'email',
  defaultValue?: string,
  placeholder?: string
}

Textarea Field

{
  name: 'description',
  label: 'Description',
  inputType: 'textarea',
  defaultValue?: string,
  placeholder?: string
}

Checkbox Field

{
  name: 'subscribe',
  label: 'Subscribe to newsletter',
  inputType: 'checkbox',
  defaultValue?: boolean
}

Select Field

{
  name: 'category',
  label: 'Category',
  inputType: 'select',
  items: [
    { label: 'Option 1', value: 'opt1' },
    { label: 'Option 2', value: 'opt2' }
  ],
  defaultValue?: string,
  placeholder?: string
}

File Field

{
  name: 'attachment',
  label: 'Attach File',
  inputType: 'file'
}

When using a file field in your form, you may need to convert the files to Base64 before sending to your backend or an external API, this can be done by using the following snippet.

function convertFilesToBase64(files: FileList) {
  const filesArray = Array.from(files);
  return Promise.all(
    filesArray.map((file) => {
      return new Promise((resolve, reject) => {
        const reader = new FileReader();
        reader.onload = (event) => {
          const result = (event.target as FileReader).result;
          const base64Data = result.replace(/^data:.+;base64,/, "");
          resolve({
            data: base64Data,
            fileName: file.name,
            mimeType: file.type,
          });
        };
        reader.onerror = (error) => reject(error);
        reader.readAsDataURL(file);
      });
    })
  );
}

Include Chat Session Field

Special field type to include chat history:

{
  _type: 'include_chat_session',
  label?: string, // Defaults to "Include chat history"
  defaultValue?: boolean,
  isHidden?: boolean
}

Button Configuration

The buttons property requires configuration for submit and optional close buttons:

{
  buttons: {
    submit: {
      label?: string, // Optional custom label
      onSubmit: async ({ values, conversation }) => {
        // Handle form submission
        // values: Record<string, any> - form field values
        // conversation: ConversationResponse | null
      }
    },
    close?: {
      action: 'return_to_chat' | 'close_modal'
    }
  }
}

Success View Configuration

The successView property configures what's shown after successful submission:

{
  successView: {
    heading: string,    // Success message heading
    message: string,    // Detailed success message
    doneButton: {
      label: string,    // Button text
      icon?: InkeepCustomIcon,  // Optional icon
      action: 'return_to_chat' | 'close_modal'
    }
  }
}

Complete Example

Here's a comprehensive example showing all available configurations:

const formSettings: FormSettings = {
  heading: "Submit Support Request",
  description: "Please provide details about your issue",
  fields: [
    {
      name: "name",
      label: "Full Name",
      inputType: "text",
      isRequired: true,
      placeholder: "John Doe",
      description: "Enter your full name as it appears on your account",
    },
    {
      name: "email",
      label: "Email Address",
      inputType: "email",
      isRequired: true,
      placeholder: "john@example.com",
    },
    {
      name: "priority",
      label: "Priority Level",
      inputType: "select",
      isRequired: true,
      items: [
        { label: "Low", value: "low" },
        { label: "Medium", value: "medium" },
        { label: "High", value: "high" },
      ],
      description: "Select the urgency of your request",
    },
    {
      name: "description",
      label: "Issue Description",
      inputType: "textarea",
      isRequired: true,
      placeholder: "Please describe your issue in detail...",
    },
    {
      name: "terms",
      label: "I agree to the terms of service",
      inputType: "checkbox",
      isRequired: true,
    },
    {
      name: "attachments",
      label: "Attachments",
      inputType: "file",
      description: "Attach any relevant screenshots or files",
    },
    {
      _type: "include_chat_session",
      label: "Include our conversation history",
      defaultValue: true,
    },
  ],
  buttons: {
    submit: {
      label: "Submit Request",
      onSubmit: async ({ values, conversation }) => {
        try {
          // Handle file conversion if needed
          if (values.attachments) {
            values.attachments = await convertFilesToBase64(values.attachments);
          }
 
          // Submit the form data
          await submitSupportRequest({
            ...values,
            chat_history: conversation?.messages,
          });
        } catch (error) {
          throw new Error("Failed to submit support request");
        }
      },
    },
    close: {
      action: "return_to_chat",
    },
  },
  successView: {
    heading: "Request Submitted Successfully",
    message:
      "We have received your support request and will respond within 24 hours.",
    doneButton: {
      label: "Return to Chat",
      icon: { builtIn: "FaArrowLeft" },
      action: "return_to_chat",
    },
  },
};