Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
bb5bb4c
Add environment settings
marceloschmidt Nov 18, 2021
64f7709
Set default value for environment = draft
marceloschmidt Nov 18, 2021
c093b8d
Bump version
marceloschmidt Nov 18, 2021
6cfe871
Update config/Settings.ts
marceloschmidt Nov 18, 2021
04301ee
Update config/Settings.ts
marceloschmidt Nov 18, 2021
715c02d
Merge pull request #71 from RocketChat/df-environment
murtaza98 Nov 30, 2021
26ed342
[IMPROVE] Increase log verbosity (#70)
murtaza98 Nov 30, 2021
d0d4dee
Chore: Replace tslint with eslint and improve typing of app (#72)
KevLehman Dec 1, 2021
9eaa8e3
[IMPROVE] Add doc link to app description & Improve app settings (#74)
murtaza98 Dec 9, 2021
567abd5
[NEW] Add multiple language support - text messages (#49)
murtaza98 Dec 21, 2021
bcaa489
[NEW] Introduce redirect URL buttons to Chatbot apps
murtaza98 Mar 15, 2022
46457d1
Update QuickReplies.md
murtaza98 Mar 15, 2022
515df00
Apply suggestions from code review
murtaza98 Mar 16, 2022
d3f239c
Merge pull request #79 from RocketChat/redirect-url-button
KevLehman Mar 17, 2022
dd31411
Chore: Bump app version to 1.2.5 (#81)
murtaza98 Mar 28, 2022
48b56cc
Merge branch 'master' into master-catchup-dd31411
AlexanderKanakis Jun 9, 2022
4217396
Fixed conflict for package/package.log
AlexanderKanakis Jun 9, 2022
5421423
Fixed merge issues
AlexanderKanakis Jun 14, 2022
52229d5
Merge branch 'master' into master-catchup-dd31411
AlexanderKanakis Jun 14, 2022
8390132
fixed workflow scripts
AlexanderKanakis Jun 14, 2022
a60f1f7
Merge branch 'master-catchup-dd31411' of github.com:WideChat/Apps.Dia…
AlexanderKanakis Jun 14, 2022
a24f715
fixed merger issue
AlexanderKanakis Jun 14, 2022
d58e739
fixed lint issues
AlexanderKanakis Jun 14, 2022
6220585
fixed workflow scripts
AlexanderKanakis Jun 14, 2022
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
5 changes: 5 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
node_modules
dist
.github
i18n
.*
15 changes: 15 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
module.exports = {
root: true,
parser: '@typescript-eslint/parser',
plugins: [
'@typescript-eslint',
],
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
],
rules: {
"no-case-declarations": "off",
"@typescript-eslint/no-unused-vars": ["error", { "vars": "all", "args": "after-used", "ignoreRestSiblings": false }]
},
};
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,6 @@ Temporary Items

.editorconfig
.vscode

# related to rc-apps cli
.rcappsconfig
4 changes: 4 additions & 0 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

npm run lint
3 changes: 3 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
node_modules
dist
.*
8 changes: 8 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"semi": true,
"trailingComma": "all",
"singleQuote": true,
"printWidth": 80,
"useTabs": true,
"tabWidth": 4
}
6 changes: 3 additions & 3 deletions app.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"id": "21b7d3ba-031b-41d9-8ff2-fbbfa081ae90",
"version": "1.2.3",
"version": "1.2.5",
"requiredApiVersion": "^1.17.0",
"iconFile": "icon.png",
"author": {
Expand All @@ -11,13 +11,13 @@
"name": "Dialogflow",
"nameSlug": "dialogflow",
"classFile": "DialogflowApp.ts",
"description": "Integration between Rocket.Chat and the Dialogflow Chatbot platform",
"description": "Integration between Rocket.Chat and the Dialogflow Chatbot platform. Relevant documentation of this app can be found [here](https://docs.rocket.chat/guides/app-guides/omnichannel-apps/dialogflow-app)",
"implements": [
"IPostMessageSent",
"IPostLivechatAgentAssigned",
"IPostLivechatAgentUnassigned",
"IPostLivechatRoomClosed",
"IUIKitLivechatInteractionHandler"
],
"commitHash": "5b598b81b19d0702a9291d58f9ed4c81e23cb5d0"
"commitHash": "4217396b4410a11d93540c83814702659c9e3dad"
}
36 changes: 35 additions & 1 deletion config/Settings.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { ISetting, SettingType } from '@rocket.chat/apps-engine/definition/settings';
import {
ISetting,
ISettingSelectValue,
SettingType,
} from '@rocket.chat/apps-engine/definition/settings';

export enum AppSetting {
DialogflowBotList = 'agents',
Expand Down Expand Up @@ -85,6 +89,36 @@ const agentConfigTemplate = JSON.stringify(
},
}], null, '\t');

export const LanguageCode: Array<ISettingSelectValue> = [
{ key: 'zh-CN', i18nLabel: 'Chinese - Simplified' },
{ key: 'da', i18nLabel: 'Danish' },
{ key: 'nl', i18nLabel: 'Dutch' },
{ key: 'en', i18nLabel: 'English' },
{ key: 'en-AU', i18nLabel: 'English - Australia' },
{ key: 'en-CA', i18nLabel: 'English - Canada' },
{ key: 'en-GB', i18nLabel: 'English - Great Britain' },
{ key: 'en-IN', i18nLabel: 'English - India' },
{ key: 'en-US', i18nLabel: 'English - US' },
{ key: 'fr-CA', i18nLabel: 'French - Canada' },
{ key: 'fr-FR', i18nLabel: 'French - France' },
{ key: 'de', i18nLabel: 'German' },
{ key: 'hi', i18nLabel: 'Hindi' },
{ key: 'id', i18nLabel: 'Indonesian' },
{ key: 'it', i18nLabel: 'Italian' },
{ key: 'ja', i18nLabel: 'Japanese' },
{ key: 'ko', i18nLabel: 'Korean' },
{ key: 'no', i18nLabel: 'Norwegian' },
{ key: 'pl', i18nLabel: 'Polish' },
{ key: 'pt-BR', i18nLabel: 'Portuguese - Brazil' },
{ key: 'pt', i18nLabel: 'Portuguese - Portugal' },
{ key: 'ru', i18nLabel: 'Russian' },
{ key: 'es', i18nLabel: 'Spanish' },
{ key: 'es-ES', i18nLabel: 'Spanish - Spain' },
{ key: 'sv', i18nLabel: 'Swedish' },
{ key: 'tr', i18nLabel: 'Turkish' },
{ key: 'uk', i18nLabel: 'Ukrainian' },
];

export const settings: Array<ISetting> = [

{
Expand Down
1 change: 1 addition & 0 deletions docs/QuickReplies.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
| **Param Name** | **Param Type** | **Description** | **Dependency** | **Acceptable Values** | **Example** |
|:--------------:|:--------------:|:--------------------------------------------------------------------------------------------------------------------------------------------------------:|:--------------:|:---------------------:|:---------------------------------------:|
| `text` | String | Title of the quick replies action. | Required | Any | ``` "text": "Start Chat" ``` |
| `url` | String | Redirect Url in-case you wish to redirect user somewhere if they click on the button. <br/> ⚠️ Recommended to only use with Livechat conversations | Optional | Any | ``` "text": "Start Chat" ``` |
| `actionId` | String | Id of the quick replies action. | Optional | Any | ``` "actionId": "sflaia-start-chat" ``` |
| `buttonStyle` | String | Button style of your quick replies action. Use `danger` to render a red colour action and `primary` for an action that matches your Livechat Bar colour. | Optional | `danger` or `primary` | ``` "buttonStyle": "primary" ``` |

Expand Down
3 changes: 1 addition & 2 deletions endpoints/FulfillmentsEndpoint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export class FulfillmentsEndpoint extends ApiEndpoint {
HttpStatusCode.OK,
{ 'Content-Type': Headers.CONTENT_TYPE_JSON },
{ fulfillmentMessages: [] });
} catch (error) {
} catch (error: any) {
this.app.getLogger().error(Logs.ENDPOINT_REQUEST_PROCESSING_ERROR, error);
return createHttpResponse(HttpStatusCode.INTERNAL_SERVER_ERROR, { 'Content-Type': Headers.CONTENT_TYPE_JSON }, { error: error.message });
}
Expand All @@ -35,7 +35,6 @@ export class FulfillmentsEndpoint extends ApiEndpoint {
const message: IDialogflowMessage = Dialogflow.parseRequest(request.content);
if (!message) { throw new Error(Logs.INVALID_REQUEST_CONTENT); }
if (!message.sessionId) { throw new Error(Logs.INVALID_SESSION_ID); }

await createDialogflowMessage(message.sessionId, read, modify, message, this.app);
await this.handleBotTyping(read, modify, message.sessionId, message);
}
Expand Down
30 changes: 17 additions & 13 deletions endpoints/IncomingEndpoint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,23 @@ import { closeChat, performHandover } from '../lib/Room';
export class IncomingEndpoint extends ApiEndpoint {
public path = 'incoming';

public async post(request: IApiRequest,
endpoint: IApiEndpointInfo,
read: IRead,
modify: IModify,
http: IHttp,
persis: IPersistence): Promise<IApiResponse> {
public async post(
request: IApiRequest,
endpoint: IApiEndpointInfo,
read: IRead,
modify: IModify,
http: IHttp,
persis: IPersistence): Promise<IApiResponse> {
this.app.getLogger().info(Logs.ENDPOINT_RECEIVED_REQUEST);

try {
const { statusCode = HttpStatusCode.OK, data = null } = await this.processRequest(read, modify, persis, http, request.content);
return createHttpResponse(statusCode, { 'Content-Type': Headers.CONTENT_TYPE_JSON }, { ...data ? { ...data } : { result: Response.SUCCESS } });
} catch (error) {
this.app.getLogger().error(Logs.ENDPOINT_REQUEST_PROCESSING_ERROR, error);
return createHttpResponse(HttpStatusCode.INTERNAL_SERVER_ERROR, { 'Content-Type': Headers.CONTENT_TYPE_JSON }, { error: error.message });
const { statusCode = HttpStatusCode.OK, data = null } = await this.processRequest(read, modify, persis, http, request.content);
return createHttpResponse(statusCode, { 'Content-Type': Headers.CONTENT_TYPE_JSON }, { ...data ? { ...data } : { result: Response.SUCCESS } });
} catch (error: any) {
this.app.getLogger().error(Logs.ENDPOINT_REQUEST_PROCESSING_ERROR, error);
return createHttpResponse(HttpStatusCode.INTERNAL_SERVER_ERROR, { 'Content-Type': Headers.CONTENT_TYPE_JSON }, { error: error.message });
}
}
}

private async processRequest(read: IRead,
modify: IModify,
Expand Down Expand Up @@ -95,6 +96,9 @@ export class IncomingEndpoint extends ApiEndpoint {
throw new Error(Logs.INVALID_ENDPOINT_ACTION);
}

return { statusCode: HttpStatusCode.OK, data: { result: Response.SUCCESS }};
return {
statusCode: HttpStatusCode.OK,
data: { result: Response.SUCCESS },
};
}
}
3 changes: 2 additions & 1 deletion enum/Dialogflow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,11 @@ export interface IDialogflowAction {

export interface IDialogflowQuickReplyOptions {
text: string;
url?: string;
actionId?: string;
buttonStyle?: ButtonStyle;
data?: {
[prop: string]: any;
[prop: string]: string;
};
}

Expand Down
49 changes: 39 additions & 10 deletions handler/ExecuteLivechatBlockActionHandler.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,52 @@
import { IHttp, IModify, IPersistence, IRead } from '@rocket.chat/apps-engine/definition/accessors';
import {
IHttp,
IModify,
IPersistence,
IRead,
} from '@rocket.chat/apps-engine/definition/accessors';
import { IApp } from '@rocket.chat/apps-engine/definition/IApp';
import { ILivechatRoom } from '@rocket.chat/apps-engine/definition/livechat';
import { IUIKitResponse, UIKitLivechatBlockInteractionContext } from '@rocket.chat/apps-engine/definition/uikit';
import {
IUIKitResponse,
UIKitLivechatBlockInteractionContext,
} from '@rocket.chat/apps-engine/definition/uikit';
import { UIKitIncomingInteractionContainerType } from '@rocket.chat/apps-engine/definition/uikit/UIKitIncomingInteractionContainer';
import { IUser } from '@rocket.chat/apps-engine/definition/users';
import { AppSetting, DefaultMessage } from '../config/Settings';
import { ActionIds } from '../enum/ActionIds';
import { createLivechatMessage, createMessage, deleteAllActionBlocks } from '../lib/Message';
import {
createLivechatMessage,
createMessage,
deleteAllActionBlocks,
} from '../lib/Message';
import { closeChat, performHandover } from '../lib/Room';
import { getLivechatAgentConfig } from '../lib/Settings';

export class ExecuteLivechatBlockActionHandler {
constructor(private readonly app: IApp,
private context: UIKitLivechatBlockInteractionContext,
private read: IRead,
private http: IHttp,
private persistence: IPersistence,
private modify: IModify) {}
constructor(
private readonly app: IApp,
private context: UIKitLivechatBlockInteractionContext,
private read: IRead,
private http: IHttp,
private persistence: IPersistence,
private modify: IModify,
) {}

public async run(): Promise<IUIKitResponse> {
try {
const interactionData = this.context.getInteractionData();
const { visitor, room, container: { id, type }, value, actionId } = interactionData;
const {
visitor,
room,
container: { id, type },
value,
actionId,
} = interactionData;

if (!value) {
// most likely, this button has a url to open. So we don't need to do anything here.
return this.context.getInteractionResponder().successResponse();
}

if (type !== UIKitIncomingInteractionContainerType.MESSAGE) {
return this.context.getInteractionResponder().successResponse();
Expand Down Expand Up @@ -63,6 +88,10 @@ export class ExecuteLivechatBlockActionHandler {
await deleteAllActionBlocks(this.modify, appUser, id);
}

if (hideQuickRepliesSetting) {
await deleteAllActionBlocks(this.modify, appUser, id);
}

return this.context.getInteractionResponder().successResponse();
} catch (error) {
this.app.getLogger().error(error);
Expand Down
10 changes: 7 additions & 3 deletions handler/OnSettingUpdatedHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ import { getError } from '../lib/Helper';
import { getAppSettingValue } from '../lib/Settings';

export class OnSettingUpdatedHandler {
constructor(private readonly app: IApp, private readonly read: IRead, private readonly http: IHttp) {}
constructor(
private readonly app: IApp,
private readonly read: IRead,
private readonly http: IHttp,
) {}

public async run() {
try {
Expand All @@ -29,15 +33,15 @@ export class OnSettingUpdatedHandler {
try {
await Dialogflow.generateNewAccessToken(this.http, clientEmail, privateKey);
this.app.getLogger().info(Logs.GOOGLE_AUTH_SUCCESS);
} catch (error) {
} catch (error: any) {
console.error(Logs.HTTP_REQUEST_ERROR, getError(error));
this.app.getLogger().error(error.message);
}
}
}

}
} catch (e) {
} catch (e: any) {
this.app.getLogger().error(Logs.AGENT_CONFIG_FORMAT_ERROR);
console.error(Logs.AGENT_CONFIG_FORMAT_ERROR, e);
throw new Error(e);
Expand Down
12 changes: 10 additions & 2 deletions handler/PostMessageSentHandler.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
import { IHttp, IModify, IPersistence, IRead } from '@rocket.chat/apps-engine/definition/accessors';
import {
IHttp,
IModify,
IPersistence,
IRead,
} from '@rocket.chat/apps-engine/definition/accessors';
import { IApp } from '@rocket.chat/apps-engine/definition/IApp';
import { ILivechatMessage, ILivechatRoom } from '@rocket.chat/apps-engine/definition/livechat';
import {
ILivechatMessage,
ILivechatRoom,
} from '@rocket.chat/apps-engine/definition/livechat';
import { RoomType } from '@rocket.chat/apps-engine/definition/rooms';
import { AppSetting } from '../config/Settings';
import { DialogflowRequestType, IDialogflowMessage, IDialogflowQuickReplies, LanguageCode, Message } from '../enum/Dialogflow';
Expand Down
28 changes: 28 additions & 0 deletions i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,34 @@
"dialogflow_hide_quick_replies_description": "If enabled, then all quick-replies will hide when a visitor clicks on any one of them",
"dialogflow_handover_failed_message": "Handover Failed Message",
"dialogflow_handover_failed_message_description": "The Bot will send this message to Visitor if the handover failed because no agents were online",
"dialogflow_default_language_description": "Define the language in which you'd be interacting with the Bot",
"dialogflow_chinese_simplified": "Chinese - Simplified",
"dialogflow_danish": "Danish",
"dialogflow_dutch": "Dutch",
"dialogflow_english": "English",
"dialogflow_english_australia": "English - Australia",
"dialogflow_english_canada": "English - Canada",
"dialogflow_english_great_britain": "English - Great Britain",
"dialogflow_english_india": "English - India",
"dialogflow_english_us": "English - US",
"dialogflow_french_canada": "French - Canada",
"dialogflow_french_france": "French - France",
"dialogflow_german": "German",
"dialogflow_hindi": "Hindi",
"dialogflow_indonesian": "Indonesian",
"dialogflow_italian": "Italian",
"dialogflow_japanese": "Japanese",
"dialogflow_korean": "Korean",
"dialogflow_norwegian": "Norwegian",
"dialogflow_polish": "Polish",
"dialogflow_portuguese-brazil": "Portuguese - Brazil",
"dialogflow_portuguese-portugal": "Portuguese - Portugal",
"dialogflow_russian": "Russian",
"dialogflow_spanish": "Spanish",
"dialogflow_spanish-spain": "Spanish - Spain",
"dialogflow_swedish": "Swedish",
"dialogflow_turkish": "Turkish",
"dialogflow_ukrainian": "Ukrainian",
"dialogflow_enable_chat_closed_by_visitor_event": "Enable Dialogflow Event When Visitor Ends Chat",
"dialogflow_enable_chat_closed_by_visitor_event_description": "If enabled, then a dialogflow event will be triggered when visitor ends chat",
"dialogflow_chat_closed_by_visitor_event_name": "Dialogflow Event Name When Visitor Ends Chat",
Expand Down
Loading