UNPKG

react-integration-buttons

Version:

A TypeScript React component for Microsoft Teams and ServiceNow integrations with deep linking support

769 lines (615 loc) • 20.5 kB
# react-integration-button A lightweight, fully typed React component for creating deep links to Microsoft Teams and ServiceNow with pre-populated messages and forms. [![npm version](https://img.shields.io/npm/v/react-integration-buttons.svg)](https://www.npmjs.com/package/react-integration-buttons) [![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue.svg)](https://www.typescriptlang.org/) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) ## Features ✨ **Dual Platform Support**: Seamlessly integrate with Microsoft Teams and ServiceNow šŸŽØ **Markdown & HTML Formatting**: Support for bold, italic, strikethrough, and line breaks šŸ”— **Deep Linking**: Open platforms with pre-populated content ⚔ **Lightweight**: Zero dependencies (except React peer dependency) šŸŽÆ **Full TypeScript Support**: Complete type definitions with IntelliSense šŸ”’ **Type Safe**: Discriminated unions ensure correct prop usage ## Installation ```bash npm install react-integration-buttons ``` or ```bash yarn add react-integration-buttons ``` ## Quick Start ### TypeScript ```tsx import { IntegrationButton } from 'react-integration-buttons'; // Microsoft Teams <IntegrationButton platform="teams" users="colleague@company.com" message="Hi! Let's discuss the project." /> // ServiceNow <IntegrationButton platform="servicenow" instanceUrl="yourcompany.service-now.com" fields={{ short_description: "System Error", description: "Application crashed", urgency: "2" }} /> ``` ### JavaScript ```jsx import { IntegrationButton } from "react-integration-buttons"; // Works the same way in JavaScript! <IntegrationButton platform="teams" users="colleague@company.com" message="Hi! Let's discuss the project." />; ``` ## TypeScript Types ```typescript import type { IntegrationButtonProps, TeamsProps, ServiceNowProps, Platform, PlatformConfig, } from "react-integration-buttons"; // Platform type type Platform = "teams" | "servicenow"; // Teams-specific props interface TeamsProps { platform: "teams"; users: string; message: string; topicName?: string; buttonText?: string; className?: string; style?: React.CSSProperties; } // ServiceNow-specific props interface ServiceNowProps { platform: "servicenow"; instanceUrl: string; table?: string; fields?: Record<string, string | number>; buttonText?: string; className?: string; style?: React.CSSProperties; } // Union type (discriminated by 'platform') type IntegrationButtonProps = TeamsProps | ServiceNowProps; ``` ## API Reference ### Common Props | Prop | Type | Required | Default | Description | | ------------ | ------------------------- | -------- | ---------------- | -------------------- | | `platform` | `'teams' \| 'servicenow'` | Yes | - | Integration platform | | `buttonText` | `string` | No | Platform default | Custom button text | | `className` | `string` | No | `''` | Custom CSS class | | `style` | `React.CSSProperties` | No | `{}` | Inline styles | ### Microsoft Teams Props | Prop | Type | Required | Description | | ----------- | -------- | -------- | ------------------------------------------------ | | `users` | `string` | Yes | Recipient email(s), comma-separated for multiple | | `message` | `string` | Yes | Pre-formatted message (supports Markdown/HTML) | | `topicName` | `string` | No | Group chat name (for multiple recipients) | ### ServiceNow Props | Prop | Type | Required | Default | Description | | ------------- | ---------------------------------- | -------- | ------------ | -------------------------------------- | | `instanceUrl` | `string` | Yes | - | Your ServiceNow instance URL | | `table` | `string` | No | `'incident'` | ServiceNow table name | | `fields` | `Record<string, string \| number>` | No | `{}` | Field names and values to pre-populate | ## Usage Examples ### 1. Basic Teams Message (TypeScript) ```tsx import { IntegrationButton, TeamsProps } from "react-integration-buttons"; const MyComponent: React.FC = () => { const teamsConfig: TeamsProps = { platform: "teams", users: "john.doe@company.com", message: "Can we schedule a meeting this week?", buttonText: "Message John", }; return <IntegrationButton {...teamsConfig} />; }; ``` ### 2. Teams with Markdown Formatting ```tsx <IntegrationButton platform="teams" users="team@company.com" message="**Project Update**\n\nStatus: *In Progress*\nDeadline: ~~Next week~~ **This Friday**" topicName="Weekly Sync" /> ``` ### 3. Teams with HTML Formatting ```tsx <IntegrationButton platform="teams" users="manager@company.com" message="<b>Urgent:</b> Please review the <i>Q4 report</i>.<br><br>Thanks!" /> ``` ### 4. Multiple Teams Recipients ```tsx <IntegrationButton platform="teams" users="user1@company.com,user2@company.com,user3@company.com" message="Meeting in 10 minutes!" topicName="Team Meeting" /> ``` ### 5. ServiceNow Incident (TypeScript) ```tsx import { IntegrationButton, ServiceNowProps } from "react-integration-buttons"; const ReportIssue: React.FC = () => { const snowConfig: ServiceNowProps = { platform: "servicenow", instanceUrl: "yourcompany.service-now.com", table: "incident", fields: { short_description: "Application Timeout Error", description: "Users experiencing timeout errors when accessing the portal", urgency: "2", impact: "2", category: "Software", assignment_group: "IT Support", }, buttonText: "Report Issue", }; return <IntegrationButton {...snowConfig} />; }; ``` ### 6. ServiceNow Service Request ```tsx <IntegrationButton platform="servicenow" instanceUrl="yourcompany.service-now.com" table="sc_request" fields={{ short_description: "New Laptop Request", description: "Requesting new MacBook Pro for new employee", requested_for: "newemployee@company.com", }} buttonText="Request Equipment" /> ``` ### 7. ServiceNow Change Request ```tsx <IntegrationButton platform="servicenow" instanceUrl="yourcompany.service-now.com" table="change_request" fields={{ short_description: "Production Deployment - v2.5.0", description: "Deploy new version to production", risk: 3, type: "Standard", category: "Software", }} buttonText="Create Change" /> ``` ### 8. Dynamic Platform Selection (TypeScript) ```tsx import React, { useState } from "react"; import { IntegrationButton, Platform } from "react-integration-buttons"; const ContactSupport: React.FC = () => { const [platform, setPlatform] = useState<Platform>("teams"); const [message, setMessage] = useState(""); return ( <div> <select value={platform} onChange={(e) => setPlatform(e.target.value as Platform)} > <option value="teams">Teams</option> <option value="servicenow">ServiceNow</option> </select> <textarea value={message} onChange={(e) => setMessage(e.target.value)} placeholder="Describe your issue..." /> {platform === "teams" ? ( <IntegrationButton platform="teams" users="support@company.com" message={message} /> ) : ( <IntegrationButton platform="servicenow" instanceUrl="yourcompany.service-now.com" fields={{ short_description: "Support Request", description: message, urgency: "3", }} /> )} </div> ); }; ``` ### 9. Context-Aware Integration (TypeScript) ```tsx interface Issue { title: string; description: string; severity: "low" | "medium" | "high"; } interface SmartButtonProps { issue: Issue; } const SmartButton: React.FC<SmartButtonProps> = ({ issue }) => { const isUrgent = issue.severity === "high"; if (isUrgent) { return ( <IntegrationButton platform="servicenow" instanceUrl="yourcompany.service-now.com" fields={{ short_description: issue.title, description: issue.description, urgency: "1", }} buttonText="Create Urgent Ticket" /> ); } return ( <IntegrationButton platform="teams" users="support@company.com" message={`Issue: ${issue.title}\n\n${issue.description}`} buttonText="Chat with Support" /> ); }; ``` ### 10. Custom Styling ```tsx <IntegrationButton platform="teams" users="team@company.com" message="Quick update" className="my-custom-class" style={{ backgroundColor: "#0078d4", padding: "15px 30px", fontSize: "16px", fontWeight: "bold", borderRadius: "8px", }} /> ``` ### 11. Typed Configuration Objects ```tsx import { TeamsProps, ServiceNowProps } from "react-integration-buttons"; // Pre-defined configurations with full type safety const SUPPORT_CONFIGS = { quickHelp: { platform: "teams", users: "support@company.com", message: "**Need Help**\n\nI need assistance with the application.", buttonText: "Quick Help", } as TeamsProps, reportBug: { platform: "servicenow", instanceUrl: "yourcompany.service-now.com", table: "incident", fields: { short_description: "Application Bug", category: "Software", urgency: "2", }, buttonText: "Report Bug", } as ServiceNowProps, passwordReset: { platform: "servicenow", instanceUrl: "yourcompany.service-now.com", fields: { short_description: "Password Reset Request", category: "Access", urgency: "3", }, buttonText: "Reset Password", } as ServiceNowProps, }; // Use with type safety const SupportButtons: React.FC = () => ( <div> <IntegrationButton {...SUPPORT_CONFIGS.quickHelp} /> <IntegrationButton {...SUPPORT_CONFIGS.reportBug} /> <IntegrationButton {...SUPPORT_CONFIGS.passwordReset} /> </div> ); ``` ## Message Formatting ### Teams Message Formatting The component supports both Markdown and HTML formatting for Teams messages: **Markdown:** - `**bold**` or `__bold__` → Bold text - `*italic*` or `_italic_` → Italic text - `~~strikethrough~~` → Strikethrough text - `\n` → Line break **HTML:** - `<b>bold</b>` → Bold text - `<i>italic</i>` → Italic text - `<u>underline</u>` → Underlined text - `<s>strikethrough</s>` → Strikethrough text - `<br>` → Line break ## ServiceNow Field Reference ### Common Incident Fields ```typescript interface IncidentFields { short_description: string; description?: string; urgency?: "1" | "2" | "3"; // 1=High, 2=Medium, 3=Low impact?: "1" | "2" | "3"; priority?: "1" | "2" | "3" | "4" | "5"; category?: "Hardware" | "Software" | "Network" | "Database" | string; subcategory?: string; assignment_group?: string; assigned_to?: string; caller_id?: string; contact_type?: "Phone" | "Email" | "Self-Service" | string; } ``` ### Service Request Fields ```typescript interface ServiceRequestFields { short_description: string; description?: string; requested_for?: string; } ``` ### Change Request Fields ```typescript interface ChangeRequestFields { short_description: string; description?: string; risk?: "1" | "2" | "3"; // 1=High, 2=Moderate, 3=Low impact?: "1" | "2" | "3"; type?: "Standard" | "Normal" | "Emergency" | string; category?: string; assignment_group?: string; } ``` **Note:** Field names may vary based on your ServiceNow configuration. Check your instance's data dictionary for exact field names. ## TypeScript IntelliSense With TypeScript, you get full IntelliSense support in your IDE: ```tsx <IntegrationButton platform="teams" // ← IDE suggests: 'teams' | 'servicenow' users="..." // ← Required when platform="teams" message="..." // ← Required when platform="teams" topicName="..." // ← Optional, shows description // TypeScript will error if you try to use ServiceNow-specific props // instanceUrl="..." ← Type error! Not available for Teams /> <IntegrationButton platform="servicenow" instanceUrl="..." // ← Required when platform="servicenow" fields={{ // ← IDE autocompletes field properties short_description: "...", urgency: "2" // ← Suggests: "1" | "2" | "3" }} // TypeScript will error if you try to use Teams-specific props // users="..." ← Type error! Not available for ServiceNow /> ``` ## Browser Compatibility - Chrome/Edge: āœ… Full support - Firefox: āœ… Full support - Safari: āœ… Full support - Mobile browsers: āš ļø Limited (Teams deep linking may not work on all mobile browsers) ## Requirements - React ≄ 16.8.0 - TypeScript ≄ 4.0 (for TypeScript projects) - Modern browser with `window.open()` support ## Troubleshooting ### Teams link doesn't open - Ensure Microsoft Teams is installed on the user's device - Check that the email addresses are valid - Verify the user is logged into Teams ### ServiceNow form not pre-populated - Verify your ServiceNow instance URL is correct - Check field names match your ServiceNow configuration - Ensure you have proper permissions in ServiceNow ### TypeScript errors - Make sure `@types/react` is installed - Check that your TypeScript version is ≄ 4.0 - Verify the `types` field in package.json points to the correct `.d.ts` file - Try deleting `node_modules` and running `npm install` again ### Button not appearing - Check that required props are provided for the selected platform - Verify React version is ≄ 16.8.0 - Check browser console for errors ## Migration from JavaScript If you're migrating from a JavaScript codebase, the component works identically. Simply install the package and optionally add type annotations: ```tsx // Before (JavaScript) <IntegrationButton platform="teams" users="user@company.com" message="Hello" /> // After (TypeScript) - same code, now with type safety! <IntegrationButton platform="teams" users="user@company.com" message="Hello" /> ``` ## Advanced TypeScript Usage ### Custom Hooks with Types ```tsx import { useState } from "react"; import { IntegrationButton, Platform, TeamsProps, ServiceNowProps, } from "react-integration-buttons"; type IntegrationConfig = TeamsProps | ServiceNowProps; function useIntegration(defaultPlatform: Platform = "teams") { const [config, setConfig] = useState<IntegrationConfig>({ platform: defaultPlatform, users: "", message: "", } as TeamsProps); const switchToTeams = (users: string, message: string) => { setConfig({ platform: "teams", users, message, }); }; const switchToServiceNow = ( instanceUrl: string, fields: Record<string, string | number> ) => { setConfig({ platform: "servicenow", instanceUrl, fields, }); }; return { config, switchToTeams, switchToServiceNow }; } // Usage const MyComponent: React.FC = () => { const { config, switchToTeams, switchToServiceNow } = useIntegration(); return ( <div> <button onClick={() => switchToTeams("support@company.com", "Need help")}> Contact via Teams </button> <button onClick={() => switchToServiceNow("company.service-now.com", { short_description: "Issue", }) } > Create Ticket </button> <IntegrationButton {...config} /> </div> ); }; ``` ### Type Guards ```tsx import { IntegrationButtonProps } from "react-integration-buttons"; function isTeamsProps(props: IntegrationButtonProps): props is TeamsProps { return props.platform === "teams"; } function isServiceNowProps( props: IntegrationButtonProps ): props is ServiceNowProps { return props.platform === "servicenow"; } // Usage function processConfig(config: IntegrationButtonProps) { if (isTeamsProps(config)) { console.log("Teams message:", config.message); console.log("Recipients:", config.users); } else if (isServiceNowProps(config)) { console.log("ServiceNow instance:", config.instanceUrl); console.log("Fields:", config.fields); } } ``` ### Extending Types ```tsx import { TeamsProps, ServiceNowProps } from "react-integration-buttons"; // Add custom analytics or tracking interface TrackedTeamsProps extends TeamsProps { analyticsId?: string; onSend?: () => void; } interface TrackedServiceNowProps extends ServiceNowProps { analyticsId?: string; onSubmit?: () => void; } type TrackedIntegrationProps = TrackedTeamsProps | TrackedServiceNowProps; const TrackedIntegrationButton: React.FC<TrackedIntegrationProps> = (props) => { const handleClick = () => { if ("onSend" in props && props.onSend) { props.onSend(); } if ("onSubmit" in props && props.onSubmit) { props.onSubmit(); } // Track analytics if (props.analyticsId) { console.log("Button clicked:", props.analyticsId); } }; return ( <div onClick={handleClick}> <IntegrationButton {...props} /> </div> ); }; ``` ## Contributing Contributions are welcome! Please feel free to submit a Pull Request. ### Development Setup 1. Fork the repository 2. Clone your fork: `git clone ttps://github.com/cozmcode/react-integration-button` 3. Install dependencies: `npm install` 4. Make your changes in `src/` 5. Run type check: `npm run type-check` 6. Build: `npm run build` 7. Test locally: `npm link` and test in another project 8. Commit your changes: `git commit -m 'Add some feature'` 9. Push to the branch: `git push origin feature/amazing-feature` 10. Open a Pull Request ### Contribution Guidelines - Write TypeScript (not JavaScript) - Maintain existing code style - Add tests for new features - Update documentation - Follow semantic versioning ## License MIT Ā© Saviour Ise ## Support - šŸ› [Report a bug](ttps://github.com/cozmcode/react-integration-button/issues) - šŸ’” [Request a feature](ttps://github.com/cozmcode/react-integration-button/issues) - šŸ“§ [Email support](mailto:ise@thecozm.com) - šŸ’¬ [Discussions](ttps://github.com/cozmcode/react-integration-button/discussions) ## Changelog ### 1.0.0 (2025-10-07) - ✨ Initial release - āœ… Microsoft Teams integration - āœ… ServiceNow integration - āœ… Full TypeScript support - āœ… Markdown and HTML formatting support - āœ… Discriminated union types for type safety - āœ… Complete type definitions with IntelliSense ## Roadmap - [ ] Add more platform integrations (Slack, Jira, etc.) - [ ] Custom styling themes - [ ] Accessibility improvements - [ ] React Native support - [ ] Comprehensive test suite - [ ] Storybook documentation ## Related Packages - [@microsoft/teams-js](https://www.npmjs.com/package/@microsoft/teams-js) - Official Microsoft Teams JavaScript SDK - [react-markdown](https://www.npmjs.com/package/react-markdown) - Render Markdown in React ## Acknowledgments - Microsoft Teams for their deep linking API - ServiceNow for their URL navigation API - The React community for feedback and support --- Made with ā¤ļø and TypeScript by [Your Name] **Keywords:** react, typescript, teams, microsoft-teams, servicenow, integration, deep-link, button, component, slack-alternative, jira-alternative