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
Markdown
# react-integration-button
A lightweight, fully typed React component for creating deep links to Microsoft Teams and ServiceNow with pre-populated messages and forms.
[](https://www.npmjs.com/package/react-integration-buttons)
[](https://www.typescriptlang.org/)
[](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