Skip to content

Commit

Permalink
Merge pull request #1081 from The-Commit-Company/1071-documentation-r…
Browse files Browse the repository at this point in the history
…equest-step-by-step-guide-for-using-raven-bot

feat: inline docs for Raven Bots
  • Loading branch information
nikkothari22 authored Oct 11, 2024
2 parents 4b39eb7 + 854c28a commit 163282d
Show file tree
Hide file tree
Showing 5 changed files with 207 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@
color: #fbbc88;
}

.tiptap pre .tiptap pre .hljs-string,
.tiptap pre .hljs-string,
.tiptap pre .hljs-symbol,
.tiptap pre .hljs-bullet {
color: #b9f18d;
Expand Down
111 changes: 111 additions & 0 deletions frontend/src/components/feature/settings/ai/bots/BotDocs.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import CodeBlock from '@/components/layout/CodeBlock'
import { Stack } from '@/components/layout/Stack'
import { RavenBot } from '@/types/RavenBot/RavenBot'
import { Code, Heading, Text } from '@radix-ui/themes'
import { useFormContext } from 'react-hook-form'

const BotDocs = () => {

const { getValues } = useFormContext<RavenBot>()

const bot_id = getValues('name')

const botVarName = bot_id.replace(/-/g, '_')

const SectionHeading = ({ children }: { children: React.ReactNode }) => {
return <Heading as='h3' size='3' className='not-cal' weight='medium'>{children}</Heading>
}

const Paragraph = ({ children }: { children: React.ReactNode }) => {
return <Text as='p' size='2' color='gray'>{children}</Text>
}

const codeSamples = {
sendMessage: `${botVarName} = frappe.get_doc("Raven Bot", "${bot_id}")
# Send a message to a channel. Text can be in HTML format.
${botVarName}.send_message(channel_id="channel-name", text="This is a test message.")`,

sendMessageInMarkdown: `${botVarName}.send_message(
channel_id="channel-name",
text="This is a test message.",
markdown=True
)`,

sendMessageWithDocumentLink: `${botVarName}.send_message(
channel_id="channel-name",
text="This is a test message.",
link_doctype="DocType",
link_document="Document Name"
)`,

sendDirectMessage: `${botVarName}.send_direct_message(
user_id="[email protected]",
text="This is a test message."
)`
}

return (
<Stack gap='3' pt='2'>
<Text as='p' size='3'>
The following code samples show how to use the bot in a Frappe app or Server Script.
</Text>
<Stack gap='0'>
<Stack gap='1'>
<SectionHeading>
Sending a message to a channel
</SectionHeading>
<Paragraph>
Bots can be used to send messages to channels with html formatted content.
</Paragraph>
</Stack>
<CodeBlock
code={codeSamples.sendMessage}
/>
</Stack>
<Stack gap='0'>
<Stack gap='1'>
<SectionHeading>
Sending a message to a channel in markdown format
</SectionHeading>
<Paragraph>
You can send markdown formatted text to a channel by setting the <Code>markdown</Code> parameter to True.
</Paragraph>
</Stack>
<CodeBlock
code={codeSamples.sendMessageInMarkdown}
/>
</Stack>

<Stack gap='0'>
<Stack gap='1'>
<SectionHeading>
Sending a message with a document link
</SectionHeading>
<Paragraph>
You can send a message with a link to any document in the system by setting the <Code>link_doctype</Code> and <Code>link_document</Code> parameters.
</Paragraph>
</Stack>
<CodeBlock
code={codeSamples.sendMessageWithDocumentLink}
/>
</Stack>
<Stack gap='0'>
<Stack gap='1'>
<SectionHeading>
Sending a direct message to a user
</SectionHeading>
<Paragraph>
You can send a direct message to a user by calling the <Code>send_direct_message</Code> method and setting the user_id parameter.
This method also accepts markdown and document link parameters.
</Paragraph>
</Stack>
<CodeBlock
code={codeSamples.sendDirectMessage}
/>
</Stack>
</Stack>
)
}

export default BotDocs
8 changes: 7 additions & 1 deletion frontend/src/components/feature/settings/ai/bots/BotForm.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { Box, Tabs } from '@radix-ui/themes'
import { LuFunctionSquare, LuSparkles } from 'react-icons/lu'
import InstructionField from '../InstructionField'
import { BiBot, BiFile } from 'react-icons/bi'
import { BiBot, BiCode, BiFile } from 'react-icons/bi'
import GeneralBotForm from './GeneralBotForm'
import AIFeaturesBotForm from './AIFeaturesBotForm'
import BotFunctionsForm from './BotFunctionsForm'
import { useFormContext } from 'react-hook-form'
import { RavenBot } from '@/types/RavenBot/RavenBot'
import BotDocs from './BotDocs'

type Props = {}

Expand All @@ -26,6 +27,7 @@ const BotForm = ({ isEdit }: { isEdit: boolean }) => {
{isAiBot ? <Tabs.Trigger value='ai'><LuSparkles {...ICON_PROPS} /> AI</Tabs.Trigger> : null}
{isAiBot ? <Tabs.Trigger value='instructions'><BiFile {...ICON_PROPS} /> Instructions</Tabs.Trigger> : null}
{isAiBot ? <Tabs.Trigger value='functions'><LuFunctionSquare {...ICON_PROPS} /> Functions</Tabs.Trigger> : null}
{isEdit ? <Tabs.Trigger value='api-docs'><BiCode {...ICON_PROPS} /> API Docs</Tabs.Trigger> : null}
</Tabs.List>
<Box pt='4'>
<Tabs.Content value='general'>
Expand All @@ -40,6 +42,10 @@ const BotForm = ({ isEdit }: { isEdit: boolean }) => {
<Tabs.Content value='functions'>
<BotFunctionsForm />
</Tabs.Content>
<Tabs.Content value='api-docs'>
<BotDocs />
</Tabs.Content>

</Box>
</Tabs.Root>
)
Expand Down
77 changes: 77 additions & 0 deletions frontend/src/components/layout/CodeBlock.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { EditorContent, useEditor } from '@tiptap/react'
import CodeBlockLowlight from '@tiptap/extension-code-block-lowlight'
import { common, createLowlight } from 'lowlight'
import python from 'highlight.js/lib/languages/python'
import css from 'highlight.js/lib/languages/css'
import js from 'highlight.js/lib/languages/javascript'
import ts from 'highlight.js/lib/languages/typescript'
import html from 'highlight.js/lib/languages/xml'
import json from 'highlight.js/lib/languages/json'
import StarterKit from '@tiptap/starter-kit'
import '@/components/feature/chat/ChatInput/tiptap.styles.css'
import { IconButton, Tooltip } from '@radix-ui/themes'
import { BiClipboard, BiCopy } from 'react-icons/bi'
import { toast } from 'sonner'

const lowlight = createLowlight(common)
lowlight.register('python', python)
lowlight.register('css', css)
lowlight.register('js', js)
lowlight.register('ts', ts)
lowlight.register('html', html)
lowlight.register('json', json)


type Props = {
code: string,
}

const CodeBlock = ({ code }: Props) => {

const editor = useEditor({
editorProps: {
attributes: {
class: 'tiptap'
}
},
editable: false,
extensions: [
StarterKit,
CodeBlockLowlight.configure({
lowlight
})
],
content: `<pre><code>${code}</code></pre>`
})

const onCopy = () => {
navigator.clipboard.writeText(code)

toast.success('Copied to clipboard', {
duration: 800
})
}

if (!editor) return null

return (
<div className='relative'>
<EditorContent editor={editor} />
<Tooltip content='Copy'>
<IconButton
variant='ghost'
size='2'
color='gray'
type='button'
className='absolute right-3 top-7 text-gray-8 hover:text-gray-1'
onClick={onCopy}
>
<BiCopy />
</IconButton>
</Tooltip>
</div>

)
}

export default CodeBlock
15 changes: 11 additions & 4 deletions raven/raven_bot/doctype/raven_bot/raven_bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,11 +249,12 @@ def send_message(
channel_id: The channel_id of the channel to send the message to
You need to provide either text or link_doctype and link_document
text: The text of the message in HTML format (markdown is not supported)
text: The text of the message in HTML format. If markdown is True, the text will be converted to HTML.
Optional:
link_doctype: The doctype of the document to link the message to
link_document: The name of the document to link the message to
markdown: If True, the text will be converted to HTML.
Returns the message ID of the message sent
"""
Expand Down Expand Up @@ -306,27 +307,33 @@ def create_direct_message_channel(self, user_id: str) -> str:
return channel.name

def send_direct_message(
self, user_id: str, text: str = None, link_doctype: str = None, link_document: str = None
self,
user_id: str,
text: str = None,
link_doctype: str = None,
link_document: str = None,
markdown: bool = False,
) -> str:
"""
Send a text message to a user in a Direct Message channel
user_id: The User's 'name' field to send the message to
You need to provide either text or link_doctype and link_document
text: The text of the message in HTML format (markdown is not supported)
text: The text of the message in HTML format. If markdown is True, the text will be converted to HTML.
Optional:
link_doctype: The doctype of the document to link the message to
link_document: The name of the document to link the message to
markdown: If True, the text will be converted to HTML.
Returns the message ID of the message sent
"""

channel_id = self.create_direct_message_channel(user_id)

if channel_id:
return self.send_message(channel_id, text, link_doctype, link_document)
return self.send_message(channel_id, text, link_doctype, link_document, markdown)

def get_last_message(self, channel_id: str = None, message_type: str = None) -> Document | None:
"""
Expand Down

0 comments on commit 163282d

Please sign in to comment.