Merge pull request #3494 from joaojmendes/OpenAIChatGPT
ChatGPT-APP, Update
This commit is contained in:
commit
7f0b96dd66
Binary file not shown.
Binary file not shown.
|
@ -101,6 +101,7 @@ This assume you have a Azure App called "OpenAIFunctionsApp", you can change thi
|
|||
Version|Date|Comments
|
||||
-------|----|--------
|
||||
1.0.0|Feb 19, 2023|Initial release
|
||||
1.1.0|March 2, 2023|Update ChatGPT-APP to use the latest API and model ChatGPT-3.5-turbo
|
||||
|
||||
## Minimal Path to Awesome
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
"This App is a implementation of OpenAI ChatGPT-3. It runs on SharePoint, Teams as Personal or Teams App and Message Extension."
|
||||
],
|
||||
"creationDateTime": "2023-02-19",
|
||||
"updateDateTime": "2023-02-19",
|
||||
"updateDateTime": "2023-03-02",
|
||||
"products": [
|
||||
"SharePoint"
|
||||
],
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
export const CARD = {
|
||||
"type": "AdaptiveCard",
|
||||
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
|
||||
"version": "1.2",
|
||||
"version": "1.3",
|
||||
"body": [
|
||||
{
|
||||
"type": "ColumnSet",
|
||||
|
@ -56,6 +56,21 @@ export const CARD = {
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "Container",
|
||||
"spacing": "medium",
|
||||
"style": "emphasis",
|
||||
"items": [
|
||||
{
|
||||
"type": "TextBlock",
|
||||
"text": "${$root.question}",
|
||||
"wrap": true,
|
||||
"horizontalAlignment": "Right",
|
||||
"color": "Accent"
|
||||
}
|
||||
],
|
||||
"$when": "${length($root.question)>0}"
|
||||
},
|
||||
{
|
||||
"type": "Container",
|
||||
"spacing": "Padding",
|
||||
|
|
|
@ -26,14 +26,19 @@ export const ChatGptControl: React.FunctionComponent<IChatGptProps> = (
|
|||
const { context } = props;
|
||||
const [appGlobalState, setAppGlobalState] = useAtom(globalState);
|
||||
const { containerStyles } = useChatGptStyles();
|
||||
const { hasTeamsContext, chatId } = appGlobalState;
|
||||
const { hasTeamsContext, chatId, channelId } = appGlobalState;
|
||||
const { getTenantProperty } = useSpAPI(context);
|
||||
const [isLoading, setIsLoading] = React.useState(true);
|
||||
const [error, setError] = React.useState<Error | undefined>(undefined);
|
||||
|
||||
const isInChat = React.useMemo((): boolean => {
|
||||
return hasTeamsContext && !!chatId;
|
||||
}, [chatId, hasTeamsContext]);
|
||||
if (hasTeamsContext && (chatId )) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}, [chatId, channelId, hasTeamsContext]);
|
||||
|
||||
const isInChannel = React.useMemo(() => !!channelId, [ channelId]);
|
||||
|
||||
const isPreviewChatId = React.useMemo((): boolean => {
|
||||
if (isInChat) {
|
||||
|
@ -91,7 +96,7 @@ export const ChatGptControl: React.FunctionComponent<IChatGptProps> = (
|
|||
return (
|
||||
<>
|
||||
<Stack tokens={{ childrenGap: 20 }} styles={containerStyles}>
|
||||
<Header isInChat={isInChat} />
|
||||
<Header isInChat={isInChat || isInChannel} />
|
||||
<RenderPreviewChatInfo isPreviewChatId={isPreviewChatId} />
|
||||
<RenderMessages isShowMessages={!isPreviewChatId} />
|
||||
</Stack>
|
||||
|
|
|
@ -14,7 +14,6 @@ import { showNotification } from '@mantine/notifications';
|
|||
import { CARD } from '../../adaptiveCards/chatGPTAnswerCard';
|
||||
import { globalState } from '../../atoms';
|
||||
import { useAdaptiveCardsUtils } from '../../hooks/useAdaptiveCardsUtils';
|
||||
import { useGraphAPI } from '../../hooks/useGraphAPI';
|
||||
import { useSendMessageToTeams } from '../../hooks/useSendMessageToTeams';
|
||||
import { IAdaptativeCardData } from '../../models/IAdaptivecardData';
|
||||
import { IRenderAnswerProps } from '../../models/IRenderAnswerProps';
|
||||
|
@ -26,24 +25,25 @@ import { SendMessageToChat } from '../SendMessageToChat/SendMessageToChat';
|
|||
export const RenderAnswer: React.FunctionComponent<IRenderAnswerProps> = (
|
||||
props: React.PropsWithChildren<IRenderAnswerProps>
|
||||
) => {
|
||||
const { answer } = props;
|
||||
const { answer, question } = props;
|
||||
const { answerStyles, nameStyles, answerContainerStyles, controlStyles } = useChatGptStyles();
|
||||
const [appGlobalState] = useAtom(globalState);
|
||||
const { lastConversation, context, chatId } = appGlobalState;
|
||||
const { lastConversation, context, chatId, teamsId, channelId, parentMessageId, hasTeamsContext } = appGlobalState;
|
||||
const [error, setError] = React.useState<Error | undefined>(undefined);
|
||||
const { sendMessage } = useGraphAPI(context);
|
||||
|
||||
const { createAdaptiveCard } = useAdaptiveCardsUtils();
|
||||
const { sendAdativeCardToUsers } = useSendMessageToTeams(context);
|
||||
const hasError = React.useMemo(() => error !== undefined, [error]);
|
||||
|
||||
|
||||
const onSendMessageToChat = React.useCallback(async () => {
|
||||
if (answer && chatId) {
|
||||
if (answer && hasTeamsContext ) {
|
||||
try {
|
||||
const cardData: IAdaptativeCardData = { date: format(new Date(), "PPpp"), answer: answer };
|
||||
const cardData: IAdaptativeCardData = { date: format(new Date(), "PPpp"), answer: answer, question: question ?? ""};
|
||||
const card = createAdaptiveCard(cardData, CARD);
|
||||
console.log("carddata", cardData);
|
||||
console.log("card", card);
|
||||
await sendAdativeCardToUsers(card, cardData, chatId);
|
||||
await sendAdativeCardToUsers(card, cardData, chatId, teamsId, channelId, parentMessageId);
|
||||
|
||||
showNotification({
|
||||
title: strings.ChatGPTAppNotificationTitle,
|
||||
|
@ -57,7 +57,7 @@ export const RenderAnswer: React.FunctionComponent<IRenderAnswerProps> = (
|
|||
setError(error);
|
||||
}
|
||||
}
|
||||
}, [answer, chatId, sendMessage, sendAdativeCardToUsers, createAdaptiveCard]);
|
||||
}, [answer,teamsId,channelId, hasTeamsContext, chatId, sendAdativeCardToUsers, createAdaptiveCard, question, parentMessageId]);
|
||||
|
||||
const islastConversation = React.useMemo(() => lastConversation === "answer", [lastConversation]);
|
||||
return (
|
||||
|
@ -86,7 +86,6 @@ export const RenderAnswer: React.FunctionComponent<IRenderAnswerProps> = (
|
|||
<SendMessageToChat onSendMessage={onSendMessageToChat} />
|
||||
</Stack>
|
||||
</Stack>
|
||||
|
||||
<Stack horizontalAlign="start" tokens={{ childrenGap: 10 }}>
|
||||
<div
|
||||
dangerouslySetInnerHTML={{ __html: answer?.replace("\n\n", " ") }}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/* eslint-disable require-atomic-updates */
|
||||
/* eslint-disable @typescript-eslint/no-floating-promises */
|
||||
import * as React from 'react';
|
||||
|
||||
import { useAtom } from 'jotai';
|
||||
|
@ -6,8 +8,12 @@ import { IIconProps } from 'office-ui-fabric-react/lib/Icon';
|
|||
import { Stack } from 'office-ui-fabric-react/lib/Stack';
|
||||
import { TextField } from 'office-ui-fabric-react/lib/TextField';
|
||||
|
||||
import { ChatMessage } from '@microsoft/microsoft-graph-types';
|
||||
|
||||
import { globalState } from '../../atoms/globalState';
|
||||
import { useChatGpt } from '../../hooks';
|
||||
import { useGraphAPI } from '../../hooks/useGraphAPI';
|
||||
import { useHtmlUtils } from '../../hooks/useHtmlUtils';
|
||||
import { useChatGptStyles } from '../ChatGpt/useChatGptStyles';
|
||||
import { ErrorMessage } from '../ErrorMessage/ErrorMessage';
|
||||
import { Loading } from '../LoadingAnswer/Loading';
|
||||
|
@ -23,7 +29,7 @@ export const RenderMessages: React.FunctionComponent<IRenderMessagesProps> = (
|
|||
) => {
|
||||
const { isShowMessages } = props;
|
||||
const [appGlobalState] = useAtom(globalState);
|
||||
const { context, appId, AzureFunctionUrl } = appGlobalState;
|
||||
const { context, appId, AzureFunctionUrl, parentMessageId, chatId, teamsId, channelId } = appGlobalState;
|
||||
const { textFieldStyles, controlStyles, buttonIconStyles } = useChatGptStyles();
|
||||
const [conversation, setConversation] = React.useState<React.ReactNode[]>([]);
|
||||
const [textToAsk, setTextToAsk] = React.useState<string>("");
|
||||
|
@ -31,6 +37,12 @@ export const RenderMessages: React.FunctionComponent<IRenderMessagesProps> = (
|
|||
const { getCompletion } = useChatGpt(context, appId, AzureFunctionUrl);
|
||||
const scrollRef = React.useRef<HTMLDivElement>(null);
|
||||
const [error, setError] = React.useState<Error | undefined>(undefined);
|
||||
const { getChatParentMessage, getChannelParentMessage } = useGraphAPI(context);
|
||||
const executeAutoGetComplete = React.useRef<boolean>(false);
|
||||
const { getTextFromHtml } = useHtmlUtils();
|
||||
|
||||
const hasParentMessage = React.useMemo(() => !!parentMessageId , [parentMessageId]);
|
||||
const isInChannel = React.useMemo(() => !!teamsId && !!channelId, [teamsId, channelId]);
|
||||
|
||||
const hasError = React.useMemo(() => error !== undefined, [error]);
|
||||
|
||||
|
@ -54,8 +66,8 @@ export const RenderMessages: React.FunctionComponent<IRenderMessagesProps> = (
|
|||
);
|
||||
|
||||
const addAnswer = React.useCallback(
|
||||
(answer: string) => {
|
||||
const newAnswer = <RenderAnswer answer={answer} key={conversation.length + 1} />;
|
||||
(answer: string, question?: string) => {
|
||||
const newAnswer = <RenderAnswer answer={answer} question={question} key={conversation.length + 1} />;
|
||||
setConversation((prev) => {
|
||||
return [...prev, newAnswer];
|
||||
});
|
||||
|
@ -92,6 +104,44 @@ export const RenderMessages: React.FunctionComponent<IRenderMessagesProps> = (
|
|||
[onSubmit]
|
||||
);
|
||||
|
||||
const runAutoGetComplete = React.useCallback(async () => {
|
||||
try {
|
||||
let messageDetails: ChatMessage = undefined;
|
||||
if (!isInChannel ) {
|
||||
messageDetails = await getChatParentMessage(chatId, parentMessageId);
|
||||
} else {
|
||||
messageDetails = await getChannelParentMessage(teamsId, channelId, parentMessageId);
|
||||
}
|
||||
const { body } = messageDetails;
|
||||
if (body) {
|
||||
setError(undefined);
|
||||
const { content, } = body;
|
||||
console.log(body);
|
||||
|
||||
const text = getTextFromHtml(content);
|
||||
if ( text ) {
|
||||
addQuestion(text);
|
||||
setIsLoading(true);
|
||||
const response = await getCompletion(text);
|
||||
addAnswer(response, text);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
setError(error);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
}, []);
|
||||
|
||||
React.useEffect(() => {
|
||||
(async () => {
|
||||
if (hasParentMessage && !executeAutoGetComplete.current) {
|
||||
executeAutoGetComplete.current = true;
|
||||
await runAutoGetComplete();
|
||||
}
|
||||
})();
|
||||
}, [hasParentMessage]);
|
||||
|
||||
if (!isShowMessages) {
|
||||
return null;
|
||||
}
|
||||
|
@ -104,7 +154,7 @@ export const RenderMessages: React.FunctionComponent<IRenderMessagesProps> = (
|
|||
|
||||
<Stack tokens={{ padding: 20, childrenGap: 10 }}>
|
||||
<Loading isLoading={isLoading} />
|
||||
<Stack horizontal tokens={{ childrenGap: 5 }} >
|
||||
<Stack horizontal tokens={{ childrenGap: 5 }}>
|
||||
{hasError ? (
|
||||
<ErrorMessage errorMessage={error?.message} showError={hasError} />
|
||||
) : (
|
||||
|
|
|
@ -18,7 +18,7 @@ export const SendMessageToChat: React.FunctionComponent<ISendMessageProps> = (
|
|||
props: React.PropsWithChildren<ISendMessageProps>
|
||||
) => {
|
||||
const [appGlobalState] = useAtom(globalState);
|
||||
const { hasTeamsContext, chatId, } = appGlobalState;
|
||||
const { hasTeamsContext, chatId,teamsId,channelId, } = appGlobalState;
|
||||
const { onSendMessage } = props;
|
||||
|
||||
const shareIcon: IIconProps = React.useMemo(() => {return { iconName: "Share" }}, []);
|
||||
|
@ -26,8 +26,8 @@ export const SendMessageToChat: React.FunctionComponent<ISendMessageProps> = (
|
|||
const tooltipId = useId("tooltip");
|
||||
|
||||
const isInChat = React.useMemo(() => {
|
||||
return hasTeamsContext && chatId;
|
||||
}, [chatId, hasTeamsContext]);
|
||||
return hasTeamsContext && (chatId || teamsId || channelId);
|
||||
}, [chatId,teamsId,channelId, hasTeamsContext]);
|
||||
|
||||
if (!isInChat) {
|
||||
return null;
|
||||
|
|
|
@ -19,7 +19,7 @@ const onProcessMarkdownHandler = (md:any, result: { outputHtml: string; didProc
|
|||
result.didProcess = false;
|
||||
}
|
||||
};
|
||||
export const useAdaptiveCardsUtils = function () {
|
||||
export const useAdaptiveCardsUtils = () => {
|
||||
|
||||
const createAdaptiveCard = React.useCallback((adaptiveCardData, card) => {
|
||||
const adaptiveCardToRender = new adaptiveCards.AdaptiveCard();
|
||||
|
|
|
@ -8,10 +8,18 @@ import {
|
|||
IHttpClientOptions,
|
||||
} from '@microsoft/sp-http';
|
||||
|
||||
/* const APPID = "6b4a20b2-bf2f-4cbb-a162-af960a40c2dc";
|
||||
const AZURE_FUNCTION_URL = "https://openaifunctionsapp.azurewebsites.net/api/OpenAICompletion"; */
|
||||
enum ERole {
|
||||
user = "user",
|
||||
assistant = "assistant",
|
||||
system = "system",
|
||||
}
|
||||
interface IMessages {
|
||||
role:ERole;
|
||||
content: string;
|
||||
}
|
||||
|
||||
export const useChatGpt = (context: BaseComponentContext, appId: string, AzureFunctionUrl: string) => {
|
||||
export const useChatGpt = (context: BaseComponentContext, appId:string, AzureFunctionUrl:string) => {
|
||||
const messages = React.useRef<IMessages[]>([]);
|
||||
const client = React.useMemo(() => {
|
||||
if (context) {
|
||||
return async () => {
|
||||
|
@ -25,27 +33,30 @@ export const useChatGpt = (context: BaseComponentContext, appId: string, AzureFu
|
|||
const getCompletion = React.useCallback(
|
||||
async (query: string): Promise<string> => {
|
||||
try {
|
||||
messages.current.push({ role: ERole.user, content: query });
|
||||
if (!client) return;
|
||||
const options: IHttpClientOptions = {
|
||||
headers: { "Content-Type": "application/json;odata=verbose", Accept: "application/json;odata=verbose" },
|
||||
mode: "cors",
|
||||
body: JSON.stringify({ prompt: query }),
|
||||
body: JSON.stringify({ messages: messages.current }),
|
||||
method: "POST",
|
||||
};
|
||||
|
||||
const response = await (await client()).post(AzureFunctionUrl, AadHttpClient.configurations.v1, options);
|
||||
const answer = await response.json();
|
||||
if (response.status === 200) {
|
||||
return answer?.choices[0].text;
|
||||
} else {
|
||||
console.log("[getCompletion] error:", answer);
|
||||
throw new Error("Error on executing the request, please try again later.");
|
||||
}
|
||||
} catch (error) {
|
||||
if (!DEBUG) {
|
||||
console.log("[getCompletion] error:", error);
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
messages.current.push(answer.choices[0].message)
|
||||
return answer.choices[0].message.content;
|
||||
} else {
|
||||
console.log("[getCompletion] error:", answer);
|
||||
throw new Error("Error on executing the request, please try again later.");
|
||||
}
|
||||
} catch (error) {
|
||||
if (!DEBUG) {
|
||||
console.log("[getCompletion] error:", error);
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
[client]
|
||||
);
|
||||
|
|
|
@ -8,27 +8,52 @@ import {
|
|||
} from '@microsoft/microsoft-graph-types';
|
||||
import { BaseComponentContext } from '@microsoft/sp-component-base';
|
||||
|
||||
export const useGraphAPI = (context: BaseComponentContext) => {
|
||||
export const useGraphAPI = (context: BaseComponentContext) => {
|
||||
const graphClient = React.useMemo(() => {
|
||||
return async () => {
|
||||
const client = await context.msGraphClientFactory.getClient("3");
|
||||
return client;
|
||||
};
|
||||
}, [context]);
|
||||
const sendMessageToChat = React.useCallback(
|
||||
async (chatId: string, chatMessagePayload: object): Promise<ChatMessage> => {
|
||||
const chatMessage = await (await graphClient()).api(`/chats/${chatId}/messages`).post(chatMessagePayload);
|
||||
return chatMessage;
|
||||
},
|
||||
[graphClient]
|
||||
);
|
||||
|
||||
const sendMessage = React.useCallback(async (chatId: string, message: string):Promise<ChatMessage> => {
|
||||
const client = await context.msGraphClientFactory.getClient("3");
|
||||
const response:ChatMessage = await client.api(`/chats/${chatId}/messages`)
|
||||
.post({
|
||||
body: {
|
||||
content: `${message} (source: ChatGPT)` ,
|
||||
},
|
||||
});
|
||||
return response;
|
||||
},[context]);
|
||||
const sendMessageToChannel = React.useCallback(
|
||||
async (teamsId: string, channelId: string, chatMessagePayload: object): Promise<ChatMessage> => {
|
||||
const channelMessage = await (await graphClient())
|
||||
.api(`/teams/${teamsId}/channels/${channelId}/messages`)
|
||||
.post(chatMessagePayload);
|
||||
return channelMessage;
|
||||
},
|
||||
[graphClient]
|
||||
);
|
||||
|
||||
const replyToMessage = React.useCallback( async (teamsId: string, channelId: string, parentMessageId: string, chatMessagePayload: object) => {
|
||||
return (await graphClient())
|
||||
.api(`/teams/${teamsId}/channels/${channelId}/messages/${parentMessageId}/replies`)
|
||||
.post(chatMessagePayload);
|
||||
}, []);
|
||||
|
||||
const getChatInfo = React.useCallback(async (chatId:string):Promise<Chat> => {
|
||||
const client = await context.msGraphClientFactory.getClient("3");
|
||||
const response:Chat = await client.api(`/chats/${chatId}?$expand=members`)
|
||||
.get();
|
||||
return response;
|
||||
},[context]);
|
||||
const getChatInfo = React.useCallback(
|
||||
async (chatId: string): Promise<Chat> => {
|
||||
const response: Chat = await (await graphClient()).api(`/chats/${chatId}`).get();
|
||||
return response;
|
||||
},
|
||||
[context]
|
||||
);
|
||||
|
||||
return {sendMessage, getChatInfo}
|
||||
const getChatParentMessage = React.useCallback(async (chatId: string, parentMessageId: string):Promise<ChatMessage> => {
|
||||
return (await graphClient()).api(`/chats/${chatId}/messages/${parentMessageId}`).get();
|
||||
}, []);
|
||||
|
||||
const getChannelParentMessage = React.useCallback(async (teamId: string,channelId:string, parentMessageId: string):Promise<ChatMessage> => {
|
||||
return (await graphClient()).api(`/teams/${teamId}/channels/${channelId}/messages/${parentMessageId}`).get();
|
||||
}, []);
|
||||
|
||||
return { sendMessageToChat, sendMessageToChannel, replyToMessage, getChatInfo, getChatParentMessage, getChannelParentMessage };
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
|
||||
interface IHtmlUtils {
|
||||
getTextFromHtml: (html: string) => string;
|
||||
}
|
||||
export const useHtmlUtils = ():IHtmlUtils => {
|
||||
|
||||
const getTextFromHtml = (html: string):string => {
|
||||
const tmp = document.createElement('DIV');
|
||||
tmp.innerHTML = html;
|
||||
return tmp.textContent || tmp.innerText || undefined;
|
||||
};
|
||||
return {getTextFromHtml}
|
||||
};
|
|
@ -4,17 +4,15 @@ import { BaseComponentContext } from '@microsoft/sp-component-base';
|
|||
import { Guid } from '@microsoft/sp-core-library';
|
||||
import { isEmpty } from '@microsoft/sp-lodash-subset';
|
||||
|
||||
import { useGraphAPI } from '../hooks/useGraphAPI';
|
||||
import { IAdaptativeCardData } from '../models/IAdaptivecardData';
|
||||
import { HostedContents } from '../models/IChatMessage';
|
||||
|
||||
/* eslint-disable @typescript-eslint/explicit-function-return-type */
|
||||
export const useSendMessageToTeams = (context: BaseComponentContext) => {
|
||||
const graphClient = React.useMemo(() => {
|
||||
return async () => {
|
||||
const client = await context.msGraphClientFactory.getClient("3");
|
||||
return client;
|
||||
};
|
||||
}, [context]);
|
||||
|
||||
const { sendMessageToChat, sendMessageToChannel, replyToMessage } = useGraphAPI(context);
|
||||
|
||||
|
||||
const getHostedContent = React.useCallback(async (adaptiveCard: object, adaptiveCardData: IAdaptativeCardData) => {
|
||||
try {
|
||||
|
@ -55,50 +53,17 @@ export const useSendMessageToTeams = (context: BaseComponentContext) => {
|
|||
[]
|
||||
);
|
||||
|
||||
/* const createChatMembers = React.useCallback((receiverEmail: string) => {
|
||||
try {
|
||||
const currentUser = context.pageContext.user.email;
|
||||
const chatMembers = [
|
||||
{
|
||||
"@odata.type": "#microsoft.graph.aadUserConversationMember",
|
||||
roles: ["owner"],
|
||||
"user@odata.bind": `https://graph.microsoft.com/v1.0/users('${currentUser}')`,
|
||||
},
|
||||
{
|
||||
"@odata.type": "#microsoft.graph.aadUserConversationMember",
|
||||
roles: ["owner"],
|
||||
"user@odata.bind": `https://graph.microsoft.com/v1.0/users('${receiverEmail}')`,
|
||||
},
|
||||
];
|
||||
return chatMembers;
|
||||
} catch (error) {
|
||||
if (DEBUG) {
|
||||
console.error(`[SendMessage.createChatMembers]: error=${error}`);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}, []); */
|
||||
/*
|
||||
const createChat = React.useCallback(
|
||||
async (receiverEmail) => {
|
||||
try {
|
||||
const members = createChatMembers(receiverEmail);
|
||||
const chat = await (await graphClient()).api("/chats").post({ chatType: "oneOnOne", members: members });
|
||||
return chat;
|
||||
} catch (error) {
|
||||
if (DEBUG) {
|
||||
console.error("[SendMessage.createChat]: error=", error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
},
|
||||
[graphClient]
|
||||
);
|
||||
*/
|
||||
const sendMessage = React.useCallback(
|
||||
async (adaptiveCard: object, adaptiveCardData: IAdaptativeCardData, chatId: string) => {
|
||||
try {
|
||||
|
||||
const sendMessage = React.useCallback(
|
||||
async (
|
||||
adaptiveCard: object,
|
||||
adaptiveCardData: IAdaptativeCardData,
|
||||
chatId: string,
|
||||
teamsId: string,
|
||||
channelId: string,
|
||||
parentMessageId: string
|
||||
) => {
|
||||
try {
|
||||
const { body, attachments, hostedContents } = await getSendMessagePayload(adaptiveCard, adaptiveCardData);
|
||||
const chatMessagePayload = {
|
||||
subject: "OpenAI Answer",
|
||||
|
@ -106,8 +71,20 @@ export const useSendMessageToTeams = (context: BaseComponentContext) => {
|
|||
attachments: attachments,
|
||||
hostedContents: hostedContents,
|
||||
};
|
||||
const chatMessage = await (await graphClient()).api(`/chats/${chatId}/messages`).post(chatMessagePayload);
|
||||
return chatMessage;
|
||||
if (chatId && !teamsId && !channelId) {
|
||||
console.log('channelId', channelId);
|
||||
console.log('teamsId', teamsId);
|
||||
const chatMessage = await sendMessageToChat(chatId, chatMessagePayload, );
|
||||
return chatMessage;
|
||||
}
|
||||
if (teamsId && channelId && !parentMessageId) {
|
||||
const channelMessage = sendMessageToChannel(teamsId, channelId, chatMessagePayload);
|
||||
return channelMessage;
|
||||
}
|
||||
if (teamsId && channelId && parentMessageId) {
|
||||
const replyMessage = await replyToMessage(teamsId, channelId, parentMessageId, chatMessagePayload);
|
||||
return replyMessage;
|
||||
}
|
||||
} catch (error) {
|
||||
if (DEBUG) {
|
||||
console.error("[SendMessage]: error=", error);
|
||||
|
@ -115,13 +92,20 @@ export const useSendMessageToTeams = (context: BaseComponentContext) => {
|
|||
}
|
||||
}
|
||||
},
|
||||
[graphClient]
|
||||
[getSendMessagePayload, sendMessageToChannel, sendMessageToChat, replyToMessage, ]
|
||||
);
|
||||
|
||||
const sendAdativeCardToUsers = React.useCallback(
|
||||
async (adaptiveCard: object, adaptiveCardData: IAdaptativeCardData, chatId: string) => {
|
||||
async (
|
||||
adaptiveCard: object,
|
||||
adaptiveCardData: IAdaptativeCardData,
|
||||
chatId: string,
|
||||
teamsId: string,
|
||||
channelId: string,
|
||||
parentMessageId: string
|
||||
) => {
|
||||
try {
|
||||
await sendMessage(adaptiveCard, adaptiveCardData, chatId);
|
||||
await sendMessage(adaptiveCard, adaptiveCardData, chatId, teamsId, channelId, parentMessageId);
|
||||
} catch (error) {
|
||||
if (DEBUG) {
|
||||
console.error(`[SendMessage.sendAdativeCardToUsers]: error=${error.message}`);
|
||||
|
@ -129,7 +113,7 @@ export const useSendMessageToTeams = (context: BaseComponentContext) => {
|
|||
}
|
||||
}
|
||||
},
|
||||
[graphClient]
|
||||
[sendMessage]
|
||||
);
|
||||
|
||||
return { sendAdativeCardToUsers };
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
export interface IAdaptativeCardData {
|
||||
date: string;
|
||||
answer: string;
|
||||
question: string;
|
||||
}
|
||||
|
|
|
@ -12,4 +12,7 @@ export interface IChatGptProps {
|
|||
context: BaseComponentContext;
|
||||
theme: ITheme | IReadonlyTheme ;
|
||||
chatId: string;
|
||||
teamsId: string;
|
||||
channelId: string;
|
||||
parentMessageId: string;
|
||||
}
|
||||
|
|
|
@ -11,6 +11,9 @@ export interface IGlobalState {
|
|||
isDarkTheme: boolean;
|
||||
hasTeamsContext: boolean;
|
||||
chatId: string;
|
||||
teamsId: string;
|
||||
channelId: string;
|
||||
parentMessageId: string;
|
||||
appId: string;
|
||||
AzureFunctionUrl: string;
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
export interface IRenderAnswerProps {
|
||||
answer: string;
|
||||
question?:string
|
||||
}
|
||||
|
|
|
@ -66,6 +66,9 @@ export default class ChatGptWebPart extends BaseClientSideWebPart<IChatGptProps>
|
|||
theme: this._currentTheme,
|
||||
context: this.context,
|
||||
chatId: this._chatId,
|
||||
teamsId: this._teamId,
|
||||
channelId: this._channelId,
|
||||
parentMessageId: this._parentMessageId,
|
||||
});
|
||||
|
||||
ReactDom.render(element, this.domElement);
|
||||
|
@ -84,6 +87,7 @@ export default class ChatGptWebPart extends BaseClientSideWebPart<IChatGptProps>
|
|||
this._channelId = teamsContext.channel?.id;
|
||||
this._parentMessageId = teamsContext.app.parentMessageId;
|
||||
|
||||
|
||||
console.log("chatId", this._chatId);
|
||||
console.log("teamId", this._teamId);
|
||||
console.log("channelId", this._channelId);
|
||||
|
|
|
@ -3,7 +3,7 @@ define([], function() {
|
|||
CgatGPTAppOpenAILabel: " Open AI",
|
||||
ChatGPTAppNotificationMessage: "Answer was sent to chat",
|
||||
ChatGPTAppNotificationTitle: "Sent to chat",
|
||||
ChatGPTAppPoweredByLabel: "Powered by OpenAI, GPT-3",
|
||||
ChatGPTAppPoweredByLabel: "Powered by OpenAI, ChatGPT-3.5-turbo",
|
||||
ChatGPTAppPreviewChatInfoMessage: " Please create a mesage first and after return here",
|
||||
PropertyPaneDescription: "ChatGPT App",
|
||||
BasicGroupName: "Properties",
|
||||
|
|
Loading…
Reference in New Issue