Teams technical integration
Ways to connect Teams and Tallyfy
Section titled “Ways to connect Teams and Tallyfy”Microsoft Teams integration relies on three main tools: Graph API, Adaptive Cards, and Power Automate. Pick whichever fits your setup.
Power Automate (recommended)
Section titled “Power Automate (recommended)”The easiest route uses Power Automate as middleware between Teams and Tallyfy:
Trigger: When a message is posted to a channelAction: HTTP POST to Tallyfy APIAction: Post Adaptive Card to Teams with workflow linkAdaptive Cards for task notifications
Section titled “Adaptive Cards for task notifications”You can send rich, interactive cards to Teams channels whenever Tallyfy tasks get assigned:
{ "$schema": "http://adaptivecards.io/schemas/adaptive-card.json", "type": "AdaptiveCard", "version": "1.4", "body": [ { "type": "TextBlock", "text": "New Task Assigned", "weight": "Bolder", "size": "Medium" }, { "type": "FactSet", "facts": [ { "title": "Task:", "value": "${taskTitle}" }, { "title": "Process:", "value": "${processName}" }, { "title": "Due:", "value": "${dueDate}" }, { "title": "Assigned by:", "value": "${assignedBy}" } ] }, { "type": "TextBlock", "text": "${taskDescription}", "wrap": true } ], "actions": [ { "type": "Action.OpenUrl", "title": "Open in Tallyfy", "url": "${taskUrl}" }, { "type": "Action.Submit", "title": "Mark Complete", "data": { "action": "complete", "taskId": "${taskId}" } } ]}Microsoft Graph API integration
Section titled “Microsoft Graph API integration”Post Tallyfy workflow updates to Teams channels through the Graph API:
const { Client } = require('@microsoft/microsoft-graph-client');
const postToTeamsChannel = async (channelId, teamId, message, card) => { const client = Client.init({ authProvider: (done) => done(null, accessToken) });
await client .api(`/teams/${teamId}/channels/${channelId}/messages`) .post({ body: { contentType: 'html', content: message }, attachments: [{ contentType: 'application/vnd.microsoft.card.adaptive', content: JSON.stringify(card) }] });};
// Example: Post when Tallyfy workflow completesconst notifyWorkflowComplete = async (workflow) => { const card = { type: 'AdaptiveCard', version: '1.4', body: [{ type: 'TextBlock', text: `✅ Workflow Complete: ${workflow.name}`, weight: 'Bolder' }, { type: 'FactSet', facts: [ { title: 'Completed by:', value: workflow.completedBy }, { title: 'Duration:', value: workflow.duration }, { title: 'Tasks:', value: `${workflow.completedTasks}/${workflow.totalTasks}` } ] }] };
await postToTeamsChannel(channelId, teamId, 'Workflow completed', card);};Incoming webhooks
Section titled “Incoming webhooks”For simpler setups, Teams incoming webhooks work well:
const postToTeamsWebhook = async (webhookUrl, message) => { await fetch(webhookUrl, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ '@type': 'MessageCard', '@context': 'http://schema.org/extensions', summary: message.title, themeColor: '0076D7', title: message.title, sections: [{ activityTitle: message.subtitle, facts: message.facts, text: message.body }], potentialAction: [{ '@type': 'OpenUri', name: 'View in Tallyfy', targets: [{ os: 'default', uri: message.url }] }] }) });};Bot Framework integration
Section titled “Bot Framework integration”Need richer interaction? You’ll want a custom Teams bot:
const { TeamsActivityHandler, CardFactory } = require('botbuilder');
class TallyfyBot extends TeamsActivityHandler { constructor() { super();
this.onMessage(async (context, next) => { const text = context.activity.text.toLowerCase();
if (text.includes('launch workflow')) { const workflowName = text.replace('launch workflow', '').trim(); const workflow = await launchTallyfyWorkflow(workflowName);
await context.sendActivity({ attachments: [CardFactory.adaptiveCard(createWorkflowCard(workflow))] }); }
if (text.includes('my tasks')) { const tasks = await getTallyfyTasks(context.activity.from.aadObjectId); await context.sendActivity({ attachments: [CardFactory.adaptiveCard(createTaskListCard(tasks))] }); }
await next(); }); }
async handleTeamsTaskSubmit(context, taskModuleRequest) { const { action, taskId } = taskModuleRequest.data;
if (action === 'complete') { await completeTallyfyTask(taskId); return { task: { type: 'message', value: 'Task marked complete!' }}; } }}Authentication setup
Section titled “Authentication setup”Teams integration uses Azure AD OAuth 2.01. Here’s the setup in Azure portal:
- Register your app in Azure AD
- Add Microsoft Graph API permissions
- Set redirect URIs for your integration
- Use client credentials flow for server-to-server calls
const { ConfidentialClientApplication } = require('@azure/msal-node');
const msalConfig = { auth: { clientId: process.env.AZURE_CLIENT_ID, clientSecret: process.env.AZURE_CLIENT_SECRET, authority: `https://login.microsoftonline.com/${process.env.AZURE_TENANT_ID}` }};
const cca = new ConfidentialClientApplication(msalConfig);
const getGraphToken = async () => { const result = await cca.acquireTokenByClientCredential({ scopes: ['https://graph.microsoft.com/.default'] }); return result.accessToken;};iPaaS alternatives
Section titled “iPaaS alternatives”If you don’t want to write custom code:
- Power Automate - Microsoft’s native automation platform
- Zapier - pre-built Teams triggers and actions
- Workato - enterprise automation with a Teams connector
- Make - visual workflow builder with Teams integration
Related articles
Section titled “Related articles”Power Automate > Integrating Power Automate approvals with Microsoft Teams
Power Automate > Connect Tallyfy to Power Automate
Footnotes
Section titled “Footnotes”-
Industry-standard protocol for secure delegated authorization without sharing passwords ↩
Was this helpful?
- 2026 Tallyfy, Inc.
- Privacy Policy
- Terms of Use
- Report Issue
- Trademarks