Skip to main content

Google Summer of Code 2023, RocketChat

· 6 min read
google-summer-of-code

Create a ready-to-go easy to embed mini-chat React component.

I worked on a project called EmbeddedChat which is an in-app chat solution that utilizes the RocketChat chat engine through its REST and real-time APIs to support powerful chat features like reactions, online presence, typing status, threads, and much more.

I would maintain this repository as the final report summary of my GSoC 2023 project and a quick guide for all future GSoC aspirants.

⭐ Project Abstract​

The goal of the project is to make a ready-to-use chat solution that could be integrated into any website, web app, or app. This project was a major refactoring and enhancement for the EmbeddedChat 2022 project.

🚢 Deliverables​

  • Improve authentication - support all OAuth services
  • Move to a mono repo - auth, api, react, react-native, HTML embed
  • HTML embed feature
  • Theming
  • Improving API
  • Support for slash commands
  • Migrating from the fuselage to our own minimal components

Demo​

Sneak Peak​

EmbeddedChat integrated into my esportsweb.in website. EmbeddedChat Reac component

Moving to mono repo​

EmbeddedChat's new mono repo structure structure

  • auth - The auth package includes functions to easily log into a Rocket chat server. Though it is used by embeddedchat's react and react-native client, developers can use this package for their own use cases.
  • api - The api package includes functions that are all required to create a chat application using the Rocketchat server. It has functions like connect, login, sendMesage, pinMessage, starMessage, deleteMessage, triggerBlockAction, etc. to perform various operations. One can listen to new/updated message events by attaching event listeners using addMessageListener. There are other event listeners which could be added using addMessageDeleteListener, addTypingStatusListener, addActionTriggeredListener, addUiInteractionListener.
  • react - The react package includes the react components to integrate EmbeddedChat.
  • react-native - The react-native project aims at using EmbeddedChat in react native mobile apps.
  • htmembed - With this project EmbeddedChat could be integrated into any web app by simply embedding an HTML snippet.

Storybook setup​

Screenshot from 2023-09-25 12-09-07

HTML Embedd Feature​

Simple integrate embedded chat by pasting html snippet into your website

<div id="embeddedchat"></div>
<script src="http://127.0.0.1:4001/embeddedchat.js"></script>
<script>
// all props for the EmbeddedChat of @embeddedchat/react will go here
// The config will be directly applied as props for the EmbeddedChat Component
const config = {
host: 'http://localhost:3000',
roomId: 'GENERAL',
isClosable: true,
setClosableState: true,
moreOpts: true,
channelName: 'general',
anonymousMode: true,
headerColor: 'white',
toastBarPosition: 'bottom-end',
showRoles: true,
showAvatar: false,
enableThreads: true,
auth: {
flow: 'MANAGED',
},
}
EmbeddedChat.renderInElementWithId(config, 'embeddedchat')
</script>

HTML Embedded in action htmlembed

Theming​

We can customize EmbeddedChat by passing a custom theme object. Hence, it could take the look and feel of the app or website. We can also customize components by custom stylesheet or passing custom class names through the theme object. Customizing using theme

Improving API​

Our api package exposes the EmbeddedChatApi class. It comes with a bunch of APIs that could be used to login, send, pin, edit, star or delete message, attach listeners for realtime events. It has the following structure:

class EmbeddedChatApi {
host: string;
rid: string;
rcClient: Rocketchat;
onMessageCallbacks: ((message: any) => void)[];
onMessageDeleteCallbacks: ((messageId: string) => void)[];
onTypingStatusCallbacks: ((users: string[]) => void)[];
onActionTriggeredCallbacks: ((data: any) => void)[];
onUiInteractionCallbacks: ((data: any) => void)[];
typingUsers: string[];
auth: RocketChatAuth;
constructor(host: string, rid: string, { getToken, saveToken, deleteToken, autoLogin }: IRocketChatAuthOptions);
setAuth(auth: RocketChatAuth): void;
getAuth(): RocketChatAuth;
getHost(): string;
googleSSOLogin(signIn: Function, acsCode: string): Promise<any>;
login(userOrEmail: string, password: string, code: string): Promise<{
status: string;
me: any;
} | undefined>;
logout(): Promise<void>;
connect(): Promise<void>;
addMessageListener(callback: (message: any) => void): Promise<void>;
removeMessageListener(callback: (message: any) => void): Promise<void>;
addMessageDeleteListener(callback: (messageId: string) => void): Promise<void>;
removeMessageDeleteListener(callback: (messageId: string) => void): Promise<void>;
addTypingStatusListener(callback: (users: string[]) => void): Promise<void>;
removeTypingStatusListener(callback: (users: string[]) => void): Promise<void>;
addActionTriggeredListener(callback: (data: any) => void): Promise<void>;
removeActionTriggeredListener(callback: (data: any) => void): Promise<void>;
addUiInteractionListener(callback: (data: any) => void): Promise<void>;
removeUiInteractionListener(callback: (data: any) => void): Promise<void>;
handleTypingEvent({ typingUser, isTyping }: {
typingUser: string;
isTyping: boolean;
}): void;
updateUserNameThroughSuggestion(userid: string): Promise<any>;
updateUserUsername(userid: string, username: string): Promise<any>;
channelInfo(): Promise<any>;
close(): Promise<void>;
getMessages(anonymousMode?: boolean, options?: {
query?: object | undefined;
field?: object | undefined;
}): Promise<any>;
getThreadMessages(tmid: string): Promise<any>;
getChannelRoles(): Promise<any>;
sendTypingStatus(username: string, typing: boolean): Promise<void>;
sendMessage(message: any, threadId: string): Promise<any>;
deleteMessage(msgId: string): Promise<any>;
updateMessage(msgId: string, text: string): Promise<any>;
starMessage(mid: string): Promise<any>;
unstarMessage(mid: string): Promise<any>;
getStarredMessages(): Promise<any>;
getPinnedMessages(): Promise<any>;
pinMessage(mid: string): Promise<any>;
unpinMessage(mid: string): Promise<any>;
reactToMessage(emoji: string, messageId: string, shouldReact: string): Promise<any>;
reportMessage(messageId: string, description: string): Promise<any>;
findOrCreateInvite(): Promise<any>;
sendAttachment(file: File, fileName: string, fileDescription?: string, threadId?: undefined): Promise<any>;
me(): Promise<any>;
getChannelMembers(): Promise<any>;
getSearchMessages(text: string): Promise<any>;
triggerBlockAction({ type, actionId, appId, rid, mid, viewId, container, ...rest }: any): Promise<any>;
getCommandsList(): Promise<any>;
execCommand({ command, params }: {
command: string;
params: string;
}): Promise<any>;
}

Demo playgroud for api package playground_api

Support for slash commands​

We have worked on supporting slash commands along with any UI interactions they perform.

https://github.com/abhinavkrin/GSoC-RocketChat-2023/assets/15830206/b4c0dd2e-e77f-49d5-8eb5-f27b1e011817

React Native​

react native

Improving Auth​

We now support token-based authentication for EmbeddedChat. An app can pass the access token of the services that are configured in RocketChat to EmbeddedChat. It would be useful when the app does not want to show any additional login UI for EmbeddedChat.

https://github.com/abhinavkrin/GSoC-RocketChat-2023/assets/15830206/8c36b974-927f-4b12-bd62-2830763ec681

🚀 Contributions​

Pull requests to Embeddedchat​

PR IDTitle with Link
217[IMPROVE] Project-restructure Link
218React bootstrap Link
222Theming Foundation Set up Link
223[NEW] Button replacement for fuselage Link
224UI refactoring/box Link
226Improve/auth + ActionButton/Icon/Input Component Link
227New/added apis Link
228New/slash commands+UI kit+theming Link
229New/html embed Link
230New/message component+avatar Link
232React Native Project Link
233Fix/new icon components Link

View all PRs to EmbeddedChat

My overall contributions to RocketChat​

Besides EmbeddedChat I also contributed to other RocketChat Projects GSoC Community Hub, RC4Community, RC4Conferences.

🎓 Mentor​

A big big thank you to my mentor for the guidance and support before and throughout GSoC. 🙏 I learned beyond GSoC from him and am forever grateful to be mentored by him.

  • Read my EmbeddedChat project proposal that got me accepted to GSoC here.

  • My GSoC Presentation can be found here.

  • Watch the above presentation in video - here !

❤️ Support​

Learned something new today? Reciprocate the love. ⭐ this repo for good karma.

💬 Connect With Me​

Want to discuss about GSoC / Rocket.Chat / Open-source ? Let's connect!

StudentAbhinav Kumar
OrganizationRocket.Chat
ProjectEmbeddedChat 2023
GitHub@abhinavkrin
LinkedInabhinavkrin
Twitterabhinavkr_in
Websiteavitechlab.com
Emailabhinav@avitechlab.com
Rocket.Chatabhinav.kumar30