1 | ;
|
2 | /**
|
3 | * @module botbuilder
|
4 | */
|
5 | /**
|
6 | * Copyright (c) Microsoft Corporation. All rights reserved.
|
7 | * Licensed under the MIT License.
|
8 | */
|
9 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
10 | return new (P || (P = Promise))(function (resolve, reject) {
|
11 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
12 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
13 | function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
|
14 | step((generator = generator.apply(thisArg, _arguments || [])).next());
|
15 | });
|
16 | };
|
17 | Object.defineProperty(exports, "__esModule", { value: true });
|
18 | const http_1 = require("http");
|
19 | const botbuilder_core_1 = require("botbuilder-core");
|
20 | const botframework_connector_1 = require("botframework-connector");
|
21 | const statusCodeError_1 = require("./statusCodeError");
|
22 | /**
|
23 | * The ChannelServiceHandler implements API to forward activity to a skill and
|
24 | * implements routing ChannelAPI calls from the Skill up through the bot/adapter.
|
25 | */
|
26 | class ChannelServiceHandler {
|
27 | /**
|
28 | * Initializes a new instance of the ChannelServiceHandler class, using a credential provider.
|
29 | * @param credentialProvider The credential provider.
|
30 | * @param authConfig The authentication configuration.
|
31 | * @param channelService A string representing the channel provider.
|
32 | */
|
33 | constructor(credentialProvider, authConfig, channelService) {
|
34 | if (!credentialProvider) {
|
35 | throw new Error('BotFrameworkHttpClient(): missing credentialProvider');
|
36 | }
|
37 | if (!authConfig) {
|
38 | throw new Error('BotFrameworkHttpClient(): missing authConfig');
|
39 | }
|
40 | this.credentialProvider = credentialProvider;
|
41 | this.authConfig = authConfig;
|
42 | this.channelService = channelService || process.env[botframework_connector_1.AuthenticationConstants.ChannelService];
|
43 | }
|
44 | handleSendToConversation(authHeader, conversationId, activity) {
|
45 | return __awaiter(this, void 0, void 0, function* () {
|
46 | const claimsIdentity = yield this.authenticate(authHeader);
|
47 | return yield this.onSendToConversation(claimsIdentity, conversationId, activity);
|
48 | });
|
49 | }
|
50 | handleReplyToActivity(authHeader, conversationId, activityId, activity) {
|
51 | return __awaiter(this, void 0, void 0, function* () {
|
52 | const claimsIdentity = yield this.authenticate(authHeader);
|
53 | return yield this.onReplyToActivity(claimsIdentity, conversationId, activityId, activity);
|
54 | });
|
55 | }
|
56 | handleUpdateActivity(authHeader, conversationId, activityId, activity) {
|
57 | return __awaiter(this, void 0, void 0, function* () {
|
58 | const claimsIdentity = yield this.authenticate(authHeader);
|
59 | return yield this.onUpdateActivity(claimsIdentity, conversationId, activityId, activity);
|
60 | });
|
61 | }
|
62 | handleDeleteActivity(authHeader, conversationId, activityId) {
|
63 | return __awaiter(this, void 0, void 0, function* () {
|
64 | const claimsIdentity = yield this.authenticate(authHeader);
|
65 | yield this.onDeleteActivity(claimsIdentity, conversationId, activityId);
|
66 | });
|
67 | }
|
68 | handleGetActivityMembers(authHeader, conversationId, activityId) {
|
69 | return __awaiter(this, void 0, void 0, function* () {
|
70 | const claimsIdentity = yield this.authenticate(authHeader);
|
71 | return yield this.onGetActivityMembers(claimsIdentity, conversationId, activityId);
|
72 | });
|
73 | }
|
74 | handleCreateConversation(authHeader, parameters) {
|
75 | return __awaiter(this, void 0, void 0, function* () {
|
76 | const claimsIdentity = yield this.authenticate(authHeader);
|
77 | return yield this.onCreateConversation(claimsIdentity, parameters);
|
78 | });
|
79 | }
|
80 | handleGetConversations(authHeader, conversationId, continuationToken /* some default */) {
|
81 | return __awaiter(this, void 0, void 0, function* () {
|
82 | const claimsIdentity = yield this.authenticate(authHeader);
|
83 | return yield this.onGetConversations(claimsIdentity, conversationId, continuationToken);
|
84 | });
|
85 | }
|
86 | handleGetConversationMembers(authHeader, conversationId) {
|
87 | return __awaiter(this, void 0, void 0, function* () {
|
88 | const claimsIdentity = yield this.authenticate(authHeader);
|
89 | return yield this.onGetConversationMembers(claimsIdentity, conversationId);
|
90 | });
|
91 | }
|
92 | handleGetConversationPagedMembers(authHeader, conversationId, pageSize = -1, continuationToken) {
|
93 | return __awaiter(this, void 0, void 0, function* () {
|
94 | const claimsIdentity = yield this.authenticate(authHeader);
|
95 | return yield this.onGetConversationPagedMembers(claimsIdentity, conversationId, pageSize, continuationToken);
|
96 | });
|
97 | }
|
98 | handleDeleteConversationMember(authHeader, conversationId, memberId) {
|
99 | return __awaiter(this, void 0, void 0, function* () {
|
100 | const claimsIdentity = yield this.authenticate(authHeader);
|
101 | yield this.onDeleteConversationMember(claimsIdentity, conversationId, memberId);
|
102 | });
|
103 | }
|
104 | handleSendConversationHistory(authHeader, conversationId, transcript) {
|
105 | return __awaiter(this, void 0, void 0, function* () {
|
106 | const claimsIdentity = yield this.authenticate(authHeader);
|
107 | return yield this.onSendConversationHistory(claimsIdentity, conversationId, transcript);
|
108 | });
|
109 | }
|
110 | handleUploadAttachment(authHeader, conversationId, attachmentUpload) {
|
111 | return __awaiter(this, void 0, void 0, function* () {
|
112 | const claimsIdentity = yield this.authenticate(authHeader);
|
113 | return yield this.onUploadAttachment(claimsIdentity, conversationId, attachmentUpload);
|
114 | });
|
115 | }
|
116 | /**
|
117 | * SendToConversation() API for Skill.
|
118 | * @remarks
|
119 | * This method allows you to send an activity to the end of a conversation.
|
120 | * This is slightly different from ReplyToActivity().
|
121 | * * SendToConversation(conversationId) - will append the activity to the end
|
122 | * of the conversation according to the timestamp or semantics of the channel.
|
123 | * * ReplyToActivity(conversationId,ActivityId) - adds the activity as a reply
|
124 | * to another activity, if the channel supports it. If the channel does not
|
125 | * support nested replies, ReplyToActivity falls back to SendToConversation.
|
126 | *
|
127 | * Use ReplyToActivity when replying to a specific activity in the
|
128 | * conversation.
|
129 | *
|
130 | * Use SendToConversation in all other cases.
|
131 | * @param claimsIdentity ClaimsIdentity for the bot, should have AudienceClaim, AppIdClaim and ServiceUrlClaim.
|
132 | * @param conversationId
|
133 | * @param activity
|
134 | */
|
135 | onSendToConversation(claimsIdentity, conversationId, activity) {
|
136 | return __awaiter(this, void 0, void 0, function* () {
|
137 | throw new Error(`ChannelServiceHandler.onSendToConversation(): ${botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED}: ${http_1.STATUS_CODES[botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED]}`);
|
138 | });
|
139 | }
|
140 | /**
|
141 | * ReplyToActivity() API for Skill.
|
142 | * @remarks
|
143 | * This method allows you to reply to an activity.
|
144 | *
|
145 | * This is slightly different from SendToConversation().
|
146 | * * SendToConversation(conversationId) - will append the activity to the end
|
147 | * of the conversation according to the timestamp or semantics of the channel.
|
148 | * * ReplyToActivity(conversationId,ActivityId) - adds the activity as a reply
|
149 | * to another activity, if the channel supports it. If the channel does not
|
150 | * support nested replies, ReplyToActivity falls back to SendToConversation.
|
151 | *
|
152 | * Use ReplyToActivity when replying to a specific activity in the
|
153 | * conversation.
|
154 | *
|
155 | * Use SendToConversation in all other cases.
|
156 | * @param claimsIdentity ClaimsIdentity for the bot, should have AudienceClaim, AppIdClaim and ServiceUrlClaim.
|
157 | * @param conversationId Conversation ID.
|
158 | * @param activityId activityId the reply is to (OPTIONAL).
|
159 | * @param activity Activity to send.
|
160 | */
|
161 | onReplyToActivity(claimsIdentity, conversationId, activityId, activity) {
|
162 | return __awaiter(this, void 0, void 0, function* () {
|
163 | throw new statusCodeError_1.StatusCodeError(botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED, `ChannelServiceHandler.onReplyToActivity(): ${botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED}: ${http_1.STATUS_CODES[botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED]}`);
|
164 | });
|
165 | }
|
166 | /**
|
167 | * UpdateActivity() API for Skill.
|
168 | * @remarks
|
169 | * Edit an existing activity.
|
170 | *
|
171 | * Some channels allow you to edit an existing activity to reflect the new
|
172 | * state of a bot conversation.
|
173 | *
|
174 | * For example, you can remove buttons after someone has clicked "Approve" button.
|
175 | * @param claimsIdentity ClaimsIdentity for the bot, should have AudienceClaim, AppIdClaim and ServiceUrlClaim.
|
176 | * @param conversationId Conversation ID.
|
177 | * @param activityId activityId to update.
|
178 | * @param activity replacement Activity.
|
179 | */
|
180 | onUpdateActivity(claimsIdentity, conversationId, activityId, activity) {
|
181 | return __awaiter(this, void 0, void 0, function* () {
|
182 | throw new statusCodeError_1.StatusCodeError(botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED, `ChannelServiceHandler.onUpdateActivity(): ${botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED}: ${http_1.STATUS_CODES[botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED]}`);
|
183 | });
|
184 | }
|
185 | /**
|
186 | * DeleteActivity() API for Skill.
|
187 | * @remarks
|
188 | * Delete an existing activity.
|
189 | *
|
190 | * Some channels allow you to delete an existing activity, and if successful
|
191 | * this method will remove the specified activity.
|
192 | *
|
193 | *
|
194 | * @param claimsIdentity ClaimsIdentity for the bot, should have AudienceClaim, AppIdClaim and ServiceUrlClaim.
|
195 | * @param conversationId Conversation ID.
|
196 | * @param activityId activityId to delete.
|
197 | */
|
198 | onDeleteActivity(claimsIdentity, conversationId, activityId) {
|
199 | return __awaiter(this, void 0, void 0, function* () {
|
200 | throw new statusCodeError_1.StatusCodeError(botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED, `ChannelServiceHandler.onDeleteActivity(): ${botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED}: ${http_1.STATUS_CODES[botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED]}`);
|
201 | });
|
202 | }
|
203 | /**
|
204 | * GetActivityMembers() API for Skill.
|
205 | * @remarks
|
206 | * Enumerate the members of an activity.
|
207 | *
|
208 | * This REST API takes a ConversationId and a ActivityId, returning an array
|
209 | * of ChannelAccount objects representing the members of the particular
|
210 | * activity in the conversation.
|
211 | * @param claimsIdentity ClaimsIdentity for the bot, should have AudienceClaim, AppIdClaim and ServiceUrlClaim.
|
212 | * @param conversationId Conversation ID.
|
213 | * @param activityId Activity ID.
|
214 | */
|
215 | onGetActivityMembers(claimsIdentity, conversationId, activityId) {
|
216 | return __awaiter(this, void 0, void 0, function* () {
|
217 | throw new statusCodeError_1.StatusCodeError(botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED, `ChannelServiceHandler.onGetActivityMembers(): ${botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED}: ${http_1.STATUS_CODES[botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED]}`);
|
218 | });
|
219 | }
|
220 | /**
|
221 | * CreateConversation() API for Skill.
|
222 | * @remarks
|
223 | * Create a new Conversation.
|
224 | *
|
225 | * POST to this method with a
|
226 | * * Bot being the bot creating the conversation
|
227 | * * IsGroup set to true if this is not a direct message (default is false)
|
228 | * * Array containing the members to include in the conversation
|
229 | *
|
230 | * The return value is a ResourceResponse which contains a conversation id
|
231 | * which is suitable for use in the message payload and REST API uris.
|
232 | *
|
233 | * Most channels only support the semantics of bots initiating a direct
|
234 | * message conversation.
|
235 | * @param claimsIdentity ClaimsIdentity for the bot, should have AudienceClaim, AppIdClaim and ServiceUrlClaim.
|
236 | * @param conversationId Conversation ID.
|
237 | * @param parameters Parameters to create the conversation from.
|
238 | */
|
239 | onCreateConversation(claimsIdentity, parameters) {
|
240 | return __awaiter(this, void 0, void 0, function* () {
|
241 | throw new statusCodeError_1.StatusCodeError(botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED, `ChannelServiceHandler.onCreateConversation(): ${botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED}: ${http_1.STATUS_CODES[botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED]}`);
|
242 | });
|
243 | }
|
244 | /**
|
245 | * onGetConversations() API for Skill.
|
246 | * @remarks
|
247 | * List the Conversations in which this bot has participated.
|
248 | *
|
249 | * GET from this method with a skip token
|
250 | *
|
251 | * The return value is a ConversationsResult, which contains an array of
|
252 | * ConversationMembers and a skip token. If the skip token is not empty, then
|
253 | * there are further values to be returned. Call this method again with the
|
254 | * returned token to get more values.
|
255 | *
|
256 | * Each ConversationMembers object contains the ID of the conversation and an
|
257 | * array of ChannelAccounts that describe the members of the conversation.
|
258 | * @param claimsIdentity ClaimsIdentity for the bot, should have AudienceClaim, AppIdClaim and ServiceUrlClaim.
|
259 | * @param conversationId Conversation ID.
|
260 | * @param continuationToken Skip or continuation token.
|
261 | */
|
262 | onGetConversations(claimsIdentity, conversationId, continuationToken) {
|
263 | return __awaiter(this, void 0, void 0, function* () {
|
264 | throw new statusCodeError_1.StatusCodeError(botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED, `ChannelServiceHandler.onGetConversations(): ${botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED}: ${http_1.STATUS_CODES[botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED]}`);
|
265 | });
|
266 | }
|
267 | /**
|
268 | * getConversationMembers() API for Skill.
|
269 | * @remarks
|
270 | * Enumerate the members of a conversation.
|
271 | *
|
272 | * This REST API takes a ConversationId and returns an array of ChannelAccount
|
273 | * objects representing the members of the conversation.
|
274 | * @param claimsIdentity ClaimsIdentity for the bot, should have AudienceClaim, AppIdClaim and ServiceUrlClaim.
|
275 | * @param conversationId Conversation ID.
|
276 | */
|
277 | onGetConversationMembers(claimsIdentity, conversationId) {
|
278 | return __awaiter(this, void 0, void 0, function* () {
|
279 | throw new statusCodeError_1.StatusCodeError(botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED, `ChannelServiceHandler.onGetConversationMembers(): ${botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED}: ${http_1.STATUS_CODES[botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED]}`);
|
280 | });
|
281 | }
|
282 | /**
|
283 | * getConversationPagedMembers() API for Skill.
|
284 | * @remarks
|
285 | * Enumerate the members of a conversation one page at a time.
|
286 | *
|
287 | * This REST API takes a ConversationId. Optionally a pageSize and/or
|
288 | * continuationToken can be provided. It returns a PagedMembersResult, which
|
289 | * contains an array
|
290 | * of ChannelAccounts representing the members of the conversation and a
|
291 | * continuation token that can be used to get more values.
|
292 | *
|
293 | * One page of ChannelAccounts records are returned with each call. The number
|
294 | * of records in a page may vary between channels and calls. The pageSize
|
295 | * parameter can be used as
|
296 | * a suggestion. If there are no additional results the response will not
|
297 | * contain a continuation token. If there are no members in the conversation
|
298 | * the Members will be empty or not present in the response.
|
299 | *
|
300 | * A response to a request that has a continuation token from a prior request
|
301 | * may rarely return members from a previous request.
|
302 | * @param claimsIdentity ClaimsIdentity for the bot, should have AudienceClaim, AppIdClaim and ServiceUrlClaim.
|
303 | * @param conversationId Conversation ID.
|
304 | * @param pageSize Suggested page size.
|
305 | * @param continuationToken Continuation Token.
|
306 | */
|
307 | onGetConversationPagedMembers(claimsIdentity, conversationId, pageSize = -1, continuationToken) {
|
308 | return __awaiter(this, void 0, void 0, function* () {
|
309 | throw new statusCodeError_1.StatusCodeError(botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED, `ChannelServiceHandler.onGetConversationPagedMembers(): ${botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED}: ${http_1.STATUS_CODES[botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED]}`);
|
310 | });
|
311 | }
|
312 | /**
|
313 | * DeleteConversationMember() API for Skill.
|
314 | * @remarks
|
315 | * Deletes a member from a conversation.
|
316 | *
|
317 | * This REST API takes a ConversationId and a memberId (of type string) and
|
318 | * removes that member from the conversation. If that member was the last member
|
319 | * of the conversation, the conversation will also be deleted.
|
320 | * @param claimsIdentity ClaimsIdentity for the bot, should have AudienceClaim, AppIdClaim and ServiceUrlClaim.
|
321 | * @param conversationId Conversation ID.
|
322 | * @param memberId ID of the member to delete from this conversation.
|
323 | */
|
324 | onDeleteConversationMember(claimsIdentity, conversationId, memberId) {
|
325 | return __awaiter(this, void 0, void 0, function* () {
|
326 | throw new statusCodeError_1.StatusCodeError(botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED, `ChannelServiceHandler.onDeleteConversationMember(): ${botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED}: ${http_1.STATUS_CODES[botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED]}`);
|
327 | });
|
328 | }
|
329 | /**
|
330 | * SendConversationHistory() API for Skill.
|
331 | * @remarks
|
332 | * This method allows you to upload the historic activities to the
|
333 | * conversation.
|
334 | *
|
335 | * Sender must ensure that the historic activities have unique ids and
|
336 | * appropriate timestamps. The ids are used by the client to deal with
|
337 | * duplicate activities and the timestamps are used by the client to render
|
338 | * the activities in the right order.
|
339 | * @param claimsIdentity ClaimsIdentity for the bot, should have AudienceClaim, AppIdClaim and ServiceUrlClaim.
|
340 | * @param conversationId Conversation ID.
|
341 | * @param transcript Transcript of activities.
|
342 | */
|
343 | onSendConversationHistory(claimsIdentity, conversationId, transcript) {
|
344 | return __awaiter(this, void 0, void 0, function* () {
|
345 | throw new statusCodeError_1.StatusCodeError(botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED, `ChannelServiceHandler.onSendConversationHistory(): ${botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED}: ${http_1.STATUS_CODES[botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED]}`);
|
346 | });
|
347 | }
|
348 | /**
|
349 | * UploadAttachment() API for Skill.
|
350 | * @remarks
|
351 | * Upload an attachment directly into a channel's blob storage.
|
352 | *
|
353 | * This is useful because it allows you to store data in a compliant store
|
354 | * when dealing with enterprises.
|
355 | *
|
356 | * The response is a ResourceResponse which contains an AttachmentId which is
|
357 | * suitable for using with the attachments API.
|
358 | * @param claimsIdentity ClaimsIdentity for the bot, should have AudienceClaim, AppIdClaim and ServiceUrlClaim.
|
359 | * @param conversationId Conversation ID.
|
360 | * @param attachmentUpload Attachment data.
|
361 | */
|
362 | onUploadAttachment(claimsIdentity, conversationId, attachmentUpload) {
|
363 | return __awaiter(this, void 0, void 0, function* () {
|
364 | throw new statusCodeError_1.StatusCodeError(botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED, `ChannelServiceHandler.onUploadAttachment(): ${botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED}: ${http_1.STATUS_CODES[botbuilder_core_1.StatusCodes.NOT_IMPLEMENTED]}`);
|
365 | });
|
366 | }
|
367 | authenticate(authHeader) {
|
368 | return __awaiter(this, void 0, void 0, function* () {
|
369 | try {
|
370 | if (!authHeader) {
|
371 | const isAuthDisable = this.credentialProvider.isAuthenticationDisabled();
|
372 | if (isAuthDisable) {
|
373 | // In the scenario where Auth is disabled, we still want to have the
|
374 | // IsAuthenticated flag set in the ClaimsIdentity. To do this requires
|
375 | // adding in an empty claim.
|
376 | return new botframework_connector_1.ClaimsIdentity([], false);
|
377 | }
|
378 | }
|
379 | return yield botframework_connector_1.JwtTokenValidation.validateAuthHeader(authHeader, this.credentialProvider, this.channelService, 'unknown', undefined, this.authConfig);
|
380 | }
|
381 | catch (err) {
|
382 | throw new statusCodeError_1.StatusCodeError(botbuilder_core_1.StatusCodes.UNAUTHORIZED);
|
383 | }
|
384 | });
|
385 | }
|
386 | }
|
387 | exports.ChannelServiceHandler = ChannelServiceHandler;
|
388 | //# sourceMappingURL=channelServiceHandler.js.map |
\ | No newline at end of file |