diff --git a/gmail-sentiment-analysis/Cards.gs b/gmail-sentiment-analysis/Cards.gs index a520eda8c..dde0a71fc 100644 --- a/gmail-sentiment-analysis/Cards.gs +++ b/gmail-sentiment-analysis/Cards.gs @@ -1,5 +1,5 @@ /* -Copyright 2024 Google LLC +Copyright 2024-2025 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -20,52 +20,46 @@ limitations under the License. * @return {CardService.Card} The card to show to the user. */ -function buildCard_GmailHome(notifyOk = false) { +function buildHomepageCard() { const imageUrl = 'https://fonts.gstatic.com/s/i/googlematerialicons/dynamic_feed/v6/black-24dp/1x/gm_dynamic_feed_black_24dp.png'; const cardHeader = CardService.newCardHeader() .setImageUrl(imageUrl) .setImageStyle(CardService.ImageStyle.CIRCLE) - .setTitle("Analyze your GMail"); + .setTitle("Analyze your Gmail"); - const action = CardService.newAction().setFunctionName('analyzeSentiment'); - const button = CardService.newTextButton() - .setText('Identify angry customers') - .setOnClickAction(action) - .setTextButtonStyle(CardService.TextButtonStyle.FILLED); + const analyzeSentimentAction = CardService.newAction().setFunctionName('analyzeSentiment'); + const analyzeSentimentBtn = CardService.newTextButton() + .setText('Analyze emails') + .setOnClickAction(analyzeSentimentAction) + .setTextButtonStyle(CardService.TextButtonStyle.FILLED) + .setBackgroundColor('#FF0000'); + + const generateSampleEmailAction = CardService.newAction().setFunctionName('generateSampleEmails'); - const generateSampleEmailsAction = CardService.newAction() - .setFunctionName('generateSampleEmails'); const generateSampleEmailsBtn = CardService.newTextButton() .setText('Generate sample emails') - .setOnClickAction(generateSampleEmailsAction) + .setOnClickAction(generateSampleEmailAction) .setTextButtonStyle(CardService.TextButtonStyle.FILLED) .setBackgroundColor('#34A853'); - const buttonSet = CardService.newButtonSet().addButton(button).addButton(generateSampleEmailsBtn); + const buttonSet = CardService.newButtonSet().addButton(generateSampleEmailsBtn).addButton(analyzeSentimentBtn); const section = CardService.newCardSection() - .setHeader("Emails sentiment analysis") .addWidget(buttonSet); const card = CardService.newCardBuilder() .setHeader(cardHeader) .addSection(section); - /** - * This builds the card that contains the footer that informs - * the user about the successful execution of the Add-on. - */ - if (notifyOk) { - const fixedFooter = CardService.newFixedFooter() - .setPrimaryButton( - CardService.newTextButton() - .setText("Analysis complete") - .setOnClickAction( - CardService.newAction() - .setFunctionName( - "buildCard_GmailHome"))); - card.setFixedFooter(fixedFooter); - } return card.build(); } + +function buildNotificationResponse(notificationText) { + const notification = CardService.newNotification().setText(notificationText); + + const actionResponse = CardService.newActionResponseBuilder() + .setNotification(notification); + + return actionResponse.build(); +} \ No newline at end of file diff --git a/gmail-sentiment-analysis/Code.gs b/gmail-sentiment-analysis/Code.gs index b599ca2cf..fd0b8816d 100644 --- a/gmail-sentiment-analysis/Code.gs +++ b/gmail-sentiment-analysis/Code.gs @@ -18,6 +18,6 @@ limitations under the License. * Callback for rendering the homepage card. * @return {CardService.Card} The card to show to the user. */ -function onHomepage(e) { - return buildCard_GmailHome(); -} +function onHomepageTrigger(e) { + return buildHomepageCard(); +} \ No newline at end of file diff --git a/gmail-sentiment-analysis/Gmail.gs b/gmail-sentiment-analysis/Gmail.gs index 64ac50675..0a27a483e 100644 --- a/gmail-sentiment-analysis/Gmail.gs +++ b/gmail-sentiment-analysis/Gmail.gs @@ -1,5 +1,5 @@ /* -Copyright 2024 Google LLC +Copyright 2024-2025 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -21,7 +21,7 @@ limitations under the License. function analyzeSentiment() { analyzeAndLabelEmailSentiment(); - return buildCard_GmailHome(true); + return buildNotificationResponse("Successfully completed sentiment analysis"); } /** @@ -63,3 +63,43 @@ function analyzeAndLabelEmailSentiment() { function isNegativeSentiment(text) { return processSentiment(text) === 'negative'; } + +/** + * Create sample emails + */ +function generateSampleEmails() { + // Get active user's email + const userEmail = Session.getActiveUser().getEmail(); + + // Send emails + GmailApp.sendEmail( + userEmail, + 'Thank you for amazing service!', + 'Hi, I really enjoyed working with you. Thank you again!', + { + name: 'Customer A', + }, + ); + + GmailApp.sendEmail( + userEmail, + 'Request for information', + 'Hello, I need more information on your recent product launch. Thank you.', + { + name: 'Customer B', + }, + ); + + GmailApp.sendEmail( + userEmail, + 'Complaint!', + '', + { + name: 'Customer C', + htmlBody: `

Hello, You are late in delivery, again.

+

Please contact me ASAP before I cancel our subscription.

`, + }, + ); + + return buildNotificationResponse("Successfully generated sample emails"); +} \ No newline at end of file diff --git a/gmail-sentiment-analysis/Samples.gs b/gmail-sentiment-analysis/Samples.gs deleted file mode 100644 index 3c906772b..000000000 --- a/gmail-sentiment-analysis/Samples.gs +++ /dev/null @@ -1,55 +0,0 @@ -/* -Copyright 2025 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. -*/ - -/** - * Create sample emails - */ -function generateSampleEmails() { - // Get active user's email - const userEmail = Session.getActiveUser().getEmail(); - - // Send emails - GmailApp.sendEmail( - userEmail, - 'Thank you for amazing service!', - 'Hi, I really enjoyed working with you. Thank you again!', - { - name: 'Customer A', - }, - ); - - GmailApp.sendEmail( - userEmail, - 'Request for information', - 'Hello, I need more information on your recent product launch. Thank you.', - { - name: 'Customer B', - }, - ); - - GmailApp.sendEmail( - userEmail, - 'Complaint!', - '', - { - name: 'Customer C', - htmlBody: `

Hello, You are late in delivery, again.

-

Please contact me ASAP before I cancel our subscription.

`, - }, - ); - - console.log('Sample email generation completed.') -} diff --git a/gmail-sentiment-analysis/Vertex.gs b/gmail-sentiment-analysis/Vertex.gs index 7c01b7a8e..221907a81 100644 --- a/gmail-sentiment-analysis/Vertex.gs +++ b/gmail-sentiment-analysis/Vertex.gs @@ -1,5 +1,5 @@ /* -Copyright 2024 Google LLC +Copyright 2024-2025 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -16,7 +16,7 @@ limitations under the License. const PROJECT_ID = '[ADD YOUR GCP PROJECT ID HERE]'; const VERTEX_AI_LOCATION = 'us-central1'; -const MODEL_ID = 'gemini-1.5-pro-002'; +const MODEL_ID = 'gemini-1.5-flash'; /** * Packages prompt and necessary settings, then sends a request to @@ -67,16 +67,12 @@ function processSentiment(emailText) { payload: JSON.stringify(request), } - const url = - `https://${VERTEX_AI_LOCATION}-aiplatform.googleapis.com/v1/` + - `projects/${PROJECT_ID}/` + - `locations/${VERTEX_AI_LOCATION}/` + - `publishers/google/` + - `models/${MODEL_ID}:generateContent`; + const url = `https://${VERTEX_AI_LOCATION}-aiplatform.googleapis.com/v1/projects/${PROJECT_ID}/` + + `locations/${VERTEX_AI_LOCATION}/publishers/google/models/${MODEL_ID}:generateContent` const response = UrlFetchApp.fetch(url, fetchOptions); const payload = JSON.parse(response.getContentText()); const text = JSON.parse(payload.candidates[0].content.parts[0].text); return text.response; -} +} \ No newline at end of file diff --git a/gmail-sentiment-analysis/appsscript.json b/gmail-sentiment-analysis/appsscript.json index 803c363e8..6018fe6ae 100644 --- a/gmail-sentiment-analysis/appsscript.json +++ b/gmail-sentiment-analysis/appsscript.json @@ -1,27 +1,27 @@ { - "timeZone": "America/Los_Angeles", + "timeZone": "America/Toronto", "oauthScopes": [ + "https://www.googleapis.com/auth/script.external_request", "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/script.locale", + "https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/gmail.addons.execute", "https://www.googleapis.com/auth/gmail.labels", - "https://www.googleapis.com/auth/gmail.modify", - "https://www.googleapis.com/auth/script.external_request", - "https://www.googleapis.com/auth/script.locale", - "https://www.googleapis.com/auth/userinfo.email" + "https://www.googleapis.com/auth/gmail.modify" ], "addOns": { "common": { - "name": "Productivity toolbox", + "name": "Sentiment Analysis", "logoUrl": "https://fonts.gstatic.com/s/i/googlematerialicons/dynamic_feed/v6/black-24dp/1x/gm_dynamic_feed_black_24dp.png", "useLocaleFromApp": true }, "gmail": { "homepageTrigger": { - "runFunction": "onHomepage", + "runFunction": "onHomepageTrigger", "enabled": true } } }, "exceptionLogging": "STACKDRIVER", "runtimeVersion": "V8" -} +} \ No newline at end of file