@microsoft/teams.apps
Version:
<p> <a href="https://www.npmjs.com/package/@microsoft/teams.apps" target="_blank"> <img src="https://img.shields.io/npm/v/@microsoft/teams.apps/latest" /> </a> <a href="https://www.npmjs.com/package/@microsoft/teams.apps?activeTab=code
257 lines • 17 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.HttpPlugin = void 0;
const http_1 = __importDefault(require("http"));
const cors_1 = __importDefault(require("cors"));
const express_1 = __importDefault(require("express"));
const teams_api_1 = require("@microsoft/teams.api");
const $http = __importStar(require("@microsoft/teams.common/http"));
const package_json_1 = __importDefault(require("../../../package.json"));
const jwt_validation_middleware_1 = require("../../middleware/jwt-validation-middleware");
const types_1 = require("../../types");
const stream_1 = require("./stream");
/**
* Can send/receive activities via http
*/
let HttpPlugin = class HttpPlugin {
logger;
client;
manifest;
credentials;
botToken;
graphToken;
$onError;
$onActivity;
get;
post;
patch;
put;
delete;
route;
use;
get server() {
return this._server;
}
_server;
get port() {
return this._port;
}
_port;
express;
pending = {};
skipAuth;
constructor(server, options) {
this.skipAuth = options?.skipAuth ?? false;
this.express = (0, express_1.default)();
this._server = server || http_1.default.createServer();
this._server.on('request', this.express);
this.get = this.express.get.bind(this.express);
this.post = this.express.post.bind(this.express);
this.patch = this.express.patch.bind(this.express);
this.put = this.express.put.bind(this.express);
this.delete = this.express.delete.bind(this.express);
this.route = this.express.route.bind(this.express);
this.use = this.express.use.bind(this.express);
this.express.use((0, cors_1.default)());
this.express.use('/api*', express_1.default.json());
}
/**
* serve static files
* @param path the url path to serve
* @param dist the dist file path to serve
*/
static(path, dist) {
this.express.use(path, express_1.default.static(dist));
return this;
}
onInit() {
const messageHandlers = [this.onRequest.bind(this)];
if (!this.skipAuth) {
// Setup /api/messages route with JWT validation middleware
const jwtMiddleware = (0, jwt_validation_middleware_1.withJwtValidation)({
credentials: this.credentials,
logger: this.logger
});
messageHandlers.unshift(jwtMiddleware);
}
this.express.post('/api/messages', ...messageHandlers);
}
async onStart({ port }) {
this._port = port;
this.express.get('/', (_, res) => {
res.send(this.manifest);
});
return await new Promise((resolve, reject) => {
this._server.on('error', (err) => {
this.$onError({ error: err });
reject(err);
});
this._server.listen(port, () => {
this.logger.info(`listening on port ${port} 🚀`);
resolve();
});
});
}
onStop() {
this._server.close();
}
onError({ error, activity }) {
if (!activity)
return;
const res = this.pending[activity.id];
if (!res) {
return;
}
if (!res.headersSent) {
res.status(500).send(error.message);
}
delete this.pending[activity.id];
}
onActivityResponse({ response, activity }) {
const res = this.pending[activity.id];
if (!res) {
return;
}
if (!res.headersSent) {
res.status(response.status || 200).send(JSON.stringify(response.body));
}
delete this.pending[activity.id];
}
async send(activity, ref) {
const api = new teams_api_1.Client(ref.serviceUrl, this.client.clone({
token: this.botToken,
}));
activity = {
...activity,
from: ref.bot,
conversation: ref.conversation,
};
if (activity.id) {
const res = await api.conversations
.activities(ref.conversation.id)
.update(activity.id, activity);
return { ...activity, ...res };
}
const res = await api.conversations.activities(ref.conversation.id).create(activity);
return { ...activity, ...res };
}
createStream(ref) {
return new stream_1.HttpStream(new teams_api_1.Client(ref.serviceUrl, this.client.clone({
token: this.botToken,
})), ref, this.logger);
}
/**
* validates an incoming http request
* @param req the incoming http request
* @param res the http response
*/
async onRequest(req, res, _next) {
const activity = req.body;
let token;
if (req.validatedToken) {
token = req.validatedToken;
}
else {
token = {
appId: '',
from: 'azure',
fromId: '',
serviceUrl: activity.serviceUrl || '',
isExpired: () => false,
};
}
this.pending[activity.id] = res;
this.$onActivity({
sender: this,
activity,
token,
});
}
};
exports.HttpPlugin = HttpPlugin;
__decorate([
(0, types_1.Logger)(),
__metadata("design:type", Object)
], HttpPlugin.prototype, "logger", void 0);
__decorate([
(0, types_1.Dependency)(),
__metadata("design:type", $http.Client)
], HttpPlugin.prototype, "client", void 0);
__decorate([
(0, types_1.Dependency)(),
__metadata("design:type", Object)
], HttpPlugin.prototype, "manifest", void 0);
__decorate([
(0, types_1.Dependency)({ optional: true }),
__metadata("design:type", Object)
], HttpPlugin.prototype, "credentials", void 0);
__decorate([
(0, types_1.Dependency)({ optional: true }),
__metadata("design:type", Function)
], HttpPlugin.prototype, "botToken", void 0);
__decorate([
(0, types_1.Dependency)({ optional: true }),
__metadata("design:type", Function)
], HttpPlugin.prototype, "graphToken", void 0);
__decorate([
(0, types_1.Event)('error'),
__metadata("design:type", Function)
], HttpPlugin.prototype, "$onError", void 0);
__decorate([
(0, types_1.Event)('activity'),
__metadata("design:type", Function)
], HttpPlugin.prototype, "$onActivity", void 0);
exports.HttpPlugin = HttpPlugin = __decorate([
(0, types_1.Plugin)({
name: 'http',
version: package_json_1.default.version,
description: 'the default plugin for sending/receiving activities',
}),
__metadata("design:paramtypes", [http_1.default.Server, Object])
], HttpPlugin);
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2luLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3BsdWdpbnMvaHR0cC9wbHVnaW4udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsZ0RBQXdCO0FBRXhCLGdEQUF3QjtBQUN4QixzREFBOEI7QUFFOUIsb0RBTzhCO0FBRzlCLG9FQUFzRDtBQUV0RCx5RUFBd0M7QUFHeEMsMEZBQW9HO0FBQ3BHLHVDQVVxQjtBQUdyQixxQ0FBc0M7QUFFdEM7O0dBRUc7QUFNSSxJQUFNLFVBQVUsR0FBaEIsTUFBTSxVQUFVO0lBRVosTUFBTSxDQUFXO0lBR2pCLE1BQU0sQ0FBZ0I7SUFHdEIsUUFBUSxDQUFxQjtJQUc3QixXQUFXLENBQWU7SUFHMUIsUUFBUSxDQUFnQjtJQUd4QixVQUFVLENBQWdCO0lBRzFCLFFBQVEsQ0FBZ0M7SUFHeEMsV0FBVyxDQUFtQztJQUU5QyxHQUFHLENBQTZCO0lBQ2hDLElBQUksQ0FBOEI7SUFDbEMsS0FBSyxDQUErQjtJQUNwQyxHQUFHLENBQTZCO0lBQ2hDLE1BQU0sQ0FBZ0M7SUFDdEMsS0FBSyxDQUErQjtJQUNwQyxHQUFHLENBQTZCO0lBRXpDLElBQUksTUFBTTtRQUNSLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQztJQUN0QixDQUFDO0lBQ1MsT0FBTyxDQUFjO0lBRS9CLElBQUksSUFBSTtRQUNOLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQztJQUNwQixDQUFDO0lBQ1MsS0FBSyxDQUFtQjtJQUV4QixPQUFPLENBQXNCO0lBQzdCLE9BQU8sR0FBcUMsRUFBRSxDQUFDO0lBQy9DLFFBQVEsQ0FBVTtJQUU1QixZQUFZLE1BQW9CLEVBQUUsT0FBZ0M7UUFDaEUsSUFBSSxDQUFDLFFBQVEsR0FBRyxPQUFPLEVBQUUsUUFBUSxJQUFJLEtBQUssQ0FBQztRQUMzQyxJQUFJLENBQUMsT0FBTyxHQUFHLElBQUEs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