UNPKG

21 kBJavaScriptView Raw
1"use strict";
2/**
3 * @module botbuilder
4 */
5/**
6 * Copyright (c) Microsoft Corporation. All rights reserved.
7 * Licensed under the MIT License.
8 */
9var __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};
17Object.defineProperty(exports, "__esModule", { value: true });
18const http_1 = require("http");
19const botbuilder_core_1 = require("botbuilder-core");
20const botframework_connector_1 = require("botframework-connector");
21const 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 */
26class 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}
387exports.ChannelServiceHandler = ChannelServiceHandler;
388//# sourceMappingURL=channelServiceHandler.js.map
\No newline at end of file