Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
fd35ce2
Can send calls to the chatbot locally
jmafoster1 Jan 31, 2025
6e466c0
User messages and chatbot responses
jmafoster1 Jan 31, 2025
d37052c
Now tagged with unique sequential IDs and who sent
jmafoster1 Jan 31, 2025
2d5339f
Easier chatbot testing
jmafoster1 Feb 3, 2025
734bb78
Feedback exports extra functions for the slack integration.
jmafoster1 Feb 7, 2025
3d3b6ba
Chatbot integration to slack now sends a link to the image
jmafoster1 Feb 14, 2025
19bed69
Integrated slack feedback into frontend
jmafoster1 Feb 17, 2025
d0051c4
Fixed slack integration problem
jmafoster1 Feb 19, 2025
f8bc1cd
Commented out slack integration so as not to spam when debugging
jmafoster1 Feb 27, 2025
e66e44d
Removed direct call in favour of going through backend like the other…
jmafoster1 Mar 7, 2025
4836d57
Removed TODO comment
jmafoster1 Mar 11, 2025
077434d
Merge branch 'beta-master' of github.com:AFP-Medialab/verification-pl…
jmafoster1 Mar 11, 2025
ea0df08
Added brackets to reducer
jmafoster1 Mar 12, 2025
0409520
Tidied up imports in chatbot interface
jmafoster1 Mar 12, 2025
35bda7d
Changed translation keywords
jmafoster1 Mar 12, 2025
d0a435b
Chatbot session IDs
jmafoster1 Mar 21, 2025
42e9773
Session removal logic
jmafoster1 Mar 21, 2025
e76179d
Clear chatbot messages
jmafoster1 Mar 25, 2025
619445a
Merge branch 'beta-master' of github.com:AFP-Medialab/verification-pl…
jmafoster1 Mar 25, 2025
1dd7095
Removed unnecessary payload from user chatbot messages
jmafoster1 Mar 25, 2025
d142bc2
Clear the session history in the chatbot backend
jmafoster1 Mar 25, 2025
230f1c4
Now passing through the tool and result
jmafoster1 Apr 15, 2025
9a6b6f5
Moved ChatbotInterface into Assistant
jmafoster1 Apr 15, 2025
e2e14a8
Removed console.log
jmafoster1 Apr 15, 2025
44e26ce
Merge branch 'beta-master' of github.com:AFP-Medialab/verification-pl…
jmafoster1 May 8, 2025
e92f58b
Merge branch 'beta-master' of github.com:AFP-Medialab/verification-pl…
jmafoster1 Jun 5, 2025
7ebc760
Only sending tool and result if changed
jmafoster1 Jun 6, 2025
7c7c939
Chatbot reducer no longer breaks the assistant page
jmafoster1 Jun 6, 2025
45f5965
Persistant chatbot session ID accross images
jmafoster1 Jun 10, 2025
c3a04ef
Added test input for test box
jmafoster1 Jul 8, 2025
8fb1fb4
Added scroll bar on chatbot messages
jmafoster1 Jul 11, 2025
e958743
Loading spinner and better error handling.
jmafoster1 Jul 11, 2025
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
118 changes: 66 additions & 52 deletions src/components/Feedback/Feedback.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,72 @@ import QuestionAnswerOutlinedIcon from "@mui/icons-material/QuestionAnswerOutlin

import { i18nLoadNamespace } from "components/Shared/Languages/i18nLoadNamespace";

const API_URL = process.env.REACT_APP_MY_WEB_HOOK_URL;

const getFeedbackMessage = (email, message, messageType, archiveURL = null) => {
if (typeof message !== "string" || typeof messageType !== "string")
throw new Error("Invalid message type");

return {
blocks: [
{
type: "header",
text: {
type: "plain_text",
text: "" + messageType + "",
},
},
...(email
? [
{
type: "section",
text: {
type: "mrkdwn",
text: "<mailto:" + email + ">",
},
},
]
: []),
{
type: "section",
text: {
type: "mrkdwn",
text: "" + message + "",
},
...(archiveURL // Conditionally add the accessory
? {
accessory: {
type: "image",
image_url: archiveURL.trim(),
alt_text: "Problematic image",
},
}
: {}), // Important: Return an empty object if archiveURL is not defined
},
],
};
};

const sendToSlack = async (email, message, messageType, archiveURL = null) => {
const feedbackMessage = getFeedbackMessage(
email,
message,
messageType,
archiveURL,
);
const response = await fetch(API_URL, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(feedbackMessage),
});

if (!response.ok) throw response;

return response;
};

const Feedback = () => {
const keyword = i18nLoadNamespace("components/FeedBack");
const API_URL = process.env.REACT_APP_MY_WEB_HOOK_URL;

const [isButtonHovered, setIsButtonHovered] = useState(false);
const [displayCard, setDisplayCard] = useState(false);
Expand All @@ -42,56 +105,6 @@ const Feedback = () => {

const containerRef = React.useRef(null);

const getFeedbackMessage = (message, messageType) => {
if (typeof message !== "string" || typeof messageType !== "string")
throw new Error("Invalid message type");

return {
blocks: [
{
type: "header",
text: {
type: "plain_text",
text: "" + messageType + "",
},
},
...(email
? [
{
type: "section",
text: {
type: "mrkdwn",
text: "<mailto:" + email + ">",
},
},
]
: []),
{
type: "section",
text: {
type: "mrkdwn",
text: "" + message + "",
},
},
],
};
};

const sendToSlack = async (message, messageType) => {
const feedbackMessage = getFeedbackMessage(message, messageType);
//console.log(feedbackMessage);
//console.log(JSON.stringify(feedbackMessage));
const response = await fetch(API_URL, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(feedbackMessage),
});

if (!response.ok) throw response;

return response;
};

const validateEmail = (email) => {
if (!email) return true; //allow to proceed if the email is empty
const re = /\S+@\S+\.\S+/; //match [email protected]
Expand All @@ -113,7 +126,7 @@ const Feedback = () => {

setIsFeedbackSending(true);

await sendToSlack(message, messageType);
await sendToSlack(email, message, messageType);

//console.log("submitted");

Expand Down Expand Up @@ -311,3 +324,4 @@ const Feedback = () => {
};

export default Feedback;
export { getFeedbackMessage, sendToSlack }; // Named exports
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import axios from "axios";

export default function assistantApiCalls() {
const assistantEndpoint = process.env.REACT_APP_ASSISTANT_URL;
const chatbotEndpoint = process.env.REACT_APP_CHATBOT_URL;

function handleAssistantError(errorResponse) {
if (errorResponse.response) {
Expand All @@ -22,6 +23,34 @@ export default function assistantApiCalls() {
}
}

const callChatbot = async (
sessionID,
userInput = null,
email = null,
archiveURL = null,
tool = null,
result = null,
) => {
let chatbotResponse;
try {
chatbotResponse = await axios.post(assistantEndpoint + "gcloud/chatbot", {
message: userInput,
sessionID: sessionID,
tool: tool,
result: result,
});
} catch (error) {
handleAssistantError(error);
}

if (chatbotResponse.data.status === "success") {
return chatbotResponse.data;
} else {
console.log("Chatbot error:", chatbotResponse);
throw new Error("assistant_error_server_error");
}
};

const callAssistantScraper = async (urlType, userInput) => {
let scrapeResult;
try {
Expand Down Expand Up @@ -294,6 +323,7 @@ export default function assistantApiCalls() {
};

return {
callChatbot,
callAssistantScraper,
callSourceCredibilityService,
callNamedEntityService,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import useMyStyles from "../../Shared/MaterialUiStyles/useMyStyles";
import {
TransHtmlDoubleLineBreak,
TransSupportedToolsLink,
TransSupportedUrlsLink,
} from "./TransComponents";

const AssistantIntroduction = (props) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,10 @@ export default function AssistantTextClassification({
if (Object.keys(filteredCategories).length === 0) {
filteredSentences = [];
}
if (credibilitySignal === keyword("subjectivity_title") && Object.keys(filteredSentences).length === 0) {
if (
credibilitySignal === keyword("subjectivity_title") &&
Object.keys(filteredSentences).length === 0
) {
filteredCategories = [];
}

Expand Down
Loading