The official SDK for developing plugins for SipLine, the professional SIP softphone. This SDK allows you to extend the application's functionality, add UI elements, and interact with SIP calls.
For more information, downloads, and documentation about the softphone itself, visit:
https://sipline.feelautom.fr
- UI Integration: Add tabs to the sidebar, buttons to the toolbar, or create full-page views using WPF.
- Interactive Dialogs: Display confirmation dialogs and prompt for user input.
- Application Context: Access current application version, theme mode (dark/light), and UI thread execution helpers.
- UI Navigation: Programmatically select sidebar tabs.
- SIP Events: Intercept incoming calls, detect outgoing calls, and monitor call state changes.
- Do Not Disturb (DND): Read and control the DND state programmatically. React to DND changes via events.
- Settings Management: Easily store and retrieve persistent configuration for your plugin.
- Notifications: Trigger native Windows toasts or in-app snackbars.
- Audio: Access audio device events (mute, volume).
To start building a plugin, create a new .NET 9.0 Windows Class Library and reference the SDK:
<ItemGroup>
<PackageReference Include="SipLine.Plugin.Sdk" Version="1.0.0" />
</ItemGroup>Note: Ensure you set
<Private>false</Private>and<ExcludeAssets>runtime</ExcludeAssets>for the SDK reference to avoid DLL conflicts at runtime.
Implement the ISipLinePlugin interface:
using SipLine.Plugin.Sdk;
using SipLine.Plugin.Sdk.Enums;
using Microsoft.Extensions.Logging;
public class MyAwesomePlugin : ISipLinePlugin
{
public string Id => "com.mycompany.plugin";
public string Name => "My Awesome Plugin";
public string Description => "Adds super powers to SipLine.";
public Version Version => new(1, 0, 0);
public string Author => "Me";
// Use standard icon
public PluginIcon? Icon => PluginIcon.Rocket;
private IPluginContext _context;
public Task InitializeAsync(IPluginContext context)
{
_context = context;
_context.Logger.LogInformation("Hello from MyAwesomePlugin!");
// Add a sidebar tab
_context.RegisterSidebarTab(new PluginSidebarTab
{
Id = "my-tab", // Unique ID for your tab
Title = "My Plugin",
Tooltip = "Open My Plugin View",
Icon = PluginIcon.Star, // Use standard icon or IconPathData for custom SVG
Order = 200, // Position in the sidebar
ContentFactory = () => new MyPluginView() // Your WPF UserControl for the tab content
});
return Task.CompletedTask;
}
public Task ShutdownAsync()
{
// Unregister your tab when the plugin shuts down
_context?.UnregisterSidebarTab("my-tab");
return Task.CompletedTask;
}
}Your plugin interacts with SipLine through the IPluginContext.
| Feature | IPluginContext Member |
Description |
|---|---|---|
| SIP Core | SipService |
Control calls (Make, Answer, Hangup, Transfer, DTMF) |
SipService.IsDndEnabled |
Read or set the Do Not Disturb state | |
SipService.OnDndChanged |
Subscribe to DND state change events | |
CallHistory |
Access call history records | |
Contacts |
Access SipLine contact list | |
| UI Interaction | ShowNotification, ShowSnackbar |
Display messages to the user |
ShowDialogAsync, ShowInputAsync |
Show modal dialogs for confirmation or input | |
SelectSidebarTab |
Programmatically select a sidebar tab | |
| App Context | IsDarkTheme, AppVersion |
Get application theme and version |
RunOnUIThread |
Execute code safely on the UI thread | |
| Plugin Specific | Logger, PluginDataPath |
Logging and persistent storage for plugin data |
GetSetting, SetSetting |
Store and retrieve plugin settings | |
RegisterSidebarTab, RegisterSettingsTab |
Extend SipLine UI with custom views | |
RegisterContextMenuOption |
Add options to context menus (Contacts, History, Active Call) |
To ensure your plugin looks native to SipLine, use the standardized theme resources provided by PluginTheme.
<UserControl ...
xmlns:theme="clr-namespace:SipLine.Plugin.Sdk.Theme;assembly=SipLine.Plugin.Sdk">
<Border Background="{DynamicResource {x:Static theme:PluginTheme.SurfaceBrushKey}}">
<TextBlock Text="Hello" Foreground="{DynamicResource {x:Static theme:PluginTheme.TextBrushKey}}"/>
</Border>
</UserControl>SipLine automatically detects Resources.resx files (e.g., MyPlugin.Resources.Strings.resx) in your plugin assembly.
Use context.Localization to access localized strings:
var greeting = context.Localization.GetString("HelloMessage");
var formattedGreeting = context.Localization.GetString("WelcomeMessage", "User123");For dynamic UI updates in XAML, implement an indexer in your ViewModel:
public string this[string key] => _context.Localization.GetString(key);
public MyViewModel(IPluginContext context)
{
_context = context;
// Notify WPF to refresh all keys when the language changes
_context.OnLanguageChanged += (lang) => OnPropertyChanged("Item[]");
}You can use standard icons from the PluginIcon enum instead of providing raw SVG paths. The host application will render them with the correct theme and style.
public PluginIcon? Icon => PluginIcon.Message;Available Icons:
Default, Phone, Message, Contact, Settings, Database, Headset, Microphone, History, Cloud, Security, Chart, Star, Home, Calendar, Camera, Wifi, Lock, User, Trash, Edit, Info, Help, Play, Pause, Stop, Warning, Error, Check, CRM.
Use SipLine.Plugin.Testing to unit test your plugin logic without running the full application.
using SipLine.Plugin.Testing;
[Fact]
public async Task Should_Log_When_Call_Incoming()
{
var mockContext = new MockPluginContext();
var plugin = new MyPlugin();
await plugin.InitializeAsync(mockContext);
// Simulate incoming call
((MockSipService)mockContext.SipService).TriggerIncomingCall("123", "456");
Assert.Contains(mockContext.Logs, l => l.Contains("Incoming call from 123"));
}- Storage: Use
context.PluginDataPathto store files. - Location:
%AppData%\SipLine\plugins\{PluginId}\data\. - Persistence: Data is preserved during plugin updates.
- Uninstall: Data is NOT automatically deleted when the plugin is removed (to prevent accidental loss).
SipLine supports three types of plugins, defined by the LicenseType property:
-
Community (Default): Free, open-source, or internal plugins. No license verification is performed.
public PluginLicenseType LicenseType => PluginLicenseType.Community;
-
Commercial: Paid plugins protected by SoftLicence. SipLine will verify the
license.jsonfile in the plugin folder.public PluginLicenseType LicenseType => PluginLicenseType.Commercial;
-
Integrated: Reserved for official built-in plugins. Do not use this type for your own plugins.
Pull requests are welcome! Please ensure your code adheres to the existing coding standards.
This project is licensed under the MIT License.