forked from microsoft/CopilotStudioSamples
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSyncToAsyncService.ts
More file actions
122 lines (104 loc) · 4.62 KB
/
Copy pathSyncToAsyncService.ts
File metadata and controls
122 lines (104 loc) · 4.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import { app, HttpRequest, HttpResponseInit, InvocationContext } from "@azure/functions";
import { Activity, ActivityTypes } from '@microsoft/agents-activity';
import { ConnectionSettings, CopilotStudioClient } from '@microsoft/agents-copilotstudio-client';
interface RequestBody {
environmentId: string;
agentIdentifier: string;
message: string;
conversationId?: string;
}
export async function SyncToAsyncService(request: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> {
context.log(`Http function processed request for url "${request.url}"`);
try {
// Extract bearer token from Authorization header
const authHeader = request.headers.get('Authorization');
if (!authHeader || !authHeader.startsWith('Bearer ')) {
return {
status: 401,
body: JSON.stringify({
error: "Unauthorized: Bearer token required in Authorization header"
}),
headers: { "Content-Type": "application/json" }
};
}
const bearerToken = authHeader.substring(7); // Remove 'Bearer ' prefix
// Parse request body
const body = await request.json() as RequestBody;
if (!body.environmentId || !body.agentIdentifier || !body.message) {
return {
status: 400,
body: JSON.stringify({
error: "Missing required parameters: environmentId, agentIdentifier, and message are required"
}),
headers: { "Content-Type": "application/json" }
};
}
// Create connection settings
const settings: ConnectionSettings = {
environmentId: body.environmentId,
agentIdentifier: body.agentIdentifier,
tenantId: '', // Not needed as token is passed as a parameter
appClientId: '' // Not needed as token is passed as a parameter
};
// Create Copilot Studio client with the bearer token from header
const copilotClient = new CopilotStudioClient(settings, bearerToken);
// Start conversation if no conversationId is provided
let conversationId = body.conversationId;
if (!conversationId) {
const startActivity = await copilotClient.startConversationAsync(true);
conversationId = startActivity.conversation?.id;
}
// Ask the question using the message from the body
const replies = await copilotClient.askQuestionAsync(body.message, conversationId!);
// Format the response - just return all activities as-is
const responseData = {
conversationId,
replies: replies.map((act: Activity) => ({
type: act.type,
text: act.text,
suggestedActions: act.suggestedActions,
attachments: act.attachments,
channelData: act.channelData
}))
};
return {
status: 200,
body: JSON.stringify(responseData),
headers: { "Content-Type": "application/json" }
};
} catch (error) {
context.error('Error in SyncToAsyncService:', error);
let errorMessage = "Internal server error";
let statusCode = 500;
if (error instanceof Error) {
// Check if it's an Axios error
if ('isAxiosError' in error && error.isAxiosError) {
const axiosError = error as any;
if (axiosError.response) {
// Pass through the status code and message from the API
statusCode = axiosError.response.status;
errorMessage = axiosError.response.data?.message || axiosError.response.statusText || error.message;
} else if (axiosError.code === 'ENOTFOUND') {
statusCode = 400;
errorMessage = "Invalid environment ID";
} else if (axiosError.code === 'ERR_NETWORK') {
errorMessage = "Network error";
}
} else {
errorMessage = error.message;
}
}
return {
status: statusCode,
body: JSON.stringify({
error: errorMessage
}),
headers: { "Content-Type": "application/json" }
};
}
}
app.http('SyncToAsyncService', {
methods: ['POST'],
authLevel: 'anonymous',
handler: SyncToAsyncService
});