-
Notifications
You must be signed in to change notification settings - Fork 262
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add Chat Apps with Gemini resources (#270)
* Initiate Google IO Gemini code lab * Fix accessory function and storage * Enable private messages * Minimize oauth scope * Removed private message logic because unsupported with accessory widgets, added other app resources * Broke down the issue management app in code lab stagesBroke d * Improve the auth credentials to be in the configuration script * Fix typo * Fix progressive oauth scopes * Remove unnecessary services * Switch to dynamic pubsub configuration * Delete subscription at issue closure * Remove unnecessary REST API implementation of app auth messaging * Improve prompt for inclusivity help * Support default agent response instead of custom payload for simplicity --------- Co-authored-by: pierrick <[email protected]>
- Loading branch information
1 parent
afef33f
commit 81d0ba6
Showing
51 changed files
with
3,496 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,3 +13,4 @@ service-account.json | |
**/python-3*/ | ||
**/.history/ | ||
.vscode/ | ||
**/.clasp.json |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
# Build apps for Google Chat with Gemini | ||
|
||
This code example creates Google Chat apps with the following advanced features: app home cards, | ||
Google Workspace Chat events, accessory widgets, Dialogflow CX agents, and Vertex AI's | ||
Gemini-powered AI models. | ||
|
||
Please see the related | ||
[code lab instructions](https://developers.google.com/codelabs/chat-apps-gemini). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
/** | ||
* Copyright 2024 Google LLC | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
const functions = require('@google-cloud/functions-framework'); | ||
|
||
/** | ||
* Handles all incoming requests. | ||
*/ | ||
functions.http('feedback-app-backend', (request, response) => { | ||
response.send('OK'); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"name": "feedback-app-backend", | ||
"version": "0.0.1", | ||
"description": "Mocks a feedback app backend.", | ||
"license": "Apache-2.0", | ||
"dependencies": { | ||
"@google-cloud/functions-framework": "^3.0.0" | ||
} | ||
} |
30 changes: 30 additions & 0 deletions
30
apps-script/chat-apps-gemini/feedback-app/service-openapi.yaml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
openapi: 3.1.0 | ||
info: | ||
title: Review Store | ||
license: | ||
name: Apache 2.0 | ||
identifier: Apache-2.0 | ||
version: 0.0.1 | ||
servers: | ||
- url: $URL | ||
paths: | ||
/store-review: | ||
post: | ||
operationId: storeReview | ||
summary: Store a new review | ||
requestBody: | ||
content: | ||
application/json: | ||
schema: | ||
type: object | ||
properties: | ||
stars: | ||
type: integer | ||
format: int64 | ||
responses: | ||
'200': | ||
description: success | ||
content: | ||
application/json: | ||
schema: | ||
type: string |
157 changes: 157 additions & 0 deletions
157
apps-script/chat-apps-gemini/issue-management-app/1-baseline/ChatApp.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,157 @@ | ||
/** | ||
* Copyright 2024 Google LLC | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
// This script contains the Google Chat-specific callback and utilities functions. | ||
|
||
/** | ||
* Responds to a MESSAGE event in Google Chat. | ||
* | ||
* Handles slash commands. | ||
* | ||
* @param {Object} event the event object from Google Chat | ||
*/ | ||
function onMessage(event) { | ||
if (event.message.slashCommand) { | ||
return processSlashCommand(event); | ||
} | ||
|
||
return { text: "Available slash commands to manage issues are '/create' and '/close'." }; | ||
} | ||
|
||
/** | ||
* Responds to a CARD_CLICKED event in Google Chat. | ||
* | ||
* Handles action funtions. | ||
* | ||
* @param {Object} event the event object from Google Chat | ||
*/ | ||
function onCardClick(event) { | ||
// Issue creation dialog form submission | ||
if (event.action.actionMethodName === "createIssue") { | ||
return createIssue(event); | ||
} | ||
} | ||
|
||
/** | ||
* Responds to a MESSAGE event with a slash command in Google Chat. | ||
* | ||
* @param {Object} event the event object from Google Chat | ||
*/ | ||
function processSlashCommand(event) { | ||
if (event.message.slashCommand.commandId == CREATE_COMMAND_ID) { | ||
// Opens the issue creation dialog. | ||
return { actionResponse: { | ||
type: "DIALOG", | ||
dialogAction: { dialog: { body: { sections: [{ | ||
header: "Create", | ||
widgets: [{ textInput: { | ||
label: "Title", | ||
name: "title" | ||
}}, { textInput: { | ||
label: "Description", | ||
type: "MULTIPLE_LINE", | ||
name: "description" | ||
}}, { buttonList: { buttons: [{ | ||
text: "Create", | ||
onClick: { action: { | ||
function: "createIssue" | ||
}} | ||
}]} | ||
}] | ||
}]}}} | ||
}}; | ||
} | ||
|
||
if (event.message.slashCommand.commandId == CLOSE_COMMAND_ID && event.message.space.type !== "DM") { | ||
// Closes the issue associated to the space. | ||
const spaceId = event.message.space.name; | ||
const resolution = event.message.argumentText; | ||
const issue = JSON.parse(appProperties.getProperty(spaceId)); | ||
const docUrl = createReport(issue.title, issue.description, resolution); | ||
saveClosedIssue(spaceId, resolution, docUrl); | ||
|
||
return { | ||
actionResponse: { type: "NEW_MESSAGE" }, | ||
text: `The issue is closed and its report generated:\n${docUrl}` | ||
}; | ||
} | ||
|
||
return { text: "The command isn't supported." }; | ||
} | ||
|
||
/** | ||
* Handles create issue dialog form submissions in Google Chat. | ||
* | ||
* @param {Object} event the event object from Google Chat | ||
*/ | ||
function createIssue(event) { | ||
// Retrieves the form inputs. | ||
const title = event.common.formInputs.title[""].stringInputs.value[0]; | ||
const description = event.common.formInputs.description[""].stringInputs.value[0]; | ||
const spaceUrl = createIssueSpace(title, description); | ||
const createdIssue = saveCreatedIssue(title, description, spaceUrl); | ||
|
||
return { | ||
actionResponse: { type: "NEW_MESSAGE" }, | ||
text: `The issue and its dedicated space were created:\n` | ||
+ `https://mail.google.com/mail/u/0/#chat/space/${createdIssue.spaceId}` | ||
}; | ||
} | ||
|
||
/** | ||
* Initializes a Google Chat space dedicated to a new issue. | ||
* | ||
* The app adds itself and sends a first message to the newly created space. | ||
* | ||
* @param {string} title the title of the issue | ||
* @param {string} description the description of the isue | ||
* @return {string} the ID of the new space | ||
*/ | ||
function createIssueSpace(title, description) { | ||
// Creates the space. | ||
const spaceId = Chat.Spaces.setup({ | ||
space: { | ||
displayName: title, | ||
spaceType: "SPACE" | ||
} | ||
}).name; | ||
|
||
// Adds itself to the space. | ||
Chat.Spaces.Members.create({ | ||
member: { | ||
name: "users/app", | ||
type: "BOT" | ||
} | ||
}, spaceId); | ||
|
||
// Sends a first message to the space | ||
createAppMessageUsingChatService({ text: description}, spaceId); | ||
return spaceId; | ||
} | ||
|
||
/** | ||
* Responds to a REMOVED_FROM_SPACE event in Google Chat. | ||
* | ||
* @param {Object} event the event object from Google Chat | ||
*/ | ||
function onRemoveFromSpace(event) {} | ||
|
||
/** | ||
* Responds to a ADDED_TO_SPACE event in Google Chat. | ||
* | ||
* @param {Object} event the event object from Google Chat | ||
*/ | ||
function onAddToSpace(event) {} |
47 changes: 47 additions & 0 deletions
47
apps-script/chat-apps-gemini/issue-management-app/1-baseline/ChatAppAuth.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
/** | ||
* Copyright 2024 Google LLC | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
// This script contains utilities functions based on app authentication. | ||
|
||
/** | ||
* Creates a new message by using the Advanced Chat Service. | ||
* | ||
* @param {Object} message the message object to send to Google Chat | ||
* @param {string} spaceId the space ID where to create the message | ||
*/ | ||
function createAppMessageUsingChatService(message, spaceId) { | ||
Chat.Spaces.Messages.create(message, spaceId, {}, { | ||
'Authorization': 'Bearer ' + getService_().getAccessToken() | ||
}); | ||
} | ||
|
||
/** | ||
* Authenticates the app service by using the OAuth2 library. | ||
* | ||
* Warning: This example uses a service account private key for simplicity's sake, it should always | ||
* be stored in an secure location. | ||
* | ||
* @return {Object} the authenticated app service | ||
*/ | ||
function getService_() { | ||
return OAuth2.createService(CHAT_CREDENTIALS.client_email) | ||
.setTokenUrl(CHAT_CREDENTIALS.token_uri) | ||
.setPrivateKey(CHAT_CREDENTIALS.private_key) | ||
.setIssuer(CHAT_CREDENTIALS.client_email) | ||
.setSubject(CHAT_CREDENTIALS.client_email) | ||
.setScope('https://www.googleapis.com/auth/chat.bot') | ||
.setPropertyStore(appProperties); | ||
} |
24 changes: 24 additions & 0 deletions
24
apps-script/chat-apps-gemini/issue-management-app/1-baseline/Configuration.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
/** | ||
* Copyright 2024 Google LLC | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
// This script initiates the app configuration. | ||
|
||
const CREATE_COMMAND_ID = 1; | ||
const CLOSE_COMMAND_ID = 2; | ||
const CHAT_CREDENTIALS = { | ||
// Replace with the Google Chat credentials to use for app authenticatio, the service account | ||
// private key's JSON. | ||
} |
36 changes: 36 additions & 0 deletions
36
apps-script/chat-apps-gemini/issue-management-app/1-baseline/Docs.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
/** | ||
* Copyright 2024 Google LLC | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
// This script contains the Google Docs-specific utilities functions. | ||
|
||
/** | ||
* Creates an issue report as a Google Doc in the user's Google Drive. | ||
* | ||
* @param {string} title the title of the issue | ||
* @param {string} description the description of the issue | ||
* @param {string} resolution the resolution of the issue | ||
* @return {string} the URL of the created report | ||
*/ | ||
function createReport(title, description, resolution) { | ||
let doc = DocumentApp.create(title); | ||
let body = doc.getBody(); | ||
body.appendParagraph(`Issue Report: ${title}`).setHeading(DocumentApp.ParagraphHeading.TITLE); | ||
body.appendParagraph("Description").setHeading(DocumentApp.ParagraphHeading.HEADING1); | ||
body.appendParagraph(description); | ||
body.appendParagraph("Resolution").setHeading(DocumentApp.ParagraphHeading.HEADING1); | ||
body.appendParagraph(resolution); | ||
return doc.getUrl(); | ||
} |
Oops, something went wrong.