Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
93 commits
Select commit Hold shift + click to select a range
a24e3fc
Merge pull request #1588 from The-Commit-Company/develop
nikkothari22 Apr 5, 2025
732c5bb
fix: lower case repo name for docker build
nikkothari22 Apr 5, 2025
fba191f
Release Version 2.2.1
nikkothari22 Apr 11, 2025
76eba71
Release v2.2.2 (#1613)
nikkothari22 Apr 13, 2025
3bc8b96
Merge branch 'develop'
nikkothari22 Apr 13, 2025
81be2e6
Merge pull request #1635 from The-Commit-Company/develop
nikkothari22 Apr 20, 2025
44d859a
Merge pull request #1658 from The-Commit-Company/develop
nikkothari22 May 2, 2025
df32a09
Merge pull request #1661 from The-Commit-Company/develop
nikkothari22 May 2, 2025
0cb112c
Merge branch 'develop'
nikkothari22 May 2, 2025
7315590
Merge pull request #1663 from The-Commit-Company/develop
nikkothari22 May 3, 2025
deeaf01
Merge pull request #1668 from The-Commit-Company/develop
nikkothari22 May 6, 2025
118a9b9
Merge pull request #1674 from The-Commit-Company/develop
nikkothari22 May 7, 2025
d4f59fe
Merge pull request #1686 from The-Commit-Company/develop
nikkothari22 May 15, 2025
bb45148
Release v2.3.0 (#1690)
nikkothari22 May 18, 2025
939333a
Merge pull request #1691 from The-Commit-Company/develop
nikkothari22 May 18, 2025
cb8b9de
Merge pull request #1695 from The-Commit-Company/develop
nikkothari22 May 20, 2025
2bfa5f9
Merge branch 'develop'
nikkothari22 May 20, 2025
1b86b13
Merge pull request #1709 from The-Commit-Company/develop
nikkothari22 May 23, 2025
56a5f54
Merge pull request #1720 from The-Commit-Company/develop
nikkothari22 May 30, 2025
de2afb5
Release v2.5.0
nikkothari22 Jun 1, 2025
3c89058
Merge pull request #1736 from The-Commit-Company/develop
nikkothari22 Jun 13, 2025
2d151cc
Merge pull request #1738 from The-Commit-Company/develop
nikkothari22 Jun 13, 2025
3c61c87
Merge pull request #1746 from The-Commit-Company/develop
nikkothari22 Jun 20, 2025
85d2161
Merge pull request #1748 from The-Commit-Company/develop
nikkothari22 Jun 22, 2025
eec2691
Merge branch 'develop'
nikkothari22 Jun 22, 2025
0a4941a
Merge pull request #1764 from The-Commit-Company/develop
nikkothari22 Jun 30, 2025
c70b282
Merge pull request #1772 from The-Commit-Company/develop
nikkothari22 Jul 4, 2025
a775da3
Merge pull request #1781 from The-Commit-Company/develop
nikkothari22 Jul 10, 2025
2b59a25
Merge pull request #1821 from The-Commit-Company/develop
nikkothari22 Aug 14, 2025
67a60de
Merge branch 'develop'
nikkothari22 Aug 20, 2025
c7bd332
Merge pull request #1847 from The-Commit-Company/develop
nikkothari22 Sep 15, 2025
8042b6f
Release v2.6.3 (#1869)
nikkothari22 Oct 1, 2025
1205900
Merge pull request #1871 from The-Commit-Company/develop
nikkothari22 Oct 1, 2025
aa3b929
Release v2.6.4 (#1874)
nikkothari22 Oct 1, 2025
2cdf429
Merge pull request #1899 from The-Commit-Company/develop
nikkothari22 Oct 31, 2025
2309813
Merge pull request from The-Commit-Company/develop (#1944)
prathameshkurunkar7 Dec 18, 2025
db14e16
Merge pull request #1949 from The-Commit-Company/develop
nikkothari22 Dec 27, 2025
766d359
Merge pull request #1972 from The-Commit-Company/develop
nikkothari22 Jan 8, 2026
2304d5f
Merge pull request #1977 from The-Commit-Company/develop
nikkothari22 Jan 9, 2026
dfde9b1
Merge pull request #1982 from The-Commit-Company/develop
nikkothari22 Jan 11, 2026
b419e86
Merge pull request #2013 from The-Commit-Company/develop
nikkothari22 Jan 31, 2026
bea0ef5
Merge branch 'develop'
nikkothari22 Jan 31, 2026
f8b345f
Merge pull request #2017 from The-Commit-Company/develop
nikkothari22 Feb 1, 2026
ec4f03c
Merge pull request #2018 from The-Commit-Company/develop
nikkothari22 Feb 1, 2026
0fe8fd0
Merge branch 'develop'
nikkothari22 Feb 1, 2026
f999d91
Merge branch 'develop'
nikkothari22 Feb 3, 2026
2ba9e9a
Merge pull request #2023 from The-Commit-Company/develop
nikkothari22 Feb 4, 2026
d2c20ed
Merge pull request #2027 from The-Commit-Company/develop
nikkothari22 Feb 5, 2026
938a6b7
Merge pull request #2032 from The-Commit-Company/develop
nikkothari22 Feb 6, 2026
56b1d31
Merge branch 'develop'
nikkothari22 Feb 12, 2026
d147777
Merge pull request #2038 from The-Commit-Company/develop
nikkothari22 Feb 12, 2026
9ef458d
Release v2.8.6 (#2069)
nikkothari22 Mar 12, 2026
d05359d
Merge pull request #2072 from The-Commit-Company/develop
nikkothari22 Mar 12, 2026
b3b67e4
Merge pull request #2080 from The-Commit-Company/develop
nikkothari22 Mar 18, 2026
460e2ab
fix: broken remove channel member logic (#2084) (#2089)
nikkothari22 Mar 24, 2026
b87e410
Merge pull request #2090 from The-Commit-Company/develop
nikkothari22 Mar 24, 2026
b92ce61
Merge pull request #2094 from The-Commit-Company/develop
prathameshkurunkar7 Mar 28, 2026
3a99cdc
Merge pull request #2096 from The-Commit-Company/develop
prathameshkurunkar7 Mar 28, 2026
7b7147c
Merge pull request #2099 from The-Commit-Company/develop
prathameshkurunkar7 Mar 30, 2026
f43c6ad
feat: add required changes
pipech Apr 6, 2026
bca15c6
feat: add channel name fix
pipech Apr 9, 2026
185c7cf
feat: add omni channel chat
pipech Apr 19, 2026
3a8f6ec
refactor: remove async io
pipech Apr 19, 2026
3f433af
refactor: convert webhook handler into class
pipech Apr 19, 2026
c8305ba
fix: rename webhook handler
pipech Apr 19, 2026
d5c26d4
refactor: improve gate
pipech Apr 19, 2026
f7251d4
refactor: update connector
pipech Apr 19, 2026
f104e49
refactor: rename class name
pipech Apr 19, 2026
4b79c82
refactor: move webhook handler into provider
pipech Apr 20, 2026
2cd8342
feat: add file and image inbound support
pipech Apr 20, 2026
2deefb5
feat: add file and image handler
pipech Apr 20, 2026
bf1fc1c
feat: add field to workspace
pipech Apr 20, 2026
eed04ff
feat: update omni channel ui
pipech Apr 20, 2026
5d62552
feat: add instagram integration
pipech Apr 20, 2026
733a669
refactor: update webhook interface
pipech Apr 20, 2026
9f0dd16
refactor: add standardize data class
pipech Apr 20, 2026
179b6f5
refactor: update msg object
pipech Apr 20, 2026
691d743
refactor: msg object
pipech Apr 21, 2026
5273fb4
fix: remove blank provider
pipech Apr 21, 2026
e40a6ac
refactor: remove instagram, it hasn't been test yet
pipech Apr 21, 2026
b1d733d
fix: json error on omni channel chat provider
pipech Apr 21, 2026
2dd7def
refactor: change to generic type
pipech Apr 21, 2026
6089fb2
fix: update msg interface
pipech Apr 21, 2026
a4d1445
refactor: message
pipech Apr 21, 2026
b7ef547
refactor: webhook handler
pipech Apr 21, 2026
f72fd08
refactor: minor cleanup
pipech Apr 21, 2026
e4a90c6
docs: add readme
pipech Apr 21, 2026
0fdd782
refactor: container
pipech Apr 21, 2026
ff910b3
refactor: connector func name
pipech Apr 22, 2026
80889c6
feat: support group chat
pipech Apr 22, 2026
b74728b
feat: support line group
pipech Apr 22, 2026
5d58560
fix: ui logic
pipech Apr 22, 2026
aa41c88
fix: channel creation method
pipech Apr 22, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 53 additions & 12 deletions frontend/src/components/feature/chat-header/ChannelHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,42 @@ import { PageHeader } from "@/components/layout/Heading/PageHeader"
import { ChannelIcon } from "@/utils/layout/channelIcon"
import { ChannelListItem } from "@/utils/channel/ChannelListProvider"
import { EditChannelNameButton } from "../channel-details/rename-channel/EditChannelNameButton"
import { Flex, Heading } from "@radix-ui/themes"
import { Flex, Heading, Text } from "@radix-ui/themes"
import ChannelHeaderMenu from "./ChannelHeaderMenu"
import { ViewChannelMemberAvatars } from "./ViewChannelMemberAvatars"
import { BiChevronLeft } from "react-icons/bi"
import { Link } from "react-router-dom"
import { ViewPinnedMessagesButton } from "../pinned-messages/ViewPinnedMessagesButton"
import { useAtomValue } from "jotai"
import { lastWorkspaceAtom } from "@/utils/lastVisitedAtoms"
import { useContext, useMemo } from "react"
import { UserListContext } from "@/utils/users/UserListProvider"
import { UserAvatar } from "@/components/common/UserAvatar"
import { FaFacebook, FaLine } from "react-icons/fa"

const PROVIDER_ICONS: Record<string, React.ReactNode> = {
line: <FaLine className='text-[#06C755]' />,
facebook: <FaFacebook className='text-[#1877F2]' />,
}

interface ChannelHeaderProps {
channelData: ChannelListItem
}

export const ChannelHeader = ({ channelData }: ChannelHeaderProps) => {

// The channel header has the channel name, the channel type icon, edit channel name button, and the view or add members button

const lastWorkspace = useAtomValue(lastWorkspaceAtom)
const { users } = useContext(UserListContext)

const customerUser = useMemo(
() => users.find(u => u.name === channelData.omni_channel_raven_user),
[users, channelData.omni_channel_raven_user]
)

const isOmniChannel = !!channelData.omni_channel_raven_user
const displayName = customerUser?.full_name ?? channelData.channel_name
const providerIcon = channelData.omni_channel_provider ? PROVIDER_ICONS[channelData.omni_channel_provider] : null
const providerDisplayName = channelData.omni_channel_display_name ?? channelData.omni_channel_chat_provider

return (
<PageHeader>
Expand All @@ -28,15 +46,38 @@ export const ChannelHeader = ({ channelData }: ChannelHeaderProps) => {
<BiChevronLeft size='24' className="block text-gray-12" />
</Link>
<Flex gap='4' align={'center'} className="group animate-fadein pr-4">
<Flex gap='1' align={'center'}>
<ChannelIcon type={channelData.type} size='18' />
<Heading
size={{
initial: '4',
sm: '5'
}}
className="mb-0.5 text-ellipsis line-clamp-1">{channelData.channel_name}</Heading>
</Flex>
{isOmniChannel ? (
<Flex gap='2' align='center'>
<UserAvatar
src={customerUser?.user_image}
alt={displayName}
size='2'
/>
<Heading
size={{ initial: '4', sm: '5' }}
className="mb-0.5 text-ellipsis line-clamp-1"
>
{displayName}
</Heading>
{providerDisplayName && (
<>
<Text color='gray' size='4'>|</Text>
{providerIcon && <span className='flex items-center text-base'>{providerIcon}</span>}
<Text size='3' color='gray' className='text-ellipsis line-clamp-1'>{providerDisplayName}</Text>
</>
)}
</Flex>
) : (
<Flex gap='1' align={'center'}>
<ChannelIcon type={channelData.type} size='18' />
<Heading
size={{
initial: '4',
sm: '5'
}}
className="mb-0.5 text-ellipsis line-clamp-1">{channelData.channel_name}</Heading>
</Flex>
)}
<EditChannelNameButton channelID={channelData.name} channel_name={channelData.channel_name} channelType={channelData.type} disabled={channelData.is_archived == 1} buttonVisible={!!channelData.pinned_messages_string} />
<ViewPinnedMessagesButton pinnedMessagesString={channelData.pinned_messages_string ?? ''} />
</Flex>
Expand Down
170 changes: 170 additions & 0 deletions frontend/src/components/layout/Sidebar/OmniChannelSidebarBody.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
import { useContext, useLayoutEffect, useMemo, useRef, useState } from 'react'
import { useParams } from 'react-router-dom'
import { Flex, ScrollArea, Text } from '@radix-ui/themes'
import { ChannelListContext, ChannelListContextType, ChannelListItem } from '@/utils/channel/ChannelListProvider'
import {
SidebarBadge,
SidebarGroup,
SidebarGroupItem,
SidebarGroupLabel,
SidebarGroupList,
SidebarIcon,
SidebarItem,
SidebarViewMoreButton,
} from './SidebarComp'
import { UserListContext } from '@/utils/users/UserListProvider'
import { UserAvatar } from '@/components/common/UserAvatar'
import { useFetchUnreadMessageCount } from '@/hooks/useUnreadMessageCount'
import { useStickyState } from '@/hooks/useStickyState'
import { __ } from '@/utils/translations'
import { FaFacebook, FaLine } from 'react-icons/fa'

type OmniChannelItem = ChannelListItem & { unread_count: number }

interface ProviderGroup {
provider?: string
channels: OmniChannelItem[]
}

const PROVIDER_ICONS: Record<string, React.ReactNode> = {
line: <FaLine className='text-[#06C755]' />,
facebook: <FaFacebook className='text-[#1877F2]' />,
}

export const OmniChannelSidebarBody = () => {
const { channels } = useContext(ChannelListContext) as ChannelListContextType
const { workspaceID } = useParams()
const unread_count = useFetchUnreadMessageCount()

const channelsWithUnread = useMemo(() => {
const workspaceChannels = channels.filter(c => c.workspace === workspaceID && !c.is_archived)
return workspaceChannels.map(c => ({
...c,
unread_count: unread_count?.message?.find(u => u.name === c.name)?.unread_count ?? 0,
})) as OmniChannelItem[]
}, [channels, workspaceID, unread_count])

const unreadChannels = useMemo(() => channelsWithUnread.filter(c => c.unread_count > 0), [channelsWithUnread])

const groupedChannels = useMemo(() => {
const groups: Record<string, ProviderGroup> = {}
channelsWithUnread.forEach(c => {
const key = c.omni_channel_display_name ?? c.omni_channel_chat_provider ?? 'Other'
if (!groups[key]) groups[key] = { provider: c.omni_channel_provider, channels: [] }
groups[key].channels.push(c)
})
return groups
}, [channelsWithUnread])

return (
<ScrollArea type="hover" scrollbars="vertical" className='h-[calc(100vh-4rem)]'>
<Flex direction='column' gap='2' className='overflow-x-hidden pb-12 sm:pb-0' px='2'>
{unreadChannels.length > 0 && (
<OmniProviderGroup
label={__("Unread")}
channels={unreadChannels}
storageKey="omni_unread"
showProvider
/>
)}
{Object.entries(groupedChannels).map(([label, group]) => (
<OmniProviderGroup
key={label}
label={label}
channels={group.channels}
provider={group.provider}
storageKey={`omni_provider_${label}`}
/>
))}
</Flex>
</ScrollArea>
)
}

interface OmniProviderGroupProps {
label: string
channels: OmniChannelItem[]
storageKey: string
provider?: string
showProvider?: boolean
}

const OmniProviderGroup = ({ label, channels, storageKey, provider, showProvider }: OmniProviderGroupProps) => {
const [showData, setShowData] = useStickyState(true, storageKey)
const toggle = () => setShowData((d: boolean) => !d)

const ref = useRef<HTMLDivElement>(null)
const [height, setHeight] = useState(ref?.current?.clientHeight ?? (showData ? channels.length * 44 : 0))

useLayoutEffect(() => {
setHeight(ref.current?.clientHeight ?? 0)
}, [channels])

const icon = provider ? PROVIDER_ICONS[provider] : null

return (
<SidebarGroup>
<SidebarGroupItem className='gap-1 pl-1'>
<Flex width='100%' justify='between' align='center' gap='2' pr='2' className='group'>
<Flex align='center' gap='2' width='100%' onClick={toggle} className='cursor-default select-none'>
{icon && <span className='flex items-center text-base'>{icon}</span>}
<SidebarGroupLabel>{label}</SidebarGroupLabel>
</Flex>
<SidebarViewMoreButton onClick={toggle} expanded={showData} />
</Flex>
</SidebarGroupItem>
<SidebarGroup>
<SidebarGroupList style={{ height: showData ? height : 0 }}>
<div ref={ref} className='flex gap-0.5 flex-col'>
{channels.map(channel => (
<OmniChannelItemRow
key={channel.name}
channel={channel}
showProvider={showProvider}
/>
))}
</div>
</SidebarGroupList>
</SidebarGroup>
</SidebarGroup>
)
}

const OmniChannelItemRow = ({ channel, showProvider }: { channel: OmniChannelItem, showProvider?: boolean }) => {
const { users } = useContext(UserListContext)
const { channelID } = useParams()

const customerUser = useMemo(() => users.find(u => u.name === channel.omni_channel_raven_user), [users, channel.omni_channel_raven_user])

const displayName = customerUser?.full_name ?? channel.channel_name
const showUnread = channel.unread_count > 0 && channelID !== channel.name

return (
<SidebarItem to={channel.name} className='py-1 px-2'>
<SidebarIcon>
<UserAvatar
src={customerUser?.user_image}
alt={displayName}
size={{ initial: '2', md: '1' }}
/>
</SidebarIcon>
<Flex direction='column' flexGrow='1' style={{ minWidth: 0 }}>
<Flex justify='between' align='center' width='100%'>
<Text
size={{ initial: '3', md: '2' }}
className='text-ellipsis line-clamp-1'
weight={showUnread ? 'bold' : 'medium'}
>
{displayName}
</Text>
{showUnread && <SidebarBadge>{channel.unread_count}</SidebarBadge>}
</Flex>
{showProvider && (channel.omni_channel_display_name ?? channel.omni_channel_chat_provider) && (
<Text size='1' color='gray' className='text-ellipsis line-clamp-1'>
{channel.omni_channel_display_name ?? channel.omni_channel_chat_provider}
</Text>
)}
</Flex>
</SidebarItem>
)
}
16 changes: 16 additions & 0 deletions frontend/src/components/layout/Sidebar/SidebarBody.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,27 @@ import { useGetChannelUnreadCounts } from './useGetChannelUnreadCounts'
import { useParams } from 'react-router-dom'
import { atomWithStorage } from 'jotai/utils'
import useUnreadThreadsCount from '@/hooks/useUnreadThreadsCount'
import useFetchWorkspaces from '@/hooks/fetchers/useFetchWorkspaces'
import { OmniChannelSidebarBody } from './OmniChannelSidebarBody'

export const showOnlyMyChannelsAtom = atomWithStorage('showOnlyMyChannels', false)

export const SidebarBody = () => {

const { workspaceID } = useParams()
const { data: workspacesData } = useFetchWorkspaces()

const isOmniChannel = workspacesData?.message.find(w => w.name === workspaceID)?.is_omni_channel_workspace === 1

if (isOmniChannel) {
return <OmniChannelSidebarBody />
}

return <StandardSidebarBody />
}

const StandardSidebarBody = () => {

const unread_count = useFetchUnreadMessageCount()
const { channels, dm_channels } = useContext(ChannelListContext) as ChannelListContextType

Expand Down
2 changes: 1 addition & 1 deletion frontend/src/hooks/fetchers/useFetchWorkspaces.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useFrappeGetCall } from 'frappe-react-sdk'
import { RavenWorkspace } from '@/types/Raven/RavenWorkspace'

export type WorkspaceFields = Pick<RavenWorkspace, 'name' | 'workspace_name' | 'logo' | 'type' | 'can_only_join_via_invite' | 'description'> & {
export type WorkspaceFields = Pick<RavenWorkspace, 'name' | 'workspace_name' | 'logo' | 'type' | 'can_only_join_via_invite' | 'description' | 'is_omni_channel_workspace'> & {
workspace_member_name?: string
is_admin?: 0 | 1
}
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/types/Raven/RavenWorkspace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,6 @@ export interface RavenWorkspace{
logo?: string
/** Only allow admins to create channels in the workspace : Check - If unchecked, any workspace member can create a channel */
only_admins_can_create_channels?: 0 | 1
/** Is Omni-Channel Workspace : Check */
is_omni_channel_workspace?: 0 | 1
}
6 changes: 6 additions & 0 deletions frontend/src/types/RavenChannelManagement/RavenChannel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,10 @@ export interface RavenChannel{
openai_thread_id?: string
/** Thread Bot : Link - Raven Bot */
thread_bot?: string
/** Is Customer : Check */
is_customer?: 0 | 1
/** Omni Channel Chat Provider : Link - Omni Channel Chat Provider */
omni_channel_chat_provider?: string
/** Raven User for Omni Channel : Link - Raven User */
omni_channel_raven_user?: string
}
3 changes: 2 additions & 1 deletion frontend/src/utils/channel/ChannelListProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ export type UnreadCountData = UnreadChannelCountItem[]

export type ChannelListItem = Pick<RavenChannel, 'name' | 'channel_name' | 'type' |
'channel_description' | 'is_direct_message' | 'is_self_message' |
'is_archived' | 'creation' | 'owner' | 'last_message_details' | 'last_message_timestamp' | 'workspace' | 'pinned_messages_string'> & { member_id: string }
'is_archived' | 'creation' | 'owner' | 'last_message_details' | 'last_message_timestamp' | 'workspace' | 'pinned_messages_string' |
'omni_channel_chat_provider' | 'omni_channel_raven_user'> & { member_id: string, omni_channel_display_name?: string, omni_channel_provider?: string }

export interface DMChannelListItem extends ChannelListItem {
peer_user_id: string,
Expand Down
8 changes: 7 additions & 1 deletion raven/api/raven_channel.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ def get_channel_list(hide_archived: bool = False):
"""
channel = frappe.qb.DocType("Raven Channel")
channel_member = frappe.qb.DocType("Raven Channel Member")

workspace_member = frappe.qb.DocType("Raven Workspace Member")
omni_provider = frappe.qb.DocType("Omni Channel Chat Provider")

query = (
frappe.qb.from_(channel)
Expand All @@ -64,6 +64,10 @@ def get_channel_list(hide_archived: bool = False):
channel.last_message_details,
channel.pinned_messages_string,
channel.workspace,
channel.omni_channel_chat_provider,
channel.omni_channel_raven_user,
omni_provider.display_name.as_("omni_channel_display_name"),
omni_provider.provider.as_("omni_channel_provider"),
channel_member.name.as_("member_id"),
)
.left_join(channel_member)
Expand All @@ -75,6 +79,8 @@ def get_channel_list(hide_archived: bool = False):
(channel.workspace == workspace_member.workspace)
& (workspace_member.user == frappe.session.user)
)
.left_join(omni_provider)
.on(channel.omni_channel_chat_provider == omni_provider.name)
.where(
((channel.is_direct_message == 1) & (channel_member.user_id == frappe.session.user))
| (
Expand Down
1 change: 1 addition & 0 deletions raven/api/workspaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ def get_list():
workspace.type,
workspace.description,
workspace.can_only_join_via_invite,
workspace.is_omni_channel_workspace,
workspace_member.name.as_("workspace_member_name"),
workspace_member.is_admin.as_("is_admin"),
)
Expand Down
3 changes: 2 additions & 1 deletion raven/modules.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ Raven Messaging
Raven Channel Management
Raven Bot
Raven Integrations
Raven AI
Raven AI
Omni-Channel Chat
Loading
Loading