Antes de empezar debes preguntarte ¿por qué deberías aprender a realizar aplicaciones para MS Teams? Y te respondo, ya seas un desarrollador que trabaja en un ERP, CRM, una aplicación de monitorización, etc. Casi seguro que tendrás alguna información que vendría bien enviarla a algun canal de Teams: comunicar nuevas oportunidades, sacar un resumen las ventas, avisar de alguna incidencia del sistema, listado de mejoras de tu última versión (aquí lo enlazas con Azure DevOps), se me ocurren muchas cosas útiles y seguro que a ti más.
No tengo que decir que esta herramienta o similares llevan más de un año siendo la herramienta principal de trabajo. Es por así decirlo la herramienta mimada de cualquier fabricante, en este caso Teams para Microsoft, y desarrollar o implantar cualquier funcionalidad directamente relacionada con tu negocio incide directamente en la productividad.
Por tanto, si ¿alguna vez te has preguntado como realizar una aplicación en Microsoft Teams? si es así, continua leyendo. En 15 minutos tendrás tu prime Hello World! con Microsoft Teams. Eso sí, descontando el tiempo que nos lleve instalar las herramientas y cuentas necesarias.
Entra en los enlaces y sigue los siguientes pasos:
-
- Crea una cuenta de desarrolladores en Microsoft 365
- Prepara el espacio empresarial de Microsoft 365
- Instala Git, NodeJS y Visual Studio Code
- En Visual Studio Code instala la extensión Preview: Team Toolkit
Entra en Quick Start, revisa los pasos y el video, aquí se explica todo muy bien, pero aun así, yo continuaré con el ejemplo:
Creamos el primer proyecto de demostración, siguiendo los pasos que indico en la imagen:
Esperas el tiempo necesario para que pueda generar todo el proyecto.
Y lo ejecutamos directamente con las opciones de ejecución y depuración de VS Code. Automáticamente se han creado con la plantilla los ficheros launch.json y tasks.json. La primera vez que lo lances realizar cosa tales como la instalación de los NPM y la Azure App Application.
Si lo deseas ya puedes poner una parada en el codigo, por ejemplo en:
Y podrás ver el resultado en tu Teams, la instalas y ejecutas el botón:
Desplegar y publicar. Para ello tienes que ejecutar los pasos que indica el Readme.md. Desde Visual Studio Code:
-
- Abrir Menú Ver >> Paleta de comandos…
- Hacer login en Azure, para ello escribes: Sign in to Azure.
- Generar recursos en Azure, en la paleta de comandos: Teams: Provisioning in the cloud.
- Desplegar: Teams: Deploy to cloud.
Con esta secciones lo que has realizado es desplegar la aplicación en Azure.
Ahora tienes que revisar que este todo bien:
-
- Run and Debug Activity Portal.
- Launch Remote (Edge)
- Ejecuta y podrás ver el correcto funcionamiento.
El ultimo paso es crear el zip para desplegar:
-
- En la paleta de comandos: Teams: Validate manifest.
- Y luego Zip Teams metada package.
- Con el zip lo podrás subir a teams.
Enhorabuena has publicado tu primera aplicación en el tenant de producción (espero que sea de test) de tu organización.
Ahora toca personalizar un poco este proyecto y para ello realiza los mismos pasos, pero esta vez usa TypeScript en un proyecto llamado upload2Storage.
El primer paso será crea un Storages Account y obtener un SAS (shared access signature), como el siguiente.
Debemos establecer CORS, de la siguiente forma:
Si no te quedan claro los anteriores pasos, puedes seguir este enlace y ver las instrucciones más detallas. Tambien te servirá para lo que viene a continuación.
Debemos hacer una limpieza en el proyecto:
Añadimos una nueva entrada en los NPM del proyecto:
Y cambiamos el código de Tab.tsx:
// ./src/App.tsx
import React, { useState } from 'react';
import Path from 'path';
import uploadFileToBlob, { isStorageConfigured } from './azure-storage-blob';
const storageConfigured = isStorageConfigured();
const App = (): JSX.Element => {
// all blobs in container
const [blobList, setBlobList] = useState<string[]>([]);
// current file to upload into container
const [fileSelected, setFileSelected] = useState(null);
// UI/form management
const [uploading, setUploading] = useState(false);
const [inputKey, setInputKey] = useState(Math.random().toString(36));
const onFileChange = (event: any) => {
// capture file into state
setFileSelected(event.target.files[0]);
};
const onFileUpload = async () => {
// prepare UI
setUploading(true);
// *** UPLOAD TO AZURE STORAGE ***
const blobsInContainer: string[] = await uploadFileToBlob(fileSelected);
// prepare UI for results
setBlobList(blobsInContainer);
// reset state/form
setFileSelected(null);
setUploading(false);
setInputKey(Math.random().toString(36));
};
// display form
const DisplayForm = () => (
<div>
<input type="file" onChange={onFileChange} key={inputKey || ''} />
<button type="submit" onClick={onFileUpload}>
Upload!
</button>
</div>
)
// display file name and image
const DisplayImagesFromContainer = () => (
<div>
<h2>Container items</h2>
<ul>
{blobList.map((item) => {
return (
<li key={item}>
<div>
{Path.basename(item)}
<br />
<img src={item} alt={item} height="200" />
</div>
</li>
);
})}
</ul>
</div>
);
return (
<div>
<h1>Upload file to Azure Blob Storage</h1>
{storageConfigured && !uploading && DisplayForm()}
{storageConfigured && uploading && <div>Uploading</div>}
<hr />
{storageConfigured && blobList.length > 0 && DisplayImagesFromContainer()}
{!storageConfigured && <div>Storage is not configured.</div>}
</div>
);
};
export default App;
Y añades codigo a azure-storage-blob.tsx:
// ./src/azure-storage-blob.ts
// <snippet_package>
// THIS IS SAMPLE CODE ONLY - NOT MEANT FOR PRODUCTION USE
import { BlobServiceClient, ContainerClient} from '@azure/storage-blob';
const containerName = `tutorial-container`;
const sasToken = process.env.REACT_APP_STORAGESASTOKEN;
const storageAccountName = process.env.REACT_APP_STORAGERESOURCENAME;
// </snippet_package>
// <snippet_isStorageConfigured>
// Feature flag - disable storage feature to app if not configured
export const isStorageConfigured = () => {
return (!storageAccountName || !sasToken) ? false : true;
}
// </snippet_isStorageConfigured>
// <snippet_getBlobsInContainer>
// return list of blobs in container to display
const getBlobsInContainer = async (containerClient: ContainerClient) => {
const returnedBlobUrls: string[] = [];
// get list of blobs in container
// eslint-disable-next-line
for await (const blob of containerClient.listBlobsFlat()) {
// if image is public, just construct URL
returnedBlobUrls.push(
`https://${storageAccountName}.blob.core.windows.net/${containerName}/${blob.name}`
);
}
return returnedBlobUrls;
}
// </snippet_getBlobsInContainer>
// <snippet_createBlobInContainer>
const createBlobInContainer = async (containerClient: ContainerClient, file: File) => {
// create blobClient for container
const blobClient = containerClient.getBlockBlobClient(file.name);
// set mimetype as determined from browser with file upload control
const options = { blobHTTPHeaders: { blobContentType: file.type } };
// upload file
await blobClient.uploadData(file, options);
}
// </snippet_createBlobInContainer>
// <snippet_uploadFileToBlob>
const uploadFileToBlob = async (file: File | null): Promise<string[]> => {
if (!file) return [];
// get BlobService = notice `?` is pulled out of sasToken - if created in Azure portal
const blobService = new BlobServiceClient(
`https://${storageAccountName}.blob.core.windows.net/?${sasToken}`
);
// get Container - full public read access
const containerClient: ContainerClient = blobService.getContainerClient(containerName);
await containerClient.createIfNotExists({
access: 'container',
});
// upload file
await createBlobInContainer(containerClient, file);
// get list of blobs in container
return getBlobsInContainer(containerClient);
};
// </snippet_uploadFileToBlob>
export default uploadFileToBlob;
Este código es el que viene del ejemplo que os he puesto anteriormente en el enlace.
Solo te queda crear en el fichero .env estas nuevas entradas, con los valores obtenidos del Azure Storage:
Ejecutas:
Y listo ya tienes tu primera aplicación de Teams personalizada.
¿Por dónde continuar?
Mi sugerencia es que crees un ejemplo con backend, el ejemplo de TO-DO que te muestra como trabajar con Managed Identity y SSO, para que tengas una visión de como gestionar los token entre Teams, Frontend y Backend.
Y otra cosa que puedes investigar por tu cuenta ya son los Bots y los mensajes.
Hasta la proxima.
Si necesitas algun tipo de ayuda...
Al igual que escribo libros para ayudar a la comunidad, también puedo ayudarte en esto. Solo tienes que contactar via DM en LinkedIn o Twitter, los canales que más visito.