<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.innovaphone.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Tfu</id>
	<title>innovaphone wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.innovaphone.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Tfu"/>
	<link rel="alternate" type="text/html" href="https://wiki.innovaphone.com/index.php?title=Special:Contributions/Tfu"/>
	<updated>2026-11-02T14:41:13Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.42.3</generator>
	<entry>
		<id>https://wiki.innovaphone.com/index.php?title=Courseware:IT_Plus_Overview&amp;diff=80767</id>
		<title>Courseware:IT Plus Overview</title>
		<link rel="alternate" type="text/html" href="https://wiki.innovaphone.com/index.php?title=Courseware:IT_Plus_Overview&amp;diff=80767"/>
		<updated>2026-11-02T12:10:43Z</updated>

		<summary type="html">&lt;p&gt;Tfu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;innovaphone Plus&#039;&#039; is a series of courses, each covering advanced aspects of the configuration of innovaphone devices in separate topics.  Each topic can be worked through on individually or in any order.  Further topics will be added over time.  Each topic is based on the latest firmware at the time of creation.  All topics based on the same firmware version (e.g. 14r2) are included in the same course of the series.  &lt;br /&gt;
&lt;br /&gt;
Access to &#039;&#039;innovaphone Plus&#039;&#039; requires a valid innovaphone &#039;&#039;Plus&#039;&#039; corporate subscription. See [https://www.innovaphone.com/en/partner/training/innovaphone-plus-training.html innovaphone Plus Training] for details.&lt;br /&gt;
&lt;br /&gt;
The rest of this article gives you an overview of the topics covered and in which course they can be found. &lt;br /&gt;
__NOEDITSECTION__ &lt;br /&gt;
{{#invoke-url: https://class.lab.innovaphone.com/itplus-overview.php?wiki=true}}&lt;/div&gt;</summary>
		<author><name>Tfu</name></author>
	</entry>
	<entry>
		<id>https://wiki.innovaphone.com/index.php?title=Courseware:IT_Plus_Overview&amp;diff=80766</id>
		<title>Courseware:IT Plus Overview</title>
		<link rel="alternate" type="text/html" href="https://wiki.innovaphone.com/index.php?title=Courseware:IT_Plus_Overview&amp;diff=80766"/>
		<updated>2026-11-02T10:25:34Z</updated>

		<summary type="html">&lt;p&gt;Tfu: Undo revision 80765 by Tfu (talk)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;innovaphone Plus&#039;&#039; is a series of courses, each covering advanced aspects of the configuration of innovaphone devices in separate topics.  Each topic can be worked through on individually or in any order.  Further topics will be added over time.  Each topic is based on the latest firmware at the time of creation.  All topics based on the same firmware version (e.g. 14r2) are included in the same course of the series.  &lt;br /&gt;
&lt;br /&gt;
Access to &#039;&#039;innovaphone Plus&#039;&#039; requires a valid innovaphone &#039;&#039;Plus&#039;&#039; corporate subscription. See [https://www.innovaphone.com/en/partner/training/innovaphone-plus-training.html innovaphone Plus Training] for details.&lt;br /&gt;
&lt;br /&gt;
The rest of this article gives you an overview of the topics covered and in which course they can be found. &lt;br /&gt;
__NOEDITSECTION__ &lt;br /&gt;
{{#invoke-url: https://class.innovaphone.com/moodle2/itplus-overview.php?wiki=true}}&lt;/div&gt;</summary>
		<author><name>Tfu</name></author>
	</entry>
	<entry>
		<id>https://wiki.innovaphone.com/index.php?title=Courseware:IT_Plus_Overview&amp;diff=80765</id>
		<title>Courseware:IT Plus Overview</title>
		<link rel="alternate" type="text/html" href="https://wiki.innovaphone.com/index.php?title=Courseware:IT_Plus_Overview&amp;diff=80765"/>
		<updated>2026-11-02T10:25:04Z</updated>

		<summary type="html">&lt;p&gt;Tfu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;innovaphone Plus&#039;&#039; is a series of courses, each covering advanced aspects of the configuration of innovaphone devices in separate topics.  Each topic can be worked through on individually or in any order.  Further topics will be added over time.  Each topic is based on the latest firmware at the time of creation.  All topics based on the same firmware version (e.g. 14r2) are included in the same course of the series.  &lt;br /&gt;
&lt;br /&gt;
Access to &#039;&#039;innovaphone Plus&#039;&#039; requires a valid innovaphone &#039;&#039;Plus&#039;&#039; corporate subscription. See [https://www.innovaphone.com/en/partner/training/innovaphone-plus-training.html innovaphone Plus Training] for details.&lt;br /&gt;
&lt;br /&gt;
The rest of this article gives you an overview of the topics covered and in which course they can be found. &lt;br /&gt;
__NOEDITSECTION__ &lt;br /&gt;
{{#invoke-url: https://class.lab.innovaphone.com/itplus-overview.php?wiki=true}}&lt;/div&gt;</summary>
		<author><name>Tfu</name></author>
	</entry>
	<entry>
		<id>https://wiki.innovaphone.com/index.php?title=Reference15r1:Concept_App_Service_Connector_for_Microsoft_365&amp;diff=80747</id>
		<title>Reference15r1:Concept App Service Connector for Microsoft 365</title>
		<link rel="alternate" type="text/html" href="https://wiki.innovaphone.com/index.php?title=Reference15r1:Concept_App_Service_Connector_for_Microsoft_365&amp;diff=80747"/>
		<updated>2026-10-26T11:03:42Z</updated>

		<summary type="html">&lt;p&gt;Tfu: /* Calendar Presence */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Concept|Apps]]&lt;br /&gt;
== Applies To == &lt;br /&gt;
&lt;br /&gt;
* Connector for Microsoft 365 from Version 15r1&lt;br /&gt;
&lt;br /&gt;
= Overview =&lt;br /&gt;
&lt;br /&gt;
Connector for Microsoft 365 synchronizes Microsoft Teams presences with the innovaphone PBX and back, and optionally additionally Calendar presence from Exchange Online (part of the Microsoft 365 Cloud Services).&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
* innovaphone PBX&lt;br /&gt;
* innovaphone Application Platform (minimum version 120004)&lt;br /&gt;
* V15r1&lt;br /&gt;
* App(Connector for Microsoft 365)&lt;br /&gt;
* PBX-App(innovaphone-microsoft365) license per user - order no. 02-00050-009&lt;br /&gt;
&lt;br /&gt;
== Concept ==&lt;br /&gt;
&lt;br /&gt;
=== User Presence ===&lt;br /&gt;
&lt;br /&gt;
==== Configuration ====&lt;br /&gt;
Please have a look into our [[Howto15r1:Configure User Presence Sync by Connector for Microsoft365|Howto guide for basic configuration aid]].&lt;br /&gt;
&lt;br /&gt;
==== Technical Overview ====&lt;br /&gt;
If the Connector for Microsoft 365 app is fully configured, the app connects to Microsoft to obtain a token. With the token, the app gets the teams users (with a Teams license) through the Microsoft Graph API.&lt;br /&gt;
A presence subscription to Microsoft is started with the licensed users of the PBX to get presence changes in Microsoft Teams for these users. A user subscription is also started to get changes of the users (adding, deleting or update). If a user has changed, the Teams users are retrieved again. If the presence has changed, it is forwarded to the PBX. The presences of Teams are mapped to the presences of the PBX.&lt;br /&gt;
&lt;br /&gt;
* User subscriptions are renewed every 60 minutes.&lt;br /&gt;
* Presence subscriptions are renewed every 10 minutes.&lt;br /&gt;
* License Check is made periodically.&lt;br /&gt;
&lt;br /&gt;
The app synchronises the PBX presence with Teams through the Graph Api. The on-the-phone presence will be renewed every 5 minutes. The other presences have a lifetime of 1 day but the away has a lifetime of 7 days.&lt;br /&gt;
The lifetimes are described [https://learn.microsoft.com/en-us/graph/api/presence-setuserpreferredpresence?view=graph-rest-1.0&amp;amp;tabs=http here]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Please be aware:&#039;&#039;&#039; The actual change of presence or line state will be live, the above-mentioned subscriptions are needed to register against the Microsoft API for changes. &lt;br /&gt;
After successful subscription Microsoft will trigger the Connector for Microsoft 365 App every time a presence or line state for a user has changed.&lt;br /&gt;
The subscription will then be renewed in the above-mentioned time interval to receive further live updates.&lt;br /&gt;
&lt;br /&gt;
===== User Matching =====&lt;br /&gt;
You now can choose the fields used for user matching on either side from the following options:&lt;br /&gt;
* PBX&lt;br /&gt;
** CN (Long Name property from the PBX user object)&lt;br /&gt;
** h323 (Name property from the PBX user object)&lt;br /&gt;
* Azure Portal&lt;br /&gt;
** displayName&lt;br /&gt;
** mail&lt;br /&gt;
** mailNickname&lt;br /&gt;
** onPremisesDistinguishedName&lt;br /&gt;
** onPremisesSamAccountName&lt;br /&gt;
** onPremisesUserPrincipalName&lt;br /&gt;
** userPrincipalName&lt;br /&gt;
&lt;br /&gt;
Additionally, you have the possibility to remove a possibly contained domain from the Azure fields content. &amp;lt;br&amp;gt;&lt;br /&gt;
Example: &#039;user@domain.tld&#039; is transformed to &#039;user&#039;, if this option is checked.&lt;br /&gt;
&lt;br /&gt;
===== Mapping Table =====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Teams Presence&lt;br /&gt;
! PBX Presence&lt;br /&gt;
|-&lt;br /&gt;
| Away&lt;br /&gt;
| away&lt;br /&gt;
|-&lt;br /&gt;
| BeRightBack&lt;br /&gt;
| away&lt;br /&gt;
|-&lt;br /&gt;
| Busy&lt;br /&gt;
| busy&lt;br /&gt;
|-&lt;br /&gt;
| DoNotDisturb&lt;br /&gt;
| dnd&lt;br /&gt;
|-&lt;br /&gt;
| InACall&lt;br /&gt;
| on-the-phone&lt;br /&gt;
|-&lt;br /&gt;
| InAMeeting&lt;br /&gt;
| meeting&lt;br /&gt;
|-&lt;br /&gt;
| Inactive&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| PresenceUnknown&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| Available&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| Offline&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| Offwork&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| OutOfOffice&lt;br /&gt;
| away&lt;br /&gt;
|-&lt;br /&gt;
| UrgentInterruptionsOnly&lt;br /&gt;
| dnd&lt;br /&gt;
|-&lt;br /&gt;
| Presenting&lt;br /&gt;
| on-the-phone&lt;br /&gt;
|-&lt;br /&gt;
| InAConferenceCall&lt;br /&gt;
| on-the-phone&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The value &amp;quot;online&amp;quot; unsets the Teams presence in the PBX.&lt;br /&gt;
&lt;br /&gt;
===== Master/Slave =====&lt;br /&gt;
&lt;br /&gt;
For Master/Slave combination the &amp;quot;Connector for Microsoft 365&amp;quot; App has to be added to the slave (if no full replication is on). The slave websocket connection is needed to display &amp;quot;on-the-phone&amp;quot; presence.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Calendar Presence ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Configuration ====&lt;br /&gt;
Please have a look into our [[Howto15r1:Configure_Calendar_Presence_Sync_by_Connector_for_Microsoft365|Howto guide for basic configuration aid]].&lt;br /&gt;
&lt;br /&gt;
==== Technical Overview ====&lt;br /&gt;
Introduced in 15r1 the Connector for Microsoft 365 will offer a possibility to sync Azure Portal calendar events (Teams, Exchange online) via the Graph API with the PBX presence.&amp;lt;br&amp;gt;&lt;br /&gt;
For now the [https://wiki.innovaphone.com/index.php?title=Reference13r3:Concept_App_Service_Calendar Calendar App] is (along with other functions) also capable of syncing calendar events, but using the old EWS mechanism, which Microsoft announced as end of life starting from 2026.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Warning:&#039;&#039;&#039; Please make sure to not use both apps for syncing calendar events in parallel, this is not supported and will most likely lead to conflicts and unexpected behaviours.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
When the configuration of the connector for Microsoft 365 Calendar Presence Sync is complete, the app connects to Microsoft to receive a token with the calendar app registered in the Azure portal.&amp;lt;br&amp;gt;&lt;br /&gt;
With the token, the app can pick up the users from the Azure portal.&amp;lt;br&amp;gt;&lt;br /&gt;
These are matched against the users in the PBX, based on the configured &amp;quot;User Assignment&amp;quot; settings.&amp;lt;br&amp;gt;&lt;br /&gt;
For each matched user with a valid Connector for Microsoft 365 licence applied, a subscription for calendar events is created at Microsoft to receive event changes in Microsoft Calendar for these users.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
A user subscription is also started to receive user changes (add, delete or update).&amp;lt;br&amp;gt;&lt;br /&gt;
If a user has changed, the users are retrieved again. &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
If a calendar event has been started or ended, it is forwarded to the PBX.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* User subscriptions are renewed every 60 minutes.&lt;br /&gt;
* Event subscriptions are renewed every day.&lt;br /&gt;
* License Check is made every hour.&lt;br /&gt;
* Synchronization is limited to events within the next 72 hours. The calendar data is refreshed once every 24 hours, so events further in the future are only synchronized with the first daily refresh after they fall into this 72-hour window.&lt;br /&gt;
&lt;br /&gt;
== Related Articles ==&lt;br /&gt;
&lt;br /&gt;
=Known Limitation=&lt;br /&gt;
&lt;br /&gt;
== General ==&lt;br /&gt;
&#039;&#039;Applies to the User Presence and the Calendar Presence&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Synchronization Delay ===&lt;br /&gt;
In the official Graph-API documentation, Microsoft is providing an overview about expected latencies for change notifications.&amp;lt;br&amp;gt;&lt;br /&gt;
You can find a whole overview table here:&amp;lt;br&amp;gt;&lt;br /&gt;
https://learn.microsoft.com/en-us/graph/change-notifications-overview#latency&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
For the user presences the resource &amp;quot;presence&amp;quot; is used and an average latency of 10 seconds but a maximum up to 1 minute is provided.&amp;lt;br&amp;gt;&lt;br /&gt;
Such a delay in syncing changed presences from Teams down to the PBX are considered normal and are caused by the Microsoft Graph-API.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
In case of calendar events the average is provided as &amp;quot;less than 1 minute&amp;quot; and the maximum to 3 minutes.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== User Presence ==&lt;br /&gt;
=== Line states set by the PBX does not block calls in Teams ===&lt;br /&gt;
Line states set by a 3rd party application (like the Connector for Microsoft 365) through the graph API are currently &#039;&#039;&#039;only for display purpose and do not block new calls&#039;&#039;&#039; in Teams.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
https://techcommunity.microsoft.com/t5/teams-developer/ms-graph-setpresence-problems/m-p/2798805/highlight/true#M3957&amp;lt;br&amp;gt;&lt;br /&gt;
As you can see in the above linked discussion, there once existed a feature request on Microsoft Voice, which is no longer available since it was not voted.&lt;br /&gt;
=== Maximum number of supported users ===&lt;br /&gt;
The connector now supports multiple Microsoft Teams communication users, which is the prerequisite to subscribe for more than 650 users. There is a new ribbon (Manage Teams Accounts) that allows you to configure as many communication users as you need. Every configured communication user can be used to subscribe 650 users, for example:&lt;br /&gt;
&lt;br /&gt;
*3 configured communication users x 650 licensed users = 1950 users can be subscribed&lt;br /&gt;
&#039;&#039;&#039;Please be aware&#039;&#039;&#039;: Each communication user must have a Teams license applied.&lt;br /&gt;
&lt;br /&gt;
This limitation is caused by Microsoft.&amp;lt;br&amp;gt;&lt;br /&gt;
In the documentation of the Graph-API you will find a hint to this limitation:&amp;lt;br&amp;gt;&lt;br /&gt;
https://learn.microsoft.com/en-us/graph/changenotifications-for-presence#subscribe-to-multiple-users-presence&amp;lt;br&amp;gt;&lt;br /&gt;
Trying to subscribe more than 650 users (with one communication user) by using the presence subscription API will be declined by the graph API with an error message, that too many users are requested.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Communication User (UserSynctoPbx) ===&lt;br /&gt;
Users with MFA (multi-factor-authentication) are not supported as technical communication user for the Connector.&lt;br /&gt;
&lt;br /&gt;
=== Multiple sites / instances require multiple communication users ===&lt;br /&gt;
Each instance or each site must have separate communication users, as Microsoft only allows one concurrent subscription per communication user. (otherwise an HTTP 409 conflict will occur)&lt;br /&gt;
&lt;br /&gt;
This means that if you want to subscribe to the same Azure Portal backend from two different sites (or instances), you will need to have multiple communication users (each with an applied Teams licence) in order to be able to subscribe from all endpoints.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Subscription Timeout ===&lt;br /&gt;
&lt;br /&gt;
==== Situation ====&lt;br /&gt;
Due to a current limitation in the Graph API it is not possible to cancel or delete an active presence subscription.&amp;lt;br&amp;gt;&lt;br /&gt;
As you can see in the [https://learn.microsoft.com/en-us/graph/api/subscription-delete?view=graph-rest-1.0&amp;amp;tabs=http|documentation of the current Graph API (1.0)] the “Delete subscription” chapter does not include presence subscriptions.&amp;lt;br&amp;gt;&lt;br /&gt;
It is also not possible to have multiple subscription in parallel. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To make sure to only request a new presence subscription when the old one is not valid anymore, the app will store the state of the presence subscription and the time until it is valid in the database.&amp;lt;br&amp;gt;&lt;br /&gt;
As mentioned in the chapter “Technical Overview” we are creating presence subscriptions with a validity of 10 minutes.&amp;lt;br&amp;gt;&lt;br /&gt;
The presence subscription will be renewed as soon as it is no longer valid which will be 10 minutes after initial subscription.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Impact ====&lt;br /&gt;
If settings are changed or the app instance is restarted it will check the corresponding database entry on startup.&amp;lt;br&amp;gt;&lt;br /&gt;
In case the last presence subscription was completed less than 10 minutes ago, there is still an active presence subscription and the app has to wait for it to become invalid. &amp;lt;br&amp;gt;&lt;br /&gt;
Some Changes (e.g., to the “Notification-URL”) will only take effect after a new created subscription. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The current Beta Version of the Graph API is already providing a function to delete presence subscriptions, so we hope we can improve this behavior in the future.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Troubleshooting=&lt;br /&gt;
== General ==&lt;br /&gt;
&lt;br /&gt;
===Creating an app trace===&lt;br /&gt;
For further analysis and creating a support ticket it will be useful to have a suitable app trace. &amp;lt;br&amp;gt;&lt;br /&gt;
Before creating the trace please make sure the following trace flags are activated for the app instance:&lt;br /&gt;
* App&lt;br /&gt;
* Database&lt;br /&gt;
* HTTP client&lt;br /&gt;
* TLS&lt;br /&gt;
* TCP&lt;br /&gt;
* App WebSocket&lt;br /&gt;
* Config&lt;br /&gt;
* Webserver&lt;br /&gt;
&lt;br /&gt;
After setting the config flags, please make sure to&lt;br /&gt;
* stop the instance&lt;br /&gt;
* deleting the current instance log&lt;br /&gt;
* start the instance&lt;br /&gt;
&#039;&#039;&#039;Now please wait at least 12 Minutes before you save the log&#039;&#039;&#039;, otherwise we could not have the whole picture in the trace.&lt;br /&gt;
&lt;br /&gt;
The restart and deletion of the the old log is useful the see the complete initialization process right away.&lt;br /&gt;
&lt;br /&gt;
===SSL Certificate for notification URL===&lt;br /&gt;
It also is useful to make sure the notification URL has a valid and public signed certificate.&amp;lt;br&amp;gt;&lt;br /&gt;
You can do that, using an SSL-Checker, for example: https://www.sslshopper.com/ssl-checker.html &amp;lt;br&amp;gt;&lt;br /&gt;
Without a valid, public signed certificate, Microsoft will decline the connection since it will not be possible to establish a trust relationship for the SSL/TLS secure channel.&lt;br /&gt;
&lt;br /&gt;
===Correctness of notification URL===&lt;br /&gt;
You can try to open the notification URL in your Browser&amp;lt;br&amp;gt;&lt;br /&gt;
Most likely you will see a HTTP 404 (Not Found) error message, which is the expected behavior since we are not providing an HTML website, the HTTP GET request from the browser will not be answered with content.&amp;lt;br&amp;gt;&lt;br /&gt;
This is perfectly fine since Microsoft will send presence updates with HTTP POST and will not try to request content from our app.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
What you can find out by trying to open the URL in your browser are the two following things: &amp;lt;br&amp;gt;&lt;br /&gt;
* If you receive a HTTP 404 error message you are most likely connected to an App Platform, if not you need to check your DNS (and maybe also reverse proxy) settings.&lt;br /&gt;
* If the URL is modified and the used build number is added, an app has answered your request&lt;br /&gt;
** Example: &amp;lt;code&amp;gt;https://public.dns/your.domain/microsoft365/subscriptions&amp;lt;/code&amp;gt; is modified to &amp;lt;code&amp;gt;https://public.dns/your.domain/microsoft365/&amp;lt;b&amp;gt;1510411&amp;lt;/b&amp;gt;/subscriptions&amp;lt;/code&amp;gt;&lt;br /&gt;
** If this is not the case, your URL is wrong. (Be aware: The URL depends on the settings of the web server path of your app instance)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Be aware:&#039;&#039;&#039; The URL-Recognition in the Application Platform is &#039;&#039;&#039;case sensitive&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Activation of &amp;quot;Public client flow&amp;quot; for the registered app in Azure Portal===&lt;br /&gt;
If the subscription is not working at all, please make sure &amp;quot;Public client flow&amp;quot; is activated for the registered app in the Azure portal (as described in our [[Howto15r1:Configure User Presence Sync by Connector for Microsoft365#Create_an_App_for_syncing_Teams_to_PBX|HowTo article]]).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
The App Service trace will contain the following message if this is not the case:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;AADSTS7000218: The request body must contain the following parameter: &#039;client_assertion&#039; or &#039;client_secret&#039;.&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== User Presence == &lt;br /&gt;
===GUI Feedback===&lt;br /&gt;
The app itself shows required states with green and red as connections to the Master PBX, Authentication and Presence Subscription to identify if there are problems. &amp;lt;br&amp;gt;&lt;br /&gt;
Sometimes it needs a little bit time until the states are changed. &amp;lt;br&amp;gt;&lt;br /&gt;
If the states remain, it is mandatory to enable logs on the app platform and check for more information. &amp;lt;br&amp;gt;&lt;br /&gt;
([[Howto13r3:Configure Connector for Microsoft365#Creating an app trace|Concept App Service Connector for Microsoft 365: Creating an app trace]])&lt;br /&gt;
&lt;br /&gt;
====No connection to Master PBX====&lt;br /&gt;
Check the MasterPBX name.&amp;lt;br&amp;gt;&lt;br /&gt;
The field must only contain the name [&amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;pbx&amp;lt;/span&amp;gt;], &#039;&#039;&#039;not the full domain&#039;&#039;&#039; [&amp;lt;span style=&amp;quot;color:red;text-decoration: line-through;&amp;quot;&amp;gt;pbx.domain.tld&amp;lt;/span&amp;gt;]. ([[Howto13r3:Configure Connector for Microsoft365#Synchronization from Teams to the PBX|Synchronization from Teams to the PBX - Master PBX field]])&lt;br /&gt;
&lt;br /&gt;
====Presence subscription failed====&lt;br /&gt;
There are many reasons why the &amp;quot;Presence subscription failed&amp;quot; message could be displayed.&amp;lt;br&amp;gt;&lt;br /&gt;
We try to list the most common reasons:&lt;br /&gt;
* The permission for the registered app in the Azure portal are not correctly set ([[Howto13r3:Configure Connector for Microsoft365#Create an App for syncing Teams to PBX|Howto: Create an App for syncing Teams to PBX]])&lt;br /&gt;
* The Notification URL is wrong ([[Reference13r3:Concept App Service Connector for Microsoft 365#Correctness of notification URL|Concept App Service Connector for Microsoft 365: Correctness of notification URL]] )&lt;br /&gt;
* The App service is not reachable from the internet ([[Reference13r3:Concept App Service Connector for Microsoft 365#Correctness of notification URL|Concept App Service Connector for Microsoft 365: Correctness of notification URL]] )&lt;br /&gt;
* The certificate for the public endpoint (e.g. reverse proxy) is not valid, or not publicly signed ([[Reference13r3:Concept App Service Connector for Microsoft 365#SSL Certificate for notification URL|Concept App Service Connector for Microsoft 365: SSL Certificate for notification URL]])&lt;br /&gt;
* The user from PBX and the Azure Portal cannot be matched ([[Reference13r3:Concept App Service Connector for Microsoft 365#User Matching|Concept App Service Connector for Microsoft 365: User Matching]])&lt;br /&gt;
* The App Platforms clock time is wrong ([[Reference13r3:Concept App Service Connector for Microsoft 365#App Platform clock time is wrong|Concept App Service Connector for Microsoft 365: App Platform clock time is wrong]])&lt;br /&gt;
* No user has a valid Connector for Microsoft 365 App license ([[Reference13r3:Concept App Service Connector for Microsoft 365#Requirements|Concept App Service Connector for Microsoft 365: Requirements]])&lt;br /&gt;
&lt;br /&gt;
===Teams License for communication user===&lt;br /&gt;
If presence subscription does not work, please check if all of the configured communication users have a Microsoft Teams license applied and no multifactor authentication is in use for this particular user. &amp;lt;br&amp;gt;&lt;br /&gt;
Also please make sure you can login with the configured credentials. (If you have set a password as an Administration, the user needs to change the password during the first login, therefore the given password will be invalid for API access).&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Sometimes, after changing setting or after the instance has restarted it can take up to 12 minutes until the presence subscription is working correctly. (Due to the subscription timeout)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
= Known Issues =&lt;br /&gt;
== Special Characters In Password ==&lt;br /&gt;
If you are using special characters (*, &amp;amp;, (, ), etc.) in your password you could run into a problem with the authentication of the communication user.&amp;lt;br&amp;gt;&lt;br /&gt;
The authentication failed status is being displayed. &amp;lt;br&amp;gt;&lt;br /&gt;
For the moment the only workaround is to eliminate special characters from your password.&lt;br /&gt;
&lt;br /&gt;
==App Platform clock time is wrong==&lt;br /&gt;
If the clock time at the App Platform is not correct, this will lead to an unstable behaviour of the Connector for Microsoft 365.&amp;lt;br&amp;gt;&lt;br /&gt;
Since the Connector for Microsoft 365 is using the Microsoft Graph APIs presence subscription function, it needs to provide in its request a precise time until the subscription validity will be expired.&amp;lt;br&amp;gt;&lt;br /&gt;
The app service is handling subscription and will automatically recreate a new subscription each time the previous one has expired.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A wrong clock time will lead to false expiration times and thus&lt;br /&gt;
*  the subscription will be expired earlier than expected (synchronisation is not working because there is no valid subscription)&lt;br /&gt;
*  the subscription will be valid longer than expected (the app service is trying to create a new subscription because it is expecting the previous one to be expired - will lead to a 409 conflict error, because only one subscription can be valid at a time)&lt;br /&gt;
&lt;br /&gt;
If you are not sure about the current time of the App Platform, you can login via SSH into the App Platform and execute the &amp;lt;code&amp;gt;date&amp;lt;/code&amp;gt; command to check the current time.&amp;lt;br&amp;gt;&lt;br /&gt;
You will receive an output like: &lt;br /&gt;
 Tue Mar 12 13:38:57 UTC 2024&lt;br /&gt;
Please be aware: The time is displayed in UTC, so please make sure to convert to your local time zone.&lt;br /&gt;
&lt;br /&gt;
==Geoblocking==&lt;br /&gt;
Since there might be no reliable country assignment for Microsoft addresses, all Microsoft addresses must be enabled on the upstream firewall in the event of geoblocking in order to ensure functionality of the Office365 Connector.&amp;lt;br&amp;gt;&lt;br /&gt;
As an alternative you might be able to configure your firewall to bypass the geoblocking for the configured notification URL.&lt;br /&gt;
&lt;br /&gt;
= Related Articles =&lt;br /&gt;
[[Howto15r1:Configure User Presence Sync by Connector for Microsoft365]] &amp;lt;br/&amp;gt;&lt;br /&gt;
[[Howto15r1:Configure Calendar Presence Sync by Connector for Microsoft365]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Howto|{{PAGENAME}}]]&lt;/div&gt;</summary>
		<author><name>Tfu</name></author>
	</entry>
	<entry>
		<id>https://wiki.innovaphone.com/index.php?title=Reference16r1:Concept_App_Service_Connector_for_Microsoft_365&amp;diff=80746</id>
		<title>Reference16r1:Concept App Service Connector for Microsoft 365</title>
		<link rel="alternate" type="text/html" href="https://wiki.innovaphone.com/index.php?title=Reference16r1:Concept_App_Service_Connector_for_Microsoft_365&amp;diff=80746"/>
		<updated>2026-10-26T11:03:11Z</updated>

		<summary type="html">&lt;p&gt;Tfu: /* Technical Overview */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Concept|Apps]]&lt;br /&gt;
== Applies To == &lt;br /&gt;
&lt;br /&gt;
* Connector for Microsoft 365 from Version 16r1&lt;br /&gt;
&lt;br /&gt;
= Overview =&lt;br /&gt;
&lt;br /&gt;
Connector for Microsoft 365 synchronizes Microsoft Teams presences with the innovaphone PBX and back, and optionally additionally Calendar presence from Exchange Online (part of the Microsoft 365 Cloud Services).&lt;br /&gt;
It is also possible to search for your own contacts. &lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
* innovaphone PBX&lt;br /&gt;
* innovaphone Application Platform (minimum version 120004)&lt;br /&gt;
* V16r1&lt;br /&gt;
* App(Connector for Microsoft 365)&lt;br /&gt;
* PBX-App(innovaphone-microsoft365) license per user - order no. 02-00050-009&lt;br /&gt;
&lt;br /&gt;
== Concept ==&lt;br /&gt;
&lt;br /&gt;
=== User Presence ===&lt;br /&gt;
&lt;br /&gt;
==== Configuration ====&lt;br /&gt;
Please have a look into our [[Howto16r1:Configure User Presence Sync by Connector for Microsoft365|Howto guide for basic configuration aid on user presence synchronisation]].&lt;br /&gt;
&lt;br /&gt;
==== Technical Overview ====&lt;br /&gt;
If the Connector for Microsoft 365 app is fully configured, the app connects to Microsoft to obtain a token. With the token, the app gets the teams users (with a Teams license) through the Microsoft Graph API.&lt;br /&gt;
A presence subscription to Microsoft is started with the licensed users of the PBX to get presence changes in Microsoft Teams for these users. A user subscription is also started to get changes of the users (adding, deleting or update). If a user has changed, the Teams users are retrieved again. If the presence has changed, it is forwarded to the PBX. The presences of Teams are mapped to the presences of the PBX.&lt;br /&gt;
&lt;br /&gt;
* User subscriptions are renewed every 60 minutes.&lt;br /&gt;
* Presence subscriptions are renewed every 10 minutes.&lt;br /&gt;
* License Check is made periodically.&lt;br /&gt;
&lt;br /&gt;
The app synchronises the PBX presence with Teams through the Graph Api. The on-the-phone presence will be renewed every 5 minutes. The other presences have a lifetime of 1 day but the away has a lifetime of 7 days.&lt;br /&gt;
The lifetimes are described [https://learn.microsoft.com/en-us/graph/api/presence-setuserpreferredpresence?view=graph-rest-1.0&amp;amp;tabs=http here]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Please be aware:&#039;&#039;&#039; The actual change of presence or line state will be live, the above-mentioned subscriptions are needed to register against the Microsoft API for changes. &lt;br /&gt;
After successful subscription Microsoft will trigger the Connector for Microsoft 365 App every time a presence or line state for a user has changed.&lt;br /&gt;
The subscription will then be renewed in the above-mentioned time interval to receive further live updates.&lt;br /&gt;
&lt;br /&gt;
===== User Matching =====&lt;br /&gt;
You now can choose the fields used for user matching on either side from the following options:&lt;br /&gt;
* PBX&lt;br /&gt;
** CN (Long Name property from the PBX user object)&lt;br /&gt;
** h323 (Name property from the PBX user object)&lt;br /&gt;
* Azure Portal&lt;br /&gt;
** displayName&lt;br /&gt;
** mail&lt;br /&gt;
** mailNickname&lt;br /&gt;
** onPremisesDistinguishedName&lt;br /&gt;
** onPremisesSamAccountName&lt;br /&gt;
** onPremisesUserPrincipalName&lt;br /&gt;
** userPrincipalName&lt;br /&gt;
&lt;br /&gt;
Additionally, you have the possibility to remove a possibly contained domain from the Azure fields content. &amp;lt;br&amp;gt;&lt;br /&gt;
Example: &#039;user@domain.tld&#039; is transformed to &#039;user&#039;, if this option is checked.&lt;br /&gt;
&lt;br /&gt;
===== Mapping Table =====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Teams Presence&lt;br /&gt;
! PBX Presence&lt;br /&gt;
|-&lt;br /&gt;
| Away&lt;br /&gt;
| away&lt;br /&gt;
|-&lt;br /&gt;
| BeRightBack&lt;br /&gt;
| away&lt;br /&gt;
|-&lt;br /&gt;
| Busy&lt;br /&gt;
| busy&lt;br /&gt;
|-&lt;br /&gt;
| DoNotDisturb&lt;br /&gt;
| dnd&lt;br /&gt;
|-&lt;br /&gt;
| InACall&lt;br /&gt;
| on-the-phone&lt;br /&gt;
|-&lt;br /&gt;
| InAMeeting&lt;br /&gt;
| meeting&lt;br /&gt;
|-&lt;br /&gt;
| Inactive&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| PresenceUnknown&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| Available&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| Offline&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| Offwork&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| OutOfOffice&lt;br /&gt;
| away&lt;br /&gt;
|-&lt;br /&gt;
| UrgentInterruptionsOnly&lt;br /&gt;
| dnd&lt;br /&gt;
|-&lt;br /&gt;
| Presenting&lt;br /&gt;
| on-the-phone&lt;br /&gt;
|-&lt;br /&gt;
| InAConferenceCall&lt;br /&gt;
| on-the-phone&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The value &amp;quot;online&amp;quot; unsets the Teams presence in the PBX.&lt;br /&gt;
&lt;br /&gt;
===== Master/Slave =====&lt;br /&gt;
&lt;br /&gt;
For Master/Slave combination the &amp;quot;Connector for Microsoft 365&amp;quot; App has to be added to the slave (if no full replication is on). The slave websocket connection is needed to display &amp;quot;on-the-phone&amp;quot; presence.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Calendar Presence ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Configuration ====&lt;br /&gt;
Please have a look into our [[Howto16r1:Configure Calendar Presence Sync by Connector for Microsoft365|Howto guide for basic configuration aid on calendar presence synchronisation]].&lt;br /&gt;
&lt;br /&gt;
==== Technical Overview ====&lt;br /&gt;
Introduced in 15r1 the Connector for Microsoft 365 will offer a possibility to sync Azure Portal calendar events (Teams, Exchange online) via the Graph API with the PBX presence.&amp;lt;br&amp;gt;&lt;br /&gt;
For now the [https://wiki.innovaphone.com/index.php?title=Reference13r3:Concept_App_Service_Calendar Calendar App] is (along with other functions) also capable of syncing calendar events, but using the old EWS mechanism. Microsoft disables EWS in Exchange Online by default starting October 1, 2026 and shuts it down permanently on April 1, 2027, see [[Support:Calendar App - Exchange Online EWS Retirement]].&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Warning:&#039;&#039;&#039; Please make sure to not use both apps for syncing calendar events in parallel, this is not supported and will most likely lead to conflicts and unexpected behaviours.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
When the configuration of the connector for Microsoft 365 Calendar Presence Sync is complete, the app connects to Microsoft to receive a token with the calendar app registered in the Azure portal.&amp;lt;br&amp;gt;&lt;br /&gt;
With the token, the app can pick up the users from the Azure portal.&amp;lt;br&amp;gt;&lt;br /&gt;
These are matched against the users in the PBX, based on the configured &amp;quot;User Assignment&amp;quot; settings.&amp;lt;br&amp;gt;&lt;br /&gt;
For each matched user with a valid Connector for Microsoft 365 licence applied, a subscription for calendar events is created at Microsoft to receive event changes in Microsoft Calendar for these users.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
A user subscription is also started to receive user changes (add, delete or update).&amp;lt;br&amp;gt;&lt;br /&gt;
If a user has changed, the users are retrieved again. &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
If a calendar event has been started or ended, it is forwarded to the PBX.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* User subscriptions are renewed every 60 minutes.&lt;br /&gt;
* Event subscriptions are renewed every day.&lt;br /&gt;
* License Check is made every hour.&lt;br /&gt;
* Synchronization is limited to events within the next 72 hours. The calendar data is refreshed once every 24 hours, so events further in the future are only synchronized with the first daily refresh after they fall into this 72-hour window.&lt;br /&gt;
&lt;br /&gt;
=== Contact Search ===&lt;br /&gt;
&lt;br /&gt;
==== Configuration ====&lt;br /&gt;
Please have a look into our [[Howto16r1:Configure_Contact_Search_by_Connector_for_Microsoft365|Howto guide for basic configuration aid on contact search]].&lt;br /&gt;
&lt;br /&gt;
==== Technical Overview ====&lt;br /&gt;
Introduced in 16r1 the Connector for Microsoft 365 will offer a possibility to search for your own contacts (Teams, Exchange online) via the Graph API.&lt;br /&gt;
&lt;br /&gt;
When the configuration of the connector for Microsoft 365 Contact Search is complete, the app connects to Microsoft to receive a token with the contact search app registered in the Azure portal.&amp;lt;br&amp;gt;&lt;br /&gt;
With the token, the app can pick up the users from the Azure portal.&amp;lt;br&amp;gt;&lt;br /&gt;
These are matched against the users in the PBX, based on the configured &amp;quot;User Assignment&amp;quot; settings.&amp;lt;br&amp;gt;&lt;br /&gt;
For each matched user with a valid Connector for Microsoft 365 licence applied, the user can search with the Phone App, for example (a myApps search provider will be provided for all apps looking using search providers looking up contacts). The search string is made available to the Connector for Microsoft 365 via the microsoft365-api. The results are sent to the consumer, e.g. the Phone App and presented there.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
A user subscription is started to receive user changes (add, delete or update).&amp;lt;br&amp;gt;&lt;br /&gt;
If a user has changed, the users are retrieved again. &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* User subscriptions are renewed every 60 minutes.&lt;br /&gt;
* License Check is made every hour.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Be aware:&#039;&#039;&#039; Since the Connector for Microsoft 365 is an app in the Scope of myApps App Platform, IP Phones and other services not using Apps cannot benefit from this search service.&lt;br /&gt;
&lt;br /&gt;
== Related Articles ==&lt;br /&gt;
&lt;br /&gt;
=Known Limitation=&lt;br /&gt;
&lt;br /&gt;
== General ==&lt;br /&gt;
&#039;&#039;Applies to the User Presence and the Calendar Presence&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Synchronization Delay ===&lt;br /&gt;
In the official Graph-API documentation, Microsoft is providing an overview about expected latencies for change notifications.&amp;lt;br&amp;gt;&lt;br /&gt;
You can find a whole overview table here:&amp;lt;br&amp;gt;&lt;br /&gt;
https://learn.microsoft.com/en-us/graph/change-notifications-overview#latency&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
For the user presences the resource &amp;quot;presence&amp;quot; is used and an average latency of 10 seconds but a maximum up to 1 minute is provided.&amp;lt;br&amp;gt;&lt;br /&gt;
Such a delay in syncing changed presences from Teams down to the PBX are considered normal and are caused by the Microsoft Graph-API.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
In case of calendar events the average is provided as &amp;quot;less than 1 minute&amp;quot; and the maximum to 3 minutes.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== User Presence ==&lt;br /&gt;
=== Line states set by the PBX does not block calls in Teams ===&lt;br /&gt;
Line states set by a 3rd party application (like the Connector for Microsoft 365) through the graph API are currently &#039;&#039;&#039;only for display purpose and do not block new calls&#039;&#039;&#039; in Teams.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
https://techcommunity.microsoft.com/t5/teams-developer/ms-graph-setpresence-problems/m-p/2798805/highlight/true#M3957&amp;lt;br&amp;gt;&lt;br /&gt;
As you can see in the above linked discussion, there once existed a feature request on Microsoft Voice, which is no longer available since it was not voted.&lt;br /&gt;
=== Maximum number of supported users ===&lt;br /&gt;
The connector now supports multiple Microsoft Teams communication users, which is the prerequisite to subscribe for more than 650 users. There is a new ribbon (Manage Teams Accounts) that allows you to configure as many communication users as you need. Every configured communication user can be used to subscribe 650 users, for example:&lt;br /&gt;
&lt;br /&gt;
*3 configured communication users x 650 licensed users = 1950 users can be subscribed&lt;br /&gt;
&#039;&#039;&#039;Please be aware&#039;&#039;&#039;: Each communication user must have a Teams license applied.&lt;br /&gt;
&lt;br /&gt;
This limitation is caused by Microsoft.&amp;lt;br&amp;gt;&lt;br /&gt;
In the documentation of the Graph-API you will find a hint to this limitation:&amp;lt;br&amp;gt;&lt;br /&gt;
https://learn.microsoft.com/en-us/graph/changenotifications-for-presence#subscribe-to-multiple-users-presence&amp;lt;br&amp;gt;&lt;br /&gt;
Trying to subscribe more than 650 users (with one communication user) by using the presence subscription API will be declined by the graph API with an error message, that too many users are requested.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Communication User (UserSynctoPbx) ===&lt;br /&gt;
Users with multi-factor authentication (MFA) are not supported as technical communication users for the Connector.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;We recommend creating a dedicated user account for this purpose rather than using an existing user account.&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;This limitation applies only to technical users used for the Connector for Microsoft 365, not standard user accounts. MFA can be used for real users.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Multiple sites / instances require multiple communication users ===&lt;br /&gt;
Each instance or each site must have separate communication users, as Microsoft only allows one concurrent subscription per communication user. (otherwise an HTTP 409 conflict will occur)&lt;br /&gt;
&lt;br /&gt;
This means that if you want to subscribe to the same Azure Portal backend from two different sites (or instances), you will need to have multiple communication users (each with an applied Teams licence) in order to be able to subscribe from all endpoints.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Subscription Timeout ===&lt;br /&gt;
&lt;br /&gt;
==== Situation ====&lt;br /&gt;
Due to a current limitation in the Graph API it is not possible to cancel or delete an active presence subscription.&amp;lt;br&amp;gt;&lt;br /&gt;
As you can see in the [https://learn.microsoft.com/en-us/graph/api/subscription-delete?view=graph-rest-1.0&amp;amp;tabs=http|documentation of the current Graph API (1.0)] the “Delete subscription” chapter does not include presence subscriptions.&amp;lt;br&amp;gt;&lt;br /&gt;
It is also not possible to have multiple subscription in parallel. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To make sure to only request a new presence subscription when the old one is not valid anymore, the app will store the state of the presence subscription and the time until it is valid in the database.&amp;lt;br&amp;gt;&lt;br /&gt;
As mentioned in the chapter “Technical Overview” we are creating presence subscriptions with a validity of 10 minutes.&amp;lt;br&amp;gt;&lt;br /&gt;
The presence subscription will be renewed as soon as it is no longer valid which will be 10 minutes after initial subscription.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Impact ====&lt;br /&gt;
If settings are changed or the app instance is restarted it will check the corresponding database entry on startup.&amp;lt;br&amp;gt;&lt;br /&gt;
In case the last presence subscription was completed less than 10 minutes ago, there is still an active presence subscription and the app has to wait for it to become invalid. &amp;lt;br&amp;gt;&lt;br /&gt;
Some Changes (e.g., to the “Notification-URL”) will only take effect after a new created subscription. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The current Beta Version of the Graph API is already providing a function to delete presence subscriptions, so we hope we can improve this behavior in the future.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Contact Search ==&lt;br /&gt;
=== Limited scope of searchable contacts ===&lt;br /&gt;
The contact search only queries the default Contacts folder of the searching user&#039;s mailbox via the Microsoft Graph API (&#039;&#039;&#039;/users/{id}/contacts&#039;&#039;&#039;). The following are currently &#039;&#039;&#039;not&#039;&#039;&#039; included in the search results:&lt;br /&gt;
&lt;br /&gt;
* Custom/subordinate contact folders&lt;br /&gt;
* Contact folders of other mailboxes shared with the user&lt;br /&gt;
* The organizational Global Address List (GAL)&lt;br /&gt;
&lt;br /&gt;
Creating and managing custom contact folders is no longer available in Microsoft&#039;s own cloud-based Outlook (Outlook on the web / new Outlook). Contacts in folders created earlier are still displayed there, listed under a different category - but the standard Microsoft Graph API contact search used by the Connector does not find these contacts.&lt;br /&gt;
&lt;br /&gt;
Search of the organizational Global Address List (GAL) is currently not supported by the Connector.&lt;br /&gt;
&lt;br /&gt;
=Troubleshooting=&lt;br /&gt;
== General ==&lt;br /&gt;
&lt;br /&gt;
===Creating an app trace===&lt;br /&gt;
For further analysis and creating a support ticket it will be useful to have a suitable app trace. &amp;lt;br&amp;gt;&lt;br /&gt;
Before creating the trace please make sure the following trace flags are activated for the app instance:&lt;br /&gt;
* App&lt;br /&gt;
* App WebSocket&lt;br /&gt;
* Config&lt;br /&gt;
* Database&lt;br /&gt;
* HTTP client&lt;br /&gt;
* TCP&lt;br /&gt;
* TLS&lt;br /&gt;
* Webserver&lt;br /&gt;
&lt;br /&gt;
After setting the config flags, please make sure to&lt;br /&gt;
* stop the instance&lt;br /&gt;
* deleting the current instance log&lt;br /&gt;
* start the instance&lt;br /&gt;
&#039;&#039;&#039;Now please wait at least 12 Minutes before you save the log&#039;&#039;&#039;, otherwise we could not have the whole picture in the trace.&lt;br /&gt;
&lt;br /&gt;
The restart and deletion of the the old log is useful the see the complete initialization process right away.&lt;br /&gt;
&lt;br /&gt;
===SSL Certificate for notification URL===&lt;br /&gt;
It also is useful to make sure the notification URL has a valid and public signed certificate.&amp;lt;br&amp;gt;&lt;br /&gt;
You can do that, using an SSL-Checker, for example: https://www.sslshopper.com/ssl-checker.html &amp;lt;br&amp;gt;&lt;br /&gt;
Without a valid, public signed certificate, Microsoft will decline the connection since it will not be possible to establish a trust relationship for the SSL/TLS secure channel.&lt;br /&gt;
&lt;br /&gt;
===Correctness of notification URL===&lt;br /&gt;
You can try to open the notification URL in your Browser&amp;lt;br&amp;gt;&lt;br /&gt;
Most likely you will see a HTTP 404 (Not Found) error message, which is the expected behavior since we are not providing an HTML website, the HTTP GET request from the browser will not be answered with content.&amp;lt;br&amp;gt;&lt;br /&gt;
This is perfectly fine since Microsoft will send presence updates with HTTP POST and will not try to request content from our app.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
What you can find out by trying to open the URL in your browser are the two following things: &amp;lt;br&amp;gt;&lt;br /&gt;
* If you receive a HTTP 404 error message you are most likely connected to an App Platform, if not you need to check your DNS (and maybe also reverse proxy) settings.&lt;br /&gt;
* If the URL is modified and the used build number is added, an app has answered your request&lt;br /&gt;
** Example: &amp;lt;code&amp;gt;https://public.dns/your.domain/microsoft365/subscriptions&amp;lt;/code&amp;gt; is modified to &amp;lt;code&amp;gt;https://public.dns/your.domain/microsoft365/&amp;lt;b&amp;gt;1510411&amp;lt;/b&amp;gt;/subscriptions&amp;lt;/code&amp;gt;&lt;br /&gt;
** If this is not the case, your URL is wrong. (Be aware: The URL depends on the settings of the web server path of your app instance)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Be aware:&#039;&#039;&#039; The URL-Recognition in the Application Platform is &#039;&#039;&#039;case sensitive&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Activation of &amp;quot;Public client flow&amp;quot; for the registered app in Azure Portal===&lt;br /&gt;
If the subscription is not working at all, please make sure &amp;quot;Public client flow&amp;quot; is activated for the registered app in the Azure portal (as described in our [[Howto16r1:Configure User Presence Sync by Connector for Microsoft365#Create an App for syncing Teams to PBX|HowTo article]]).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
The App Service trace will contain the following message if this is not the case:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;AADSTS7000218: The request body must contain the following parameter: &#039;client_assertion&#039; or &#039;client_secret&#039;.&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== User Presence == &lt;br /&gt;
===GUI Feedback===&lt;br /&gt;
The app itself shows required states with green and red as connections to the Master PBX, Authentication and Presence Subscription to identify if there are problems. &amp;lt;br&amp;gt;&lt;br /&gt;
Sometimes it needs a little bit time until the states are changed. &amp;lt;br&amp;gt;&lt;br /&gt;
If the states remain, it is mandatory to enable logs on the app platform and check for more information. &amp;lt;br&amp;gt;&lt;br /&gt;
([[Howto13r3:Configure Connector for Microsoft365#Creating an app trace|Concept App Service Connector for Microsoft 365: Creating an app trace]])&lt;br /&gt;
&lt;br /&gt;
====No connection to Master PBX====&lt;br /&gt;
Check the MasterPBX name.&amp;lt;br&amp;gt;&lt;br /&gt;
The field must only contain the name [&amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;pbx&amp;lt;/span&amp;gt;], &#039;&#039;&#039;not the full domain&#039;&#039;&#039; [&amp;lt;span style=&amp;quot;color:red;text-decoration: line-through;&amp;quot;&amp;gt;pbx.domain.tld&amp;lt;/span&amp;gt;]. ([[Howto13r3:Configure Connector for Microsoft365#Synchronization from Teams to the PBX|Synchronization from Teams to the PBX - Master PBX field]])&lt;br /&gt;
&lt;br /&gt;
====Presence subscription failed====&lt;br /&gt;
There are many reasons why the &amp;quot;Presence subscription failed&amp;quot; message could be displayed.&amp;lt;br&amp;gt;&lt;br /&gt;
We try to list the most common reasons:&lt;br /&gt;
* The permission for the registered app in the Azure portal are not correctly set ([[Howto13r3:Configure Connector for Microsoft365#Create an App for syncing Teams to PBX|Howto: Create an App for syncing Teams to PBX]])&lt;br /&gt;
* The Notification URL is wrong ([[Reference13r3:Concept App Service Connector for Microsoft 365#Correctness of notification URL|Concept App Service Connector for Microsoft 365: Correctness of notification URL]] )&lt;br /&gt;
* The App service is not reachable from the internet ([[Reference13r3:Concept App Service Connector for Microsoft 365#Correctness of notification URL|Concept App Service Connector for Microsoft 365: Correctness of notification URL]] )&lt;br /&gt;
* The certificate for the public endpoint (e.g. reverse proxy) is not valid, or not publicly signed ([[Reference13r3:Concept App Service Connector for Microsoft 365#SSL Certificate for notification URL|Concept App Service Connector for Microsoft 365: SSL Certificate for notification URL]])&lt;br /&gt;
* The user from PBX and the Azure Portal cannot be matched ([[Reference13r3:Concept App Service Connector for Microsoft 365#User Matching|Concept App Service Connector for Microsoft 365: User Matching]])&lt;br /&gt;
* The App Platforms clock time is wrong ([[Reference13r3:Concept App Service Connector for Microsoft 365#App Platform clock time is wrong|Concept App Service Connector for Microsoft 365: App Platform clock time is wrong]])&lt;br /&gt;
* No user has a valid Connector for Microsoft 365 App license ([[Reference13r3:Concept App Service Connector for Microsoft 365#Requirements|Concept App Service Connector for Microsoft 365: Requirements]])&lt;br /&gt;
&lt;br /&gt;
===Teams License for communication user===&lt;br /&gt;
If presence subscription does not work, please check if all of the configured communication users have a Microsoft Teams license applied and no multifactor authentication is in use for this particular user. &amp;lt;br&amp;gt;&lt;br /&gt;
Also please make sure you can login with the configured credentials. (If you have set a password as an Administration, the user needs to change the password during the first login, therefore the given password will be invalid for API access).&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Sometimes, after changing setting or after the instance has restarted it can take up to 12 minutes until the presence subscription is working correctly. (Due to the subscription timeout)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
= Known Issues =&lt;br /&gt;
== Special Characters In Password ==&lt;br /&gt;
If you are using special characters (*, &amp;amp;, (, ), etc.) in your password you could run into a problem with the authentication of the communication user.&amp;lt;br&amp;gt;&lt;br /&gt;
The authentication failed status is being displayed. &amp;lt;br&amp;gt;&lt;br /&gt;
For the moment the only workaround is to eliminate special characters from your password.&lt;br /&gt;
&lt;br /&gt;
==App Platform clock time is wrong==&lt;br /&gt;
If the clock time at the App Platform is not correct, this will lead to an unstable behaviour of the Connector for Microsoft 365.&amp;lt;br&amp;gt;&lt;br /&gt;
Since the Connector for Microsoft 365 is using the Microsoft Graph APIs presence subscription function, it needs to provide in its request a precise time until the subscription validity will be expired.&amp;lt;br&amp;gt;&lt;br /&gt;
The app service is handling subscription and will automatically recreate a new subscription each time the previous one has expired.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A wrong clock time will lead to false expiration times and thus&lt;br /&gt;
*  the subscription will be expired earlier than expected (synchronisation is not working because there is no valid subscription)&lt;br /&gt;
*  the subscription will be valid longer than expected (the app service is trying to create a new subscription because it is expecting the previous one to be expired - will lead to a 409 conflict error, because only one subscription can be valid at a time)&lt;br /&gt;
&lt;br /&gt;
If you are not sure about the current time of the App Platform, you can login via SSH into the App Platform and execute the &amp;lt;code&amp;gt;date&amp;lt;/code&amp;gt; command to check the current time.&amp;lt;br&amp;gt;&lt;br /&gt;
You will receive an output like: &lt;br /&gt;
 Tue Mar 12 13:38:57 UTC 2024&lt;br /&gt;
Please be aware: The time is displayed in UTC, so please make sure to convert to your local time zone.&lt;br /&gt;
&lt;br /&gt;
==Geoblocking==&lt;br /&gt;
Since there might be no reliable country assignment for Microsoft addresses, all Microsoft addresses must be enabled on the upstream firewall in the event of geoblocking in order to ensure functionality of the Office365 Connector.&amp;lt;br&amp;gt;&lt;br /&gt;
As an alternative you might be able to configure your firewall to bypass the geoblocking for the configured notification URL.&lt;br /&gt;
&lt;br /&gt;
= Related Articles =&lt;br /&gt;
[[Howto16r1:Configure User Presence Sync by Connector for Microsoft365]] &amp;lt;br/&amp;gt;&lt;br /&gt;
[[Howto16r1:Configure Calendar Presence Sync by Connector for Microsoft365]] &amp;lt;br/&amp;gt;&lt;br /&gt;
[[Howto16r1:Configure Contact Search by Connector for Microsoft365]] &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Howto|{{PAGENAME}}]]&lt;/div&gt;</summary>
		<author><name>Tfu</name></author>
	</entry>
	<entry>
		<id>https://wiki.innovaphone.com/index.php?title=Reference:IP73_WLAN_WiFi_Wireless_IP-Phone&amp;diff=80714</id>
		<title>Reference:IP73 WLAN WiFi Wireless IP-Phone</title>
		<link rel="alternate" type="text/html" href="https://wiki.innovaphone.com/index.php?title=Reference:IP73_WLAN_WiFi_Wireless_IP-Phone&amp;diff=80714"/>
		<updated>2026-10-15T15:16:23Z</updated>

		<summary type="html">&lt;p&gt;Tfu: Add WinPDM Numbers tab hint to LDAP root certificate upload sentence - Co-Authored-By: AI&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This article describes the IP73 WLAN/WiFi wireless IP phone, differences to the deprecated IP62 Wireless IP phone and a list of compatible WLAN infrastructures.&lt;br /&gt;
&lt;br /&gt;
==Applies To==&lt;br /&gt;
This information applies to:&lt;br /&gt;
*innovaphone IP73 (50-00073-001)&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
&lt;br /&gt;
To perform configuration changes on the IP73 device a desktop programming kit (IP62/IP64/IP65/IP73) (Art.No. 50-00060-021 / Prod.ID DP1-UAAA/1A1) is required. The programming kit enables to connect the IP73 handset to a PC in order the configuration changes can be done using WinPDM software.&lt;br /&gt;
&lt;br /&gt;
==Feature Comparison==&lt;br /&gt;
This chapter describes the differences in the feature sets between old and new WiFi handsets.&lt;br /&gt;
&lt;br /&gt;
{|border=&amp;quot;2&amp;quot; cellspacing=&amp;quot;4&amp;quot; cellpadding=&amp;quot;3&amp;quot; rules=&amp;quot;all&amp;quot; style=&amp;quot;margin:1em 1em 1em 0; border:solid 1px #AAAAAA; border-collapse:collapse;empty-cells:show;&amp;quot;&lt;br /&gt;
|+ Handset Features Matrix&lt;br /&gt;
! Feature !! IP62 !! IP73 !! Description&lt;br /&gt;
|-&lt;br /&gt;
| Signaling Protocols ||  H.323/SIP || SIP only ||&lt;br /&gt;
|-&lt;br /&gt;
| Codecs || G.711, G.722, G.729 A || Opus Wideband, G.711, G.722, G.729 A/B/AB ||&lt;br /&gt;
|-&lt;br /&gt;
| Talk Time/ Standby Time || 15 h / 100 h || 10 h / 100 h || with U-APSD&lt;br /&gt;
|-&lt;br /&gt;
| WiFi Standards || 802.11 a/b/g/n || 802.11 a/b/g/n/ac, 802.11r, 802.11k || MCS 0-7 only, Fast BSS Transition (FT or 802.11r)&lt;br /&gt;
|-&lt;br /&gt;
| SSL Certificates || customer managed || preinstalled by innovaphone/customer managed ||&lt;br /&gt;
|-&lt;br /&gt;
| call diversion || ok || only with DTMF ||&lt;br /&gt;
|-&lt;br /&gt;
| Headset Connector || 2,5 mm || 3,5 mm ||&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
As of firmware version 4.0.0, the connection of a central telephone book via LDAP is supported. For configuration to be carried out refer to the [[#Central Phonebook Access|corresponding section below]].&lt;br /&gt;
&lt;br /&gt;
==WLAN Infrastructure Compatibility==&lt;br /&gt;
&lt;br /&gt;
===Certified WLAN Platforms===&lt;br /&gt;
&#039;&#039;&#039;IMPORTANT&#039;&#039;&#039;: Ask [mailto:presales_AT_innovaphone_D0T_com innovaphone Presales Team] for possible interop configuration recommendations and pitfalls before you order the WiFi equipment and start with the roll-out.&lt;br /&gt;
&lt;br /&gt;
Note that availability and combinations of controllers and access points may be subject to change by the manufacturer and are not in the responsability of innovaphone. Errors and omissions excepted.&lt;br /&gt;
&lt;br /&gt;
Wi-Fi infrastructures not listed in this document are not supported. Use of the IP73 in unsupported infrastructures is at your own risk.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Certified WLAN Platforms as of March 2026&lt;br /&gt;
!AP Model&lt;br /&gt;
!Controller Model&lt;br /&gt;
!SW Version&lt;br /&gt;
!Test date&lt;br /&gt;
!Report&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;5&amp;quot; |Aruba&lt;br /&gt;
|-&lt;br /&gt;
|AP 303, 304, 305, 314, 315, 324, 325, 334, 335, 344, 345, 504, 505, 514, 515, 534, 535, 554, 555, 635, 655&lt;br /&gt;
|7000/7200/9000/MX-VA-xxx&lt;br /&gt;
|8.10.0.13 LSR&lt;br /&gt;
|09-Sep-2024&lt;br /&gt;
|[[File:P2pdf.png|40px|link={{fullurl:Special:FilePath/i63_interop_aruba_networking_8_10_0_13.pdf}}]]&lt;br /&gt;
|-&lt;br /&gt;
|AP 303, 304, 305, 314, 315, 324, 325, 334, 335, 344, 345, 504, 505, 514, 515, 534, 535, 554, 555, 635, 655&lt;br /&gt;
|Networking Central&lt;br /&gt;
|10.4.1.3_90100&lt;br /&gt;
|12-Aug-2024&lt;br /&gt;
|[[File:P2pdf.png|40px|link={{fullurl:Special:FilePath/i63_interop_aruba_networking_central_10_4_1_3.pdf}}]]&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;5&amp;quot; |Cisco&lt;br /&gt;
|-&lt;br /&gt;
|AP 1832, 1852, 2802, 3802, 4800, 9105, 9115, 9117, 9120, 9130&lt;br /&gt;
|WLC 3504, 5520, 8540, vWLC, Mobility Express Solution&lt;br /&gt;
|8.10.162&lt;br /&gt;
|04-Feb-2022&lt;br /&gt;
|[[File:P2pdf.png|40px|link={{fullurl:Special:FilePath/i63_interop_cisco_wlc_8_10_162.pdf}}]]&lt;br /&gt;
|-&lt;br /&gt;
|AP 1602, 2602, 3502, 3602, 1702, 2702, 3700, 2802, 3802, 1832, 1852&lt;br /&gt;
|WLC 2504, 3504, 5508, 5520, 7510, 8510, 8540, vWLC&lt;br /&gt;
|8.5.182&lt;br /&gt;
|14-Feb-2022&lt;br /&gt;
|[[File:P2pdf.png|40px|link={{fullurl:Special:FilePath/i63_interop_cisco_wlc_8_5_182.pdf}}]]&lt;br /&gt;
|-&lt;br /&gt;
|AP 1702, 2702, 3702&lt;br /&gt;
|Catalyst 9800&lt;br /&gt;
|17.3.3&lt;br /&gt;
|01-Jun-2021&lt;br /&gt;
|[[File:P2pdf.png|40px|link={{fullurl:Special:FilePath/i63_interop_cisco_catalyst_17_3_3.pdf}}]]&lt;br /&gt;
|-&lt;br /&gt;
|AP 1832, 1852, 2802, 3802, 4800, 9115, 9117, 9120, 9130, 9136&lt;br /&gt;
|Catalyst 9800&lt;br /&gt;
|17.9.3&lt;br /&gt;
|20-Jun-2022&lt;br /&gt;
|[[File:P2pdf.png|40px|link={{fullurl:Special:FilePath/i63_interop_cisco_catalyst_17_9_3.pdf}}]]&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;5&amp;quot; |Cisco Meraki&lt;br /&gt;
|-&lt;br /&gt;
|MR20/MR30H/MR33/MR42/MR42E/MR52/MR53/MR53E/MR70/MR74/MR84 (802.11ac wave 2)&lt;br /&gt;
MR36/MR44/MR46/MR46E/MR76/MR86 (802.11ax)&lt;br /&gt;
| -&lt;br /&gt;
|MR 27.7.1&lt;br /&gt;
|29-Sept-2021&lt;br /&gt;
|[[File:P2pdf.png|40px|link={{fullurl:Special:FilePath/i63_interop_meraki_mr_27_7_1.pdf}}]]&lt;br /&gt;
|-&lt;br /&gt;
|MR36/MR44/MR46/MR46E/MR76/MR86 (802.11ax)&lt;br /&gt;
CW9162/CW9163E/CW9164/CW9166/CW9166D1 (Wifi 6E)&lt;br /&gt;
| -&lt;br /&gt;
|MR 30.7&lt;br /&gt;
|Nov-2024&lt;br /&gt;
|[[File:P2pdf.png|40px|link={{fullurl:Special:FilePath/i63_interop_meraki_mr_30_7.pdf}}]]&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;5&amp;quot; |Extreme Networks (Enterasys/IdentiFi)&lt;br /&gt;
|-&lt;br /&gt;
|AP 3801, 3805, 3825, 3865, 3935&lt;br /&gt;
|Extreme Wireless C25, C35, C2110, C5110, C5210, v2110&lt;br /&gt;
|AP:10.51.10&lt;br /&gt;
|03-Feb-2020&lt;br /&gt;
|[[File:P2pdf.png|40px|link={{fullurl:Special:FilePath/i63_interop_extreme_wireless_10_51_10.pdf}}]]&lt;br /&gt;
|-&lt;br /&gt;
|AP 122, 130, 230, 250, 550, 650&lt;br /&gt;
|Extreme Cloud&lt;br /&gt;
|AP 10.0r8, Cloud 20.1.1.3&lt;br /&gt;
|19-Mar-2020&lt;br /&gt;
|[[File:P2pdf.png|40px|link={{fullurl:Special:FilePath/i63_interop_extreme_cloud_10_0r8.pdf}}]]&lt;br /&gt;
|-&lt;br /&gt;
|AP 310i/e, 410i/e, 505i/e, 510i/e, 360i/e, 460i/e, 560&lt;br /&gt;
|XCC Controllers E1120, E2120, E3120, VE6120/VE6125, VE6120H&lt;br /&gt;
|05.16.01.0025&lt;br /&gt;
|10-Dec-2020&lt;br /&gt;
|[[File:P2pdf.png|40px|link={{fullurl:Special:FilePath/i63_interop_extreme_xcc_05_16_01_0025.pdf}}]]&lt;br /&gt;
|-&lt;br /&gt;
|AP305c/cx, 410c, 460c, 510c/cx, 650&lt;br /&gt;
|Extreme Cloud C25, C35, C2110, C5110, C5210, v2110&lt;br /&gt;
|AP 10.2.4.0, Cloud 20.1.1.3&lt;br /&gt;
|20-Jan-2021&lt;br /&gt;
|[[File:P2pdf.png|40px|link={{fullurl:Special:FilePath/i63_interop_extreme_cloud_10_2_4_0.pdf}}]]&lt;br /&gt;
|-&lt;br /&gt;
|AP310i/e, 410i/e, 460i/e, 510i/e, 650i&lt;br /&gt;
|Extreme WING NX 5500, 75xx, 9500, 9510, 9600, 9610, VX9000&lt;br /&gt;
|7.5.2.0&lt;br /&gt;
|12-Apr-2021&lt;br /&gt;
|[[File:P2pdf.png|40px|link={{fullurl:Special:FilePath/i63_interop_extreme_wing_7_5_2_0.pdf}}]]&lt;br /&gt;
|-&lt;br /&gt;
|AP 305c/305cx, 410c, 460c, 510c/510cx, 650/650x, 4000, 5010&lt;br /&gt;
|Extreme Cloud iQ&lt;br /&gt;
|AP 10.8.3.0, Cloud 25.4.3-40&lt;br /&gt;
|Aug-2025&lt;br /&gt;
|[[File:P2pdf.png|40px|link={{fullurl:Special:FilePath/i63_interop_extreme_cloud_10_8_3_0.pdf}}]]&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;5&amp;quot; |Fortinet&lt;br /&gt;
|-&lt;br /&gt;
|AP1010/1014/1020/822/832, APU221EV/U223EV/U321EV/U323EV/U421EV/U423EV&lt;br /&gt;
|MC1550/3x00/4x00/5000/6000&amp;lt;br&amp;gt;FortiWLC-50D ,200D, 500D, 1000D, 3000D&amp;lt;br&amp;gt;FWC- VM-50, 200, 500, 1000, 3000&lt;br /&gt;
|8.5-2-5&lt;br /&gt;
|03-Jun-2021&lt;br /&gt;
|[[File:P2pdf.png|40px|link={{fullurl:Special:FilePath/i63_interop_fortinet_wlc_8_5_2_5.pdf}}]]&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;5&amp;quot; |Huawei&lt;br /&gt;
|-&lt;br /&gt;
|AirEngine5760-51/5760-22W/6760-X1/6760-X1E/6760R-51/6760R-51E/8760-X1-PRO/8760R-X1/8760R-X1E&lt;br /&gt;
|AirEngine 9700-M1, AC6508/6805/6800V, iMaster NCE-Campus&lt;br /&gt;
|V200R022C10SPC100&lt;br /&gt;
|10-May-2023&lt;br /&gt;
|[[File:P2pdf.png|40px|link={{fullurl:Special:FilePath/i63_interop_huawei_airengine_V200R022C10SPC100.pdf}}]]&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;5&amp;quot; |Juniper Mist&lt;br /&gt;
|-&lt;br /&gt;
|AP34, AP45&lt;br /&gt;
|Mist  Cloud&lt;br /&gt;
|0.12.26354&lt;br /&gt;
|Aug-2023&lt;br /&gt;
|[[File:P2pdf.png|40px|link={{fullurl:Special:FilePath/i63_interop_juniper_0_12_26354.pdf}}]]&lt;br /&gt;
|-&lt;br /&gt;
|AP12, AP32, AP33, AP41, AP 43, AP61, AP 63&lt;br /&gt;
|Mist  Cloud&lt;br /&gt;
|0.12.27139&lt;br /&gt;
|Feb-2024&lt;br /&gt;
|[[File:P2pdf.png|40px|link={{fullurl:Special:FilePath/i63_interop_juniper_0_12_27139.pdf}}]]&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;5&amp;quot; |Ruckus&lt;br /&gt;
|-&lt;br /&gt;
|SmartZone ZoneFlex R300, R310, T300, T310, R500, R510, H510, R600, R610, R710, R720&lt;br /&gt;
|SmartZone platform, vSZ-(H,E,D), SZ100/300&lt;br /&gt;
|5.2.0.0.699&lt;br /&gt;
|27-Apr-2024&lt;br /&gt;
|[[File:P2pdf.png|40px|link={{fullurl:Special:FilePath/i63_interop_ruckus_smartzone_5_2_0_0.pdf}}]]&lt;br /&gt;
|-&lt;br /&gt;
|SmartZone ZoneFlex R350, R350e, T350, R550, R650, R750, T750, R850, R500, R510, R610, R710, R720&lt;br /&gt;
|SmartZone platform, vSZ-(H,E,D), SZ144/300&lt;br /&gt;
|6.1.2.0.404&lt;br /&gt;
|29-Apr-2024&lt;br /&gt;
|[[File:P2pdf.png|40px|link={{fullurl:Special:FilePath/i63_interop_ruckus_smartzone_6_1_2_0.pdf}}]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== DAS Compatibility ===&lt;br /&gt;
[http://en.wikipedia.org/wiki/Distributed_antenna_system Distributed Antenna Systems (DAS)] provide a cost-effective solution for extending radio coverage inside large facilities. Simply put, a DAS can be seen as a long cable starting at a base station or access point to which many antennas are connected. While the architecture can be utilized to mitigate certain coverage issues, the innovaphone IP73 was not designed to accommodate for such RF environments. Furthermore it is difficult to ascertain and ensure WLAN reliability in regard to interference, capacity, roaming, location-based services, and some important [http://en.wikipedia.org/wiki/IEEE_802.11n 802.11n] features, such as [http://en.wikipedia.org/wiki/Multiple-input_multiple-output MIMO]. As a consequence thereof, innovaphone will not endorse nor provide RF support for WiFi deployments over any Distributed Antenna System.&lt;br /&gt;
&lt;br /&gt;
=== WPA3 Compatibility ===&lt;br /&gt;
The IP73 already supports the configuration option for &#039;&#039;WPA3&#039;&#039;. However, this should not yet be actively used.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;WPA3&#039;&#039; is currently only recommended for demo purposes. Support for &#039;&#039;WPA3&#039;&#039; is implemented, but no successful interoperability tests have been performed. WPA3 is not recommended being used except for demo purposes.&lt;br /&gt;
&lt;br /&gt;
=== U-APSD Required ===&lt;br /&gt;
U-APSD is a power saving function that is always enabled on the IP73. It must also be enabled/supported on the AP to avoid packet loss/voice problems.&lt;br /&gt;
&lt;br /&gt;
==Configuration==&lt;br /&gt;
IP73 configuration is done via WinPDM-application available at [https://store.innovaphone.com the Software section of the innovaphone App Store]. Use of desktop programming kit (IP62/IP64/IP65) (50-00060-021) is required.&lt;br /&gt;
&lt;br /&gt;
=== Security ===&lt;br /&gt;
From version 7.x onwards, the IP73 firmware includes several changes to achieve compliance with the EU Radio Equipment Directive (RED) and the Cybersecurity Delegated Act.&lt;br /&gt;
&lt;br /&gt;
This requires some additional configuration changes to get the handset operational:&lt;br /&gt;
&lt;br /&gt;
====New handset initial configuration====&lt;br /&gt;
{{IP73_703_WinPDM_Auth}}&lt;br /&gt;
&lt;br /&gt;
Resolution is to enter the [[#Shortcuts|default admin access code &#039;&#039;&#039;40022&#039;&#039;&#039;]] and afterwards to either disable WinPDM Authentication or change the Admin access code:&lt;br /&gt;
&lt;br /&gt;
[[Image:IP73 703 WinPDMAuth.png|ip73_703_winpdmauth.png/]]&lt;br /&gt;
&lt;br /&gt;
====Configuration changes for PBX connection====&lt;br /&gt;
For handsets running firmware 7.x, the following settings must be configured via WinPDM in order to enable a PBX connection:&lt;br /&gt;
* Unite connection mode must be set to ‘Off’ at [Device/Unite/Connection mode].&lt;br /&gt;
* Admin access code must be set at [Device/General/Admin access code]. 5 - 10 characters required.&lt;br /&gt;
* Phone lock code must be set at [Device/Settings/Force phone lock]. 4 - 8 characters required.&amp;lt;br&amp;gt;By setting the phone lock code the phone lock will be applied for every subsequent bootup.&amp;lt;br&amp;gt;Phone lock is enforced on by default but can be turned off by parameter [Device/Settings/Force phone lock] or by admin menu in handset GUI. Note that handset does not comply with RED by turning off forced phone lock! &lt;br /&gt;
* Security has also been strengthen by disabling some outdated security protocols by default. If a service is no longer working after upgrade try to use more modern cryptographic protocol or set parameter “&amp;lt;service&amp;gt;/Allow outdated security protocols” to ‘Yes’.&lt;br /&gt;
&lt;br /&gt;
===PBX Registration===&lt;br /&gt;
====Authentication via client certificate====&lt;br /&gt;
The recommended way to register an IP73 handset at the innovaphone PBX is SIP over TLS with authentication by a client certificate. The IP73 handset is delivered with a preinstalled device certificate already trusted by an innovaphone PBX.&lt;br /&gt;
&lt;br /&gt;
Prerequisites on the PBX for such type of authentication are:&lt;br /&gt;
&lt;br /&gt;
*The issuer of the IP73 client certificate is on the Trust List of the PBX gateway&lt;br /&gt;
*The CN of the client certificate used by IP73 equals the MAC address of the IP73 itself (alternatively other CN and registration identity can be used)&lt;br /&gt;
*User Object contains a Device with a Hardware Id matching the MAC address of the IP73&lt;br /&gt;
&lt;br /&gt;
On the IP73 the following settings must be configured. Note that the handset parameters (including the certificate selection) are opened in the &#039;&#039;Numbers&#039;&#039; tab of the WinPDM software:&lt;br /&gt;
*VoIP-&amp;gt;SIP&lt;br /&gt;
**SIP TLS client certificate: &amp;lt;select certificate with MAC address as CN&amp;gt; or &amp;lt;Automatic if preinstalled certificate is used&amp;gt;&lt;br /&gt;
**SIP Transport: TLS&lt;br /&gt;
**Primary SIP proxy: &amp;lt;IP-address of the PBX&amp;gt; or &amp;lt;DNS-name of PBX&amp;gt;&lt;br /&gt;
**SIP proxy ID: &amp;lt;PBX system name&amp;gt;&lt;br /&gt;
**SIP proxy password: &amp;lt;no password is required&amp;gt;&lt;br /&gt;
**Registration and Authentication identity: MAC address&lt;br /&gt;
&lt;br /&gt;
====Authentication via username/hardware id and password====&lt;br /&gt;
*VoIP-&amp;gt;General-&amp;gt;Endpoint ID: username or hardware id on User Object&lt;br /&gt;
*VoIP-&amp;gt;SIP&lt;br /&gt;
**SIP Transport: TCP or UDP&lt;br /&gt;
**SIP proxy password: &amp;lt;password on the User Object or PBX System password, depending on Users Device configuration&amp;gt;&lt;br /&gt;
**Registration and Authentication identity: Endpoint ID&lt;br /&gt;
&lt;br /&gt;
=== ICE/TURN ===&lt;br /&gt;
ICE is enabled by default. It is required to provide STUN and TURN server configuration under VoIP-&amp;gt;General to secure correct negotiation of media channels.&lt;br /&gt;
&lt;br /&gt;
=== Factory Reset ===&lt;br /&gt;
You can use the local &#039;&#039;Admin menu&#039;&#039; on the Phone or the WinPDM Software (Rightclick on the device) to make a Factory Reset.&lt;br /&gt;
&lt;br /&gt;
=== MWI for IP73===&lt;br /&gt;
The IP73 can be configured to display a message waiting indication / MWI.&lt;br /&gt;
You need a programming shell and the WinPDM software (available for download in our [https://store.innovaphone.com/release/141A000/download.htm Store] under the Software tab).&lt;br /&gt;
*Connect programming cradle to the administration PC&lt;br /&gt;
*Install WinPDM and start the application&lt;br /&gt;
*Place IP73 into the programming cradle&lt;br /&gt;
*If the IP73 is recognized in WinPDM, the parameter settings can be opened by switching to the Numbers tab (1)&lt;br /&gt;
*select the respective device type (2 -&amp;gt; WH2 = IP73) and double-clicking the device line (3).&lt;br /&gt;
*Select menu Device (4) and step to Message Centre (5)&lt;br /&gt;
*Insert the number of the voicemail object for the Message Centre Number (6)&lt;br /&gt;
*Insert the user number for the voice mail number (7)&lt;br /&gt;
Confirm settings with OK and ensure correct synchronisation of config changes to the handset. Reset of handset is recommended.&lt;br /&gt;
&lt;br /&gt;
[[Image:WIFIMwi.PNG|wifimwi.png/]]&lt;br /&gt;
&lt;br /&gt;
===Central Phonebook Access===&lt;br /&gt;
The device offers access to a central LDAP-based directory. Following configuration steps have to be carried out by the administrator:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Device Configuration via the WinPDM application&#039;&#039;&#039;&lt;br /&gt;
* Device has to be plugged into programming cradle and edited via WinPDM&lt;br /&gt;
* Device has to be operated with at least firmware &#039;&#039;&#039;6.1.13&#039;&#039;&#039; available at the [https://store.innovaphone.com innovaphone store].&lt;br /&gt;
* Open section Device and step to Central phonebook. Change the central phonebook mode to LDAP and enter the appropriate parameters for the ldap directory to be queried.&lt;br /&gt;
&lt;br /&gt;
For innovaphone PBX query, the following settings and attributes can be used and adapted to the PBX setup.&lt;br /&gt;
&lt;br /&gt;
[[image:IP73_PBX_query.png|ip73_pbx_query.png/]]&lt;br /&gt;
&lt;br /&gt;
In case of using LDAP-secure-queries, upload of the LDAP-server-&#039;&#039;&#039;ROOT&#039;&#039;&#039; certificate to the IP73 trust list is required (select and upload the certificate in the &#039;&#039;Numbers&#039;&#039; tab of the WinPDM software):&lt;br /&gt;
&lt;br /&gt;
[[image:IP73_Certificate.png|ip73_certificate.png/]]&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting==&lt;br /&gt;
Log Options can be configured in the WinPDM software, under Device-&amp;gt;Log.&lt;br /&gt;
&lt;br /&gt;
===Remote PCAP Tracing===&lt;br /&gt;
You can activate the remote PCAP interface and Trace flags directly in the phone configuration (Admin Menu :: Logging :: Mode) or via WinPDM under Device-&amp;gt;Log-&amp;gt;PCAP capturing: RPCAP.&lt;br /&gt;
&lt;br /&gt;
 Only IP traces are available via RPCAP, no innovaphone or device internal traces are logged.&lt;br /&gt;
&lt;br /&gt;
===PCAP to file via USB Tracing===&lt;br /&gt;
It is possible to store PCAP trace file in the &#039;&#039;pcap&#039;&#039; folder on the handset by setting in the phone configuration (Admin Menu :: Logging :: Mode) or via WinPDM under Device-&amp;gt;Log-&amp;gt;PCAP capturing the option &amp;quot;PCAP to file&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
To access the file set Device -&amp;gt; General -&amp;gt; USB behavior to &amp;quot;Ask&amp;quot; and select &amp;quot;File transfer&amp;quot;, when connect the handset to the WinPDM. Navigate to the folder &#039;&#039;pcap&#039;&#039; on the &#039;&#039;Handset diagnostics&#039;&#039; drive.&lt;br /&gt;
&lt;br /&gt;
===Trace Options===&lt;br /&gt;
Following additional trace options are available:&lt;br /&gt;
&lt;br /&gt;
*WLAN Trace&lt;br /&gt;
*Configuration Trace&lt;br /&gt;
*GUI Trace&lt;br /&gt;
*GLI Trace&lt;br /&gt;
*Unite Trace&lt;br /&gt;
*VoIP Trace&lt;br /&gt;
*System Trace&lt;br /&gt;
*Protector Trace&lt;br /&gt;
*SaS Trace&lt;br /&gt;
*Bluetooth Trace&lt;br /&gt;
&lt;br /&gt;
 The resulting traces are available via USB file transfer and are encrypted. The encrypted log files can be encrypted by support only.&lt;br /&gt;
&lt;br /&gt;
===Logging via Syslog, SFTP or logfile===&lt;br /&gt;
&lt;br /&gt;
The handset can be configured to send Syslog messages to a Syslog server, an SFTP server or to a local logfile located in the folder &#039;&#039;tracelog&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The configuration is available via WinPDM Device -&amp;gt; Log -&amp;gt; Syslog or SFTP.&lt;br /&gt;
&lt;br /&gt;
===Handset Error Messages===&lt;br /&gt;
&lt;br /&gt;
====No network====&lt;br /&gt;
The &#039;&#039;No network&#039;&#039; message indicates missing WLAN connection. It can be caused by wrong settings for SSID, Security, reg. domain and WLAN channels or lack of coverage.&lt;br /&gt;
&lt;br /&gt;
====No access====&lt;br /&gt;
The &#039;&#039;No access&#039;&#039; message is caused by missing IP connectivity to the PBX or wrong configuration for authentication at the PBX.&lt;br /&gt;
&lt;br /&gt;
== Shortcuts ==&lt;br /&gt;
There are some hidden tools for information and analysis, which can be accessed via specific menus and codes:&lt;br /&gt;
&lt;br /&gt;
;Handset Device Information&lt;br /&gt;
:&#039;&#039;*#34#&#039;&#039; in the main display&lt;br /&gt;
&lt;br /&gt;
;RSSI Indicator&lt;br /&gt;
:&#039;&#039;*#76#&#039;&#039; in the main display. Type again to exit.&lt;br /&gt;
: Here you find the following information in the display:&lt;br /&gt;
:* Line 1: SSID&lt;br /&gt;
:* Line 2: Current AP&lt;br /&gt;
:* Line 3: Current AP MAC&lt;br /&gt;
:* Line 4: Previous AP&lt;br /&gt;
:* Line 5: Previous AP MAC&lt;br /&gt;
&lt;br /&gt;
;Site Survey Tool&lt;br /&gt;
:&#039;&#039;*#77#&#039;&#039; in the main display.&lt;br /&gt;
&lt;br /&gt;
;Admin Menu&lt;br /&gt;
: Go to the &#039;&#039;Settings menu&#039;&#039; and type in &#039;&#039;40022&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Known Problems==&lt;br /&gt;
&lt;br /&gt;
===Packet loss and voice quality issues with non-tested WLAN AP and IP73===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Issuer: Ascom&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Published: 2022-12-07&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Background&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
It has come to our (Ascom) knowledge that in later Aruba software versions than Ascom-certified v.8.7.1.1 there is a critical issue affecting clients using power save (U-APSD).&amp;lt;br&amp;gt;&lt;br /&gt;
Data packets will not be transmitted properly to clients in power save.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Affected Ascom Certified Aruba Access Points:&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
7000/7200/9000/MX-VA-xxx Controllers&amp;lt;br&amp;gt;&lt;br /&gt;
AP-303, 304, 305, 314, 315, 324, 325, 334, 335, 344, 345,&amp;lt;br&amp;gt;&lt;br /&gt;
504, 505, 514, 515, 534, 535, 554, 555, 635&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Typical symptoms are:&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Poor voice quality issues.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Workaround&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Currently none available. Disabling U-APSD on the SSID isn’t a viable workaround as this is a requirement for Ascom i63 handsets in enterprise-grade VoWi-Fi deployments.&amp;lt;br&amp;gt;&lt;br /&gt;
Thus it is strongly recommended to avoid upgrades to v. 8.9.x and higher at this point.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Solution&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Update Aruba equipment to ArubaOS-8.10.0.11, see [https://arubanetworking.hpe.com/techdocs/ArubaOS-8.x-Books/Release-Notes/810/ArubaOS-8.10.0.11-Release-Notes.pdf Aruba Release notes (search for Ascom)] for details.&lt;br /&gt;
&lt;br /&gt;
===Bluetooth automatically disabled===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Issuer: Ascom&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Version&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Handset Firmware 4.0.6&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Detailed Information&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
If you have enabled Bluetooth over WinPDM and you want to configure (establish connection to the headset), you get the message &amp;quot;Bluetooth automatically disabled&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Background&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
The chip responsible for handling wireless radio communication, WLAN and BT, has a bug in its current firmware. Thus, using WLAN and BT on similar frequency bands does not work well.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Solution/Workaround&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Bluetooth is prohibited to be used when WLAN band 2.4 is in use by being automatically disabled. Bluetooth can only be used when WLAN on the 2.4 GHz band is inactive.&amp;lt;br&amp;gt;&lt;br /&gt;
You can disable WLAN 2.4 band over the WinPDM tool.&lt;br /&gt;
&lt;br /&gt;
==Related Articles==&lt;br /&gt;
*[[IP73 Technical Data EN]]&lt;br /&gt;
*[[Reference:IP62 WLAN WiFi Wireless IP-Phone]]&lt;/div&gt;</summary>
		<author><name>Tfu</name></author>
	</entry>
	<entry>
		<id>https://wiki.innovaphone.com/index.php?title=Reference:IP73_WLAN_WiFi_Wireless_IP-Phone&amp;diff=80713</id>
		<title>Reference:IP73 WLAN WiFi Wireless IP-Phone</title>
		<link rel="alternate" type="text/html" href="https://wiki.innovaphone.com/index.php?title=Reference:IP73_WLAN_WiFi_Wireless_IP-Phone&amp;diff=80713"/>
		<updated>2026-10-15T14:08:42Z</updated>

		<summary type="html">&lt;p&gt;Tfu: Clarify that handset parameters (incl. certificate selection) are configured in the WinPDM Numbers tab; specify &amp;#039;Off&amp;#039; for Unite connection mode - Co-Authored-By: AI&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This article describes the IP73 WLAN/WiFi wireless IP phone, differences to the deprecated IP62 Wireless IP phone and a list of compatible WLAN infrastructures.&lt;br /&gt;
&lt;br /&gt;
==Applies To==&lt;br /&gt;
This information applies to:&lt;br /&gt;
*innovaphone IP73 (50-00073-001)&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
&lt;br /&gt;
To perform configuration changes on the IP73 device a desktop programming kit (IP62/IP64/IP65/IP73) (Art.No. 50-00060-021 / Prod.ID DP1-UAAA/1A1) is required. The programming kit enables to connect the IP73 handset to a PC in order the configuration changes can be done using WinPDM software.&lt;br /&gt;
&lt;br /&gt;
==Feature Comparison==&lt;br /&gt;
This chapter describes the differences in the feature sets between old and new WiFi handsets.&lt;br /&gt;
&lt;br /&gt;
{|border=&amp;quot;2&amp;quot; cellspacing=&amp;quot;4&amp;quot; cellpadding=&amp;quot;3&amp;quot; rules=&amp;quot;all&amp;quot; style=&amp;quot;margin:1em 1em 1em 0; border:solid 1px #AAAAAA; border-collapse:collapse;empty-cells:show;&amp;quot;&lt;br /&gt;
|+ Handset Features Matrix&lt;br /&gt;
! Feature !! IP62 !! IP73 !! Description&lt;br /&gt;
|-&lt;br /&gt;
| Signaling Protocols ||  H.323/SIP || SIP only ||&lt;br /&gt;
|-&lt;br /&gt;
| Codecs || G.711, G.722, G.729 A || Opus Wideband, G.711, G.722, G.729 A/B/AB ||&lt;br /&gt;
|-&lt;br /&gt;
| Talk Time/ Standby Time || 15 h / 100 h || 10 h / 100 h || with U-APSD&lt;br /&gt;
|-&lt;br /&gt;
| WiFi Standards || 802.11 a/b/g/n || 802.11 a/b/g/n/ac, 802.11r, 802.11k || MCS 0-7 only, Fast BSS Transition (FT or 802.11r)&lt;br /&gt;
|-&lt;br /&gt;
| SSL Certificates || customer managed || preinstalled by innovaphone/customer managed ||&lt;br /&gt;
|-&lt;br /&gt;
| call diversion || ok || only with DTMF ||&lt;br /&gt;
|-&lt;br /&gt;
| Headset Connector || 2,5 mm || 3,5 mm ||&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
As of firmware version 4.0.0, the connection of a central telephone book via LDAP is supported. For configuration to be carried out refer to the [[#Central Phonebook Access|corresponding section below]].&lt;br /&gt;
&lt;br /&gt;
==WLAN Infrastructure Compatibility==&lt;br /&gt;
&lt;br /&gt;
===Certified WLAN Platforms===&lt;br /&gt;
&#039;&#039;&#039;IMPORTANT&#039;&#039;&#039;: Ask [mailto:presales_AT_innovaphone_D0T_com innovaphone Presales Team] for possible interop configuration recommendations and pitfalls before you order the WiFi equipment and start with the roll-out.&lt;br /&gt;
&lt;br /&gt;
Note that availability and combinations of controllers and access points may be subject to change by the manufacturer and are not in the responsability of innovaphone. Errors and omissions excepted.&lt;br /&gt;
&lt;br /&gt;
Wi-Fi infrastructures not listed in this document are not supported. Use of the IP73 in unsupported infrastructures is at your own risk.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Certified WLAN Platforms as of March 2026&lt;br /&gt;
!AP Model&lt;br /&gt;
!Controller Model&lt;br /&gt;
!SW Version&lt;br /&gt;
!Test date&lt;br /&gt;
!Report&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;5&amp;quot; |Aruba&lt;br /&gt;
|-&lt;br /&gt;
|AP 303, 304, 305, 314, 315, 324, 325, 334, 335, 344, 345, 504, 505, 514, 515, 534, 535, 554, 555, 635, 655&lt;br /&gt;
|7000/7200/9000/MX-VA-xxx&lt;br /&gt;
|8.10.0.13 LSR&lt;br /&gt;
|09-Sep-2024&lt;br /&gt;
|[[File:P2pdf.png|40px|link={{fullurl:Special:FilePath/i63_interop_aruba_networking_8_10_0_13.pdf}}]]&lt;br /&gt;
|-&lt;br /&gt;
|AP 303, 304, 305, 314, 315, 324, 325, 334, 335, 344, 345, 504, 505, 514, 515, 534, 535, 554, 555, 635, 655&lt;br /&gt;
|Networking Central&lt;br /&gt;
|10.4.1.3_90100&lt;br /&gt;
|12-Aug-2024&lt;br /&gt;
|[[File:P2pdf.png|40px|link={{fullurl:Special:FilePath/i63_interop_aruba_networking_central_10_4_1_3.pdf}}]]&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;5&amp;quot; |Cisco&lt;br /&gt;
|-&lt;br /&gt;
|AP 1832, 1852, 2802, 3802, 4800, 9105, 9115, 9117, 9120, 9130&lt;br /&gt;
|WLC 3504, 5520, 8540, vWLC, Mobility Express Solution&lt;br /&gt;
|8.10.162&lt;br /&gt;
|04-Feb-2022&lt;br /&gt;
|[[File:P2pdf.png|40px|link={{fullurl:Special:FilePath/i63_interop_cisco_wlc_8_10_162.pdf}}]]&lt;br /&gt;
|-&lt;br /&gt;
|AP 1602, 2602, 3502, 3602, 1702, 2702, 3700, 2802, 3802, 1832, 1852&lt;br /&gt;
|WLC 2504, 3504, 5508, 5520, 7510, 8510, 8540, vWLC&lt;br /&gt;
|8.5.182&lt;br /&gt;
|14-Feb-2022&lt;br /&gt;
|[[File:P2pdf.png|40px|link={{fullurl:Special:FilePath/i63_interop_cisco_wlc_8_5_182.pdf}}]]&lt;br /&gt;
|-&lt;br /&gt;
|AP 1702, 2702, 3702&lt;br /&gt;
|Catalyst 9800&lt;br /&gt;
|17.3.3&lt;br /&gt;
|01-Jun-2021&lt;br /&gt;
|[[File:P2pdf.png|40px|link={{fullurl:Special:FilePath/i63_interop_cisco_catalyst_17_3_3.pdf}}]]&lt;br /&gt;
|-&lt;br /&gt;
|AP 1832, 1852, 2802, 3802, 4800, 9115, 9117, 9120, 9130, 9136&lt;br /&gt;
|Catalyst 9800&lt;br /&gt;
|17.9.3&lt;br /&gt;
|20-Jun-2022&lt;br /&gt;
|[[File:P2pdf.png|40px|link={{fullurl:Special:FilePath/i63_interop_cisco_catalyst_17_9_3.pdf}}]]&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;5&amp;quot; |Cisco Meraki&lt;br /&gt;
|-&lt;br /&gt;
|MR20/MR30H/MR33/MR42/MR42E/MR52/MR53/MR53E/MR70/MR74/MR84 (802.11ac wave 2)&lt;br /&gt;
MR36/MR44/MR46/MR46E/MR76/MR86 (802.11ax)&lt;br /&gt;
| -&lt;br /&gt;
|MR 27.7.1&lt;br /&gt;
|29-Sept-2021&lt;br /&gt;
|[[File:P2pdf.png|40px|link={{fullurl:Special:FilePath/i63_interop_meraki_mr_27_7_1.pdf}}]]&lt;br /&gt;
|-&lt;br /&gt;
|MR36/MR44/MR46/MR46E/MR76/MR86 (802.11ax)&lt;br /&gt;
CW9162/CW9163E/CW9164/CW9166/CW9166D1 (Wifi 6E)&lt;br /&gt;
| -&lt;br /&gt;
|MR 30.7&lt;br /&gt;
|Nov-2024&lt;br /&gt;
|[[File:P2pdf.png|40px|link={{fullurl:Special:FilePath/i63_interop_meraki_mr_30_7.pdf}}]]&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;5&amp;quot; |Extreme Networks (Enterasys/IdentiFi)&lt;br /&gt;
|-&lt;br /&gt;
|AP 3801, 3805, 3825, 3865, 3935&lt;br /&gt;
|Extreme Wireless C25, C35, C2110, C5110, C5210, v2110&lt;br /&gt;
|AP:10.51.10&lt;br /&gt;
|03-Feb-2020&lt;br /&gt;
|[[File:P2pdf.png|40px|link={{fullurl:Special:FilePath/i63_interop_extreme_wireless_10_51_10.pdf}}]]&lt;br /&gt;
|-&lt;br /&gt;
|AP 122, 130, 230, 250, 550, 650&lt;br /&gt;
|Extreme Cloud&lt;br /&gt;
|AP 10.0r8, Cloud 20.1.1.3&lt;br /&gt;
|19-Mar-2020&lt;br /&gt;
|[[File:P2pdf.png|40px|link={{fullurl:Special:FilePath/i63_interop_extreme_cloud_10_0r8.pdf}}]]&lt;br /&gt;
|-&lt;br /&gt;
|AP 310i/e, 410i/e, 505i/e, 510i/e, 360i/e, 460i/e, 560&lt;br /&gt;
|XCC Controllers E1120, E2120, E3120, VE6120/VE6125, VE6120H&lt;br /&gt;
|05.16.01.0025&lt;br /&gt;
|10-Dec-2020&lt;br /&gt;
|[[File:P2pdf.png|40px|link={{fullurl:Special:FilePath/i63_interop_extreme_xcc_05_16_01_0025.pdf}}]]&lt;br /&gt;
|-&lt;br /&gt;
|AP305c/cx, 410c, 460c, 510c/cx, 650&lt;br /&gt;
|Extreme Cloud C25, C35, C2110, C5110, C5210, v2110&lt;br /&gt;
|AP 10.2.4.0, Cloud 20.1.1.3&lt;br /&gt;
|20-Jan-2021&lt;br /&gt;
|[[File:P2pdf.png|40px|link={{fullurl:Special:FilePath/i63_interop_extreme_cloud_10_2_4_0.pdf}}]]&lt;br /&gt;
|-&lt;br /&gt;
|AP310i/e, 410i/e, 460i/e, 510i/e, 650i&lt;br /&gt;
|Extreme WING NX 5500, 75xx, 9500, 9510, 9600, 9610, VX9000&lt;br /&gt;
|7.5.2.0&lt;br /&gt;
|12-Apr-2021&lt;br /&gt;
|[[File:P2pdf.png|40px|link={{fullurl:Special:FilePath/i63_interop_extreme_wing_7_5_2_0.pdf}}]]&lt;br /&gt;
|-&lt;br /&gt;
|AP 305c/305cx, 410c, 460c, 510c/510cx, 650/650x, 4000, 5010&lt;br /&gt;
|Extreme Cloud iQ&lt;br /&gt;
|AP 10.8.3.0, Cloud 25.4.3-40&lt;br /&gt;
|Aug-2025&lt;br /&gt;
|[[File:P2pdf.png|40px|link={{fullurl:Special:FilePath/i63_interop_extreme_cloud_10_8_3_0.pdf}}]]&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;5&amp;quot; |Fortinet&lt;br /&gt;
|-&lt;br /&gt;
|AP1010/1014/1020/822/832, APU221EV/U223EV/U321EV/U323EV/U421EV/U423EV&lt;br /&gt;
|MC1550/3x00/4x00/5000/6000&amp;lt;br&amp;gt;FortiWLC-50D ,200D, 500D, 1000D, 3000D&amp;lt;br&amp;gt;FWC- VM-50, 200, 500, 1000, 3000&lt;br /&gt;
|8.5-2-5&lt;br /&gt;
|03-Jun-2021&lt;br /&gt;
|[[File:P2pdf.png|40px|link={{fullurl:Special:FilePath/i63_interop_fortinet_wlc_8_5_2_5.pdf}}]]&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;5&amp;quot; |Huawei&lt;br /&gt;
|-&lt;br /&gt;
|AirEngine5760-51/5760-22W/6760-X1/6760-X1E/6760R-51/6760R-51E/8760-X1-PRO/8760R-X1/8760R-X1E&lt;br /&gt;
|AirEngine 9700-M1, AC6508/6805/6800V, iMaster NCE-Campus&lt;br /&gt;
|V200R022C10SPC100&lt;br /&gt;
|10-May-2023&lt;br /&gt;
|[[File:P2pdf.png|40px|link={{fullurl:Special:FilePath/i63_interop_huawei_airengine_V200R022C10SPC100.pdf}}]]&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;5&amp;quot; |Juniper Mist&lt;br /&gt;
|-&lt;br /&gt;
|AP34, AP45&lt;br /&gt;
|Mist  Cloud&lt;br /&gt;
|0.12.26354&lt;br /&gt;
|Aug-2023&lt;br /&gt;
|[[File:P2pdf.png|40px|link={{fullurl:Special:FilePath/i63_interop_juniper_0_12_26354.pdf}}]]&lt;br /&gt;
|-&lt;br /&gt;
|AP12, AP32, AP33, AP41, AP 43, AP61, AP 63&lt;br /&gt;
|Mist  Cloud&lt;br /&gt;
|0.12.27139&lt;br /&gt;
|Feb-2024&lt;br /&gt;
|[[File:P2pdf.png|40px|link={{fullurl:Special:FilePath/i63_interop_juniper_0_12_27139.pdf}}]]&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;5&amp;quot; |Ruckus&lt;br /&gt;
|-&lt;br /&gt;
|SmartZone ZoneFlex R300, R310, T300, T310, R500, R510, H510, R600, R610, R710, R720&lt;br /&gt;
|SmartZone platform, vSZ-(H,E,D), SZ100/300&lt;br /&gt;
|5.2.0.0.699&lt;br /&gt;
|27-Apr-2024&lt;br /&gt;
|[[File:P2pdf.png|40px|link={{fullurl:Special:FilePath/i63_interop_ruckus_smartzone_5_2_0_0.pdf}}]]&lt;br /&gt;
|-&lt;br /&gt;
|SmartZone ZoneFlex R350, R350e, T350, R550, R650, R750, T750, R850, R500, R510, R610, R710, R720&lt;br /&gt;
|SmartZone platform, vSZ-(H,E,D), SZ144/300&lt;br /&gt;
|6.1.2.0.404&lt;br /&gt;
|29-Apr-2024&lt;br /&gt;
|[[File:P2pdf.png|40px|link={{fullurl:Special:FilePath/i63_interop_ruckus_smartzone_6_1_2_0.pdf}}]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== DAS Compatibility ===&lt;br /&gt;
[http://en.wikipedia.org/wiki/Distributed_antenna_system Distributed Antenna Systems (DAS)] provide a cost-effective solution for extending radio coverage inside large facilities. Simply put, a DAS can be seen as a long cable starting at a base station or access point to which many antennas are connected. While the architecture can be utilized to mitigate certain coverage issues, the innovaphone IP73 was not designed to accommodate for such RF environments. Furthermore it is difficult to ascertain and ensure WLAN reliability in regard to interference, capacity, roaming, location-based services, and some important [http://en.wikipedia.org/wiki/IEEE_802.11n 802.11n] features, such as [http://en.wikipedia.org/wiki/Multiple-input_multiple-output MIMO]. As a consequence thereof, innovaphone will not endorse nor provide RF support for WiFi deployments over any Distributed Antenna System.&lt;br /&gt;
&lt;br /&gt;
=== WPA3 Compatibility ===&lt;br /&gt;
The IP73 already supports the configuration option for &#039;&#039;WPA3&#039;&#039;. However, this should not yet be actively used.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;WPA3&#039;&#039; is currently only recommended for demo purposes. Support for &#039;&#039;WPA3&#039;&#039; is implemented, but no successful interoperability tests have been performed. WPA3 is not recommended being used except for demo purposes.&lt;br /&gt;
&lt;br /&gt;
=== U-APSD Required ===&lt;br /&gt;
U-APSD is a power saving function that is always enabled on the IP73. It must also be enabled/supported on the AP to avoid packet loss/voice problems.&lt;br /&gt;
&lt;br /&gt;
==Configuration==&lt;br /&gt;
IP73 configuration is done via WinPDM-application available at [https://store.innovaphone.com the Software section of the innovaphone App Store]. Use of desktop programming kit (IP62/IP64/IP65) (50-00060-021) is required.&lt;br /&gt;
&lt;br /&gt;
=== Security ===&lt;br /&gt;
From version 7.x onwards, the IP73 firmware includes several changes to achieve compliance with the EU Radio Equipment Directive (RED) and the Cybersecurity Delegated Act.&lt;br /&gt;
&lt;br /&gt;
This requires some additional configuration changes to get the handset operational:&lt;br /&gt;
&lt;br /&gt;
====New handset initial configuration====&lt;br /&gt;
{{IP73_703_WinPDM_Auth}}&lt;br /&gt;
&lt;br /&gt;
Resolution is to enter the [[#Shortcuts|default admin access code &#039;&#039;&#039;40022&#039;&#039;&#039;]] and afterwards to either disable WinPDM Authentication or change the Admin access code:&lt;br /&gt;
&lt;br /&gt;
[[Image:IP73 703 WinPDMAuth.png|ip73_703_winpdmauth.png/]]&lt;br /&gt;
&lt;br /&gt;
====Configuration changes for PBX connection====&lt;br /&gt;
For handsets running firmware 7.x, the following settings must be configured via WinPDM in order to enable a PBX connection:&lt;br /&gt;
* Unite connection mode must be set to ‘Off’ at [Device/Unite/Connection mode].&lt;br /&gt;
* Admin access code must be set at [Device/General/Admin access code]. 5 - 10 characters required.&lt;br /&gt;
* Phone lock code must be set at [Device/Settings/Force phone lock]. 4 - 8 characters required.&amp;lt;br&amp;gt;By setting the phone lock code the phone lock will be applied for every subsequent bootup.&amp;lt;br&amp;gt;Phone lock is enforced on by default but can be turned off by parameter [Device/Settings/Force phone lock] or by admin menu in handset GUI. Note that handset does not comply with RED by turning off forced phone lock! &lt;br /&gt;
* Security has also been strengthen by disabling some outdated security protocols by default. If a service is no longer working after upgrade try to use more modern cryptographic protocol or set parameter “&amp;lt;service&amp;gt;/Allow outdated security protocols” to ‘Yes’.&lt;br /&gt;
&lt;br /&gt;
===PBX Registration===&lt;br /&gt;
====Authentication via client certificate====&lt;br /&gt;
The recommended way to register an IP73 handset at the innovaphone PBX is SIP over TLS with authentication by a client certificate. The IP73 handset is delivered with a preinstalled device certificate already trusted by an innovaphone PBX.&lt;br /&gt;
&lt;br /&gt;
Prerequisites on the PBX for such type of authentication are:&lt;br /&gt;
&lt;br /&gt;
*The issuer of the IP73 client certificate is on the Trust List of the PBX gateway&lt;br /&gt;
*The CN of the client certificate used by IP73 equals the MAC address of the IP73 itself (alternatively other CN and registration identity can be used)&lt;br /&gt;
*User Object contains a Device with a Hardware Id matching the MAC address of the IP73&lt;br /&gt;
&lt;br /&gt;
On the IP73 the following settings must be configured. Note that the handset parameters (including the certificate selection) are opened in the &#039;&#039;Numbers&#039;&#039; tab of the WinPDM software:&lt;br /&gt;
*VoIP-&amp;gt;SIP&lt;br /&gt;
**SIP TLS client certificate: &amp;lt;select certificate with MAC address as CN&amp;gt; or &amp;lt;Automatic if preinstalled certificate is used&amp;gt;&lt;br /&gt;
**SIP Transport: TLS&lt;br /&gt;
**Primary SIP proxy: &amp;lt;IP-address of the PBX&amp;gt; or &amp;lt;DNS-name of PBX&amp;gt;&lt;br /&gt;
**SIP proxy ID: &amp;lt;PBX system name&amp;gt;&lt;br /&gt;
**SIP proxy password: &amp;lt;no password is required&amp;gt;&lt;br /&gt;
**Registration and Authentication identity: MAC address&lt;br /&gt;
&lt;br /&gt;
====Authentication via username/hardware id and password====&lt;br /&gt;
*VoIP-&amp;gt;General-&amp;gt;Endpoint ID: username or hardware id on User Object&lt;br /&gt;
*VoIP-&amp;gt;SIP&lt;br /&gt;
**SIP Transport: TCP or UDP&lt;br /&gt;
**SIP proxy password: &amp;lt;password on the User Object or PBX System password, depending on Users Device configuration&amp;gt;&lt;br /&gt;
**Registration and Authentication identity: Endpoint ID&lt;br /&gt;
&lt;br /&gt;
=== ICE/TURN ===&lt;br /&gt;
ICE is enabled by default. It is required to provide STUN and TURN server configuration under VoIP-&amp;gt;General to secure correct negotiation of media channels.&lt;br /&gt;
&lt;br /&gt;
=== Factory Reset ===&lt;br /&gt;
You can use the local &#039;&#039;Admin menu&#039;&#039; on the Phone or the WinPDM Software (Rightclick on the device) to make a Factory Reset.&lt;br /&gt;
&lt;br /&gt;
=== MWI for IP73===&lt;br /&gt;
The IP73 can be configured to display a message waiting indication / MWI.&lt;br /&gt;
You need a programming shell and the WinPDM software (available for download in our [https://store.innovaphone.com/release/141A000/download.htm Store] under the Software tab).&lt;br /&gt;
*Connect programming cradle to the administration PC&lt;br /&gt;
*Install WinPDM and start the application&lt;br /&gt;
*Place IP73 into the programming cradle&lt;br /&gt;
*If the IP73 is recognized in WinPDM, the parameter settings can be opened by switching to the Numbers tab (1)&lt;br /&gt;
*select the respective device type (2 -&amp;gt; WH2 = IP73) and double-clicking the device line (3).&lt;br /&gt;
*Select menu Device (4) and step to Message Centre (5)&lt;br /&gt;
*Insert the number of the voicemail object for the Message Centre Number (6)&lt;br /&gt;
*Insert the user number for the voice mail number (7)&lt;br /&gt;
Confirm settings with OK and ensure correct synchronisation of config changes to the handset. Reset of handset is recommended.&lt;br /&gt;
&lt;br /&gt;
[[Image:WIFIMwi.PNG|wifimwi.png/]]&lt;br /&gt;
&lt;br /&gt;
===Central Phonebook Access===&lt;br /&gt;
The device offers access to a central LDAP-based directory. Following configuration steps have to be carried out by the administrator:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Device Configuration via the WinPDM application&#039;&#039;&#039;&lt;br /&gt;
* Device has to be plugged into programming cradle and edited via WinPDM&lt;br /&gt;
* Device has to be operated with at least firmware &#039;&#039;&#039;6.1.13&#039;&#039;&#039; available at the [https://store.innovaphone.com innovaphone store].&lt;br /&gt;
* Open section Device and step to Central phonebook. Change the central phonebook mode to LDAP and enter the appropriate parameters for the ldap directory to be queried.&lt;br /&gt;
&lt;br /&gt;
For innovaphone PBX query, the following settings and attributes can be used and adapted to the PBX setup.&lt;br /&gt;
&lt;br /&gt;
[[image:IP73_PBX_query.png|ip73_pbx_query.png/]]&lt;br /&gt;
&lt;br /&gt;
In case of using LDAP-secure-queries, upload of the LDAP-server-&#039;&#039;&#039;ROOT&#039;&#039;&#039; certificate to the IP73 trust list is required:&lt;br /&gt;
&lt;br /&gt;
[[image:IP73_Certificate.png|ip73_certificate.png/]]&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting==&lt;br /&gt;
Log Options can be configured in the WinPDM software, under Device-&amp;gt;Log.&lt;br /&gt;
&lt;br /&gt;
===Remote PCAP Tracing===&lt;br /&gt;
You can activate the remote PCAP interface and Trace flags directly in the phone configuration (Admin Menu :: Logging :: Mode) or via WinPDM under Device-&amp;gt;Log-&amp;gt;PCAP capturing: RPCAP.&lt;br /&gt;
&lt;br /&gt;
 Only IP traces are available via RPCAP, no innovaphone or device internal traces are logged.&lt;br /&gt;
&lt;br /&gt;
===PCAP to file via USB Tracing===&lt;br /&gt;
It is possible to store PCAP trace file in the &#039;&#039;pcap&#039;&#039; folder on the handset by setting in the phone configuration (Admin Menu :: Logging :: Mode) or via WinPDM under Device-&amp;gt;Log-&amp;gt;PCAP capturing the option &amp;quot;PCAP to file&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
To access the file set Device -&amp;gt; General -&amp;gt; USB behavior to &amp;quot;Ask&amp;quot; and select &amp;quot;File transfer&amp;quot;, when connect the handset to the WinPDM. Navigate to the folder &#039;&#039;pcap&#039;&#039; on the &#039;&#039;Handset diagnostics&#039;&#039; drive.&lt;br /&gt;
&lt;br /&gt;
===Trace Options===&lt;br /&gt;
Following additional trace options are available:&lt;br /&gt;
&lt;br /&gt;
*WLAN Trace&lt;br /&gt;
*Configuration Trace&lt;br /&gt;
*GUI Trace&lt;br /&gt;
*GLI Trace&lt;br /&gt;
*Unite Trace&lt;br /&gt;
*VoIP Trace&lt;br /&gt;
*System Trace&lt;br /&gt;
*Protector Trace&lt;br /&gt;
*SaS Trace&lt;br /&gt;
*Bluetooth Trace&lt;br /&gt;
&lt;br /&gt;
 The resulting traces are available via USB file transfer and are encrypted. The encrypted log files can be encrypted by support only.&lt;br /&gt;
&lt;br /&gt;
===Logging via Syslog, SFTP or logfile===&lt;br /&gt;
&lt;br /&gt;
The handset can be configured to send Syslog messages to a Syslog server, an SFTP server or to a local logfile located in the folder &#039;&#039;tracelog&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The configuration is available via WinPDM Device -&amp;gt; Log -&amp;gt; Syslog or SFTP.&lt;br /&gt;
&lt;br /&gt;
===Handset Error Messages===&lt;br /&gt;
&lt;br /&gt;
====No network====&lt;br /&gt;
The &#039;&#039;No network&#039;&#039; message indicates missing WLAN connection. It can be caused by wrong settings for SSID, Security, reg. domain and WLAN channels or lack of coverage.&lt;br /&gt;
&lt;br /&gt;
====No access====&lt;br /&gt;
The &#039;&#039;No access&#039;&#039; message is caused by missing IP connectivity to the PBX or wrong configuration for authentication at the PBX.&lt;br /&gt;
&lt;br /&gt;
== Shortcuts ==&lt;br /&gt;
There are some hidden tools for information and analysis, which can be accessed via specific menus and codes:&lt;br /&gt;
&lt;br /&gt;
;Handset Device Information&lt;br /&gt;
:&#039;&#039;*#34#&#039;&#039; in the main display&lt;br /&gt;
&lt;br /&gt;
;RSSI Indicator&lt;br /&gt;
:&#039;&#039;*#76#&#039;&#039; in the main display. Type again to exit.&lt;br /&gt;
: Here you find the following information in the display:&lt;br /&gt;
:* Line 1: SSID&lt;br /&gt;
:* Line 2: Current AP&lt;br /&gt;
:* Line 3: Current AP MAC&lt;br /&gt;
:* Line 4: Previous AP&lt;br /&gt;
:* Line 5: Previous AP MAC&lt;br /&gt;
&lt;br /&gt;
;Site Survey Tool&lt;br /&gt;
:&#039;&#039;*#77#&#039;&#039; in the main display.&lt;br /&gt;
&lt;br /&gt;
;Admin Menu&lt;br /&gt;
: Go to the &#039;&#039;Settings menu&#039;&#039; and type in &#039;&#039;40022&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Known Problems==&lt;br /&gt;
&lt;br /&gt;
===Packet loss and voice quality issues with non-tested WLAN AP and IP73===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Issuer: Ascom&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Published: 2022-12-07&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Background&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
It has come to our (Ascom) knowledge that in later Aruba software versions than Ascom-certified v.8.7.1.1 there is a critical issue affecting clients using power save (U-APSD).&amp;lt;br&amp;gt;&lt;br /&gt;
Data packets will not be transmitted properly to clients in power save.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Affected Ascom Certified Aruba Access Points:&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
7000/7200/9000/MX-VA-xxx Controllers&amp;lt;br&amp;gt;&lt;br /&gt;
AP-303, 304, 305, 314, 315, 324, 325, 334, 335, 344, 345,&amp;lt;br&amp;gt;&lt;br /&gt;
504, 505, 514, 515, 534, 535, 554, 555, 635&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Typical symptoms are:&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Poor voice quality issues.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Workaround&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Currently none available. Disabling U-APSD on the SSID isn’t a viable workaround as this is a requirement for Ascom i63 handsets in enterprise-grade VoWi-Fi deployments.&amp;lt;br&amp;gt;&lt;br /&gt;
Thus it is strongly recommended to avoid upgrades to v. 8.9.x and higher at this point.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Solution&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Update Aruba equipment to ArubaOS-8.10.0.11, see [https://arubanetworking.hpe.com/techdocs/ArubaOS-8.x-Books/Release-Notes/810/ArubaOS-8.10.0.11-Release-Notes.pdf Aruba Release notes (search for Ascom)] for details.&lt;br /&gt;
&lt;br /&gt;
===Bluetooth automatically disabled===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Issuer: Ascom&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Version&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Handset Firmware 4.0.6&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Detailed Information&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
If you have enabled Bluetooth over WinPDM and you want to configure (establish connection to the headset), you get the message &amp;quot;Bluetooth automatically disabled&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Background&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
The chip responsible for handling wireless radio communication, WLAN and BT, has a bug in its current firmware. Thus, using WLAN and BT on similar frequency bands does not work well.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Solution/Workaround&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Bluetooth is prohibited to be used when WLAN band 2.4 is in use by being automatically disabled. Bluetooth can only be used when WLAN on the 2.4 GHz band is inactive.&amp;lt;br&amp;gt;&lt;br /&gt;
You can disable WLAN 2.4 band over the WinPDM tool.&lt;br /&gt;
&lt;br /&gt;
==Related Articles==&lt;br /&gt;
*[[IP73 Technical Data EN]]&lt;br /&gt;
*[[Reference:IP62 WLAN WiFi Wireless IP-Phone]]&lt;/div&gt;</summary>
		<author><name>Tfu</name></author>
	</entry>
	<entry>
		<id>https://wiki.innovaphone.com/index.php?title=Reference16r1:Concept_App_Service_Connector_for_Microsoft_365&amp;diff=80680</id>
		<title>Reference16r1:Concept App Service Connector for Microsoft 365</title>
		<link rel="alternate" type="text/html" href="https://wiki.innovaphone.com/index.php?title=Reference16r1:Concept_App_Service_Connector_for_Microsoft_365&amp;diff=80680"/>
		<updated>2026-10-13T14:35:11Z</updated>

		<summary type="html">&lt;p&gt;Tfu: App trace: wait at least 12 minutes instead of 5 before saving the log&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Concept|Apps]]&lt;br /&gt;
== Applies To == &lt;br /&gt;
&lt;br /&gt;
* Connector for Microsoft 365 from Version 16r1&lt;br /&gt;
&lt;br /&gt;
= Overview =&lt;br /&gt;
&lt;br /&gt;
Connector for Microsoft 365 synchronizes Microsoft Teams presences with the innovaphone PBX and back, and optionally additionally Calendar presence from Exchange Online (part of the Microsoft 365 Cloud Services).&lt;br /&gt;
It is also possible to search for your own contacts. &lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
* innovaphone PBX&lt;br /&gt;
* innovaphone Application Platform (minimum version 120004)&lt;br /&gt;
* V16r1&lt;br /&gt;
* App(Connector for Microsoft 365)&lt;br /&gt;
* PBX-App(innovaphone-microsoft365) license per user - order no. 02-00050-009&lt;br /&gt;
&lt;br /&gt;
== Concept ==&lt;br /&gt;
&lt;br /&gt;
=== User Presence ===&lt;br /&gt;
&lt;br /&gt;
==== Configuration ====&lt;br /&gt;
Please have a look into our [[Howto16r1:Configure User Presence Sync by Connector for Microsoft365|Howto guide for basic configuration aid on user presence synchronisation]].&lt;br /&gt;
&lt;br /&gt;
==== Technical Overview ====&lt;br /&gt;
If the Connector for Microsoft 365 app is fully configured, the app connects to Microsoft to obtain a token. With the token, the app gets the teams users (with a Teams license) through the Microsoft Graph API.&lt;br /&gt;
A presence subscription to Microsoft is started with the licensed users of the PBX to get presence changes in Microsoft Teams for these users. A user subscription is also started to get changes of the users (adding, deleting or update). If a user has changed, the Teams users are retrieved again. If the presence has changed, it is forwarded to the PBX. The presences of Teams are mapped to the presences of the PBX.&lt;br /&gt;
&lt;br /&gt;
* User subscriptions are renewed every 60 minutes.&lt;br /&gt;
* Presence subscriptions are renewed every 10 minutes.&lt;br /&gt;
* License Check is made periodically.&lt;br /&gt;
&lt;br /&gt;
The app synchronises the PBX presence with Teams through the Graph Api. The on-the-phone presence will be renewed every 5 minutes. The other presences have a lifetime of 1 day but the away has a lifetime of 7 days.&lt;br /&gt;
The lifetimes are described [https://learn.microsoft.com/en-us/graph/api/presence-setuserpreferredpresence?view=graph-rest-1.0&amp;amp;tabs=http here]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Please be aware:&#039;&#039;&#039; The actual change of presence or line state will be live, the above-mentioned subscriptions are needed to register against the Microsoft API for changes. &lt;br /&gt;
After successful subscription Microsoft will trigger the Connector for Microsoft 365 App every time a presence or line state for a user has changed.&lt;br /&gt;
The subscription will then be renewed in the above-mentioned time interval to receive further live updates.&lt;br /&gt;
&lt;br /&gt;
===== User Matching =====&lt;br /&gt;
You now can choose the fields used for user matching on either side from the following options:&lt;br /&gt;
* PBX&lt;br /&gt;
** CN (Long Name property from the PBX user object)&lt;br /&gt;
** h323 (Name property from the PBX user object)&lt;br /&gt;
* Azure Portal&lt;br /&gt;
** displayName&lt;br /&gt;
** mail&lt;br /&gt;
** mailNickname&lt;br /&gt;
** onPremisesDistinguishedName&lt;br /&gt;
** onPremisesSamAccountName&lt;br /&gt;
** onPremisesUserPrincipalName&lt;br /&gt;
** userPrincipalName&lt;br /&gt;
&lt;br /&gt;
Additionally, you have the possibility to remove a possibly contained domain from the Azure fields content. &amp;lt;br&amp;gt;&lt;br /&gt;
Example: &#039;user@domain.tld&#039; is transformed to &#039;user&#039;, if this option is checked.&lt;br /&gt;
&lt;br /&gt;
===== Mapping Table =====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Teams Presence&lt;br /&gt;
! PBX Presence&lt;br /&gt;
|-&lt;br /&gt;
| Away&lt;br /&gt;
| away&lt;br /&gt;
|-&lt;br /&gt;
| BeRightBack&lt;br /&gt;
| away&lt;br /&gt;
|-&lt;br /&gt;
| Busy&lt;br /&gt;
| busy&lt;br /&gt;
|-&lt;br /&gt;
| DoNotDisturb&lt;br /&gt;
| dnd&lt;br /&gt;
|-&lt;br /&gt;
| InACall&lt;br /&gt;
| on-the-phone&lt;br /&gt;
|-&lt;br /&gt;
| InAMeeting&lt;br /&gt;
| meeting&lt;br /&gt;
|-&lt;br /&gt;
| Inactive&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| PresenceUnknown&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| Available&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| Offline&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| Offwork&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| OutOfOffice&lt;br /&gt;
| away&lt;br /&gt;
|-&lt;br /&gt;
| UrgentInterruptionsOnly&lt;br /&gt;
| dnd&lt;br /&gt;
|-&lt;br /&gt;
| Presenting&lt;br /&gt;
| on-the-phone&lt;br /&gt;
|-&lt;br /&gt;
| InAConferenceCall&lt;br /&gt;
| on-the-phone&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The value &amp;quot;online&amp;quot; unsets the Teams presence in the PBX.&lt;br /&gt;
&lt;br /&gt;
===== Master/Slave =====&lt;br /&gt;
&lt;br /&gt;
For Master/Slave combination the &amp;quot;Connector for Microsoft 365&amp;quot; App has to be added to the slave (if no full replication is on). The slave websocket connection is needed to display &amp;quot;on-the-phone&amp;quot; presence.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Calendar Presence ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Configuration ====&lt;br /&gt;
Please have a look into our [[Howto16r1:Configure Calendar Presence Sync by Connector for Microsoft365|Howto guide for basic configuration aid on calendar presence synchronisation]].&lt;br /&gt;
&lt;br /&gt;
==== Technical Overview ====&lt;br /&gt;
Introduced in 15r1 the Connector for Microsoft 365 will offer a possibility to sync Azure Portal calendar events (Teams, Exchange online) via the Graph API with the PBX presence.&amp;lt;br&amp;gt;&lt;br /&gt;
For now the [https://wiki.innovaphone.com/index.php?title=Reference13r3:Concept_App_Service_Calendar Calendar App] is (along with other functions) also capable of syncing calendar events, but using the old EWS mechanism, which Microsoft announced as end of life starting from 2026.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Warning:&#039;&#039;&#039; Please make sure to not use both apps for syncing calendar events in parallel, this is not supported and will most likely lead to conflicts and unexpected behaviours.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
When the configuration of the connector for Microsoft 365 Calendar Presence Sync is complete, the app connects to Microsoft to receive a token with the calendar app registered in the Azure portal.&amp;lt;br&amp;gt;&lt;br /&gt;
With the token, the app can pick up the users from the Azure portal.&amp;lt;br&amp;gt;&lt;br /&gt;
These are matched against the users in the PBX, based on the configured &amp;quot;User Assignment&amp;quot; settings.&amp;lt;br&amp;gt;&lt;br /&gt;
For each matched user with a valid Connector for Microsoft 365 licence applied, a subscription for calendar events is created at Microsoft to receive event changes in Microsoft Calendar for these users.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
A user subscription is also started to receive user changes (add, delete or update).&amp;lt;br&amp;gt;&lt;br /&gt;
If a user has changed, the users are retrieved again. &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
If a calendar event has been started or ended, it is forwarded to the PBX.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* User subscriptions are renewed every 60 minutes.&lt;br /&gt;
* Event subscriptions are renewed every day.&lt;br /&gt;
* License Check is made every hour.&lt;br /&gt;
&lt;br /&gt;
=== Contact Search ===&lt;br /&gt;
&lt;br /&gt;
==== Configuration ====&lt;br /&gt;
Please have a look into our [[Howto16r1:Configure_Contact_Search_by_Connector_for_Microsoft365|Howto guide for basic configuration aid on contact search]].&lt;br /&gt;
&lt;br /&gt;
==== Technical Overview ====&lt;br /&gt;
Introduced in 16r1 the Connector for Microsoft 365 will offer a possibility to search for your own contacts (Teams, Exchange online) via the Graph API.&lt;br /&gt;
&lt;br /&gt;
When the configuration of the connector for Microsoft 365 Contact Search is complete, the app connects to Microsoft to receive a token with the contact search app registered in the Azure portal.&amp;lt;br&amp;gt;&lt;br /&gt;
With the token, the app can pick up the users from the Azure portal.&amp;lt;br&amp;gt;&lt;br /&gt;
These are matched against the users in the PBX, based on the configured &amp;quot;User Assignment&amp;quot; settings.&amp;lt;br&amp;gt;&lt;br /&gt;
For each matched user with a valid Connector for Microsoft 365 licence applied, the user can search with the Phone App, for example (a myApps search provider will be provided for all apps looking using search providers looking up contacts). The search string is made available to the Connector for Microsoft 365 via the microsoft365-api. The results are sent to the consumer, e.g. the Phone App and presented there.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
A user subscription is started to receive user changes (add, delete or update).&amp;lt;br&amp;gt;&lt;br /&gt;
If a user has changed, the users are retrieved again. &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* User subscriptions are renewed every 60 minutes.&lt;br /&gt;
* License Check is made every hour.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Be aware:&#039;&#039;&#039; Since the Connector for Microsoft 365 is an app in the Scope of myApps App Platform, IP Phones and other services not using Apps cannot benefit from this search service.&lt;br /&gt;
&lt;br /&gt;
== Related Articles ==&lt;br /&gt;
&lt;br /&gt;
=Known Limitation=&lt;br /&gt;
&lt;br /&gt;
== General ==&lt;br /&gt;
&#039;&#039;Applies to the User Presence and the Calendar Presence&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Synchronization Delay ===&lt;br /&gt;
In the official Graph-API documentation, Microsoft is providing an overview about expected latencies for change notifications.&amp;lt;br&amp;gt;&lt;br /&gt;
You can find a whole overview table here:&amp;lt;br&amp;gt;&lt;br /&gt;
https://learn.microsoft.com/en-us/graph/change-notifications-overview#latency&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
For the user presences the resource &amp;quot;presence&amp;quot; is used and an average latency of 10 seconds but a maximum up to 1 minute is provided.&amp;lt;br&amp;gt;&lt;br /&gt;
Such a delay in syncing changed presences from Teams down to the PBX are considered normal and are caused by the Microsoft Graph-API.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
In case of calendar events the average is provided as &amp;quot;less than 1 minute&amp;quot; and the maximum to 3 minutes.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== User Presence ==&lt;br /&gt;
=== Line states set by the PBX does not block calls in Teams ===&lt;br /&gt;
Line states set by a 3rd party application (like the Connector for Microsoft 365) through the graph API are currently &#039;&#039;&#039;only for display purpose and do not block new calls&#039;&#039;&#039; in Teams.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
https://techcommunity.microsoft.com/t5/teams-developer/ms-graph-setpresence-problems/m-p/2798805/highlight/true#M3957&amp;lt;br&amp;gt;&lt;br /&gt;
As you can see in the above linked discussion, there once existed a feature request on Microsoft Voice, which is no longer available since it was not voted.&lt;br /&gt;
=== Maximum number of supported users ===&lt;br /&gt;
The connector now supports multiple Microsoft Teams communication users, which is the prerequisite to subscribe for more than 650 users. There is a new ribbon (Manage Teams Accounts) that allows you to configure as many communication users as you need. Every configured communication user can be used to subscribe 650 users, for example:&lt;br /&gt;
&lt;br /&gt;
*3 configured communication users x 650 licensed users = 1950 users can be subscribed&lt;br /&gt;
&#039;&#039;&#039;Please be aware&#039;&#039;&#039;: Each communication user must have a Teams license applied.&lt;br /&gt;
&lt;br /&gt;
This limitation is caused by Microsoft.&amp;lt;br&amp;gt;&lt;br /&gt;
In the documentation of the Graph-API you will find a hint to this limitation:&amp;lt;br&amp;gt;&lt;br /&gt;
https://learn.microsoft.com/en-us/graph/changenotifications-for-presence#subscribe-to-multiple-users-presence&amp;lt;br&amp;gt;&lt;br /&gt;
Trying to subscribe more than 650 users (with one communication user) by using the presence subscription API will be declined by the graph API with an error message, that too many users are requested.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Communication User (UserSynctoPbx) ===&lt;br /&gt;
Users with multi-factor authentication (MFA) are not supported as technical communication users for the Connector.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;We recommend creating a dedicated user account for this purpose rather than using an existing user account.&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;This limitation applies only to technical users used for the Connector for Microsoft 365, not standard user accounts. MFA can be used for real users.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Multiple sites / instances require multiple communication users ===&lt;br /&gt;
Each instance or each site must have separate communication users, as Microsoft only allows one concurrent subscription per communication user. (otherwise an HTTP 409 conflict will occur)&lt;br /&gt;
&lt;br /&gt;
This means that if you want to subscribe to the same Azure Portal backend from two different sites (or instances), you will need to have multiple communication users (each with an applied Teams licence) in order to be able to subscribe from all endpoints.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Subscription Timeout ===&lt;br /&gt;
&lt;br /&gt;
==== Situation ====&lt;br /&gt;
Due to a current limitation in the Graph API it is not possible to cancel or delete an active presence subscription.&amp;lt;br&amp;gt;&lt;br /&gt;
As you can see in the [https://learn.microsoft.com/en-us/graph/api/subscription-delete?view=graph-rest-1.0&amp;amp;tabs=http|documentation of the current Graph API (1.0)] the “Delete subscription” chapter does not include presence subscriptions.&amp;lt;br&amp;gt;&lt;br /&gt;
It is also not possible to have multiple subscription in parallel. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To make sure to only request a new presence subscription when the old one is not valid anymore, the app will store the state of the presence subscription and the time until it is valid in the database.&amp;lt;br&amp;gt;&lt;br /&gt;
As mentioned in the chapter “Technical Overview” we are creating presence subscriptions with a validity of 10 minutes.&amp;lt;br&amp;gt;&lt;br /&gt;
The presence subscription will be renewed as soon as it is no longer valid which will be 10 minutes after initial subscription.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Impact ====&lt;br /&gt;
If settings are changed or the app instance is restarted it will check the corresponding database entry on startup.&amp;lt;br&amp;gt;&lt;br /&gt;
In case the last presence subscription was completed less than 10 minutes ago, there is still an active presence subscription and the app has to wait for it to become invalid. &amp;lt;br&amp;gt;&lt;br /&gt;
Some Changes (e.g., to the “Notification-URL”) will only take effect after a new created subscription. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The current Beta Version of the Graph API is already providing a function to delete presence subscriptions, so we hope we can improve this behavior in the future.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Contact Search ==&lt;br /&gt;
=== Limited scope of searchable contacts ===&lt;br /&gt;
The contact search only queries the default Contacts folder of the searching user&#039;s mailbox via the Microsoft Graph API (&#039;&#039;&#039;/users/{id}/contacts&#039;&#039;&#039;). The following are currently &#039;&#039;&#039;not&#039;&#039;&#039; included in the search results:&lt;br /&gt;
&lt;br /&gt;
* Custom/subordinate contact folders&lt;br /&gt;
* Contact folders of other mailboxes shared with the user&lt;br /&gt;
* The organizational Global Address List (GAL)&lt;br /&gt;
&lt;br /&gt;
Creating and managing custom contact folders is no longer available in Microsoft&#039;s own cloud-based Outlook (Outlook on the web / new Outlook). Contacts in folders created earlier are still displayed there, listed under a different category - but the standard Microsoft Graph API contact search used by the Connector does not find these contacts.&lt;br /&gt;
&lt;br /&gt;
Search of the organizational Global Address List (GAL) is currently not supported by the Connector.&lt;br /&gt;
&lt;br /&gt;
=Troubleshooting=&lt;br /&gt;
== General ==&lt;br /&gt;
&lt;br /&gt;
===Creating an app trace===&lt;br /&gt;
For further analysis and creating a support ticket it will be useful to have a suitable app trace. &amp;lt;br&amp;gt;&lt;br /&gt;
Before creating the trace please make sure the following trace flags are activated for the app instance:&lt;br /&gt;
* App&lt;br /&gt;
* App WebSocket&lt;br /&gt;
* Config&lt;br /&gt;
* Database&lt;br /&gt;
* HTTP client&lt;br /&gt;
* TCP&lt;br /&gt;
* TLS&lt;br /&gt;
* Webserver&lt;br /&gt;
&lt;br /&gt;
After setting the config flags, please make sure to&lt;br /&gt;
* stop the instance&lt;br /&gt;
* deleting the current instance log&lt;br /&gt;
* start the instance&lt;br /&gt;
&#039;&#039;&#039;Now please wait at least 12 Minutes before you save the log&#039;&#039;&#039;, otherwise we could not have the whole picture in the trace.&lt;br /&gt;
&lt;br /&gt;
The restart and deletion of the the old log is useful the see the complete initialization process right away.&lt;br /&gt;
&lt;br /&gt;
===SSL Certificate for notification URL===&lt;br /&gt;
It also is useful to make sure the notification URL has a valid and public signed certificate.&amp;lt;br&amp;gt;&lt;br /&gt;
You can do that, using an SSL-Checker, for example: https://www.sslshopper.com/ssl-checker.html &amp;lt;br&amp;gt;&lt;br /&gt;
Without a valid, public signed certificate, Microsoft will decline the connection since it will not be possible to establish a trust relationship for the SSL/TLS secure channel.&lt;br /&gt;
&lt;br /&gt;
===Correctness of notification URL===&lt;br /&gt;
You can try to open the notification URL in your Browser&amp;lt;br&amp;gt;&lt;br /&gt;
Most likely you will see a HTTP 404 (Not Found) error message, which is the expected behavior since we are not providing an HTML website, the HTTP GET request from the browser will not be answered with content.&amp;lt;br&amp;gt;&lt;br /&gt;
This is perfectly fine since Microsoft will send presence updates with HTTP POST and will not try to request content from our app.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
What you can find out by trying to open the URL in your browser are the two following things: &amp;lt;br&amp;gt;&lt;br /&gt;
* If you receive a HTTP 404 error message you are most likely connected to an App Platform, if not you need to check your DNS (and maybe also reverse proxy) settings.&lt;br /&gt;
* If the URL is modified and the used build number is added, an app has answered your request&lt;br /&gt;
** Example: &amp;lt;code&amp;gt;https://public.dns/your.domain/microsoft365/subscriptions&amp;lt;/code&amp;gt; is modified to &amp;lt;code&amp;gt;https://public.dns/your.domain/microsoft365/&amp;lt;b&amp;gt;1510411&amp;lt;/b&amp;gt;/subscriptions&amp;lt;/code&amp;gt;&lt;br /&gt;
** If this is not the case, your URL is wrong. (Be aware: The URL depends on the settings of the web server path of your app instance)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Be aware:&#039;&#039;&#039; The URL-Recognition in the Application Platform is &#039;&#039;&#039;case sensitive&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Activation of &amp;quot;Public client flow&amp;quot; for the registered app in Azure Portal===&lt;br /&gt;
If the subscription is not working at all, please make sure &amp;quot;Public client flow&amp;quot; is activated for the registered app in the Azure portal (as described in our [[Howto16r1:Configure User Presence Sync by Connector for Microsoft365#Create an App for syncing Teams to PBX|HowTo article]]).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
The App Service trace will contain the following message if this is not the case:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;AADSTS7000218: The request body must contain the following parameter: &#039;client_assertion&#039; or &#039;client_secret&#039;.&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== User Presence == &lt;br /&gt;
===GUI Feedback===&lt;br /&gt;
The app itself shows required states with green and red as connections to the Master PBX, Authentication and Presence Subscription to identify if there are problems. &amp;lt;br&amp;gt;&lt;br /&gt;
Sometimes it needs a little bit time until the states are changed. &amp;lt;br&amp;gt;&lt;br /&gt;
If the states remain, it is mandatory to enable logs on the app platform and check for more information. &amp;lt;br&amp;gt;&lt;br /&gt;
([[Howto13r3:Configure Connector for Microsoft365#Creating an app trace|Concept App Service Connector for Microsoft 365: Creating an app trace]])&lt;br /&gt;
&lt;br /&gt;
====No connection to Master PBX====&lt;br /&gt;
Check the MasterPBX name.&amp;lt;br&amp;gt;&lt;br /&gt;
The field must only contain the name [&amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;pbx&amp;lt;/span&amp;gt;], &#039;&#039;&#039;not the full domain&#039;&#039;&#039; [&amp;lt;span style=&amp;quot;color:red;text-decoration: line-through;&amp;quot;&amp;gt;pbx.domain.tld&amp;lt;/span&amp;gt;]. ([[Howto13r3:Configure Connector for Microsoft365#Synchronization from Teams to the PBX|Synchronization from Teams to the PBX - Master PBX field]])&lt;br /&gt;
&lt;br /&gt;
====Presence subscription failed====&lt;br /&gt;
There are many reasons why the &amp;quot;Presence subscription failed&amp;quot; message could be displayed.&amp;lt;br&amp;gt;&lt;br /&gt;
We try to list the most common reasons:&lt;br /&gt;
* The permission for the registered app in the Azure portal are not correctly set ([[Howto13r3:Configure Connector for Microsoft365#Create an App for syncing Teams to PBX|Howto: Create an App for syncing Teams to PBX]])&lt;br /&gt;
* The Notification URL is wrong ([[Reference13r3:Concept App Service Connector for Microsoft 365#Correctness of notification URL|Concept App Service Connector for Microsoft 365: Correctness of notification URL]] )&lt;br /&gt;
* The App service is not reachable from the internet ([[Reference13r3:Concept App Service Connector for Microsoft 365#Correctness of notification URL|Concept App Service Connector for Microsoft 365: Correctness of notification URL]] )&lt;br /&gt;
* The certificate for the public endpoint (e.g. reverse proxy) is not valid, or not publicly signed ([[Reference13r3:Concept App Service Connector for Microsoft 365#SSL Certificate for notification URL|Concept App Service Connector for Microsoft 365: SSL Certificate for notification URL]])&lt;br /&gt;
* The user from PBX and the Azure Portal cannot be matched ([[Reference13r3:Concept App Service Connector for Microsoft 365#User Matching|Concept App Service Connector for Microsoft 365: User Matching]])&lt;br /&gt;
* The App Platforms clock time is wrong ([[Reference13r3:Concept App Service Connector for Microsoft 365#App Platform clock time is wrong|Concept App Service Connector for Microsoft 365: App Platform clock time is wrong]])&lt;br /&gt;
* No user has a valid Connector for Microsoft 365 App license ([[Reference13r3:Concept App Service Connector for Microsoft 365#Requirements|Concept App Service Connector for Microsoft 365: Requirements]])&lt;br /&gt;
&lt;br /&gt;
===Teams License for communication user===&lt;br /&gt;
If presence subscription does not work, please check if all of the configured communication users have a Microsoft Teams license applied and no multifactor authentication is in use for this particular user. &amp;lt;br&amp;gt;&lt;br /&gt;
Also please make sure you can login with the configured credentials. (If you have set a password as an Administration, the user needs to change the password during the first login, therefore the given password will be invalid for API access).&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Sometimes, after changing setting or after the instance has restarted it can take up to 12 minutes until the presence subscription is working correctly. (Due to the subscription timeout)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
= Known Issues =&lt;br /&gt;
== Special Characters In Password ==&lt;br /&gt;
If you are using special characters (*, &amp;amp;, (, ), etc.) in your password you could run into a problem with the authentication of the communication user.&amp;lt;br&amp;gt;&lt;br /&gt;
The authentication failed status is being displayed. &amp;lt;br&amp;gt;&lt;br /&gt;
For the moment the only workaround is to eliminate special characters from your password.&lt;br /&gt;
&lt;br /&gt;
==App Platform clock time is wrong==&lt;br /&gt;
If the clock time at the App Platform is not correct, this will lead to an unstable behaviour of the Connector for Microsoft 365.&amp;lt;br&amp;gt;&lt;br /&gt;
Since the Connector for Microsoft 365 is using the Microsoft Graph APIs presence subscription function, it needs to provide in its request a precise time until the subscription validity will be expired.&amp;lt;br&amp;gt;&lt;br /&gt;
The app service is handling subscription and will automatically recreate a new subscription each time the previous one has expired.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A wrong clock time will lead to false expiration times and thus&lt;br /&gt;
*  the subscription will be expired earlier than expected (synchronisation is not working because there is no valid subscription)&lt;br /&gt;
*  the subscription will be valid longer than expected (the app service is trying to create a new subscription because it is expecting the previous one to be expired - will lead to a 409 conflict error, because only one subscription can be valid at a time)&lt;br /&gt;
&lt;br /&gt;
If you are not sure about the current time of the App Platform, you can login via SSH into the App Platform and execute the &amp;lt;code&amp;gt;date&amp;lt;/code&amp;gt; command to check the current time.&amp;lt;br&amp;gt;&lt;br /&gt;
You will receive an output like: &lt;br /&gt;
 Tue Mar 12 13:38:57 UTC 2024&lt;br /&gt;
Please be aware: The time is displayed in UTC, so please make sure to convert to your local time zone.&lt;br /&gt;
&lt;br /&gt;
==Geoblocking==&lt;br /&gt;
Since there might be no reliable country assignment for Microsoft addresses, all Microsoft addresses must be enabled on the upstream firewall in the event of geoblocking in order to ensure functionality of the Office365 Connector.&amp;lt;br&amp;gt;&lt;br /&gt;
As an alternative you might be able to configure your firewall to bypass the geoblocking for the configured notification URL.&lt;br /&gt;
&lt;br /&gt;
= Related Articles =&lt;br /&gt;
[[Howto16r1:Configure User Presence Sync by Connector for Microsoft365]] &amp;lt;br/&amp;gt;&lt;br /&gt;
[[Howto16r1:Configure Calendar Presence Sync by Connector for Microsoft365]] &amp;lt;br/&amp;gt;&lt;br /&gt;
[[Howto16r1:Configure Contact Search by Connector for Microsoft365]] &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Howto|{{PAGENAME}}]]&lt;/div&gt;</summary>
		<author><name>Tfu</name></author>
	</entry>
	<entry>
		<id>https://wiki.innovaphone.com/index.php?title=Reference15r1:Concept_App_Service_Connector_for_Microsoft_365&amp;diff=80679</id>
		<title>Reference15r1:Concept App Service Connector for Microsoft 365</title>
		<link rel="alternate" type="text/html" href="https://wiki.innovaphone.com/index.php?title=Reference15r1:Concept_App_Service_Connector_for_Microsoft_365&amp;diff=80679"/>
		<updated>2026-10-13T14:35:10Z</updated>

		<summary type="html">&lt;p&gt;Tfu: App trace: wait at least 12 minutes instead of 5 before saving the log&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Concept|Apps]]&lt;br /&gt;
== Applies To == &lt;br /&gt;
&lt;br /&gt;
* Connector for Microsoft 365 from Version 15r1&lt;br /&gt;
&lt;br /&gt;
= Overview =&lt;br /&gt;
&lt;br /&gt;
Connector for Microsoft 365 synchronizes Microsoft Teams presences with the innovaphone PBX and back, and optionally additionally Calendar presence from Exchange Online (part of the Microsoft 365 Cloud Services).&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
* innovaphone PBX&lt;br /&gt;
* innovaphone Application Platform (minimum version 120004)&lt;br /&gt;
* V15r1&lt;br /&gt;
* App(Connector for Microsoft 365)&lt;br /&gt;
* PBX-App(innovaphone-microsoft365) license per user - order no. 02-00050-009&lt;br /&gt;
&lt;br /&gt;
== Concept ==&lt;br /&gt;
&lt;br /&gt;
=== User Presence ===&lt;br /&gt;
&lt;br /&gt;
==== Configuration ====&lt;br /&gt;
Please have a look into our [[Howto15r1:Configure User Presence Sync by Connector for Microsoft365|Howto guide for basic configuration aid]].&lt;br /&gt;
&lt;br /&gt;
==== Technical Overview ====&lt;br /&gt;
If the Connector for Microsoft 365 app is fully configured, the app connects to Microsoft to obtain a token. With the token, the app gets the teams users (with a Teams license) through the Microsoft Graph API.&lt;br /&gt;
A presence subscription to Microsoft is started with the licensed users of the PBX to get presence changes in Microsoft Teams for these users. A user subscription is also started to get changes of the users (adding, deleting or update). If a user has changed, the Teams users are retrieved again. If the presence has changed, it is forwarded to the PBX. The presences of Teams are mapped to the presences of the PBX.&lt;br /&gt;
&lt;br /&gt;
* User subscriptions are renewed every 60 minutes.&lt;br /&gt;
* Presence subscriptions are renewed every 10 minutes.&lt;br /&gt;
* License Check is made periodically.&lt;br /&gt;
&lt;br /&gt;
The app synchronises the PBX presence with Teams through the Graph Api. The on-the-phone presence will be renewed every 5 minutes. The other presences have a lifetime of 1 day but the away has a lifetime of 7 days.&lt;br /&gt;
The lifetimes are described [https://learn.microsoft.com/en-us/graph/api/presence-setuserpreferredpresence?view=graph-rest-1.0&amp;amp;tabs=http here]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Please be aware:&#039;&#039;&#039; The actual change of presence or line state will be live, the above-mentioned subscriptions are needed to register against the Microsoft API for changes. &lt;br /&gt;
After successful subscription Microsoft will trigger the Connector for Microsoft 365 App every time a presence or line state for a user has changed.&lt;br /&gt;
The subscription will then be renewed in the above-mentioned time interval to receive further live updates.&lt;br /&gt;
&lt;br /&gt;
===== User Matching =====&lt;br /&gt;
You now can choose the fields used for user matching on either side from the following options:&lt;br /&gt;
* PBX&lt;br /&gt;
** CN (Long Name property from the PBX user object)&lt;br /&gt;
** h323 (Name property from the PBX user object)&lt;br /&gt;
* Azure Portal&lt;br /&gt;
** displayName&lt;br /&gt;
** mail&lt;br /&gt;
** mailNickname&lt;br /&gt;
** onPremisesDistinguishedName&lt;br /&gt;
** onPremisesSamAccountName&lt;br /&gt;
** onPremisesUserPrincipalName&lt;br /&gt;
** userPrincipalName&lt;br /&gt;
&lt;br /&gt;
Additionally, you have the possibility to remove a possibly contained domain from the Azure fields content. &amp;lt;br&amp;gt;&lt;br /&gt;
Example: &#039;user@domain.tld&#039; is transformed to &#039;user&#039;, if this option is checked.&lt;br /&gt;
&lt;br /&gt;
===== Mapping Table =====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Teams Presence&lt;br /&gt;
! PBX Presence&lt;br /&gt;
|-&lt;br /&gt;
| Away&lt;br /&gt;
| away&lt;br /&gt;
|-&lt;br /&gt;
| BeRightBack&lt;br /&gt;
| away&lt;br /&gt;
|-&lt;br /&gt;
| Busy&lt;br /&gt;
| busy&lt;br /&gt;
|-&lt;br /&gt;
| DoNotDisturb&lt;br /&gt;
| dnd&lt;br /&gt;
|-&lt;br /&gt;
| InACall&lt;br /&gt;
| on-the-phone&lt;br /&gt;
|-&lt;br /&gt;
| InAMeeting&lt;br /&gt;
| meeting&lt;br /&gt;
|-&lt;br /&gt;
| Inactive&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| PresenceUnknown&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| Available&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| Offline&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| Offwork&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| OutOfOffice&lt;br /&gt;
| away&lt;br /&gt;
|-&lt;br /&gt;
| UrgentInterruptionsOnly&lt;br /&gt;
| dnd&lt;br /&gt;
|-&lt;br /&gt;
| Presenting&lt;br /&gt;
| on-the-phone&lt;br /&gt;
|-&lt;br /&gt;
| InAConferenceCall&lt;br /&gt;
| on-the-phone&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The value &amp;quot;online&amp;quot; unsets the Teams presence in the PBX.&lt;br /&gt;
&lt;br /&gt;
===== Master/Slave =====&lt;br /&gt;
&lt;br /&gt;
For Master/Slave combination the &amp;quot;Connector for Microsoft 365&amp;quot; App has to be added to the slave (if no full replication is on). The slave websocket connection is needed to display &amp;quot;on-the-phone&amp;quot; presence.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Calendar Presence ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Configuration ====&lt;br /&gt;
Please have a look into our [[Howto15r1:Configure_Calendar_Presence_Sync_by_Connector_for_Microsoft365|Howto guide for basic configuration aid]].&lt;br /&gt;
&lt;br /&gt;
==== Technical Overview ====&lt;br /&gt;
Introduced in 15r1 the Connector for Microsoft 365 will offer a possibility to sync Azure Portal calendar events (Teams, Exchange online) via the Graph API with the PBX presence.&amp;lt;br&amp;gt;&lt;br /&gt;
For now the [https://wiki.innovaphone.com/index.php?title=Reference13r3:Concept_App_Service_Calendar Calendar App] is (along with other functions) also capable of syncing calendar events, but using the old EWS mechanism, which Microsoft announced as end of life starting from 2026.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Warning:&#039;&#039;&#039; Please make sure to not use both apps for syncing calendar events in parallel, this is not supported and will most likely lead to conflicts and unexpected behaviours.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
When the configuration of the connector for Microsoft 365 Calendar Presence Sync is complete, the app connects to Microsoft to receive a token with the calendar app registered in the Azure portal.&amp;lt;br&amp;gt;&lt;br /&gt;
With the token, the app can pick up the users from the Azure portal.&amp;lt;br&amp;gt;&lt;br /&gt;
These are matched against the users in the PBX, based on the configured &amp;quot;User Assignment&amp;quot; settings.&amp;lt;br&amp;gt;&lt;br /&gt;
For each matched user with a valid Connector for Microsoft 365 licence applied, a subscription for calendar events is created at Microsoft to receive event changes in Microsoft Calendar for these users.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
A user subscription is also started to receive user changes (add, delete or update).&amp;lt;br&amp;gt;&lt;br /&gt;
If a user has changed, the users are retrieved again. &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
If a calendar event has been started or ended, it is forwarded to the PBX.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* User subscriptions are renewed every 60 minutes.&lt;br /&gt;
* Event subscriptions are renewed every day.&lt;br /&gt;
* License Check is made every hour.&lt;br /&gt;
&lt;br /&gt;
== Related Articles ==&lt;br /&gt;
&lt;br /&gt;
=Known Limitation=&lt;br /&gt;
&lt;br /&gt;
== General ==&lt;br /&gt;
&#039;&#039;Applies to the User Presence and the Calendar Presence&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Synchronization Delay ===&lt;br /&gt;
In the official Graph-API documentation, Microsoft is providing an overview about expected latencies for change notifications.&amp;lt;br&amp;gt;&lt;br /&gt;
You can find a whole overview table here:&amp;lt;br&amp;gt;&lt;br /&gt;
https://learn.microsoft.com/en-us/graph/change-notifications-overview#latency&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
For the user presences the resource &amp;quot;presence&amp;quot; is used and an average latency of 10 seconds but a maximum up to 1 minute is provided.&amp;lt;br&amp;gt;&lt;br /&gt;
Such a delay in syncing changed presences from Teams down to the PBX are considered normal and are caused by the Microsoft Graph-API.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
In case of calendar events the average is provided as &amp;quot;less than 1 minute&amp;quot; and the maximum to 3 minutes.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== User Presence ==&lt;br /&gt;
=== Line states set by the PBX does not block calls in Teams ===&lt;br /&gt;
Line states set by a 3rd party application (like the Connector for Microsoft 365) through the graph API are currently &#039;&#039;&#039;only for display purpose and do not block new calls&#039;&#039;&#039; in Teams.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
https://techcommunity.microsoft.com/t5/teams-developer/ms-graph-setpresence-problems/m-p/2798805/highlight/true#M3957&amp;lt;br&amp;gt;&lt;br /&gt;
As you can see in the above linked discussion, there once existed a feature request on Microsoft Voice, which is no longer available since it was not voted.&lt;br /&gt;
=== Maximum number of supported users ===&lt;br /&gt;
The connector now supports multiple Microsoft Teams communication users, which is the prerequisite to subscribe for more than 650 users. There is a new ribbon (Manage Teams Accounts) that allows you to configure as many communication users as you need. Every configured communication user can be used to subscribe 650 users, for example:&lt;br /&gt;
&lt;br /&gt;
*3 configured communication users x 650 licensed users = 1950 users can be subscribed&lt;br /&gt;
&#039;&#039;&#039;Please be aware&#039;&#039;&#039;: Each communication user must have a Teams license applied.&lt;br /&gt;
&lt;br /&gt;
This limitation is caused by Microsoft.&amp;lt;br&amp;gt;&lt;br /&gt;
In the documentation of the Graph-API you will find a hint to this limitation:&amp;lt;br&amp;gt;&lt;br /&gt;
https://learn.microsoft.com/en-us/graph/changenotifications-for-presence#subscribe-to-multiple-users-presence&amp;lt;br&amp;gt;&lt;br /&gt;
Trying to subscribe more than 650 users (with one communication user) by using the presence subscription API will be declined by the graph API with an error message, that too many users are requested.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Communication User (UserSynctoPbx) ===&lt;br /&gt;
Users with MFA (multi-factor-authentication) are not supported as technical communication user for the Connector.&lt;br /&gt;
&lt;br /&gt;
=== Multiple sites / instances require multiple communication users ===&lt;br /&gt;
Each instance or each site must have separate communication users, as Microsoft only allows one concurrent subscription per communication user. (otherwise an HTTP 409 conflict will occur)&lt;br /&gt;
&lt;br /&gt;
This means that if you want to subscribe to the same Azure Portal backend from two different sites (or instances), you will need to have multiple communication users (each with an applied Teams licence) in order to be able to subscribe from all endpoints.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Subscription Timeout ===&lt;br /&gt;
&lt;br /&gt;
==== Situation ====&lt;br /&gt;
Due to a current limitation in the Graph API it is not possible to cancel or delete an active presence subscription.&amp;lt;br&amp;gt;&lt;br /&gt;
As you can see in the [https://learn.microsoft.com/en-us/graph/api/subscription-delete?view=graph-rest-1.0&amp;amp;tabs=http|documentation of the current Graph API (1.0)] the “Delete subscription” chapter does not include presence subscriptions.&amp;lt;br&amp;gt;&lt;br /&gt;
It is also not possible to have multiple subscription in parallel. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To make sure to only request a new presence subscription when the old one is not valid anymore, the app will store the state of the presence subscription and the time until it is valid in the database.&amp;lt;br&amp;gt;&lt;br /&gt;
As mentioned in the chapter “Technical Overview” we are creating presence subscriptions with a validity of 10 minutes.&amp;lt;br&amp;gt;&lt;br /&gt;
The presence subscription will be renewed as soon as it is no longer valid which will be 10 minutes after initial subscription.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Impact ====&lt;br /&gt;
If settings are changed or the app instance is restarted it will check the corresponding database entry on startup.&amp;lt;br&amp;gt;&lt;br /&gt;
In case the last presence subscription was completed less than 10 minutes ago, there is still an active presence subscription and the app has to wait for it to become invalid. &amp;lt;br&amp;gt;&lt;br /&gt;
Some Changes (e.g., to the “Notification-URL”) will only take effect after a new created subscription. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The current Beta Version of the Graph API is already providing a function to delete presence subscriptions, so we hope we can improve this behavior in the future.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Troubleshooting=&lt;br /&gt;
== General ==&lt;br /&gt;
&lt;br /&gt;
===Creating an app trace===&lt;br /&gt;
For further analysis and creating a support ticket it will be useful to have a suitable app trace. &amp;lt;br&amp;gt;&lt;br /&gt;
Before creating the trace please make sure the following trace flags are activated for the app instance:&lt;br /&gt;
* App&lt;br /&gt;
* Database&lt;br /&gt;
* HTTP client&lt;br /&gt;
* TLS&lt;br /&gt;
* TCP&lt;br /&gt;
* App WebSocket&lt;br /&gt;
* Config&lt;br /&gt;
* Webserver&lt;br /&gt;
&lt;br /&gt;
After setting the config flags, please make sure to&lt;br /&gt;
* stop the instance&lt;br /&gt;
* deleting the current instance log&lt;br /&gt;
* start the instance&lt;br /&gt;
&#039;&#039;&#039;Now please wait at least 12 Minutes before you save the log&#039;&#039;&#039;, otherwise we could not have the whole picture in the trace.&lt;br /&gt;
&lt;br /&gt;
The restart and deletion of the the old log is useful the see the complete initialization process right away.&lt;br /&gt;
&lt;br /&gt;
===SSL Certificate for notification URL===&lt;br /&gt;
It also is useful to make sure the notification URL has a valid and public signed certificate.&amp;lt;br&amp;gt;&lt;br /&gt;
You can do that, using an SSL-Checker, for example: https://www.sslshopper.com/ssl-checker.html &amp;lt;br&amp;gt;&lt;br /&gt;
Without a valid, public signed certificate, Microsoft will decline the connection since it will not be possible to establish a trust relationship for the SSL/TLS secure channel.&lt;br /&gt;
&lt;br /&gt;
===Correctness of notification URL===&lt;br /&gt;
You can try to open the notification URL in your Browser&amp;lt;br&amp;gt;&lt;br /&gt;
Most likely you will see a HTTP 404 (Not Found) error message, which is the expected behavior since we are not providing an HTML website, the HTTP GET request from the browser will not be answered with content.&amp;lt;br&amp;gt;&lt;br /&gt;
This is perfectly fine since Microsoft will send presence updates with HTTP POST and will not try to request content from our app.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
What you can find out by trying to open the URL in your browser are the two following things: &amp;lt;br&amp;gt;&lt;br /&gt;
* If you receive a HTTP 404 error message you are most likely connected to an App Platform, if not you need to check your DNS (and maybe also reverse proxy) settings.&lt;br /&gt;
* If the URL is modified and the used build number is added, an app has answered your request&lt;br /&gt;
** Example: &amp;lt;code&amp;gt;https://public.dns/your.domain/microsoft365/subscriptions&amp;lt;/code&amp;gt; is modified to &amp;lt;code&amp;gt;https://public.dns/your.domain/microsoft365/&amp;lt;b&amp;gt;1510411&amp;lt;/b&amp;gt;/subscriptions&amp;lt;/code&amp;gt;&lt;br /&gt;
** If this is not the case, your URL is wrong. (Be aware: The URL depends on the settings of the web server path of your app instance)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Be aware:&#039;&#039;&#039; The URL-Recognition in the Application Platform is &#039;&#039;&#039;case sensitive&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Activation of &amp;quot;Public client flow&amp;quot; for the registered app in Azure Portal===&lt;br /&gt;
If the subscription is not working at all, please make sure &amp;quot;Public client flow&amp;quot; is activated for the registered app in the Azure portal (as described in our [[Howto15r1:Configure User Presence Sync by Connector for Microsoft365#Create_an_App_for_syncing_Teams_to_PBX|HowTo article]]).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
The App Service trace will contain the following message if this is not the case:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;AADSTS7000218: The request body must contain the following parameter: &#039;client_assertion&#039; or &#039;client_secret&#039;.&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== User Presence == &lt;br /&gt;
===GUI Feedback===&lt;br /&gt;
The app itself shows required states with green and red as connections to the Master PBX, Authentication and Presence Subscription to identify if there are problems. &amp;lt;br&amp;gt;&lt;br /&gt;
Sometimes it needs a little bit time until the states are changed. &amp;lt;br&amp;gt;&lt;br /&gt;
If the states remain, it is mandatory to enable logs on the app platform and check for more information. &amp;lt;br&amp;gt;&lt;br /&gt;
([[Howto13r3:Configure Connector for Microsoft365#Creating an app trace|Concept App Service Connector for Microsoft 365: Creating an app trace]])&lt;br /&gt;
&lt;br /&gt;
====No connection to Master PBX====&lt;br /&gt;
Check the MasterPBX name.&amp;lt;br&amp;gt;&lt;br /&gt;
The field must only contain the name [&amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;pbx&amp;lt;/span&amp;gt;], &#039;&#039;&#039;not the full domain&#039;&#039;&#039; [&amp;lt;span style=&amp;quot;color:red;text-decoration: line-through;&amp;quot;&amp;gt;pbx.domain.tld&amp;lt;/span&amp;gt;]. ([[Howto13r3:Configure Connector for Microsoft365#Synchronization from Teams to the PBX|Synchronization from Teams to the PBX - Master PBX field]])&lt;br /&gt;
&lt;br /&gt;
====Presence subscription failed====&lt;br /&gt;
There are many reasons why the &amp;quot;Presence subscription failed&amp;quot; message could be displayed.&amp;lt;br&amp;gt;&lt;br /&gt;
We try to list the most common reasons:&lt;br /&gt;
* The permission for the registered app in the Azure portal are not correctly set ([[Howto13r3:Configure Connector for Microsoft365#Create an App for syncing Teams to PBX|Howto: Create an App for syncing Teams to PBX]])&lt;br /&gt;
* The Notification URL is wrong ([[Reference13r3:Concept App Service Connector for Microsoft 365#Correctness of notification URL|Concept App Service Connector for Microsoft 365: Correctness of notification URL]] )&lt;br /&gt;
* The App service is not reachable from the internet ([[Reference13r3:Concept App Service Connector for Microsoft 365#Correctness of notification URL|Concept App Service Connector for Microsoft 365: Correctness of notification URL]] )&lt;br /&gt;
* The certificate for the public endpoint (e.g. reverse proxy) is not valid, or not publicly signed ([[Reference13r3:Concept App Service Connector for Microsoft 365#SSL Certificate for notification URL|Concept App Service Connector for Microsoft 365: SSL Certificate for notification URL]])&lt;br /&gt;
* The user from PBX and the Azure Portal cannot be matched ([[Reference13r3:Concept App Service Connector for Microsoft 365#User Matching|Concept App Service Connector for Microsoft 365: User Matching]])&lt;br /&gt;
* The App Platforms clock time is wrong ([[Reference13r3:Concept App Service Connector for Microsoft 365#App Platform clock time is wrong|Concept App Service Connector for Microsoft 365: App Platform clock time is wrong]])&lt;br /&gt;
* No user has a valid Connector for Microsoft 365 App license ([[Reference13r3:Concept App Service Connector for Microsoft 365#Requirements|Concept App Service Connector for Microsoft 365: Requirements]])&lt;br /&gt;
&lt;br /&gt;
===Teams License for communication user===&lt;br /&gt;
If presence subscription does not work, please check if all of the configured communication users have a Microsoft Teams license applied and no multifactor authentication is in use for this particular user. &amp;lt;br&amp;gt;&lt;br /&gt;
Also please make sure you can login with the configured credentials. (If you have set a password as an Administration, the user needs to change the password during the first login, therefore the given password will be invalid for API access).&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Sometimes, after changing setting or after the instance has restarted it can take up to 12 minutes until the presence subscription is working correctly. (Due to the subscription timeout)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
= Known Issues =&lt;br /&gt;
== Special Characters In Password ==&lt;br /&gt;
If you are using special characters (*, &amp;amp;, (, ), etc.) in your password you could run into a problem with the authentication of the communication user.&amp;lt;br&amp;gt;&lt;br /&gt;
The authentication failed status is being displayed. &amp;lt;br&amp;gt;&lt;br /&gt;
For the moment the only workaround is to eliminate special characters from your password.&lt;br /&gt;
&lt;br /&gt;
==App Platform clock time is wrong==&lt;br /&gt;
If the clock time at the App Platform is not correct, this will lead to an unstable behaviour of the Connector for Microsoft 365.&amp;lt;br&amp;gt;&lt;br /&gt;
Since the Connector for Microsoft 365 is using the Microsoft Graph APIs presence subscription function, it needs to provide in its request a precise time until the subscription validity will be expired.&amp;lt;br&amp;gt;&lt;br /&gt;
The app service is handling subscription and will automatically recreate a new subscription each time the previous one has expired.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A wrong clock time will lead to false expiration times and thus&lt;br /&gt;
*  the subscription will be expired earlier than expected (synchronisation is not working because there is no valid subscription)&lt;br /&gt;
*  the subscription will be valid longer than expected (the app service is trying to create a new subscription because it is expecting the previous one to be expired - will lead to a 409 conflict error, because only one subscription can be valid at a time)&lt;br /&gt;
&lt;br /&gt;
If you are not sure about the current time of the App Platform, you can login via SSH into the App Platform and execute the &amp;lt;code&amp;gt;date&amp;lt;/code&amp;gt; command to check the current time.&amp;lt;br&amp;gt;&lt;br /&gt;
You will receive an output like: &lt;br /&gt;
 Tue Mar 12 13:38:57 UTC 2024&lt;br /&gt;
Please be aware: The time is displayed in UTC, so please make sure to convert to your local time zone.&lt;br /&gt;
&lt;br /&gt;
==Geoblocking==&lt;br /&gt;
Since there might be no reliable country assignment for Microsoft addresses, all Microsoft addresses must be enabled on the upstream firewall in the event of geoblocking in order to ensure functionality of the Office365 Connector.&amp;lt;br&amp;gt;&lt;br /&gt;
As an alternative you might be able to configure your firewall to bypass the geoblocking for the configured notification URL.&lt;br /&gt;
&lt;br /&gt;
= Related Articles =&lt;br /&gt;
[[Howto15r1:Configure User Presence Sync by Connector for Microsoft365]] &amp;lt;br/&amp;gt;&lt;br /&gt;
[[Howto15r1:Configure Calendar Presence Sync by Connector for Microsoft365]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Howto|{{PAGENAME}}]]&lt;/div&gt;</summary>
		<author><name>Tfu</name></author>
	</entry>
	<entry>
		<id>https://wiki.innovaphone.com/index.php?title=Reference14r2:Concept_App_Service_Connector_for_Microsoft_365&amp;diff=80678</id>
		<title>Reference14r2:Concept App Service Connector for Microsoft 365</title>
		<link rel="alternate" type="text/html" href="https://wiki.innovaphone.com/index.php?title=Reference14r2:Concept_App_Service_Connector_for_Microsoft_365&amp;diff=80678"/>
		<updated>2026-10-13T14:35:07Z</updated>

		<summary type="html">&lt;p&gt;Tfu: App trace: wait at least 12 minutes instead of 5 before saving the log&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Concept|Apps]]&lt;br /&gt;
== Applies To == &lt;br /&gt;
&lt;br /&gt;
* Connector for Microsoft 365 from Version 14r2&lt;br /&gt;
&lt;br /&gt;
= Overview =&lt;br /&gt;
&lt;br /&gt;
Connector for Microsoft 365 synchronises Microsoft Teams presences with the innovaphone PBX and back.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
* innovaphone PBX&lt;br /&gt;
* innovaphone Application Platform&lt;br /&gt;
* App(Connector for Microsoft 365)&lt;br /&gt;
* PBX-App(innovaphone-microsoft365) license per user - order no. 02-00050-009&lt;br /&gt;
&lt;br /&gt;
== Concept ==&lt;br /&gt;
&lt;br /&gt;
=== Configuration ===&lt;br /&gt;
Please have a look into our [[How to: Configure Connector for Microsoft365|Howto guide for basic configuration aid]].&lt;br /&gt;
&lt;br /&gt;
=== Technical Overview ===&lt;br /&gt;
If the Connector for Microsoft 365 app is fully configured, the app connects to Microsoft to obtain a token. With the token, the app gets the teams users (with a Teams license) through the Microsoft Graph API.&lt;br /&gt;
A presence subscription to Microsoft is started with the licensed users of the PBX to get presence changes in Microsoft Teams for these users. A user subscription is also started to get changes of the users (adding, deleting or update). If a user has changed, the Teams users are retrieved again. If the presence has changed, it is forwarded to the PBX. The presences of Teams are mapped to the presences of the PBX.&lt;br /&gt;
&lt;br /&gt;
* User subscriptions are renewed every 60 minutes.&lt;br /&gt;
* Presence subscriptions are renewed every 10 minutes.&lt;br /&gt;
* License Check is made periodically.&lt;br /&gt;
&lt;br /&gt;
The app synchronises the PBX presence with Teams through the Graph Api. The on-the-phone presence will be renewed every 5 minutes. The other presences have a lifetime of 1 day but the away has a lifetime of 7 days.&lt;br /&gt;
The lifetimes are described [https://learn.microsoft.com/en-us/graph/api/presence-setuserpreferredpresence?view=graph-rest-1.0&amp;amp;tabs=http here]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Please be aware:&#039;&#039;&#039; The actual change of presence or line state will be live, the above-mentioned subscriptions are needed to register against the Microsoft API for changes. &lt;br /&gt;
After successful subscription Microsoft will trigger the Connector for Microsoft 365 App every time a presence or line state for a user has changed.&lt;br /&gt;
The subscription will then be renewed in the above-mentioned time interval to receive further live updates.&lt;br /&gt;
&lt;br /&gt;
==== User Matching ====&lt;br /&gt;
You now can choose the fields used for user matching on either side from the following options:&lt;br /&gt;
* PBX&lt;br /&gt;
** CN (Long Name property from the PBX user object)&lt;br /&gt;
** h323 (Name property from the PBX user object)&lt;br /&gt;
* Azure Portal&lt;br /&gt;
** displayName&lt;br /&gt;
** mail&lt;br /&gt;
** mailNickname&lt;br /&gt;
** onPremisesDistinguishedName&lt;br /&gt;
** onPremisesSamAccountName&lt;br /&gt;
** onPremisesUserPrincipalName&lt;br /&gt;
** userPrincipalName&lt;br /&gt;
&lt;br /&gt;
Additionally, you have the possibility to remove a possibly contained domain from the Azure fields content. &amp;lt;br&amp;gt;&lt;br /&gt;
Example: &#039;user@domain.tld&#039; is transformed to &#039;user&#039;, if this option is checked.&lt;br /&gt;
&lt;br /&gt;
==== Mapping Table ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Teams Presence&lt;br /&gt;
! PBX Presence&lt;br /&gt;
|-&lt;br /&gt;
| Away&lt;br /&gt;
| away&lt;br /&gt;
|-&lt;br /&gt;
| BeRightBack&lt;br /&gt;
| away&lt;br /&gt;
|-&lt;br /&gt;
| Busy&lt;br /&gt;
| busy&lt;br /&gt;
|-&lt;br /&gt;
| DoNotDisturb&lt;br /&gt;
| dnd&lt;br /&gt;
|-&lt;br /&gt;
| InACall&lt;br /&gt;
| on-the-phone&lt;br /&gt;
|-&lt;br /&gt;
| InAMeeting&lt;br /&gt;
| meeting&lt;br /&gt;
|-&lt;br /&gt;
| Inactive&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| PresenceUnknown&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| Available&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| Offline&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| Offwork&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| OutOfOffice&lt;br /&gt;
| away&lt;br /&gt;
|-&lt;br /&gt;
| UrgentInterruptionsOnly&lt;br /&gt;
| dnd&lt;br /&gt;
|-&lt;br /&gt;
| Presenting&lt;br /&gt;
| on-the-phone&lt;br /&gt;
|-&lt;br /&gt;
| InAConferenceCall&lt;br /&gt;
| on-the-phone&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The value &amp;quot;online&amp;quot; unsets the Teams presence in the PBX.&lt;br /&gt;
&lt;br /&gt;
==== Master/Slave ====&lt;br /&gt;
&lt;br /&gt;
For Master/Slave combination the &amp;quot;Connector for Microsoft 365&amp;quot; App has to be added to the slave (if no full replication is on). The slave websocket connection is needed to display &amp;quot;on-the-phone&amp;quot; presence.&lt;br /&gt;
&lt;br /&gt;
== Related Articles ==&lt;br /&gt;
&lt;br /&gt;
=Known Limitation=&lt;br /&gt;
&lt;br /&gt;
== Line states set by the PBX does not block calls in Teams ==&lt;br /&gt;
Line states set by a 3rd party application (like the Connector for Microsoft 365) through the graph API are currently &#039;&#039;&#039;only for display purpose and do not block new calls&#039;&#039;&#039; in Teams.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
https://techcommunity.microsoft.com/t5/teams-developer/ms-graph-setpresence-problems/m-p/2798805/highlight/true#M3957&amp;lt;br&amp;gt;&lt;br /&gt;
As you can see in the above linked discussion, there once existed a feature request on Microsoft Voice, which is no longer available since it was not voted.&lt;br /&gt;
== Maximum number of supported users ==&lt;br /&gt;
The connector now supports multiple Microsoft Teams communication users, which is the prerequisite to subscribe for more than 650 users. There is a new ribbon (Manage Teams Accounts) that allows you to configure as many communication users as you need. Every configured communication user can be used to subscribe 650 users, for example:&lt;br /&gt;
&lt;br /&gt;
*3 configured communication users x 650 licensed users = 1950 users can be subscribed&lt;br /&gt;
&#039;&#039;&#039;Please be aware&#039;&#039;&#039;: Each communication user must have a Teams license applied.&lt;br /&gt;
&lt;br /&gt;
This limitation is caused by Microsoft.&amp;lt;br&amp;gt;&lt;br /&gt;
In the documentation of the Graph-API you will find a hint to this limitation:&amp;lt;br&amp;gt;&lt;br /&gt;
https://learn.microsoft.com/en-us/graph/changenotifications-for-presence#subscribe-to-multiple-users-presence&amp;lt;br&amp;gt;&lt;br /&gt;
Trying to subscribe more than 650 users (with one communication user) by using the presence subscription API will be declined by the graph API with an error message, that too many users are requested.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Synchronization Delay ==&lt;br /&gt;
In the official Graph-API documentation, Microsoft is providing an overview about expected latencies for change notifications.&amp;lt;br&amp;gt;&lt;br /&gt;
You can find a whole overview table here:&amp;lt;br&amp;gt;&lt;br /&gt;
https://learn.microsoft.com/en-us/graph/change-notifications-overview#latency&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
For the used resource &amp;quot;presence&amp;quot; an average latency of 10 seconds but a maximum up to 1 minute is provided.&amp;lt;br&amp;gt;&lt;br /&gt;
Such a delay in syncing changed presences from Teams down to the PBX are considered normal and are caused by the Microsoft Graph-API.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Communication User (UserSynctoPbx) ==&lt;br /&gt;
Users with MFA (multi-factor-authentication) are not supported as technical communication user for the Connector.&lt;br /&gt;
&lt;br /&gt;
== Multiple sites / instances require multiple communication users ==&lt;br /&gt;
Each instance or each site must have separate communication users, as Microsoft only allows one concurrent subscription per communication user. (otherwise an HTTP 409 conflict will occur)&lt;br /&gt;
&lt;br /&gt;
This means that if you want to subscribe to the same Azure Portal backend from two different sites (or instances), you will need to have multiple communication users (each with an applied Teams licence) in order to be able to subscribe from all endpoints.&lt;br /&gt;
&lt;br /&gt;
== Subscription Timeout ==&lt;br /&gt;
&lt;br /&gt;
=== Situation ===&lt;br /&gt;
Due to a current limitation in the Graph API it is not possible to cancel or delete an active presence subscription.&amp;lt;br&amp;gt;&lt;br /&gt;
As you can see in the [https://learn.microsoft.com/en-us/graph/api/subscription-delete?view=graph-rest-1.0&amp;amp;tabs=http|documentation of the current Graph API (1.0)] the “Delete subscription” chapter does not include presence subscriptions.&amp;lt;br&amp;gt;&lt;br /&gt;
It is also not possible to have multiple subscription in parallel. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To make sure to only request a new presence subscription when the old one is not valid anymore, the app will store the state of the presence subscription and the time until it is valid in the database.&amp;lt;br&amp;gt;&lt;br /&gt;
As mentioned in the chapter “Technical Overview” we are creating presence subscriptions with a validity of 10 minutes.&amp;lt;br&amp;gt;&lt;br /&gt;
The presence subscription will be renewed as soon as it is no longer valid which will be 10 minutes after initial subscription.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Impact ===&lt;br /&gt;
If settings are changed or the app instance is restarted it will check the corresponding database entry on startup.&amp;lt;br&amp;gt;&lt;br /&gt;
In case the last presence subscription was completed less than 10 minutes ago, there is still an active presence subscription and the app has to wait for it to become invalid. &amp;lt;br&amp;gt;&lt;br /&gt;
Some Changes (e.g., to the “Notification-URL”) will only take effect after a new created subscription. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The current Beta Version of the Graph API is already providing a function to delete presence subscriptions, so we hope we can improve this behavior in the future.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Troubleshooting=&lt;br /&gt;
&lt;br /&gt;
==Creating an app trace==&lt;br /&gt;
For further analysis and creating a support ticket it will be useful to have a suitable app trace. &amp;lt;br&amp;gt;&lt;br /&gt;
Before creating the trace please make sure the following trace flags are activated for the app instance:&lt;br /&gt;
* App&lt;br /&gt;
* Database&lt;br /&gt;
* HTTP client&lt;br /&gt;
* TLS&lt;br /&gt;
* TCP&lt;br /&gt;
* App WebSocket&lt;br /&gt;
* Config&lt;br /&gt;
* Webserver&lt;br /&gt;
&lt;br /&gt;
After setting the config flags, please make sure to&lt;br /&gt;
* stop the instance&lt;br /&gt;
* deleting the current instance log&lt;br /&gt;
* start the instance&lt;br /&gt;
&#039;&#039;&#039;Now please wait at least 12 Minutes before you save the log&#039;&#039;&#039;, otherwise we could not have the whole picture in the trace.&lt;br /&gt;
&lt;br /&gt;
The restart and deletion of the the old log is useful the see the complete initialization process right away.&lt;br /&gt;
&lt;br /&gt;
==GUI Feedback==&lt;br /&gt;
The app itself shows required states with green and red as connections to the Master PBX, Authentication and Presence Subscription to identify if there are problems. &amp;lt;br&amp;gt;&lt;br /&gt;
Sometimes it needs a little bit time until the states are changed. &amp;lt;br&amp;gt;&lt;br /&gt;
If the states remain, it is mandatory to enable logs on the app platform and check for more information. &amp;lt;br&amp;gt;&lt;br /&gt;
([[Howto13r3:Configure Connector for Microsoft365#Creating an app trace|Concept App Service Connector for Microsoft 365: Creating an app trace]])&lt;br /&gt;
&lt;br /&gt;
===No connection to Master PBX===&lt;br /&gt;
Check the MasterPBX name.&amp;lt;br&amp;gt;&lt;br /&gt;
The field must only contain the name [&amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;pbx&amp;lt;/span&amp;gt;], &#039;&#039;&#039;not the full domain&#039;&#039;&#039; [&amp;lt;span style=&amp;quot;color:red;text-decoration: line-through;&amp;quot;&amp;gt;pbx.domain.tld&amp;lt;/span&amp;gt;]. ([[Howto13r3:Configure Connector for Microsoft365#Synchronization from Teams to the PBX|Synchronization from Teams to the PBX - Master PBX field]])&lt;br /&gt;
&lt;br /&gt;
===Presence subscription failed===&lt;br /&gt;
There are many reasons why the &amp;quot;Presence subscription failed&amp;quot; message could be displayed.&amp;lt;br&amp;gt;&lt;br /&gt;
We try to list the most common reasons:&lt;br /&gt;
* The permission for the registered app in the Azure portal are not correctly set ([[Howto13r3:Configure Connector for Microsoft365#Create an App for syncing Teams to PBX|Howto: Create an App for syncing Teams to PBX]])&lt;br /&gt;
* The Notification URL is wrong ([[Reference13r3:Concept App Service Connector for Microsoft 365#Correctness of notification URL|Concept App Service Connector for Microsoft 365: Correctness of notification URL]] )&lt;br /&gt;
* The App service is not reachable from the internet ([[Reference13r3:Concept App Service Connector for Microsoft 365#Correctness of notification URL|Concept App Service Connector for Microsoft 365: Correctness of notification URL]] )&lt;br /&gt;
* The certificate for the public endpoint (e.g. reverse proxy) is not valid, or not publicly signed ([[Reference13r3:Concept App Service Connector for Microsoft 365#SSL Certificate for notification URL|Concept App Service Connector for Microsoft 365: SSL Certificate for notification URL]])&lt;br /&gt;
* The user from PBX and the Azure Portal cannot be matched ([[Reference13r3:Concept App Service Connector for Microsoft 365#User Matching|Concept App Service Connector for Microsoft 365: User Matching]])&lt;br /&gt;
* The App Platforms clock time is wrong ([[Reference13r3:Concept App Service Connector for Microsoft 365#App Platform clock time is wrong|Concept App Service Connector for Microsoft 365: App Platform clock time is wrong]])&lt;br /&gt;
* No user has a valid Connector for Microsoft 365 App license ([[Reference13r3:Concept App Service Connector for Microsoft 365#Requirements|Concept App Service Connector for Microsoft 365: Requirements]])&lt;br /&gt;
&lt;br /&gt;
==Teams License for communication user==&lt;br /&gt;
If presence subscription does not work, please check if all of the configured communication users have a Microsoft Teams license applied and no multifactor authentication is in use for this particular user. &amp;lt;br&amp;gt;&lt;br /&gt;
Also please make sure you can login with the configured credentials. (If you have set a password as an Administration, the user needs to change the password during the first login, therefore the given password will be invalid for API access).&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Sometimes, after changing setting or after the instance has restarted it can take up to 12 minutes until the presence subscription is working correctly. (Due to the subscription timeout)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==SSL Certificate for notification URL==&lt;br /&gt;
It also is useful to make sure the notification URL has a valid and public signed certificate.&amp;lt;br&amp;gt;&lt;br /&gt;
You can do that, using an SSL-Checker, for example: https://www.sslshopper.com/ssl-checker.html &amp;lt;br&amp;gt;&lt;br /&gt;
Without a valid, public signed certificate, Microsoft will decline the connection since it will not be possible to establish a trust relationship for the SSL/TLS secure channel.&lt;br /&gt;
&lt;br /&gt;
==Correctness of notification URL==&lt;br /&gt;
You can try to open the notification URL in your Browser&amp;lt;br&amp;gt;&lt;br /&gt;
Most likely you will see a HTTP 404 (Not Found) error message, which is the expected behavior since we are not providing an HTML website, the HTTP GET request from the browser will not be answered with content.&amp;lt;br&amp;gt;&lt;br /&gt;
This is perfectly fine since Microsoft will send presence updates with HTTP POST and will not try to request content from our app.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
What you can find out by trying to open the URL in your browser are the two following things: &amp;lt;br&amp;gt;&lt;br /&gt;
* If you receive a HTTP 404 error message you are most likely connected to an App Platform, if not you need to check your DNS (and maybe also reverse proxy) settings.&lt;br /&gt;
* If the URL is modified and the used build number is added, an app has answered your request&lt;br /&gt;
** Example: &amp;lt;code&amp;gt;https://public.dns/your.domain/microsoft365/subscriptions&amp;lt;/code&amp;gt; is modified to &amp;lt;code&amp;gt;https://public.dns/your.domain/microsoft365/&amp;lt;b&amp;gt;137786&amp;lt;/b&amp;gt;/subscriptions&amp;lt;/code&amp;gt;&lt;br /&gt;
** If this is not the case, your URL is wrong. (Be aware: The URL depends on the settings of the web server path of your app instance)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Be aware:&#039;&#039;&#039; The URL-Recognition in the Application Platform is &#039;&#039;&#039;case sensitive&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
= Known Issues =&lt;br /&gt;
== Special Characters In Password ==&lt;br /&gt;
If you are using special characters (*, &amp;amp;, (, ), etc.) in your password you could run into a problem with the authentication of the communication user.&amp;lt;br&amp;gt;&lt;br /&gt;
The authentication failed status is being displayed. &amp;lt;br&amp;gt;&lt;br /&gt;
For the moment the only workaround is to eliminate special characters from your password.&lt;br /&gt;
&lt;br /&gt;
==App Platform clock time is wrong==&lt;br /&gt;
If the clock time at the App Platform is not correct, this will lead to an unstable behaviour of the Connector for Microsoft 365.&amp;lt;br&amp;gt;&lt;br /&gt;
Since the Connector for Microsoft 365 is using the Microsoft Graph APIs presence subscription function, it needs to provide in its request a precise time until the subscription validity will be expired.&amp;lt;br&amp;gt;&lt;br /&gt;
The app service is handling subscription and will automatically recreate a new subscription each time the previous one has expired.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A wrong clock time will lead to false expiration times and thus&lt;br /&gt;
*  the subscription will be expired earlier than expected (synchronisation is not working because there is no valid subscription)&lt;br /&gt;
*  the subscription will be valid longer than expected (the app service is trying to create a new subscription because it is expecting the previous one to be expired - will lead to a 409 conflict error, because only one subscription can be valid at a time)&lt;br /&gt;
&lt;br /&gt;
If you are not sure about the current time of the App Platform, you can login via SSH into the App Platform and execute the &amp;lt;code&amp;gt;date&amp;lt;/code&amp;gt; command to check the current time.&amp;lt;br&amp;gt;&lt;br /&gt;
You will receive an output like: &lt;br /&gt;
 Tue Mar 12 13:38:57 UTC 2024&lt;br /&gt;
Please be aware: The time is displayed in UTC, so please make sure to convert to your local time zone.&lt;br /&gt;
&lt;br /&gt;
==Geoblocking==&lt;br /&gt;
Since there might be no reliable country assignment for Microsoft addresses, all Microsoft addresses must be enabled on the upstream firewall in the event of geoblocking in order to ensure functionality of the Office365 Connector.&amp;lt;br&amp;gt;&lt;br /&gt;
As an alternative you might be able to configure your firewall to bypass the geoblocking for the configured notification URL.&lt;br /&gt;
&lt;br /&gt;
= Related Articles =&lt;br /&gt;
[[Howto14r2:Configure Connector for Microsoft365]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Howto|{{PAGENAME}}]]&lt;/div&gt;</summary>
		<author><name>Tfu</name></author>
	</entry>
	<entry>
		<id>https://wiki.innovaphone.com/index.php?title=Reference16r1:Concept_App_Service_TechAssist&amp;diff=80618</id>
		<title>Reference16r1:Concept App Service TechAssist</title>
		<link rel="alternate" type="text/html" href="https://wiki.innovaphone.com/index.php?title=Reference16r1:Concept_App_Service_TechAssist&amp;diff=80618"/>
		<updated>2026-10-06T08:09:16Z</updated>

		<summary type="html">&lt;p&gt;Tfu: /* Configurations */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Concept|Apps]]&lt;br /&gt;
[[Category:Concept App Service TechAssist]]&lt;br /&gt;
&amp;lt;!-- techassist, ticket, analyze, debug, tests --&amp;gt;&lt;br /&gt;
== Applies To == &lt;br /&gt;
&lt;br /&gt;
* innovaphone PBX from version 15r1&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
The idea of the TechAssist app is to provide helpful tools for technicians, as well as to analyze static and runtime information of a system and check for problems and improvements. In this way, the app can help you find and solve problems and misconfigurations independently and quickly.&lt;br /&gt;
For this purpose, the app supports&lt;br /&gt;
* the execution of &#039;&#039;tests&#039;&#039;&lt;br /&gt;
** a bunch of manufacturer tests are supplied with the app&lt;br /&gt;
** you can create and save your own tests&lt;br /&gt;
** testresults can be downloaded to attach them to a support ticket&lt;br /&gt;
* a PBX license overview&lt;br /&gt;
&lt;br /&gt;
== Licensing ==&lt;br /&gt;
There are no licenses needed for this app&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
The TechAssist App is installed by default for every new installation and is accessible from the Config Admin template.&lt;br /&gt;
&lt;br /&gt;
=== With the PBX manager AP app installer plug-in === &lt;br /&gt;
[[File:Ap_app_installer.png|ap_app_installer.png/|ap_app_installer.png/]]&lt;br /&gt;
&lt;br /&gt;
Go to the PBX manager and open the &#039;&#039;&#039;&amp;quot;AP app installer&amp;quot;&#039;&#039;&#039; plugin. On the right panel, the App Store will be shown. &#039;&#039;Hint : if you access it for the first time, you will need to accept the &amp;quot;Terms of Use of the innovaphone App Store&amp;quot;&#039;&#039;&lt;br /&gt;
* In the search field located on the top right corner of the store, search for &#039;&#039;&#039;&amp;quot;Techassist&amp;quot;&#039;&#039;&#039; and click on it&lt;br /&gt;
* Select the proper firmware version, here &#039;&#039;&#039;&amp;quot;v14&amp;quot;&#039;&#039;&#039; and click on install&lt;br /&gt;
* Tick &amp;quot;I accept the terms of use&amp;quot; and continue by clicking on the install yellow button&lt;br /&gt;
* Wait until the install has been finished&lt;br /&gt;
* Close and open the PBX manager to refresh the list of the available colored AP plugin&lt;br /&gt;
* Click on the &#039;&#039;&#039;&amp;quot;AP techassist&amp;quot;&#039;&#039;&#039; and click on &#039;&#039;&#039;&amp;quot; + Add an App&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
* Enter a &#039;&#039;&#039;&amp;quot;Name&amp;quot;&#039;&#039;&#039; that is used as display name &#039;&#039;(all character allowed)&#039;&#039; for it and the &#039;&#039;&#039;&amp;quot;SIP&amp;quot;&#039;&#039;&#039; name that is the administrative field &#039;&#039;(no space, no capital letters)&#039;&#039;. &#039;&#039;e.g : Name: TechAssist, SIP: techassist&#039;&#039;&lt;br /&gt;
&#039;&#039;Hint : The App needs access-right to one devices-api. The access to &amp;quot;devices-api&amp;quot; will be set automatically. If you want to have another devices-apis working with techassist, you have to configure it manually in the advanced UI.&#039;&#039;&lt;br /&gt;
* Tick the appropriate template to distribute the App&lt;br /&gt;
* Click OK to save the settings and a green check mark will be shown to inform you that the configuration is good&lt;br /&gt;
&lt;br /&gt;
== Test Engine ==&lt;br /&gt;
=== Overview ===&lt;br /&gt;
==== Technical look inside ====&lt;br /&gt;
[[File:Concept_TechAssist.png|thumb|upright=1.0|right|concept_techassist.png/|concept_techassist.png/]]&lt;br /&gt;
The app service receives multiple incoming websocket connections of the app objects from the PBXes. By assigning rights to a to your desired &amp;quot;devices-apis&amp;quot; (in the Apps tab), the app service receives the corresponding rights to connect to the respectively activated DevicesApps. All managed domains and devices can then be read in via this connection. (One TechAssist can only connect with one device-api)&lt;br /&gt;
With this procedure, you can work with one DevicesApp instance and across all domains and devices in it.&lt;br /&gt;
&lt;br /&gt;
==== Submodules ====&lt;br /&gt;
The app contains various sub-modules in order to be able to carry out the tests provided by the manufacturer and also to be able to integrate custom tests created by yourself.&lt;br /&gt;
&lt;br /&gt;
;scheduler&lt;br /&gt;
: The scheduler initially loads all tests and performs a plausibility check of the individual tests. From this status onwards, the scheduler ensures that all tests are executed in the required time intervals.&lt;br /&gt;
: Inside the Scheduler the tick is 5000 milliseconds, and test are executed sequentially to prevent high system load&lt;br /&gt;
;cmd&lt;br /&gt;
: The cmd submodule (derived from &amp;quot;command&amp;quot;) can communicate with devices in the installation to query a status, the config or similar. The submodule takes care of all the information that tests from an installation want to have, consolidates them so that queries do not have to be executed multiple times and caches the results.&lt;br /&gt;
;test&lt;br /&gt;
: The test submodule is instantiated per test and provides all necessary functionalities within a test.&lt;br /&gt;
&lt;br /&gt;
==== UI Language ====&lt;br /&gt;
By design, only the app itself is available in multiple languages. The content of the tests and technical output is intentionally only available in english.&lt;br /&gt;
&lt;br /&gt;
==== Tests ====&lt;br /&gt;
The app contains a bunch of embedded test, but it is also possible to create and save your own tests.&lt;br /&gt;
&lt;br /&gt;
=== UI ===&lt;br /&gt;
&lt;br /&gt;
==== Tests ====&lt;br /&gt;
;Execute all&lt;br /&gt;
:This Button will trigger all tests. Keep in mind that this trigger used the cached version of commands.&lt;br /&gt;
;Execute all without cache&lt;br /&gt;
:This Button will trigger all tests but will clear the cache for all commands before&lt;br /&gt;
;Execute a dedicated test&lt;br /&gt;
: In this execution, no cache will be used&lt;br /&gt;
&lt;br /&gt;
==== Expert Mode ====&lt;br /&gt;
By default there are some expert information hidden in the left menu bar. You will find a switch for that in the left menu (non-mobile-view) to enable all menu items.&lt;br /&gt;
&lt;br /&gt;
==== Dealing with the Code Editor ====&lt;br /&gt;
The Code Editor is a tool for viewing the tests supplied and writing your own tests based on these tests.&lt;br /&gt;
&lt;br /&gt;
The editor is divided into 3 basic areas.&lt;br /&gt;
;Left - Code Editor&lt;br /&gt;
:This is the code editor where you can write your test code in the browser. When you close the app, the content in the editor is saved, so that the next time you open the app you will find your old code again.&lt;br /&gt;
&lt;br /&gt;
;Top right - Menu bar&lt;br /&gt;
:Here you will find the following functions:&lt;br /&gt;
:Selection of all existing Tests (predefined vendor Tests and your own custom Tests)&lt;br /&gt;
:Load the source code of the selected Test to the code editor&lt;br /&gt;
:Delete the selected test from the app (This is only possible for custom tests)&lt;br /&gt;
:Execute the source code (with or without cached commands in the service) in the Code Editor and show the result&lt;br /&gt;
:Clear the Code Editor&lt;br /&gt;
:Save the current Content from the code Editor as Test&lt;br /&gt;
::The title of your test is divided from the &#039;&#039;title&#039;&#039; property in your test (lower based without non-alphanumeric characters). This means: If you save another Test with the same &#039;&#039;title&#039;&#039; the value will be saved in the other test.&lt;br /&gt;
&lt;br /&gt;
;Top right - Results&lt;br /&gt;
:If you execute, save or delete a test you will get the response/results in this area&lt;br /&gt;
&lt;br /&gt;
=== Create your own Testscript ===&lt;br /&gt;
You can create your own Test scripts in a JavaScript based environment.&lt;br /&gt;
A test itself is a JavaScript object with some configurations properties and a section of &#039;&#039;freestyle&#039;&#039; code to use JavaScript habits to perform your test. If your test will be executed, an above layer will call your &#039;&#039;test()&#039;&#039; method and want to have a return object with your result.&lt;br /&gt;
&lt;br /&gt;
There already exists a global Object called &#039;&#039;&#039;tests_add&#039;&#039;&#039;. You can add your own Test as Property to this existing Object like:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
tests_add.my_new_test = tests_add.my_new_test || {&lt;br /&gt;
   title: &#039;Check for xyz&#039;,&lt;br /&gt;
   // configuration properties&lt;br /&gt;
   &lt;br /&gt;
   test: function (cmd, result, storage) {&lt;br /&gt;
       // your custom test code&lt;br /&gt;
&lt;br /&gt;
       return {&lt;br /&gt;
           success: false,&lt;br /&gt;
           msg: &#039;....&#039;&lt;br /&gt;
       };&lt;br /&gt;
   }&lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The way to add a test with &amp;lt;code&amp;gt;tests_add.my_new_test = tests_add.my_new_test || {}&amp;lt;/code&amp;gt; is important so that two tests do not overwrite each other. Please also pay attention to this. In this example, we have a &#039;&#039;logical condition&#039;&#039; in the first line. If the test &#039;&#039;my_new_test&#039;&#039; already exists in the object &#039;&#039;tests_add&#039;&#039; the left side from the &#039;&#039;OR-condition&#039;&#039; is &#039;&#039;true&#039;&#039;, and the existing test takes place. Otherwise, it is &#039;&#039;false&#039;&#039; and the right side (your new test object) will be written to &#039;&#039;tests_add.my_new_test&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==== Configuration Properties ====&lt;br /&gt;
You must configure certain properties in your test so that the scheduler knows exactly how to handle your test.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
tests_add.my_new_test = tests_add.my_new_test || {&lt;br /&gt;
  title: &#039;Unknown / New devices&#039;,&lt;br /&gt;
  description: &#039;Check for unassigned devices in your installation&#039;,&lt;br /&gt;
  todo: &#039;Please check the unknown devices in your installation and acceppt or delete the devices&#039;,&lt;br /&gt;
  author: &#039;slu@innovaphone.com&#039;,&lt;br /&gt;
  enabled: true,&lt;br /&gt;
  schedule: &#039;1h&#039;,&lt;br /&gt;
  commands: { ... },&lt;br /&gt;
&lt;br /&gt;
  test: function (cmd, result, storage) {&lt;br /&gt;
    // your custom test code&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Mandatory properties =====&lt;br /&gt;
&lt;br /&gt;
; title&lt;br /&gt;
: string | The title of your test, which is displayed in the UI&lt;br /&gt;
; description&lt;br /&gt;
: string | A short description of your test, which is displayed in the UI&lt;br /&gt;
; todo&lt;br /&gt;
: string | An instruction on what the user has to do if the check fails. It will be displayed above the logfile in failed tests. (You can use &#039;&#039;\r\n&#039;&#039; for line breaks)&lt;br /&gt;
: Variable &amp;lt;nowiki&amp;gt;{{VERSION}}&amp;lt;/nowiki&amp;gt; will be replaced to current Version of the app like &amp;quot;14r1&amp;quot;&lt;br /&gt;
; author&lt;br /&gt;
: string | The contact of the person who create the test&lt;br /&gt;
; schedule&lt;br /&gt;
: string | The time interval during which the test is to be carried out independently. The format is composed of a numerical value and interval value. This allows you to create combinations such as &amp;lt;code&amp;gt;5m (every 5 minutes), 10h (every 10 hours) or 1d (every day) &amp;lt;/code&amp;gt;. A special case which is also allowed is the value &#039;&#039;none&#039;&#039;. With a &#039;&#039;none&#039;&#039; value, your test will not be executed automatically, but is available in the app. So the user is able to execute your test manually.&lt;br /&gt;
: Possible interval values are:&lt;br /&gt;
: &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt; (seconds)&lt;br /&gt;
: &amp;lt;code&amp;gt;m&amp;lt;/code&amp;gt; (minutes)&lt;br /&gt;
: &amp;lt;code&amp;gt;h&amp;lt;/code&amp;gt; (hours)&lt;br /&gt;
: &amp;lt;code&amp;gt;d&amp;lt;/code&amp;gt; (days)&lt;br /&gt;
: &amp;lt;code&amp;gt;w&amp;lt;/code&amp;gt; (weeks)&lt;br /&gt;
: Please note that each execution of a test requires resources. For example, if you create a test with &#039;&#039;1m&#039;&#039; that is executed every minute, you may well create an unpleasant impact! The system automatically checks the execution time of your test against your specified interval. If your test runs for a longer time than your schedule, your &#039;&#039;schedule&#039;&#039; parameter is automatically doubled by the system.&lt;br /&gt;
: Please note the [[#Submodules|Submodule Scheduler]] with Tick and synchronous execution. For example, it is not possible to execute a test every second. &lt;br /&gt;
&lt;br /&gt;
===== Optional properties =====&lt;br /&gt;
&lt;br /&gt;
; commands&lt;br /&gt;
: object | An object in which you can list all the commands, values, etc. that you want to use later in your test. As soon as your test() method is called, the returns of these commands are passed in as parameters so that you can analyze them. For detailed documentation, please see the [[#Property_&amp;quot;commands&amp;quot;|commands-documentation]] below.&lt;br /&gt;
; minBuild&lt;br /&gt;
: int | The minimum build version of the app, that the Test will be executed.&lt;br /&gt;
; oneTime&lt;br /&gt;
: bool | If &#039;&#039;true&#039;&#039; the test will be self-deactivated after the first successful execution.&lt;br /&gt;
; enabled&lt;br /&gt;
: bool | If &#039;&#039;false&#039;&#039; the test will be loaded but not executed. The user will see the test in the list of test, and it is possible to enable it (default: &#039;&#039;true&#039;&#039;)&lt;br /&gt;
; hidden&lt;br /&gt;
: bool | If &#039;&#039;true&#039;&#039; the test will be skipped by the system and will not be loaded (default: &#039;&#039;false&#039;&#039;) &lt;br /&gt;
&lt;br /&gt;
==== Property &amp;quot;commands&amp;quot; ====&lt;br /&gt;
The property &#039;&#039;commands&#039;&#039; is an object where you can define innovaphone specific commands that are executed before your test will be executed. The results of the given commands will be passed to your test in the parameter &#039;&#039;results&#039;&#039;. Think about that, all your commands will be cached until the &#039;&#039;schedule&#039;&#039; timeout is exceeded. This means that you will only get a new result of the command after the schedule time has elapsed in relation to the time of your last execution. The only exceptions is when the user manually re-executes a test via the UI or caching has been explicitly disabled at the command&lt;br /&gt;
&lt;br /&gt;
You have to consider a special nested notation when creating your commands, so that you can use them later.&lt;br /&gt;
&lt;br /&gt;
===== outer commands-object =====&lt;br /&gt;
Let&#039;s start with some first basic rules:&lt;br /&gt;
* &#039;&#039;commands&#039;&#039; is an object with one property per command. At this moment we only list commands, we don&#039;t take care about specific devices, types of models or so on.&lt;br /&gt;
* Every child-property (let&#039;s call it &amp;quot;command-object&amp;quot;) is a new object which contains all needed information for this specific command&lt;br /&gt;
* The title of the property &amp;quot;command-object&amp;quot; is defined by yourself&lt;br /&gt;
** Spoiler: The title of your &amp;quot;command-object&amp;quot; should be used later if you want to read the result for a specific device&lt;br /&gt;
* You can list multiple &amp;quot;command-objects&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Up to here we have the following and can define it like this:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
commands: {&lt;br /&gt;
  my_command_one: {},&lt;br /&gt;
  my_command_two: {},&lt;br /&gt;
},&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== single command-object =====&lt;br /&gt;
&lt;br /&gt;
Then we have some new rules per &amp;quot;command-object&amp;quot;:&lt;br /&gt;
* A property called &#039;&#039;cmd&#039;&#039; is expected. This property contains the real command which shall be executed (Remember, at this moment we only list commands, we don&#039;t take care about specific devices, types of models or so on)&lt;br /&gt;
** Example 1: &amp;lt;code&amp;gt;cmd: &#039;CMD0/box_info.xml&#039;&amp;lt;/code&amp;gt; will give you the xml output of the general overview page&lt;br /&gt;
** Example 2: &amp;lt;code&amp;gt;cmd: &#039;!mod cmd CDR0 qs&#039;&amp;lt;/code&amp;gt; will give you the amount of buffered CDRs in the CDR0 interface&lt;br /&gt;
** Example 3: &amp;lt;code&amp;gt;cmd: &#039;cfg.txt&#039;&amp;lt;/code&amp;gt; will give you back the full configuration file&lt;br /&gt;
** If you are already firm with the innovaphone based command syntax, you will see that you can use any HTTP command which can be sent to an innovaphone device&lt;br /&gt;
* Some more properties can be defined optionally. See documentation below&lt;br /&gt;
&lt;br /&gt;
Up to here we have an idea of a specific &amp;quot;command-object&amp;quot; and can do the following now:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
commands: {&lt;br /&gt;
  buffered_cdr0: {&lt;br /&gt;
    cmd: &#039;!mod cmd CDR0 qs&#039;,&lt;br /&gt;
  },&lt;br /&gt;
  buffered_cdr1: {&lt;br /&gt;
    cmd: &#039;!mod cmd CDR1 qs&#039;,&lt;br /&gt;
  },&lt;br /&gt;
},&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With this command, we can collect the &amp;quot;buffered CDRs&amp;quot; on both CDR Interfaces in our boxes. Maybe you see it directly... This will not make really sense in a real setup because CDRs only generated by Gateways/PBXes. So we don&#039;t need to bother phones with these requests.&lt;br /&gt;
So from now on we take care about our defined command. There are optional parameters that we can also list inside a &amp;quot;command-object&amp;quot; to let the system know what is the to-do with this command.&lt;br /&gt;
&lt;br /&gt;
;cmd&lt;br /&gt;
: string | Any HTTP command you can send to an innovaphone device. There is a limit of 15 seconds for every http request. If your request exceeds this limit the request will be cancelled.&lt;br /&gt;
;cat&lt;br /&gt;
: array | An optional list of device types on which the command is to be executed. If &#039;&#039;cat&#039;&#039; is empty, it means all devices in your installation.&lt;br /&gt;
: You can define the following device categories:&lt;br /&gt;
: &amp;lt;code&amp;gt;pbx&amp;lt;/code&amp;gt; - all PBXes&lt;br /&gt;
: &amp;lt;code&amp;gt;gw&amp;lt;/code&amp;gt; - all Gateways&lt;br /&gt;
: &amp;lt;code&amp;gt;ap&amp;lt;/code&amp;gt; - all App Platforms &#039;&#039;(effect at the moement)&#039;&#039;&lt;br /&gt;
: &amp;lt;code&amp;gt;dect&amp;lt;/code&amp;gt; - all Dect Gateways&lt;br /&gt;
: &amp;lt;code&amp;gt;phone&amp;lt;/code&amp;gt; - all Phones&lt;br /&gt;
: &amp;lt;code&amp;gt;monitoring&amp;lt;/code&amp;gt; - all categories based on Monitoring settings&lt;br /&gt;
;cache&lt;br /&gt;
: bool | If you set it to &#039;&#039;false&#039;&#039; you will never get a cached value. Please use this option wisely and only if you really need it. (default: &#039;&#039;true&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
Now let&#039;s improve our example from above and get the bufferd CDRx information only from pbxes and gateways.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
commands: {&lt;br /&gt;
  buffered_cdr0: {&lt;br /&gt;
    cmd: &#039;!mod cmd CDR0 qs&#039;,&lt;br /&gt;
    cat: [&#039;pbx&#039;, &#039;gw&#039;],&lt;br /&gt;
  },&lt;br /&gt;
  buffered_cdr1: {&lt;br /&gt;
    cmd: &#039;!mod cmd CDR1 qs&#039;,&lt;br /&gt;
    cat: [&#039;pbx&#039;, &#039;gw&#039;],&lt;br /&gt;
  },&lt;br /&gt;
},&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== execution and results of commands =====&lt;br /&gt;
Up to now, we have only defined commands that are to be executed on certain devices. When your test is executed, the previously defined commands are executed and the system collects the returns in a corresponding object (called &amp;lt;code&amp;gt;results&amp;lt;/code&amp;gt;) which is passed into your &amp;lt;code&amp;gt;test(cmd, results)&amp;lt;/code&amp;gt; method. There you can access the results and do whatever you want to test/analyze or whatever with the return value. You will find an example and some sample-code how to use the results-object in the description of the &#039;&#039;test() method&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===== nested commands-objects =====&lt;br /&gt;
You can now send any commands and the results will be returned to you for evaluation.&lt;br /&gt;
As you may have already noticed, there is no possibility to place multiple commands in dependency. But this is the way to do this.&lt;br /&gt;
&lt;br /&gt;
For more complicated tests, it is necessary to execute several commands one after the other and to generate following commands dynamically on the basis of the result of the first command.&lt;br /&gt;
&lt;br /&gt;
For such tests, there is the possibility to specify an object &amp;quot;commands&amp;quot; within a &amp;quot;command-object&amp;quot;. From this level, you can define a dynamic function in which you can apply your own code based on the first result, and then return a new &#039;&#039;commands-object&#039;&#039;. In this return statement, you also have the option of returning another dynamic function in order to be able to create processes of any complexity. Please note that if you not return an &#039;&#039;object&#039;&#039; your return value will be discarded. The results of your nested &#039;&#039;command-objects&#039;&#039; will be passed to the &#039;&#039;test()&#039;&#039; method inside the &#039;&#039;results&#039;&#039; object.&lt;br /&gt;
&lt;br /&gt;
This is certainly not easy to understand. Therefore, let us take a closer look at it with an example.&lt;br /&gt;
&lt;br /&gt;
====== example: nested commands-object which generates the second command from the first result ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
commands: {&lt;br /&gt;
  certificates: {&lt;br /&gt;
    cmd: &#039;X509/mod_cmd.xml&#039;,&lt;br /&gt;
    cat: [&#039;pbx&#039;, &#039;gw&#039;, &#039;dect&#039;],&lt;br /&gt;
    commands: function(cmd, result) {&lt;br /&gt;
                // free style code to build the following commands&lt;br /&gt;
                var xml = cmd.parse_xml(result);&lt;br /&gt;
                //log(JSON.stringify(xml));&lt;br /&gt;
                &lt;br /&gt;
                var fingerprint;&lt;br /&gt;
                // get the fingerprint for single cert&lt;br /&gt;
                if (typeof xml.info.servercert.certificate[&#039;@fingerprint&#039;] !== &#039;undefined&#039;) {&lt;br /&gt;
                    fingerprint = xml.info.servercert.certificate[&#039;@fingerprint&#039;]&lt;br /&gt;
                }&lt;br /&gt;
                // use last certificates in case of multiple&lt;br /&gt;
                else {&lt;br /&gt;
                    fingerprint = xml.info.servercert.certificate[xml.info.servercert.certificate.length - 1][&#039;@fingerprint&#039;];&lt;br /&gt;
                }&lt;br /&gt;
                cmd.log(&#039;Fingerprint: &#039;+fingerprint);&lt;br /&gt;
                &lt;br /&gt;
                return {&lt;br /&gt;
                    certificate: {&lt;br /&gt;
                        cmd: &#039;X509/mod_cmd.xml?cmd=servercert-details&amp;amp;fingerprint=&#039;+fingerprint,&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    },&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Our goal is to check which key-length is used in the device certificate. But there i no direct command to get this information. So we have to do it in multipe steps.&lt;br /&gt;
&lt;br /&gt;
In this sample, we request the following in the commands object:&lt;br /&gt;
# Execute our command &amp;quot;certificates&amp;quot; on devices (pbx, gw, dect) the command &amp;quot;X509/mod_cmd.xml&amp;quot; which will give you back the xml payload of the page [[{{NAMESPACE}}:General/Certificates|Reference15r1:General/Certificates]]&lt;br /&gt;
# If the first request is done, the nested &amp;quot;commands&amp;quot; object should be called and we get the result from the first command&lt;br /&gt;
## Now, inside the function &amp;lt;code&amp;gt;commands: function(cmd, result) {&amp;lt;/code&amp;gt; we can use some free-style code to to what we need, to build a following command&lt;br /&gt;
## Here we convert xml to an object and extract the certificate fingerprint from the result of the first request&lt;br /&gt;
## then we return an object with &amp;quot;command-objects&amp;quot;&lt;br /&gt;
### think about that is possible to add an new &amp;lt;code&amp;gt;commands: function(cmd, result) {&amp;lt;/code&amp;gt; inside the return to add a new level :-)&lt;br /&gt;
## this second command will be executed to for every device and the xml payload contains the device certifcate of the current device. (like the popup in the UI if you click on a specific certificate)&lt;br /&gt;
#If all nested commands are processed, then your test() will be called, and you get all the results (in this case &amp;quot;certificates&amp;quot; and &amp;quot;certificate&amp;quot;) in the results-object&lt;br /&gt;
&lt;br /&gt;
====== example: nested commands-object which generates various commands from the first result ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
commands: {&lt;br /&gt;
	config: {&lt;br /&gt;
		cmd: &#039;cfg.txt&#039;,&lt;br /&gt;
		cat: [&#039;pbx&#039;],&lt;br /&gt;
		commands: function(cmd, result) {&lt;br /&gt;
			var lines = result.split(&amp;quot;\r\n&amp;quot;);&lt;br /&gt;
			var output = {};&lt;br /&gt;
			&lt;br /&gt;
			// get pbx loc&lt;br /&gt;
			var loc = false;&lt;br /&gt;
			for (var l = 0; l &amp;lt; lines.length; l++) {&lt;br /&gt;
				if (!lines[l].startsWith(&#039;config change PBX0&#039;)) continue; // skip non pbx line&lt;br /&gt;
				if (lines[l].includes(&#039;/mode standby&#039;)) continue; // skip slave pbxes&lt;br /&gt;
				&lt;br /&gt;
				var match = lines[l].match(/config change PBX0 (.*) \/loc ([^ ][^/]+)/);&lt;br /&gt;
				loc = match[2].substr(0, match[2].length-1);&lt;br /&gt;
				l = lines.length;&lt;br /&gt;
			}&lt;br /&gt;
			cmd.log(&#039;use pbx loc: &#039;+loc);&lt;br /&gt;
			&lt;br /&gt;
			// get user objects&lt;br /&gt;
			var regex = new RegExp(&#039;/\(loc=&#039;+loc+&#039;\)(.*)\(guid;bin=([0-9A-Za-z]+)\)/&#039;);&lt;br /&gt;
			for (var l = 0; l &amp;lt; lines.length; l++) {&lt;br /&gt;
				// skip if user is not from this pbx&lt;br /&gt;
				if (!lines[l].includes(&#039;(loc=&#039;+loc+&#039;)&#039;)) continue;&lt;br /&gt;
				&lt;br /&gt;
				var match = lines[l].match(/\(guid;bin=([0-9A-Za-z]+)\)/);&lt;br /&gt;
				if (!match) continue;&lt;br /&gt;
				cmd.log(&#039;user found: &#039;+match[1]);&lt;br /&gt;
				output[match[1]] = {cmd: &#039;PBX0/ADMIN/mod_cmd_login.xml?cmd=show&amp;amp;user-guid=&#039;+match[1]};&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			return output;&lt;br /&gt;
		}&lt;br /&gt;
	},&lt;br /&gt;
},&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Our goal is to get the xml output from the advanced ui for every pbx object. But there i no direct command to get this information. So we have to do it in multipe steps.&lt;br /&gt;
&lt;br /&gt;
In this sample, we request the following in the commands object:&lt;br /&gt;
# Execute our command &amp;quot;config&amp;quot; on PBXes the get the plain configuration file&lt;br /&gt;
# If the first request is done, the nested &amp;quot;commands&amp;quot; object should be called, and we get the result from the first command&lt;br /&gt;
## Now, inside the function &amp;lt;code&amp;gt;commands: function(cmd, result) {&amp;lt;/code&amp;gt; we can use some free-style code to do what we need, to build multiple following commands&lt;br /&gt;
&lt;br /&gt;
## Here we split the config file by lines breaks and iterate the whole config&lt;br /&gt;
## then we generate an empty return object to fill it later&lt;br /&gt;
### think about that is possible to add an new &amp;lt;code&amp;gt;commands: function(cmd, result) {&amp;lt;/code&amp;gt; inside the return to add a new level :-)&lt;br /&gt;
## If we have checked the pbx and the userobject we add with &amp;lt;code&amp;gt;output[match[1]] = {cmd: &#039;PBX0/ADMIN/mod_cmd_login.xml?cmd=show&amp;amp;user-guid=&#039;+match[1]};&amp;lt;/code&amp;gt; a specific command to the retunr value&lt;br /&gt;
&lt;br /&gt;
In the end, we have a big return object with multiple cmd&#039;s&lt;br /&gt;
In this case we will get all the results in the test() later and can do further stuff with the results.&lt;br /&gt;
&lt;br /&gt;
==== Executable method test() ====&lt;br /&gt;
The upper layer expects a method &amp;lt;code&amp;gt;test(cmd, results, storage)&amp;lt;/code&amp;gt; in your JavaScript object. This method has three parameters.&lt;br /&gt;
&lt;br /&gt;
;cmd&lt;br /&gt;
:An object that offers you a wide range of predefined functions and options. You can see it as a kind of library, which is documented at the [[#cmd object|cmd object]].&lt;br /&gt;
&lt;br /&gt;
;results&lt;br /&gt;
:An object of the results of your commands from the given &#039;&#039;command-objects&#039;&#039; in your test definition.&lt;br /&gt;
&amp;lt;spoiler show=&amp;quot;show sample strcuture of the results object&amp;quot; hide=&amp;quot;hide sample strcuture of the results object&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// structure of results object&lt;br /&gt;
{&lt;br /&gt;
  // your command is the property&lt;br /&gt;
  &#039;buffered_cdr0&#039; : {&lt;br /&gt;
    // the unique id of the device is the property&lt;br /&gt;
    &#039;1&#039;: &#039;QS messages: 0 max 2000 chars: 0 max 300000&#039;,&lt;br /&gt;
    &#039;4&#039;: &#039;QS messages: 0 max 2000 chars: 0 max 300000&#039;,&lt;br /&gt;
  },&lt;br /&gt;
  &#039;buffered_cdr1&#039; : {&lt;br /&gt;
    // the unique id of the device is the property&lt;br /&gt;
    &#039;1&#039;: &#039;QS messages: 0 max 2000 chars: 0 max 300000&#039;,&lt;br /&gt;
    &#039;4&#039;: &#039;QS messages: 0 max 2000 chars: 0 max 300000&#039;,&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/spoiler&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;spoiler show=&amp;quot;show best practice code to deal with the results object&amp;quot; hide=&amp;quot;hide best practice code to deal with the results object&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// you can use this inside your function &amp;quot;test: function (cmd, results, storage)&amp;quot; to iterate all commands over all affected devices&lt;br /&gt;
        &lt;br /&gt;
Object.keys(results).forEach(function(command) {&lt;br /&gt;
  log.push(&#039;command: &#039;+command);&lt;br /&gt;
  Object.keys(results[command]).forEach(function(device) {&lt;br /&gt;
    log.push(&#039;device: &#039;+device);&lt;br /&gt;
    var output = results[command][device];&lt;br /&gt;
  });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
// expected log array from the code above:&lt;br /&gt;
// $ command: buffered_cdr0&lt;br /&gt;
// $ device: 1&lt;br /&gt;
// $ device: 4&lt;br /&gt;
// $ command: buffered_cdr1&lt;br /&gt;
// $ device: 1&lt;br /&gt;
// $ device: 4&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/spoiler&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;storage&lt;br /&gt;
:If the test has written something to the test volatile memory during the last execution, you will get the last value back here. (Note that the storage is not available for one-time tests in the code editor. There you will always get an empty storage)&lt;br /&gt;
&lt;br /&gt;
===== return test result =====&lt;br /&gt;
Your test has to be return an object with your test result. The system expect an object with the following properties.&lt;br /&gt;
&lt;br /&gt;
; success&lt;br /&gt;
: boolean | indicates if your test was successful or not&lt;br /&gt;
; msg&lt;br /&gt;
: string | an optional short message that will be displayed in the UI as preview&lt;br /&gt;
; log&lt;br /&gt;
: array | an optional array with lines of logfile that you can use to display detailed information in the UI at your test result. Use &amp;lt;code&amp;gt;log.push()&amp;lt;/code&amp;gt; to fill up the logfile array. In the frontend, the log will be parsed and mac addresses &amp;lt;code&amp;gt;/(^|\W)([a-f0-9]{12})(\W|$)/i&amp;lt;/code&amp;gt; will be updated with an internal link to devices app. (If you want to create instead debug output to the app-instance logfile you can use &amp;lt;code&amp;gt;cmd.log()&amp;lt;/code&amp;gt;)&lt;br /&gt;
;storage&lt;br /&gt;
: string | an optional string, which can be json or similar, that is stored for this test. The next time the test is executed, the payload saved here is available inside the test again.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
test: function (cmd, results, storage) {&lt;br /&gt;
  // your stuff&lt;br /&gt;
  var count = 2;&lt;br /&gt;
 &lt;br /&gt;
  return {&lt;br /&gt;
    success: false,&lt;br /&gt;
    msg: &#039;There are &#039;+count+&#039; new/unassigned devices in your setup&#039;&lt;br /&gt;
  };&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== The full picture ====&lt;br /&gt;
===== Complete sample test to check buffered CDRs =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
tests_add.cdrs_buffered = tests_add.cdrs_buffered || {&lt;br /&gt;
    title: &#039;Buffered CDRs&#039;,&lt;br /&gt;
    description: &#039;This test will check if CDRs on a gateway was buffered and are not transmit to the CDR target yet&#039;,&lt;br /&gt;
    todo: &#039;Check the CDR target&#039;,&lt;br /&gt;
    author: &#039;slu@innovaphone.com&#039;,&lt;br /&gt;
    enabled: true,&lt;br /&gt;
    schedule: &#039;10m&#039;,&lt;br /&gt;
    &lt;br /&gt;
    commands: {&lt;br /&gt;
        cdr0: {&lt;br /&gt;
            cmd: &#039;!mod cmd CDR0 qs&#039;,&lt;br /&gt;
            cat: [&#039;gw&#039;],&lt;br /&gt;
        },&lt;br /&gt;
        cdr1: {&lt;br /&gt;
            cmd: &#039;!mod cmd CDR1 qs&#039;,&lt;br /&gt;
            cat: [&#039;gw&#039;],&lt;br /&gt;
        },&lt;br /&gt;
        cdr2: {&lt;br /&gt;
            cmd: &#039;!mod cmd CDR2 qs&#039;,&lt;br /&gt;
            cat: [&#039;gw&#039;],&lt;br /&gt;
        },&lt;br /&gt;
        cdr3: {&lt;br /&gt;
            cmd: &#039;!mod cmd CDR3 qs&#039;,&lt;br /&gt;
            cat: [&#039;gw&#039;],&lt;br /&gt;
        },&lt;br /&gt;
        cdr4: {&lt;br /&gt;
            cmd: &#039;!mod cmd CDR4 qs&#039;,&lt;br /&gt;
            cat: [&#039;gw&#039;],&lt;br /&gt;
        },&lt;br /&gt;
    },&lt;br /&gt;
    &lt;br /&gt;
    test: function (cmd, results, storage) {&lt;br /&gt;
        var log = [];&lt;br /&gt;
        var success = true;&lt;br /&gt;
        &lt;br /&gt;
        for (var n = 0; n &amp;lt; 5; n++) {&lt;br /&gt;
            Object.keys(results[&#039;cdr&#039;+n]).forEach(function(i){&lt;br /&gt;
                var check = calculate_cdrs(results[&#039;cdr&#039;+n][i]);&lt;br /&gt;
                // result was not good, lets create a human error message&lt;br /&gt;
                if (check !== true) {&lt;br /&gt;
                    log.push(cmd.get_device(i).product+&#039; / &#039;+cmd.get_device(i).hwId+&#039; / &#039;+check+&#039;% - &#039;+results[&#039;cdr&#039;+n][i]);&lt;br /&gt;
                    if (success) success = false;&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    &lt;br /&gt;
        return {&lt;br /&gt;
            success: success,&lt;br /&gt;
            msg: success ? &#039;&#039; : &#039;Devices with buffered CDRs exists&#039;,&lt;br /&gt;
            log: log&lt;br /&gt;
        };&lt;br /&gt;
    &lt;br /&gt;
        function calculate_cdrs(str) {&lt;br /&gt;
            // QS messages: 0 max 2000 chars: 0 max 300000&lt;br /&gt;
            var check = 0;&lt;br /&gt;
            str = str.split(&#039; &#039;);&lt;br /&gt;
            // log.push(str);&lt;br /&gt;
        &lt;br /&gt;
            var messages_current = str[2];&lt;br /&gt;
            var messages_max = str[4];&lt;br /&gt;
            var chars_current = str[6];&lt;br /&gt;
            var chars_max = str[8];&lt;br /&gt;
        &lt;br /&gt;
            // check messages&lt;br /&gt;
            check = cmd.percent(messages_current, messages_max);&lt;br /&gt;
            if (check &amp;gt;= 30) return check;&lt;br /&gt;
        &lt;br /&gt;
            // check chars&lt;br /&gt;
            check = cmd.percent(chars_current, chars_max);&lt;br /&gt;
            if (check &amp;gt;= 30) return check;&lt;br /&gt;
        &lt;br /&gt;
            return true;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Complete sample test to check firmware versions =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
tests_add.firmware_version = tests_add.firmware_version || {&lt;br /&gt;
    title: &#039;Supported firmware versions&#039;,&lt;br /&gt;
    description: &#039;Check if you have unsupported firmware version in use&#039;,&lt;br /&gt;
    todo: &#039;Update the firmware on affected devices&#039;,&lt;br /&gt;
    author: &#039;slu@innovaphone.com&#039;,&lt;br /&gt;
    schedule: &#039;1d&#039;,&lt;br /&gt;
    commands: {&lt;br /&gt;
        box_info: {&lt;br /&gt;
            cmd: &#039;CMD0/box_info.xml&#039;,&lt;br /&gt;
        },&lt;br /&gt;
    },&lt;br /&gt;
    &lt;br /&gt;
    test: function (cmd, results, storage) {&lt;br /&gt;
        var log = [];&lt;br /&gt;
        var success = true;&lt;br /&gt;
        var msg = &#039;&#039;;&lt;br /&gt;
        &lt;br /&gt;
        Object.keys(results.box_info).forEach(function(i){&lt;br /&gt;
            var xml = cmd.parse_xml(results.box_info[i]);&lt;br /&gt;
            if (typeof xml.info === &#039;undefined&#039;) return;&lt;br /&gt;
            if (typeof xml.info.sys === &#039;undefined&#039;) return;&lt;br /&gt;
            if (typeof xml.info.sys[&#039;@version&#039;] === &#039;undefined&#039;) return;&lt;br /&gt;
            &lt;br /&gt;
            if (&lt;br /&gt;
                xml.info.sys[&#039;@version&#039;].includes(&#039;6.00&#039;) ||&lt;br /&gt;
                xml.info.sys[&#039;@version&#039;].includes(&#039;7.00&#039;) ||&lt;br /&gt;
                xml.info.sys[&#039;@version&#039;].includes(&#039;8.00&#039;) ||&lt;br /&gt;
                xml.info.sys[&#039;@version&#039;].includes(&#039;9.00&#039;) ||&lt;br /&gt;
                xml.info.sys[&#039;@version&#039;].includes(&#039;10.00&#039;) ||&lt;br /&gt;
                xml.info.sys[&#039;@version&#039;].includes(&#039;11.00&#039;) ||&lt;br /&gt;
                xml.info.sys[&#039;@version&#039;].includes(&#039;11r1&#039;) ||&lt;br /&gt;
                xml.info.sys[&#039;@version&#039;].includes(&#039;12r1&#039;) ||&lt;br /&gt;
                xml.info.sys[&#039;@version&#039;].includes(&#039;13r1&#039;)&lt;br /&gt;
            ) {&lt;br /&gt;
                log.push(cmd.get_device(i).product+&#039; / &#039;+cmd.get_device(i).hwId+&#039; / &#039;+xml.info.sys[&#039;@version&#039;]);&lt;br /&gt;
                if (success) success = false;&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
        &lt;br /&gt;
        return {&lt;br /&gt;
            success: success,&lt;br /&gt;
            msg: success ? &#039;&#039; : &#039;You use old firmware which is no longer be supported&#039;,&lt;br /&gt;
            log: log&lt;br /&gt;
        };&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== cmd object ====&lt;br /&gt;
The &#039;&#039;&#039;cmd&#039;&#039;&#039; object provides you the following methods:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== get device information / system information =====&lt;br /&gt;
&lt;br /&gt;
====== get_build() : object ======&lt;br /&gt;
You will receive back the current version build of the app&lt;br /&gt;
&lt;br /&gt;
&amp;lt;spoiler show=&amp;quot;show sample code&amp;quot; hide=&amp;quot;hide sample code&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var build = cmd.get_build();&lt;br /&gt;
console.log(build);&lt;br /&gt;
// 15012456&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/spoiler&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== get_domains() : object ======&lt;br /&gt;
You will receive all existing domains&lt;br /&gt;
&lt;br /&gt;
&amp;lt;spoiler show=&amp;quot;show sample code&amp;quot; hide=&amp;quot;hide sample code&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var domains = cmd.get_domains();&lt;br /&gt;
console.log(domains);&lt;br /&gt;
{&lt;br /&gt;
 &amp;quot;1&amp;quot;: {&lt;br /&gt;
   &amp;quot;id&amp;quot;: 1,&lt;br /&gt;
   &amp;quot;name&amp;quot;: &amp;quot;slu.de&amp;quot;,&lt;br /&gt;
   &amp;quot;deployAdminPasswords&amp;quot;: true,&lt;br /&gt;
   &amp;quot;isInstanceDomain&amp;quot;: true,&lt;br /&gt;
   &amp;quot;categories&amp;quot;: [ ... ]&lt;br /&gt;
 }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/spoiler&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== get_devices() : object ======&lt;br /&gt;
You will receive all existing devices&lt;br /&gt;
&lt;br /&gt;
&amp;lt;spoiler show=&amp;quot;show sample code&amp;quot; hide=&amp;quot;hide sample code&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var devices = cmd.get_devices();&lt;br /&gt;
console.log(devices);&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;0_009033420623&amp;quot;: {&lt;br /&gt;
    &amp;quot;id&amp;quot;: &amp;quot;0_009033420623&amp;quot;,&lt;br /&gt;
    &amp;quot;hwId&amp;quot;: &amp;quot;009033420623&amp;quot;,&lt;br /&gt;
    &amp;quot;domainId&amp;quot;: 0,&lt;br /&gt;
    &amp;quot;product&amp;quot;: &amp;quot;IP0011&amp;quot;,&lt;br /&gt;
    &amp;quot;version&amp;quot;: &amp;quot;13r3 dvl [13.7526/132035/600]&amp;quot;,&lt;br /&gt;
    &amp;quot;type&amp;quot;: &amp;quot;GW&amp;quot;,&lt;br /&gt;
    &amp;quot;pbxActive&amp;quot;: false,&lt;br /&gt;
    &amp;quot;online&amp;quot;: true,&lt;br /&gt;
    &amp;quot;ethIfs&amp;quot;: [ ... ]&lt;br /&gt;
  },&lt;br /&gt;
  &amp;quot;1&amp;quot;: {&lt;br /&gt;
    &amp;quot;id&amp;quot;: 1,&lt;br /&gt;
    &amp;quot;hwId&amp;quot;: &amp;quot;009033420621&amp;quot;,&lt;br /&gt;
    &amp;quot;name&amp;quot;: &amp;quot;PBX - pbx.slu.de&amp;quot;,&lt;br /&gt;
    &amp;quot;domainId&amp;quot;: 1,&lt;br /&gt;
    &amp;quot;product&amp;quot;: &amp;quot;IP0011&amp;quot;,&lt;br /&gt;
    &amp;quot;version&amp;quot;: &amp;quot;13r3 beta4 [13.7688/137623/600]&amp;quot;,&lt;br /&gt;
    &amp;quot;type&amp;quot;: &amp;quot;GW&amp;quot;,&lt;br /&gt;
    &amp;quot;pbxActive&amp;quot;: true,&lt;br /&gt;
    &amp;quot;online&amp;quot;: true,&lt;br /&gt;
    &amp;quot;ethIfs&amp;quot;: [ ... ]&lt;br /&gt;
  },&lt;br /&gt;
  &amp;quot;2&amp;quot;: {&lt;br /&gt;
    &amp;quot;id&amp;quot;: 2,&lt;br /&gt;
    &amp;quot;hwId&amp;quot;: &amp;quot;029033420621&amp;quot;,&lt;br /&gt;
    &amp;quot;name&amp;quot;: &amp;quot;AP - apps.slu.de&amp;quot;,&lt;br /&gt;
    &amp;quot;domainId&amp;quot;: 1,&lt;br /&gt;
    &amp;quot;product&amp;quot;: &amp;quot;AppPlatform ARM&amp;quot;,&lt;br /&gt;
    &amp;quot;version&amp;quot;: &amp;quot;110002 dvl (13r3 137688 beta4 )&amp;quot;,&lt;br /&gt;
    &amp;quot;type&amp;quot;: &amp;quot;APP_PLATFORM&amp;quot;,&lt;br /&gt;
    &amp;quot;pbxActive&amp;quot;: false,&lt;br /&gt;
    &amp;quot;online&amp;quot;: true,&lt;br /&gt;
    &amp;quot;ethIfs&amp;quot;: [ ... ]&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/spoiler&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== get_devices_from_domain(int id) : object ======&lt;br /&gt;
You will receive all devices which are assigned to the given domain&lt;br /&gt;
&lt;br /&gt;
&amp;lt;spoiler show=&amp;quot;show sample code&amp;quot; hide=&amp;quot;hide sample code&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var devices = cmd.get_devices_from_domain(1);&lt;br /&gt;
console.log(devices);&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;1&amp;quot;: {&lt;br /&gt;
    &amp;quot;id&amp;quot;: 1,&lt;br /&gt;
    &amp;quot;hwId&amp;quot;: &amp;quot;009033420621&amp;quot;,&lt;br /&gt;
    &amp;quot;name&amp;quot;: &amp;quot;PBX - pbx.slu.de&amp;quot;,&lt;br /&gt;
    &amp;quot;domainId&amp;quot;: 1,&lt;br /&gt;
    &amp;quot;product&amp;quot;: &amp;quot;IP0011&amp;quot;,&lt;br /&gt;
    &amp;quot;version&amp;quot;: &amp;quot;13r3 beta4 [13.7688/137623/600]&amp;quot;,&lt;br /&gt;
    &amp;quot;type&amp;quot;: &amp;quot;GW&amp;quot;,&lt;br /&gt;
    &amp;quot;pbxActive&amp;quot;: true,&lt;br /&gt;
    &amp;quot;online&amp;quot;: true,&lt;br /&gt;
    &amp;quot;ethIfs&amp;quot;: [ ... ]&lt;br /&gt;
  },&lt;br /&gt;
  &amp;quot;2&amp;quot;: {&lt;br /&gt;
    &amp;quot;id&amp;quot;: 2,&lt;br /&gt;
    &amp;quot;hwId&amp;quot;: &amp;quot;029033420621&amp;quot;,&lt;br /&gt;
    &amp;quot;name&amp;quot;: &amp;quot;AP - apps.slu.de&amp;quot;,&lt;br /&gt;
    &amp;quot;domainId&amp;quot;: 1,&lt;br /&gt;
    &amp;quot;product&amp;quot;: &amp;quot;AppPlatform ARM&amp;quot;,&lt;br /&gt;
    &amp;quot;version&amp;quot;: &amp;quot;110002 dvl (13r3 137688 beta4 )&amp;quot;,&lt;br /&gt;
    &amp;quot;type&amp;quot;: &amp;quot;APP_PLATFORM&amp;quot;,&lt;br /&gt;
    &amp;quot;pbxActive&amp;quot;: false,&lt;br /&gt;
    &amp;quot;online&amp;quot;: true,&lt;br /&gt;
    &amp;quot;ethIfs&amp;quot;: [ ... ]&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/spoiler&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== get_device(int id) : object ======&lt;br /&gt;
You will receive a specific device&lt;br /&gt;
&lt;br /&gt;
&amp;lt;spoiler show=&amp;quot;show sample code&amp;quot; hide=&amp;quot;hide sample code&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var device = cmd.get_device(2);&lt;br /&gt;
console.log(device);&lt;br /&gt;
{&lt;br /&gt;
   &amp;quot;id&amp;quot;: 2,&lt;br /&gt;
   &amp;quot;hwId&amp;quot;: &amp;quot;029033420621&amp;quot;,&lt;br /&gt;
   &amp;quot;name&amp;quot;: &amp;quot;AP - apps.slu.de&amp;quot;,&lt;br /&gt;
   &amp;quot;domainId&amp;quot;: 1,&lt;br /&gt;
   &amp;quot;product&amp;quot;: &amp;quot;AppPlatform ARM&amp;quot;,&lt;br /&gt;
   &amp;quot;version&amp;quot;: &amp;quot;110002 dvl (13r3 137688 beta4 )&amp;quot;,&lt;br /&gt;
   &amp;quot;type&amp;quot;: &amp;quot;APP_PLATFORM&amp;quot;,&lt;br /&gt;
   &amp;quot;pbxActive&amp;quot;: false,&lt;br /&gt;
   &amp;quot;online&amp;quot;: true,&lt;br /&gt;
   &amp;quot;ethIfs&amp;quot;: [ ... ]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/spoiler&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== helper functions =====&lt;br /&gt;
&lt;br /&gt;
====== percent(int value, int total) : float ======&lt;br /&gt;
Returns the number of percent of value to total&lt;br /&gt;
&lt;br /&gt;
&amp;lt;spoiler show=&amp;quot;show sample code&amp;quot; hide=&amp;quot;hide sample code&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var check = cmd.percent(50, 100);&lt;br /&gt;
console.log(check);&lt;br /&gt;
50&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/spoiler&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== parse_xml(string xml, string element = &amp;lt;nowiki&amp;gt;&#039;&#039;&amp;lt;/nowiki&amp;gt;) : object ======&lt;br /&gt;
Returns an object/array representation of given XML string. Note that very large XML inputs cannot be converted directly because there are some restrictions in the duktape environment. If you receive an exception with &#039;&#039;Error: RangeError: regexp executor recursion limit&#039;&#039; you have to define which element do you want to converted (See the second example).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;spoiler show=&amp;quot;show sample code&amp;quot; hide=&amp;quot;hide sample code&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var json = cmd.parse_xml(&#039;&amp;lt;sample&amp;gt;&amp;lt;item property_1=&amp;quot;value_1&amp;quot; property_2=&amp;quot;value_2&amp;quot;&amp;gt;content of item&amp;lt;/item&amp;gt;&amp;lt;item_short prop_1=&amp;quot;value_prop_1&amp;quot; /&amp;gt;&amp;lt;/sample&amp;gt;&#039;);&lt;br /&gt;
console.log(json);&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;sample&amp;quot;: {&lt;br /&gt;
    &amp;quot;item&amp;quot;: {&lt;br /&gt;
      &amp;quot;@property_1&amp;quot;: &amp;quot;value_1&amp;quot;,&lt;br /&gt;
      &amp;quot;@property_2&amp;quot;: &amp;quot;value_2&amp;quot;,&lt;br /&gt;
      &amp;quot;#&amp;quot;: &amp;quot;content of item&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    &amp;quot;item_short&amp;quot;: {&lt;br /&gt;
      &amp;quot;@prop_1&amp;quot;: &amp;quot;value_prop_1&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/spoiler&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;spoiler show=&amp;quot;show sample code with large xml payload&amp;quot; hide=&amp;quot;hide sample code with large xml payload&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
var xml_registrations_on_big_pbx = &#039;\&lt;br /&gt;
  &amp;lt;show state=&amp;quot;up&amp;quot; time=&amp;quot;267993&amp;quot; loc=&amp;quot;pbx&amp;quot;&amp;gt;\&lt;br /&gt;
    &amp;lt;attrs&amp;gt;&amp;lt;/attrs&amp;gt;\&lt;br /&gt;
    &amp;lt;reg cn=&amp;quot;Fax&amp;quot; guid=&amp;quot;829a6aeec2a76401c62600155d50c817&amp;quot; h323=&amp;quot;fax&amp;quot; pwd=&amp;quot;********&amp;quot; pwdx=&amp;quot;********&amp;quot; prot=&amp;quot;JSON&amp;quot;&amp;gt;\&lt;br /&gt;
      &amp;lt;ep type=&amp;quot;gk&amp;quot; addr=&amp;quot;172.16.176.205&amp;quot; time=&amp;quot;10&amp;quot;/&amp;gt;\&lt;br /&gt;
      &amp;lt;pseudo-common lics=&amp;quot;.reporting.&amp;quot;/&amp;gt;\&lt;br /&gt;
      &amp;lt;pseudo type=&amp;quot;fax&amp;quot;/&amp;gt;\&lt;br /&gt;
    &amp;lt;/reg&amp;gt;\&lt;br /&gt;
    &amp;lt;reg cn=&amp;quot;Voicemail de&amp;quot; guid=&amp;quot;5ceb0ee7c2a76401bb2600155d50c817&amp;quot; h323=&amp;quot;voicemail-de&amp;quot; pwd=&amp;quot;********&amp;quot; pwdx=&amp;quot;********&amp;quot; prot=&amp;quot;JSON&amp;quot;&amp;gt;\&lt;br /&gt;
      &amp;lt;ep type=&amp;quot;gk&amp;quot; addr=&amp;quot;172.16.176.205&amp;quot; time=&amp;quot;10&amp;quot;/&amp;gt;\&lt;br /&gt;
      &amp;lt;pseudo-common lics=&amp;quot;.uc.voicemail.reporting.&amp;quot;/&amp;gt;\&lt;br /&gt;
      &amp;lt;pseudo type=&amp;quot;vm&amp;quot;/&amp;gt;\&lt;br /&gt;
    &amp;lt;/reg&amp;gt;\&lt;br /&gt;
    ... and so on ...\&lt;br /&gt;
  &amp;lt;/show&amp;gt;&#039;;&lt;br /&gt;
var json = cmd.parse_xml(xml_registrations_on_big_pbx, &#039;reg&#039;);&lt;br /&gt;
console.log(json);&lt;br /&gt;
[&lt;br /&gt;
  {&amp;quot;@cn&amp;quot;:&amp;quot;Fax&amp;quot;, &amp;quot;@guid&amp;quot;:&amp;quot;829a6aeec2a76401c62600155d50c817&amp;quot;, ... &amp;quot;ep&amp;quot;:{&amp;quot;@type&amp;quot;:&amp;quot;gk&amp;quot;,&amp;quot;@addr&amp;quot;:&amp;quot;172.16.176.205&amp;quot;,&amp;quot;@time&amp;quot;:&amp;quot;10&amp;quot;}, ...},&lt;br /&gt;
  {&amp;quot;@cn&amp;quot;:&amp;quot;Voicemail&amp;quot;, &amp;quot;@guid&amp;quot;:&amp;quot;5ceb0ee7c2a76401bb2600155d50c817&amp;quot;, ... &amp;quot;ep&amp;quot;:{&amp;quot;@type&amp;quot;:&amp;quot;gk&amp;quot;,&amp;quot;@addr&amp;quot;:&amp;quot;172.16.176.205&amp;quot;,&amp;quot;@time&amp;quot;:&amp;quot;10&amp;quot;}, ...},&lt;br /&gt;
  ...&lt;br /&gt;
]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/spoiler&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== is_supported_version(string version) : object ======&lt;br /&gt;
Return if the given Version string is supported according to [[Howto:Supported innovaphone versions]].&lt;br /&gt;
&amp;lt;spoiler show=&amp;quot;show sample code&amp;quot; hide=&amp;quot;hide sample code&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
cmd.is_supported_version(&#039;13r3 sr9 [13.7886/1000/0]&#039;); // return &amp;quot;true&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/spoiler&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== get_version_from_build(int build) : string ======&lt;br /&gt;
Return the named version from given build number. (13r3, 14r1 or similar)&lt;br /&gt;
&amp;lt;spoiler show=&amp;quot;show sample code&amp;quot; hide=&amp;quot;hide sample code&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
cmd.get_version_from_build(1410485); // return &amp;quot;14r1&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/spoiler&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== get_pbx_objects_from_config(string config) : array =====&lt;br /&gt;
Extract from a config file PBX Objects with support for different views, DynPBXes and the removal of marks-as-deleted objects&lt;br /&gt;
&amp;lt;spoiler show=&amp;quot;show sample code&amp;quot; hide=&amp;quot;hide sample code&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// &amp;quot;config&amp;quot; contains the result from your &amp;quot;cfg.txt&amp;quot;&lt;br /&gt;
cmd.get_pbx_objects_from_config(config); &lt;br /&gt;
// return &lt;br /&gt;
[&lt;br /&gt;
   &amp;quot;mod cmd FLASHDIR0 add-item 102 (cn=user-1)(h323=user-1)(e164=10)&amp;quot;,&lt;br /&gt;
   &amp;quot;mod cmd FLASHDIR0 add-item 102 (cn=user-2)(h323=user-2)(e164=20)&amp;quot;,&lt;br /&gt;
   &amp;quot;mod cmd FLASHDIR0 add-item 105 (cn=user-1-in-dynpbx)(h323=user-1-in-dynpbx)(e164=50)&amp;quot;,&lt;br /&gt;
]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/spoiler&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== debug =====&lt;br /&gt;
&lt;br /&gt;
====== log(string message) : void ======&lt;br /&gt;
You can write a logfile line to the app debug log&lt;br /&gt;
&lt;br /&gt;
&amp;lt;spoiler show=&amp;quot;show sample code&amp;quot; hide=&amp;quot;hide sample code&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var domains = cmd.log(&#039;my first logfile line&#039;);&lt;br /&gt;
07-26 07:58:33.179 TechAssist@slu.de (b0728708) | Test &amp;quot;sample_test&amp;quot; | my first logfile line&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/spoiler&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Secret knowledge for good tests ===&lt;br /&gt;
; use &amp;quot;get_pbx_objects_from_config()&amp;quot; to get Objects from PBX config&lt;br /&gt;
: To really get all the required objects (dyn PBXes, different views, deleted objects), there are a few things to consider. It is therefore advisable to always use this function in a test.&lt;br /&gt;
; bool PBX-Object config attributes&lt;br /&gt;
: You will find config attributes like &amp;lt;code&amp;gt;no-subscribe=&amp;quot;true&amp;quot;&amp;lt;/code&amp;gt; (this is from a Trunk Object) in the config. Please note that if the attribute is &#039;&#039;missing&#039;&#039; or the value is &#039;&#039;false&#039;&#039; it is false, otherwise it is &#039;&#039;true&#039;&#039;. For example, the value &amp;lt;code&amp;gt;no-subscribe=&amp;quot;on&amp;quot;&amp;lt;/code&amp;gt; is also true.&lt;br /&gt;
; bool Interface config attributes&lt;br /&gt;
: You will find config attributes like &amp;lt;code&amp;gt;/direct-sig on&amp;lt;/code&amp;gt; (this is from a SIP interface) in the config. Please note that they are exists bool-attribute which are &#039;&#039;true&#039;&#039; if the attribute is existing. In the case of bool-attribute the following value make no matter. For example, the attribute &amp;lt;code&amp;gt;/direct-sig off&amp;lt;/code&amp;gt; is also true.&lt;br /&gt;
&lt;br /&gt;
== Monitoring ==&lt;br /&gt;
The App supports a monitoring interface where well known IT-Monitoring Systems or other Statistics Services can connect and collect various data for the whole innovaphone installation.&lt;br /&gt;
&lt;br /&gt;
===Requirements===&lt;br /&gt;
* Only devices that are known by the &#039;&#039;Devices App&#039;&#039; will be included in the monitoring data&lt;br /&gt;
* Only devices that have a non-empty &amp;quot;Name&amp;quot; in the &#039;&#039;Devices App&#039;&#039; will be included in the monitoring data&lt;br /&gt;
* Depending on your monitoring system (to support the automatic host matching magic) it can be needed that all devices has the same &#039;&#039;Name&#039;&#039; in your &#039;&#039;Devices App&#039;&#039; and your external System (Usually the FQDN is used)&lt;br /&gt;
&lt;br /&gt;
===Configurations===&lt;br /&gt;
* In the TechAssist Plugin in Settings (former PBX Manager), you have to configure the credentials for the HTTP authorization to get monitoring data&lt;br /&gt;
* In the TechAssist App in the settings area, you have to:&lt;br /&gt;
** enable/disable the whole monitoring feature. Default is disabled.&lt;br /&gt;
** select categories (PBXes, Gateways, AP Platforms, Apps, DECT, Phones) which should be included in the monitoring data&lt;br /&gt;
* For all app services that provide statistics, the TechAssist app object must have access rights to these apps (the apps must be checked in the &amp;quot;Apps&amp;quot; tab of the PBX object)&lt;br /&gt;
** All Metrics will be placed (in the monitoring output) at the AP where TechAssist is running&lt;br /&gt;
&lt;br /&gt;
===Internal Timers===&lt;br /&gt;
*The data for monitoring systems will be updated every 15 minutes by default. You can adjust this timer in the App Settings.&lt;br /&gt;
*App Metrics will be updated every 1 minute internally&lt;br /&gt;
*App Metrics for the TechAssist itself always have live values&lt;br /&gt;
&lt;br /&gt;
=== HTTP Response Codes ===&lt;br /&gt;
&lt;br /&gt;
* 501 - Monitoring feature is disabled...&lt;br /&gt;
* 503 - Service is starting... | You have to try it again later. The app service is starting.&lt;br /&gt;
* 503 - Data will be collected... | You have to try it again later. The first bunch of data will be collected at this moment.&lt;br /&gt;
&lt;br /&gt;
===Internal Cached Monitoring Data===&lt;br /&gt;
The monitoring data is cached internally. After starting the app, no monitoring data is processed at all to save resources if this function is not used.&lt;br /&gt;
If the first call is made to an interface, the data is prepared in Background and you will get a &amp;quot;503 - Data will be collected...&amp;quot;. This means that the first call fails. From then on, the app knows that monitoring data is being retrieved and prepares the data in a 1-minute interval so that a call to the monitoring system receives the cached data.&lt;br /&gt;
&lt;br /&gt;
===Supported Integrations===&lt;br /&gt;
We support various output formats over different interfaces. Your System can pull the information and append in the needed Interface/Format to the URL. &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Example: https://apps.slu.de/slu.de/techassist/monitoring/JSON (Here is &amp;quot;JSON&amp;quot; the used interface, see below)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you use an old/legacy system that only support http basic-auth instead of digest-auth you can add a &amp;quot;/basic&amp;quot; to the endpoint url. &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Example: https://&amp;lt;/nowiki&amp;gt;apps.slu.de/slu.de/techassist&#039;&#039;&#039;/basic&#039;&#039;&#039;/monitoring/JSON&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== RAW ====&lt;br /&gt;
The interface &amp;quot;/RAW&amp;quot; provides the internal TechAssist format as JSON.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;spoiler show=&amp;quot;show sample output&amp;quot; hide=&amp;quot;hide sample output&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
[&lt;br /&gt;
  {&lt;br /&gt;
    &amp;quot;id&amp;quot;: &amp;quot;1&amp;quot;,&lt;br /&gt;
    &amp;quot;title&amp;quot;: &amp;quot;pbx.domain.de&amp;quot;,&lt;br /&gt;
    &amp;quot;metrics&amp;quot;: [&lt;br /&gt;
      {&lt;br /&gt;
        &amp;quot;id&amp;quot;: &amp;quot;online&amp;quot;,&lt;br /&gt;
        &amp;quot;value&amp;quot;: 1,&lt;br /&gt;
        &amp;quot;valuePercent&amp;quot;: null,&lt;br /&gt;
        &amp;quot;comment&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
        &amp;quot;min&amp;quot;: null,&lt;br /&gt;
        &amp;quot;max&amp;quot;: null&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        &amp;quot;id&amp;quot;: &amp;quot;serialnumber&amp;quot;,&lt;br /&gt;
        &amp;quot;value&amp;quot;: &amp;quot;005056001338&amp;quot;,&lt;br /&gt;
        &amp;quot;valuePercent&amp;quot;: null,&lt;br /&gt;
        &amp;quot;comment&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
        &amp;quot;min&amp;quot;: null,&lt;br /&gt;
        &amp;quot;max&amp;quot;: null&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        &amp;quot;id&amp;quot;: &amp;quot;product&amp;quot;,&lt;br /&gt;
        &amp;quot;value&amp;quot;: &amp;quot;IPVA&amp;quot;,&lt;br /&gt;
        &amp;quot;valuePercent&amp;quot;: null,&lt;br /&gt;
        &amp;quot;comment&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
        &amp;quot;min&amp;quot;: null,&lt;br /&gt;
        &amp;quot;max&amp;quot;: null&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        &amp;quot;id&amp;quot;: &amp;quot;version&amp;quot;,&lt;br /&gt;
        &amp;quot;value&amp;quot;: &amp;quot;15r1 dvl [15.1.0130/1000/0]&amp;quot;,&lt;br /&gt;
        &amp;quot;valuePercent&amp;quot;: null,&lt;br /&gt;
        &amp;quot;comment&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
        &amp;quot;min&amp;quot;: null,&lt;br /&gt;
        &amp;quot;max&amp;quot;: null&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        &amp;quot;id&amp;quot;: &amp;quot;versionIsSupported&amp;quot;,&lt;br /&gt;
        &amp;quot;value&amp;quot;: 1,&lt;br /&gt;
        &amp;quot;valuePercent&amp;quot;: null,&lt;br /&gt;
        &amp;quot;comment&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
        &amp;quot;min&amp;quot;: null,&lt;br /&gt;
        &amp;quot;max&amp;quot;: null&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        &amp;quot;id&amp;quot;: &amp;quot;uptime&amp;quot;,&lt;br /&gt;
        &amp;quot;value&amp;quot;: 2747,&lt;br /&gt;
        &amp;quot;valuePercent&amp;quot;: null,&lt;br /&gt;
        &amp;quot;comment&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
        &amp;quot;min&amp;quot;: null,&lt;br /&gt;
        &amp;quot;max&amp;quot;: null&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        &amp;quot;id&amp;quot;: &amp;quot;CPU&amp;quot;,&lt;br /&gt;
        &amp;quot;value&amp;quot;: 1,&lt;br /&gt;
        &amp;quot;valuePercent&amp;quot;: 1,&lt;br /&gt;
        &amp;quot;comment&amp;quot;: null,&lt;br /&gt;
        &amp;quot;min&amp;quot;: 0,&lt;br /&gt;
        &amp;quot;max&amp;quot;: 100&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        &amp;quot;id&amp;quot;: &amp;quot;CPU-R&amp;quot;,&lt;br /&gt;
        &amp;quot;value&amp;quot;: 0,&lt;br /&gt;
        &amp;quot;valuePercent&amp;quot;: 0,&lt;br /&gt;
        &amp;quot;comment&amp;quot;: null,&lt;br /&gt;
        &amp;quot;min&amp;quot;: 0,&lt;br /&gt;
        &amp;quot;max&amp;quot;: 26000&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        &amp;quot;id&amp;quot;: &amp;quot;MEM&amp;quot;,&lt;br /&gt;
        &amp;quot;value&amp;quot;: 46,&lt;br /&gt;
        &amp;quot;valuePercent&amp;quot;: 0.09,&lt;br /&gt;
        &amp;quot;comment&amp;quot;: null,&lt;br /&gt;
        &amp;quot;min&amp;quot;: 0,&lt;br /&gt;
        &amp;quot;max&amp;quot;: 49793&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        &amp;quot;id&amp;quot;: &amp;quot;ETH0&amp;quot;,&lt;br /&gt;
        &amp;quot;value&amp;quot;: 10,&lt;br /&gt;
        &amp;quot;valuePercent&amp;quot;: 0,&lt;br /&gt;
        &amp;quot;comment&amp;quot;: null,&lt;br /&gt;
        &amp;quot;min&amp;quot;: 0,&lt;br /&gt;
        &amp;quot;max&amp;quot;: 1000000&lt;br /&gt;
      }&lt;br /&gt;
    ]&lt;br /&gt;
  },&lt;br /&gt;
  {&lt;br /&gt;
    &amp;quot;id&amp;quot;: &amp;quot;47&amp;quot;,&lt;br /&gt;
    &amp;quot;title&amp;quot;: &amp;quot;ap.domain.de&amp;quot;,&lt;br /&gt;
    &amp;quot;metrics&amp;quot;: [&lt;br /&gt;
      {&lt;br /&gt;
        &amp;quot;id&amp;quot;: &amp;quot;online&amp;quot;,&lt;br /&gt;
        &amp;quot;value&amp;quot;: 1,&lt;br /&gt;
        &amp;quot;valuePercent&amp;quot;: null,&lt;br /&gt;
        &amp;quot;comment&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
        &amp;quot;min&amp;quot;: null,&lt;br /&gt;
        &amp;quot;max&amp;quot;: null&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        &amp;quot;id&amp;quot;: &amp;quot;serialnumber&amp;quot;,&lt;br /&gt;
        &amp;quot;value&amp;quot;: &amp;quot;00155db3c306&amp;quot;,&lt;br /&gt;
        &amp;quot;valuePercent&amp;quot;: null,&lt;br /&gt;
        &amp;quot;comment&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
        &amp;quot;min&amp;quot;: null,&lt;br /&gt;
        &amp;quot;max&amp;quot;: null&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        &amp;quot;id&amp;quot;: &amp;quot;product&amp;quot;,&lt;br /&gt;
        &amp;quot;value&amp;quot;: &amp;quot;AppPlatform x86_64&amp;quot;,&lt;br /&gt;
        &amp;quot;valuePercent&amp;quot;: null,&lt;br /&gt;
        &amp;quot;comment&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
        &amp;quot;min&amp;quot;: null,&lt;br /&gt;
        &amp;quot;max&amp;quot;: null&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        &amp;quot;id&amp;quot;: &amp;quot;version&amp;quot;,&lt;br /&gt;
        &amp;quot;value&amp;quot;: &amp;quot;120010  (15r1 1510130 dvl )&amp;quot;,&lt;br /&gt;
        &amp;quot;valuePercent&amp;quot;: null,&lt;br /&gt;
        &amp;quot;comment&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
        &amp;quot;min&amp;quot;: null,&lt;br /&gt;
        &amp;quot;max&amp;quot;: null&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        &amp;quot;id&amp;quot;: &amp;quot;versionIsSupported&amp;quot;,&lt;br /&gt;
        &amp;quot;value&amp;quot;: 1,&lt;br /&gt;
        &amp;quot;valuePercent&amp;quot;: null,&lt;br /&gt;
        &amp;quot;comment&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
        &amp;quot;min&amp;quot;: null,&lt;br /&gt;
        &amp;quot;max&amp;quot;: null&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;&amp;quot;&lt;br /&gt;
    ]&lt;br /&gt;
  }&lt;br /&gt;
]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/spoiler&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== CSV ====&lt;br /&gt;
The interface &amp;quot;/CSV&amp;quot; provides a simple text based comma separated structure.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;spoiler show=&amp;quot;show sample output&amp;quot; hide=&amp;quot;hide sample output&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;Hostname&amp;gt;;&amp;lt;Metric&amp;gt;;&amp;lt;Value&amp;gt;;&amp;lt;Result&amp;gt;;&amp;lt;Comment&amp;gt;&lt;br /&gt;
pbx.domain.de;&amp;quot;online&amp;quot;;true;&lt;br /&gt;
pbx.domain.de;&amp;quot;serialnumber&amp;quot;;005056001338;&lt;br /&gt;
pbx.domain.de;&amp;quot;product&amp;quot;;IPVA;&lt;br /&gt;
pbx.domain.de;&amp;quot;version&amp;quot;;15r1 dvl [15.1.0130/1000/0];&lt;br /&gt;
pbx.domain.de;&amp;quot;versionIsSupported&amp;quot;;true;&lt;br /&gt;
pbx.domain.de;&amp;quot;uptime&amp;quot;;3050;&lt;br /&gt;
pbx.domain.de;&amp;quot;CPU&amp;quot;;2;null&lt;br /&gt;
pbx.domain.de;&amp;quot;CPU-R&amp;quot;;0;null&lt;br /&gt;
pbx.domain.de;&amp;quot;MEM&amp;quot;;0.09;null&lt;br /&gt;
pbx.domain.de;&amp;quot;ETH0&amp;quot;;18;null&lt;br /&gt;
ap.domain.de;&amp;quot;online&amp;quot;;true;&lt;br /&gt;
ap.domain.de;&amp;quot;serialnumber&amp;quot;;00155db3c306;&lt;br /&gt;
ap.domain.de;&amp;quot;product&amp;quot;;AppPlatform x86_64;&lt;br /&gt;
ap.domain.de;&amp;quot;version&amp;quot;;120010  (15r1 1510130 dvl );&lt;br /&gt;
ap.domain.de;&amp;quot;versionIsSupported&amp;quot;;true;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/spoiler&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== JSON ====&lt;br /&gt;
The interface &amp;quot;/JSON&amp;quot; provides a JSON formatted structure.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;spoiler show=&amp;quot;show sample output&amp;quot; hide=&amp;quot;hide sample output&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;pbx.domain.de&amp;quot;: [&lt;br /&gt;
    {&amp;quot;device&amp;quot;:&amp;quot;pbx.domain.de&amp;quot;,&amp;quot;metric&amp;quot;:&amp;quot;online&amp;quot;,&amp;quot;value&amp;quot;:&amp;quot;true&amp;quot;,&amp;quot;result&amp;quot;:true&amp;quot;comment&amp;quot;:&amp;quot;&amp;quot;},&lt;br /&gt;
    {&amp;quot;device&amp;quot;:&amp;quot;pbx.domain.de&amp;quot;,&amp;quot;metric&amp;quot;:&amp;quot;serialnumber&amp;quot;,&amp;quot;value&amp;quot;:005056001338,&amp;quot;comment&amp;quot;:&amp;quot;&amp;quot;},&lt;br /&gt;
    {&amp;quot;device&amp;quot;:&amp;quot;pbx.domain.de&amp;quot;,&amp;quot;metric&amp;quot;:&amp;quot;product&amp;quot;,&amp;quot;value&amp;quot;:IPVA,&amp;quot;comment&amp;quot;:&amp;quot;&amp;quot;},&lt;br /&gt;
    {&amp;quot;device&amp;quot;:&amp;quot;pbx.domain.de&amp;quot;,&amp;quot;metric&amp;quot;:&amp;quot;version&amp;quot;,&amp;quot;value&amp;quot;:15r1 dvl [15.1.0130/1000/0],&amp;quot;comment&amp;quot;:&amp;quot;&amp;quot;},&lt;br /&gt;
    {&amp;quot;device&amp;quot;:&amp;quot;pbx.domain.de&amp;quot;,&amp;quot;metric&amp;quot;:&amp;quot;versionIsSupported&amp;quot;,&amp;quot;value&amp;quot;:&amp;quot;true&amp;quot;,&amp;quot;result&amp;quot;:true&amp;quot;comment&amp;quot;:&amp;quot;&amp;quot;},&lt;br /&gt;
    {&amp;quot;device&amp;quot;:&amp;quot;pbx.domain.de&amp;quot;,&amp;quot;metric&amp;quot;:&amp;quot;uptime&amp;quot;,&amp;quot;value&amp;quot;:3050,&amp;quot;comment&amp;quot;:&amp;quot;&amp;quot;},&lt;br /&gt;
    {&amp;quot;device&amp;quot;:&amp;quot;pbx.domain.de&amp;quot;,&amp;quot;metric&amp;quot;:&amp;quot;CPU&amp;quot;,&amp;quot;value&amp;quot;:2,&amp;quot;comment&amp;quot;:&amp;quot;null&amp;quot;},&lt;br /&gt;
    {&amp;quot;device&amp;quot;:&amp;quot;pbx.domain.de&amp;quot;,&amp;quot;metric&amp;quot;:&amp;quot;CPU-R&amp;quot;,&amp;quot;value&amp;quot;:0,&amp;quot;comment&amp;quot;:&amp;quot;null&amp;quot;},&lt;br /&gt;
    {&amp;quot;device&amp;quot;:&amp;quot;pbx.domain.de&amp;quot;,&amp;quot;metric&amp;quot;:&amp;quot;MEM&amp;quot;,&amp;quot;value&amp;quot;:0.09,&amp;quot;comment&amp;quot;:&amp;quot;null&amp;quot;},&lt;br /&gt;
    {&amp;quot;device&amp;quot;:&amp;quot;pbx.domain.de&amp;quot;,&amp;quot;metric&amp;quot;:&amp;quot;ETH0&amp;quot;,&amp;quot;value&amp;quot;:18,&amp;quot;comment&amp;quot;:&amp;quot;null&amp;quot;}&lt;br /&gt;
  ],&lt;br /&gt;
  &amp;quot;ap.domain.de&amp;quot;: [&lt;br /&gt;
    {&amp;quot;device&amp;quot;:&amp;quot;ap.domain.de&amp;quot;,&amp;quot;metric&amp;quot;:&amp;quot;online&amp;quot;,&amp;quot;value&amp;quot;:&amp;quot;true&amp;quot;,&amp;quot;result&amp;quot;:true,&amp;quot;comment&amp;quot;:&amp;quot;&amp;quot;},&lt;br /&gt;
    {&amp;quot;device&amp;quot;:&amp;quot;ap.domain.de&amp;quot;,&amp;quot;metric&amp;quot;:&amp;quot;serialnumber&amp;quot;,&amp;quot;value&amp;quot;:00155db3c306,&amp;quot;comment&amp;quot;:&amp;quot;&amp;quot;},&lt;br /&gt;
    {&amp;quot;device&amp;quot;:&amp;quot;ap.domain.de&amp;quot;,&amp;quot;metric&amp;quot;:&amp;quot;product&amp;quot;,&amp;quot;value&amp;quot;:AppPlatform x86_64,&amp;quot;comment&amp;quot;:&amp;quot;&amp;quot;},&lt;br /&gt;
    {&amp;quot;device&amp;quot;:&amp;quot;ap.domain.de&amp;quot;,&amp;quot;metric&amp;quot;:&amp;quot;version&amp;quot;,&amp;quot;value&amp;quot;:120010  (15r1 1510130 dvl ),&amp;quot;comment&amp;quot;:&amp;quot;&amp;quot;},&lt;br /&gt;
    {&amp;quot;device&amp;quot;:&amp;quot;ap.domain.de&amp;quot;,&amp;quot;metric&amp;quot;:&amp;quot;versionIsSupported&amp;quot;,&amp;quot;value&amp;quot;:&amp;quot;true&amp;quot;,&amp;quot;result&amp;quot;:true,&amp;quot;comment&amp;quot;:&amp;quot;&amp;quot;},&lt;br /&gt;
  ]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/spoiler&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Checkmk ====&lt;br /&gt;
The interface &amp;quot;/Checkmk&amp;quot; provides a native integration to your Checkmk system with [https://docs.checkmk.com/latest/en/piggyback.html Piggyback] information for all known hosts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;spoiler show=&amp;quot;show sample output&amp;quot; hide=&amp;quot;hide sample output&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;&amp;lt;&amp;lt;&amp;lt;pbx.domain.de&amp;gt;&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;&amp;lt;&amp;lt;check_mk&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
AgentOS: innovaphone TechAssist&lt;br /&gt;
Hostname: pbx.domain.de&lt;br /&gt;
&amp;lt;&amp;lt;&amp;lt;uptime&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
3050&lt;br /&gt;
&amp;lt;&amp;lt;&amp;lt;kernel&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
util 0&lt;br /&gt;
cpu 1728891356864 0 0 1728891356960 0 0 0 0 0 0&lt;br /&gt;
&amp;lt;&amp;lt;&amp;lt;mem&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
MemTotal: 49793 kB&lt;br /&gt;
MemFree: 49747 kB&lt;br /&gt;
MemAvailable: 49747 kB&lt;br /&gt;
Buffers: 0 kB&lt;br /&gt;
Cached: 0 kB&lt;br /&gt;
SwapTotal: 0 kB&lt;br /&gt;
SwapFree: 0 kB&lt;br /&gt;
Dirty: 0 kB&lt;br /&gt;
Writeback: 0 kB&lt;br /&gt;
&amp;lt;&amp;lt;&amp;lt;lnx_thermal&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;&amp;lt;&amp;lt;local&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
0 &amp;quot;online&amp;quot; - online=1&lt;br /&gt;
0 &amp;quot;serialnumber&amp;quot; - serialnumber=005056001338&lt;br /&gt;
0 &amp;quot;product&amp;quot; - product=IPVA&lt;br /&gt;
0 &amp;quot;version&amp;quot; - version=15r1 dvl [15.1.0130/1000/0]&lt;br /&gt;
0 &amp;quot;versionIsSupported&amp;quot; - versionIsSupported=1&lt;br /&gt;
0 &amp;quot;CPU-R&amp;quot; - CPU-R=0&lt;br /&gt;
0 &amp;quot;ETH0&amp;quot; - ETH0=18&lt;br /&gt;
&amp;lt;&amp;lt;&amp;lt;innovaphone&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;&amp;lt;&amp;lt;&amp;lt;ap.domain.de&amp;gt;&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;&amp;lt;&amp;lt;check_mk&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
AgentOS: innovaphone TechAssist&lt;br /&gt;
Hostname: ap.domain.de&lt;br /&gt;
&amp;lt;&amp;lt;&amp;lt;uptime&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;&amp;lt;&amp;lt;kernel&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;&amp;lt;&amp;lt;mem&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;&amp;lt;&amp;lt;lnx_thermal&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;&amp;lt;&amp;lt;local&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
0 &amp;quot;online&amp;quot; - online=1&lt;br /&gt;
0 &amp;quot;serialnumber&amp;quot; - serialnumber=00155db3c306&lt;br /&gt;
0 &amp;quot;product&amp;quot; - product=AppPlatform x86_64&lt;br /&gt;
0 &amp;quot;version&amp;quot; - version=120010  (15r1 1510130 dvl )&lt;br /&gt;
0 &amp;quot;versionIsSupported&amp;quot; - versionIsSupported=1&lt;br /&gt;
&amp;lt;&amp;lt;&amp;lt;innovaphone&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/spoiler&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Configure your Checkmk installation =====&lt;br /&gt;
#Setup your Hosts in Checkmk&lt;br /&gt;
#*Make sure that &amp;quot;Checkmk agent / API integrations&amp;quot; in the Hostconfiguration of your Application Platform is set to &amp;quot;API integrations if configured, else Checkmk agent&amp;quot;, all other Hosts hat to bet set to &amp;quot;No API integrations, no Checkmk agent&amp;quot;.&lt;br /&gt;
#Create a new Rule for &amp;quot;Individual program call instead of agent access&amp;quot; in &amp;quot;Setup &amp;gt; Agents &amp;gt; Other integrations&amp;quot;&lt;br /&gt;
#*Command line to execute: &amp;lt;code&amp;gt;curl --digest -u &amp;quot;user:pass&amp;quot; https://ap.domain.tld/domain.de/techassist/monitoring/Checkmk&amp;lt;/code&amp;gt;&lt;br /&gt;
#*Explicit hosts: Set this to the Host of your Application Platform&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
After that, you can run the service discovery and receive new checks for your devices&lt;br /&gt;
&lt;br /&gt;
[[File:Checkmk new checks.png|frameless|500px|checkmk_new_checks.png/|checkmk_new_checks.png/]]&lt;br /&gt;
&lt;br /&gt;
==== Icinga ====&lt;br /&gt;
The interface &amp;quot;/Icinga&amp;quot; provides a native integration to your Icinga system for all known hosts.&lt;br /&gt;
&lt;br /&gt;
{{FIXME|reason=This interface is currently being researched, and it is being checked whether icinga can read such data as expected}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;spoiler show=&amp;quot;show sample output&amp;quot; hide=&amp;quot;hide sample output&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
[&lt;br /&gt;
  {&lt;br /&gt;
    &amp;quot;_host&amp;quot;: &amp;quot;pbx.domain.de&amp;quot;,&lt;br /&gt;
    &amp;quot;_ETH0_ipv4&amp;quot;: &amp;quot;10.0.102.7&amp;quot;,&lt;br /&gt;
    &amp;quot;online&amp;quot;:1,&lt;br /&gt;
    &amp;quot;serialnumber&amp;quot;:005056001338,&lt;br /&gt;
    &amp;quot;product&amp;quot;:IPVA,&lt;br /&gt;
    &amp;quot;version&amp;quot;:15r1 dvl [15.1.0130/1000/0],&lt;br /&gt;
    &amp;quot;versionIsSupported&amp;quot;:1,&lt;br /&gt;
    &amp;quot;uptime&amp;quot;:3353,&lt;br /&gt;
    &amp;quot;CPU&amp;quot;:1,&lt;br /&gt;
    &amp;quot;CPU-R&amp;quot;:0,&lt;br /&gt;
    &amp;quot;MEM&amp;quot;:0.09,&lt;br /&gt;
    &amp;quot;ETH0&amp;quot;:14&lt;br /&gt;
  },&lt;br /&gt;
  {&lt;br /&gt;
    &amp;quot;_host&amp;quot;: &amp;quot;ap.domain.de&amp;quot;,&lt;br /&gt;
    &amp;quot;_eth0_ipv4&amp;quot;: &amp;quot;10.0.102.8&amp;quot;,&lt;br /&gt;
    &amp;quot;_eth0_ipv6&amp;quot;: &amp;quot;2001:4090:e000:9a1::8&amp;quot;,&lt;br /&gt;
    &amp;quot;online&amp;quot;:1,&lt;br /&gt;
    &amp;quot;serialnumber&amp;quot;:00155db3c306,&lt;br /&gt;
    &amp;quot;product&amp;quot;:AppPlatform x86_64,&lt;br /&gt;
    &amp;quot;version&amp;quot;:120010  (15r1 1510130 dvl ),&lt;br /&gt;
    &amp;quot;versionIsSupported&amp;quot;:1&lt;br /&gt;
  }&lt;br /&gt;
]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/spoiler&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Configure your Icinga installation =====&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
=== Startup Logfile ===&lt;br /&gt;
If you enable the traceflag &#039;&#039;App&#039;&#039; in your App instance, you will find the following logs:&lt;br /&gt;
&lt;br /&gt;
 AppService::AppStart TechAssist@slu.de&lt;br /&gt;
 App instance started 14C1363 14C1363&lt;br /&gt;
 ...&lt;br /&gt;
 // App begins to load embedded tests&lt;br /&gt;
 JavaScript: Files tests/*&lt;br /&gt;
 ...&lt;br /&gt;
 // Scheduler begins to load all the tests&lt;br /&gt;
 scheduler init&lt;br /&gt;
 init test &amp;quot;firmware_version&amp;quot;&lt;br /&gt;
 firmware_version: Test added successful&lt;br /&gt;
 init test &amp;quot;pbx_mediarelay&amp;quot;&lt;br /&gt;
 pbx_mediarelay: Test added successful&lt;br /&gt;
&lt;br /&gt;
=== Websocket Connections ===&lt;br /&gt;
The App holds Websocket connections to various targets. To debug and follow these connections in the logfile you will find special log output for outgoing websocket connections.&lt;br /&gt;
&lt;br /&gt;
You can filter the logfile with &amp;lt;code&amp;gt;Websocket Log&amp;lt;/code&amp;gt; to get the Websocket flow. Then a good practice should be to click on these lines and check the lines before.&lt;br /&gt;
 C:\Users\slu\Downloads\techassist-x86_64-20241112-131349.txt (8 Treffer)&lt;br /&gt;
 Zeile   9: 11-12 13:13:46.288 techassist@slu.de Websocket Log - ServicesInfoApis::close | {...}&lt;br /&gt;
 Zeile  12: 11-12 13:13:46.288 techassist@slu.de Websocket Log - ServicesInfoApis::close | {...}&lt;br /&gt;
 Zeile  18: 11-12 13:13:46.288 techassist@slu.de Websocket Log - ServicesInfoApis::add | {...}&lt;br /&gt;
 Zeile  22: 11-12 13:13:46.288 techassist@slu.de Websocket Log - ServicesInfoApis::add | {...}&lt;br /&gt;
 Zeile  34: 11-12 13:13:46.290 techassist@slu.de Websocket Log - ServicesInfoApis::remove | {...}&lt;br /&gt;
 Zeile  41: 11-12 13:13:46.290 techassist@slu.de Websocket Log - ServicesInfoApis::remove | {...}&lt;br /&gt;
 Zeile  66: 11-12 13:13:46.307 techassist@slu.de Websocket Log - ServicesInfoApis::find | {...}&lt;br /&gt;
 Zeile 321: 11-12 13:13:46.324 techassist@slu.de Websocket Log - ServicesInfoApis::find | {...}&lt;/div&gt;</summary>
		<author><name>Tfu</name></author>
	</entry>
	<entry>
		<id>https://wiki.innovaphone.com/index.php?title=Reference16r1:Concept_App_Service_TechAssist&amp;diff=80617</id>
		<title>Reference16r1:Concept App Service TechAssist</title>
		<link rel="alternate" type="text/html" href="https://wiki.innovaphone.com/index.php?title=Reference16r1:Concept_App_Service_TechAssist&amp;diff=80617"/>
		<updated>2026-10-06T08:08:49Z</updated>

		<summary type="html">&lt;p&gt;Tfu: /* Configurations */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Concept|Apps]]&lt;br /&gt;
[[Category:Concept App Service TechAssist]]&lt;br /&gt;
&amp;lt;!-- techassist, ticket, analyze, debug, tests --&amp;gt;&lt;br /&gt;
== Applies To == &lt;br /&gt;
&lt;br /&gt;
* innovaphone PBX from version 15r1&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
The idea of the TechAssist app is to provide helpful tools for technicians, as well as to analyze static and runtime information of a system and check for problems and improvements. In this way, the app can help you find and solve problems and misconfigurations independently and quickly.&lt;br /&gt;
For this purpose, the app supports&lt;br /&gt;
* the execution of &#039;&#039;tests&#039;&#039;&lt;br /&gt;
** a bunch of manufacturer tests are supplied with the app&lt;br /&gt;
** you can create and save your own tests&lt;br /&gt;
** testresults can be downloaded to attach them to a support ticket&lt;br /&gt;
* a PBX license overview&lt;br /&gt;
&lt;br /&gt;
== Licensing ==&lt;br /&gt;
There are no licenses needed for this app&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
The TechAssist App is installed by default for every new installation and is accessible from the Config Admin template.&lt;br /&gt;
&lt;br /&gt;
=== With the PBX manager AP app installer plug-in === &lt;br /&gt;
[[File:Ap_app_installer.png|ap_app_installer.png/|ap_app_installer.png/]]&lt;br /&gt;
&lt;br /&gt;
Go to the PBX manager and open the &#039;&#039;&#039;&amp;quot;AP app installer&amp;quot;&#039;&#039;&#039; plugin. On the right panel, the App Store will be shown. &#039;&#039;Hint : if you access it for the first time, you will need to accept the &amp;quot;Terms of Use of the innovaphone App Store&amp;quot;&#039;&#039;&lt;br /&gt;
* In the search field located on the top right corner of the store, search for &#039;&#039;&#039;&amp;quot;Techassist&amp;quot;&#039;&#039;&#039; and click on it&lt;br /&gt;
* Select the proper firmware version, here &#039;&#039;&#039;&amp;quot;v14&amp;quot;&#039;&#039;&#039; and click on install&lt;br /&gt;
* Tick &amp;quot;I accept the terms of use&amp;quot; and continue by clicking on the install yellow button&lt;br /&gt;
* Wait until the install has been finished&lt;br /&gt;
* Close and open the PBX manager to refresh the list of the available colored AP plugin&lt;br /&gt;
* Click on the &#039;&#039;&#039;&amp;quot;AP techassist&amp;quot;&#039;&#039;&#039; and click on &#039;&#039;&#039;&amp;quot; + Add an App&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
* Enter a &#039;&#039;&#039;&amp;quot;Name&amp;quot;&#039;&#039;&#039; that is used as display name &#039;&#039;(all character allowed)&#039;&#039; for it and the &#039;&#039;&#039;&amp;quot;SIP&amp;quot;&#039;&#039;&#039; name that is the administrative field &#039;&#039;(no space, no capital letters)&#039;&#039;. &#039;&#039;e.g : Name: TechAssist, SIP: techassist&#039;&#039;&lt;br /&gt;
&#039;&#039;Hint : The App needs access-right to one devices-api. The access to &amp;quot;devices-api&amp;quot; will be set automatically. If you want to have another devices-apis working with techassist, you have to configure it manually in the advanced UI.&#039;&#039;&lt;br /&gt;
* Tick the appropriate template to distribute the App&lt;br /&gt;
* Click OK to save the settings and a green check mark will be shown to inform you that the configuration is good&lt;br /&gt;
&lt;br /&gt;
== Test Engine ==&lt;br /&gt;
=== Overview ===&lt;br /&gt;
==== Technical look inside ====&lt;br /&gt;
[[File:Concept_TechAssist.png|thumb|upright=1.0|right|concept_techassist.png/|concept_techassist.png/]]&lt;br /&gt;
The app service receives multiple incoming websocket connections of the app objects from the PBXes. By assigning rights to a to your desired &amp;quot;devices-apis&amp;quot; (in the Apps tab), the app service receives the corresponding rights to connect to the respectively activated DevicesApps. All managed domains and devices can then be read in via this connection. (One TechAssist can only connect with one device-api)&lt;br /&gt;
With this procedure, you can work with one DevicesApp instance and across all domains and devices in it.&lt;br /&gt;
&lt;br /&gt;
==== Submodules ====&lt;br /&gt;
The app contains various sub-modules in order to be able to carry out the tests provided by the manufacturer and also to be able to integrate custom tests created by yourself.&lt;br /&gt;
&lt;br /&gt;
;scheduler&lt;br /&gt;
: The scheduler initially loads all tests and performs a plausibility check of the individual tests. From this status onwards, the scheduler ensures that all tests are executed in the required time intervals.&lt;br /&gt;
: Inside the Scheduler the tick is 5000 milliseconds, and test are executed sequentially to prevent high system load&lt;br /&gt;
;cmd&lt;br /&gt;
: The cmd submodule (derived from &amp;quot;command&amp;quot;) can communicate with devices in the installation to query a status, the config or similar. The submodule takes care of all the information that tests from an installation want to have, consolidates them so that queries do not have to be executed multiple times and caches the results.&lt;br /&gt;
;test&lt;br /&gt;
: The test submodule is instantiated per test and provides all necessary functionalities within a test.&lt;br /&gt;
&lt;br /&gt;
==== UI Language ====&lt;br /&gt;
By design, only the app itself is available in multiple languages. The content of the tests and technical output is intentionally only available in english.&lt;br /&gt;
&lt;br /&gt;
==== Tests ====&lt;br /&gt;
The app contains a bunch of embedded test, but it is also possible to create and save your own tests.&lt;br /&gt;
&lt;br /&gt;
=== UI ===&lt;br /&gt;
&lt;br /&gt;
==== Tests ====&lt;br /&gt;
;Execute all&lt;br /&gt;
:This Button will trigger all tests. Keep in mind that this trigger used the cached version of commands.&lt;br /&gt;
;Execute all without cache&lt;br /&gt;
:This Button will trigger all tests but will clear the cache for all commands before&lt;br /&gt;
;Execute a dedicated test&lt;br /&gt;
: In this execution, no cache will be used&lt;br /&gt;
&lt;br /&gt;
==== Expert Mode ====&lt;br /&gt;
By default there are some expert information hidden in the left menu bar. You will find a switch for that in the left menu (non-mobile-view) to enable all menu items.&lt;br /&gt;
&lt;br /&gt;
==== Dealing with the Code Editor ====&lt;br /&gt;
The Code Editor is a tool for viewing the tests supplied and writing your own tests based on these tests.&lt;br /&gt;
&lt;br /&gt;
The editor is divided into 3 basic areas.&lt;br /&gt;
;Left - Code Editor&lt;br /&gt;
:This is the code editor where you can write your test code in the browser. When you close the app, the content in the editor is saved, so that the next time you open the app you will find your old code again.&lt;br /&gt;
&lt;br /&gt;
;Top right - Menu bar&lt;br /&gt;
:Here you will find the following functions:&lt;br /&gt;
:Selection of all existing Tests (predefined vendor Tests and your own custom Tests)&lt;br /&gt;
:Load the source code of the selected Test to the code editor&lt;br /&gt;
:Delete the selected test from the app (This is only possible for custom tests)&lt;br /&gt;
:Execute the source code (with or without cached commands in the service) in the Code Editor and show the result&lt;br /&gt;
:Clear the Code Editor&lt;br /&gt;
:Save the current Content from the code Editor as Test&lt;br /&gt;
::The title of your test is divided from the &#039;&#039;title&#039;&#039; property in your test (lower based without non-alphanumeric characters). This means: If you save another Test with the same &#039;&#039;title&#039;&#039; the value will be saved in the other test.&lt;br /&gt;
&lt;br /&gt;
;Top right - Results&lt;br /&gt;
:If you execute, save or delete a test you will get the response/results in this area&lt;br /&gt;
&lt;br /&gt;
=== Create your own Testscript ===&lt;br /&gt;
You can create your own Test scripts in a JavaScript based environment.&lt;br /&gt;
A test itself is a JavaScript object with some configurations properties and a section of &#039;&#039;freestyle&#039;&#039; code to use JavaScript habits to perform your test. If your test will be executed, an above layer will call your &#039;&#039;test()&#039;&#039; method and want to have a return object with your result.&lt;br /&gt;
&lt;br /&gt;
There already exists a global Object called &#039;&#039;&#039;tests_add&#039;&#039;&#039;. You can add your own Test as Property to this existing Object like:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
tests_add.my_new_test = tests_add.my_new_test || {&lt;br /&gt;
   title: &#039;Check for xyz&#039;,&lt;br /&gt;
   // configuration properties&lt;br /&gt;
   &lt;br /&gt;
   test: function (cmd, result, storage) {&lt;br /&gt;
       // your custom test code&lt;br /&gt;
&lt;br /&gt;
       return {&lt;br /&gt;
           success: false,&lt;br /&gt;
           msg: &#039;....&#039;&lt;br /&gt;
       };&lt;br /&gt;
   }&lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The way to add a test with &amp;lt;code&amp;gt;tests_add.my_new_test = tests_add.my_new_test || {}&amp;lt;/code&amp;gt; is important so that two tests do not overwrite each other. Please also pay attention to this. In this example, we have a &#039;&#039;logical condition&#039;&#039; in the first line. If the test &#039;&#039;my_new_test&#039;&#039; already exists in the object &#039;&#039;tests_add&#039;&#039; the left side from the &#039;&#039;OR-condition&#039;&#039; is &#039;&#039;true&#039;&#039;, and the existing test takes place. Otherwise, it is &#039;&#039;false&#039;&#039; and the right side (your new test object) will be written to &#039;&#039;tests_add.my_new_test&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==== Configuration Properties ====&lt;br /&gt;
You must configure certain properties in your test so that the scheduler knows exactly how to handle your test.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
tests_add.my_new_test = tests_add.my_new_test || {&lt;br /&gt;
  title: &#039;Unknown / New devices&#039;,&lt;br /&gt;
  description: &#039;Check for unassigned devices in your installation&#039;,&lt;br /&gt;
  todo: &#039;Please check the unknown devices in your installation and acceppt or delete the devices&#039;,&lt;br /&gt;
  author: &#039;slu@innovaphone.com&#039;,&lt;br /&gt;
  enabled: true,&lt;br /&gt;
  schedule: &#039;1h&#039;,&lt;br /&gt;
  commands: { ... },&lt;br /&gt;
&lt;br /&gt;
  test: function (cmd, result, storage) {&lt;br /&gt;
    // your custom test code&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Mandatory properties =====&lt;br /&gt;
&lt;br /&gt;
; title&lt;br /&gt;
: string | The title of your test, which is displayed in the UI&lt;br /&gt;
; description&lt;br /&gt;
: string | A short description of your test, which is displayed in the UI&lt;br /&gt;
; todo&lt;br /&gt;
: string | An instruction on what the user has to do if the check fails. It will be displayed above the logfile in failed tests. (You can use &#039;&#039;\r\n&#039;&#039; for line breaks)&lt;br /&gt;
: Variable &amp;lt;nowiki&amp;gt;{{VERSION}}&amp;lt;/nowiki&amp;gt; will be replaced to current Version of the app like &amp;quot;14r1&amp;quot;&lt;br /&gt;
; author&lt;br /&gt;
: string | The contact of the person who create the test&lt;br /&gt;
; schedule&lt;br /&gt;
: string | The time interval during which the test is to be carried out independently. The format is composed of a numerical value and interval value. This allows you to create combinations such as &amp;lt;code&amp;gt;5m (every 5 minutes), 10h (every 10 hours) or 1d (every day) &amp;lt;/code&amp;gt;. A special case which is also allowed is the value &#039;&#039;none&#039;&#039;. With a &#039;&#039;none&#039;&#039; value, your test will not be executed automatically, but is available in the app. So the user is able to execute your test manually.&lt;br /&gt;
: Possible interval values are:&lt;br /&gt;
: &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt; (seconds)&lt;br /&gt;
: &amp;lt;code&amp;gt;m&amp;lt;/code&amp;gt; (minutes)&lt;br /&gt;
: &amp;lt;code&amp;gt;h&amp;lt;/code&amp;gt; (hours)&lt;br /&gt;
: &amp;lt;code&amp;gt;d&amp;lt;/code&amp;gt; (days)&lt;br /&gt;
: &amp;lt;code&amp;gt;w&amp;lt;/code&amp;gt; (weeks)&lt;br /&gt;
: Please note that each execution of a test requires resources. For example, if you create a test with &#039;&#039;1m&#039;&#039; that is executed every minute, you may well create an unpleasant impact! The system automatically checks the execution time of your test against your specified interval. If your test runs for a longer time than your schedule, your &#039;&#039;schedule&#039;&#039; parameter is automatically doubled by the system.&lt;br /&gt;
: Please note the [[#Submodules|Submodule Scheduler]] with Tick and synchronous execution. For example, it is not possible to execute a test every second. &lt;br /&gt;
&lt;br /&gt;
===== Optional properties =====&lt;br /&gt;
&lt;br /&gt;
; commands&lt;br /&gt;
: object | An object in which you can list all the commands, values, etc. that you want to use later in your test. As soon as your test() method is called, the returns of these commands are passed in as parameters so that you can analyze them. For detailed documentation, please see the [[#Property_&amp;quot;commands&amp;quot;|commands-documentation]] below.&lt;br /&gt;
; minBuild&lt;br /&gt;
: int | The minimum build version of the app, that the Test will be executed.&lt;br /&gt;
; oneTime&lt;br /&gt;
: bool | If &#039;&#039;true&#039;&#039; the test will be self-deactivated after the first successful execution.&lt;br /&gt;
; enabled&lt;br /&gt;
: bool | If &#039;&#039;false&#039;&#039; the test will be loaded but not executed. The user will see the test in the list of test, and it is possible to enable it (default: &#039;&#039;true&#039;&#039;)&lt;br /&gt;
; hidden&lt;br /&gt;
: bool | If &#039;&#039;true&#039;&#039; the test will be skipped by the system and will not be loaded (default: &#039;&#039;false&#039;&#039;) &lt;br /&gt;
&lt;br /&gt;
==== Property &amp;quot;commands&amp;quot; ====&lt;br /&gt;
The property &#039;&#039;commands&#039;&#039; is an object where you can define innovaphone specific commands that are executed before your test will be executed. The results of the given commands will be passed to your test in the parameter &#039;&#039;results&#039;&#039;. Think about that, all your commands will be cached until the &#039;&#039;schedule&#039;&#039; timeout is exceeded. This means that you will only get a new result of the command after the schedule time has elapsed in relation to the time of your last execution. The only exceptions is when the user manually re-executes a test via the UI or caching has been explicitly disabled at the command&lt;br /&gt;
&lt;br /&gt;
You have to consider a special nested notation when creating your commands, so that you can use them later.&lt;br /&gt;
&lt;br /&gt;
===== outer commands-object =====&lt;br /&gt;
Let&#039;s start with some first basic rules:&lt;br /&gt;
* &#039;&#039;commands&#039;&#039; is an object with one property per command. At this moment we only list commands, we don&#039;t take care about specific devices, types of models or so on.&lt;br /&gt;
* Every child-property (let&#039;s call it &amp;quot;command-object&amp;quot;) is a new object which contains all needed information for this specific command&lt;br /&gt;
* The title of the property &amp;quot;command-object&amp;quot; is defined by yourself&lt;br /&gt;
** Spoiler: The title of your &amp;quot;command-object&amp;quot; should be used later if you want to read the result for a specific device&lt;br /&gt;
* You can list multiple &amp;quot;command-objects&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Up to here we have the following and can define it like this:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
commands: {&lt;br /&gt;
  my_command_one: {},&lt;br /&gt;
  my_command_two: {},&lt;br /&gt;
},&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== single command-object =====&lt;br /&gt;
&lt;br /&gt;
Then we have some new rules per &amp;quot;command-object&amp;quot;:&lt;br /&gt;
* A property called &#039;&#039;cmd&#039;&#039; is expected. This property contains the real command which shall be executed (Remember, at this moment we only list commands, we don&#039;t take care about specific devices, types of models or so on)&lt;br /&gt;
** Example 1: &amp;lt;code&amp;gt;cmd: &#039;CMD0/box_info.xml&#039;&amp;lt;/code&amp;gt; will give you the xml output of the general overview page&lt;br /&gt;
** Example 2: &amp;lt;code&amp;gt;cmd: &#039;!mod cmd CDR0 qs&#039;&amp;lt;/code&amp;gt; will give you the amount of buffered CDRs in the CDR0 interface&lt;br /&gt;
** Example 3: &amp;lt;code&amp;gt;cmd: &#039;cfg.txt&#039;&amp;lt;/code&amp;gt; will give you back the full configuration file&lt;br /&gt;
** If you are already firm with the innovaphone based command syntax, you will see that you can use any HTTP command which can be sent to an innovaphone device&lt;br /&gt;
* Some more properties can be defined optionally. See documentation below&lt;br /&gt;
&lt;br /&gt;
Up to here we have an idea of a specific &amp;quot;command-object&amp;quot; and can do the following now:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
commands: {&lt;br /&gt;
  buffered_cdr0: {&lt;br /&gt;
    cmd: &#039;!mod cmd CDR0 qs&#039;,&lt;br /&gt;
  },&lt;br /&gt;
  buffered_cdr1: {&lt;br /&gt;
    cmd: &#039;!mod cmd CDR1 qs&#039;,&lt;br /&gt;
  },&lt;br /&gt;
},&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With this command, we can collect the &amp;quot;buffered CDRs&amp;quot; on both CDR Interfaces in our boxes. Maybe you see it directly... This will not make really sense in a real setup because CDRs only generated by Gateways/PBXes. So we don&#039;t need to bother phones with these requests.&lt;br /&gt;
So from now on we take care about our defined command. There are optional parameters that we can also list inside a &amp;quot;command-object&amp;quot; to let the system know what is the to-do with this command.&lt;br /&gt;
&lt;br /&gt;
;cmd&lt;br /&gt;
: string | Any HTTP command you can send to an innovaphone device. There is a limit of 15 seconds for every http request. If your request exceeds this limit the request will be cancelled.&lt;br /&gt;
;cat&lt;br /&gt;
: array | An optional list of device types on which the command is to be executed. If &#039;&#039;cat&#039;&#039; is empty, it means all devices in your installation.&lt;br /&gt;
: You can define the following device categories:&lt;br /&gt;
: &amp;lt;code&amp;gt;pbx&amp;lt;/code&amp;gt; - all PBXes&lt;br /&gt;
: &amp;lt;code&amp;gt;gw&amp;lt;/code&amp;gt; - all Gateways&lt;br /&gt;
: &amp;lt;code&amp;gt;ap&amp;lt;/code&amp;gt; - all App Platforms &#039;&#039;(effect at the moement)&#039;&#039;&lt;br /&gt;
: &amp;lt;code&amp;gt;dect&amp;lt;/code&amp;gt; - all Dect Gateways&lt;br /&gt;
: &amp;lt;code&amp;gt;phone&amp;lt;/code&amp;gt; - all Phones&lt;br /&gt;
: &amp;lt;code&amp;gt;monitoring&amp;lt;/code&amp;gt; - all categories based on Monitoring settings&lt;br /&gt;
;cache&lt;br /&gt;
: bool | If you set it to &#039;&#039;false&#039;&#039; you will never get a cached value. Please use this option wisely and only if you really need it. (default: &#039;&#039;true&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
Now let&#039;s improve our example from above and get the bufferd CDRx information only from pbxes and gateways.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
commands: {&lt;br /&gt;
  buffered_cdr0: {&lt;br /&gt;
    cmd: &#039;!mod cmd CDR0 qs&#039;,&lt;br /&gt;
    cat: [&#039;pbx&#039;, &#039;gw&#039;],&lt;br /&gt;
  },&lt;br /&gt;
  buffered_cdr1: {&lt;br /&gt;
    cmd: &#039;!mod cmd CDR1 qs&#039;,&lt;br /&gt;
    cat: [&#039;pbx&#039;, &#039;gw&#039;],&lt;br /&gt;
  },&lt;br /&gt;
},&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== execution and results of commands =====&lt;br /&gt;
Up to now, we have only defined commands that are to be executed on certain devices. When your test is executed, the previously defined commands are executed and the system collects the returns in a corresponding object (called &amp;lt;code&amp;gt;results&amp;lt;/code&amp;gt;) which is passed into your &amp;lt;code&amp;gt;test(cmd, results)&amp;lt;/code&amp;gt; method. There you can access the results and do whatever you want to test/analyze or whatever with the return value. You will find an example and some sample-code how to use the results-object in the description of the &#039;&#039;test() method&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===== nested commands-objects =====&lt;br /&gt;
You can now send any commands and the results will be returned to you for evaluation.&lt;br /&gt;
As you may have already noticed, there is no possibility to place multiple commands in dependency. But this is the way to do this.&lt;br /&gt;
&lt;br /&gt;
For more complicated tests, it is necessary to execute several commands one after the other and to generate following commands dynamically on the basis of the result of the first command.&lt;br /&gt;
&lt;br /&gt;
For such tests, there is the possibility to specify an object &amp;quot;commands&amp;quot; within a &amp;quot;command-object&amp;quot;. From this level, you can define a dynamic function in which you can apply your own code based on the first result, and then return a new &#039;&#039;commands-object&#039;&#039;. In this return statement, you also have the option of returning another dynamic function in order to be able to create processes of any complexity. Please note that if you not return an &#039;&#039;object&#039;&#039; your return value will be discarded. The results of your nested &#039;&#039;command-objects&#039;&#039; will be passed to the &#039;&#039;test()&#039;&#039; method inside the &#039;&#039;results&#039;&#039; object.&lt;br /&gt;
&lt;br /&gt;
This is certainly not easy to understand. Therefore, let us take a closer look at it with an example.&lt;br /&gt;
&lt;br /&gt;
====== example: nested commands-object which generates the second command from the first result ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
commands: {&lt;br /&gt;
  certificates: {&lt;br /&gt;
    cmd: &#039;X509/mod_cmd.xml&#039;,&lt;br /&gt;
    cat: [&#039;pbx&#039;, &#039;gw&#039;, &#039;dect&#039;],&lt;br /&gt;
    commands: function(cmd, result) {&lt;br /&gt;
                // free style code to build the following commands&lt;br /&gt;
                var xml = cmd.parse_xml(result);&lt;br /&gt;
                //log(JSON.stringify(xml));&lt;br /&gt;
                &lt;br /&gt;
                var fingerprint;&lt;br /&gt;
                // get the fingerprint for single cert&lt;br /&gt;
                if (typeof xml.info.servercert.certificate[&#039;@fingerprint&#039;] !== &#039;undefined&#039;) {&lt;br /&gt;
                    fingerprint = xml.info.servercert.certificate[&#039;@fingerprint&#039;]&lt;br /&gt;
                }&lt;br /&gt;
                // use last certificates in case of multiple&lt;br /&gt;
                else {&lt;br /&gt;
                    fingerprint = xml.info.servercert.certificate[xml.info.servercert.certificate.length - 1][&#039;@fingerprint&#039;];&lt;br /&gt;
                }&lt;br /&gt;
                cmd.log(&#039;Fingerprint: &#039;+fingerprint);&lt;br /&gt;
                &lt;br /&gt;
                return {&lt;br /&gt;
                    certificate: {&lt;br /&gt;
                        cmd: &#039;X509/mod_cmd.xml?cmd=servercert-details&amp;amp;fingerprint=&#039;+fingerprint,&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    },&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Our goal is to check which key-length is used in the device certificate. But there i no direct command to get this information. So we have to do it in multipe steps.&lt;br /&gt;
&lt;br /&gt;
In this sample, we request the following in the commands object:&lt;br /&gt;
# Execute our command &amp;quot;certificates&amp;quot; on devices (pbx, gw, dect) the command &amp;quot;X509/mod_cmd.xml&amp;quot; which will give you back the xml payload of the page [[{{NAMESPACE}}:General/Certificates|Reference15r1:General/Certificates]]&lt;br /&gt;
# If the first request is done, the nested &amp;quot;commands&amp;quot; object should be called and we get the result from the first command&lt;br /&gt;
## Now, inside the function &amp;lt;code&amp;gt;commands: function(cmd, result) {&amp;lt;/code&amp;gt; we can use some free-style code to to what we need, to build a following command&lt;br /&gt;
## Here we convert xml to an object and extract the certificate fingerprint from the result of the first request&lt;br /&gt;
## then we return an object with &amp;quot;command-objects&amp;quot;&lt;br /&gt;
### think about that is possible to add an new &amp;lt;code&amp;gt;commands: function(cmd, result) {&amp;lt;/code&amp;gt; inside the return to add a new level :-)&lt;br /&gt;
## this second command will be executed to for every device and the xml payload contains the device certifcate of the current device. (like the popup in the UI if you click on a specific certificate)&lt;br /&gt;
#If all nested commands are processed, then your test() will be called, and you get all the results (in this case &amp;quot;certificates&amp;quot; and &amp;quot;certificate&amp;quot;) in the results-object&lt;br /&gt;
&lt;br /&gt;
====== example: nested commands-object which generates various commands from the first result ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
commands: {&lt;br /&gt;
	config: {&lt;br /&gt;
		cmd: &#039;cfg.txt&#039;,&lt;br /&gt;
		cat: [&#039;pbx&#039;],&lt;br /&gt;
		commands: function(cmd, result) {&lt;br /&gt;
			var lines = result.split(&amp;quot;\r\n&amp;quot;);&lt;br /&gt;
			var output = {};&lt;br /&gt;
			&lt;br /&gt;
			// get pbx loc&lt;br /&gt;
			var loc = false;&lt;br /&gt;
			for (var l = 0; l &amp;lt; lines.length; l++) {&lt;br /&gt;
				if (!lines[l].startsWith(&#039;config change PBX0&#039;)) continue; // skip non pbx line&lt;br /&gt;
				if (lines[l].includes(&#039;/mode standby&#039;)) continue; // skip slave pbxes&lt;br /&gt;
				&lt;br /&gt;
				var match = lines[l].match(/config change PBX0 (.*) \/loc ([^ ][^/]+)/);&lt;br /&gt;
				loc = match[2].substr(0, match[2].length-1);&lt;br /&gt;
				l = lines.length;&lt;br /&gt;
			}&lt;br /&gt;
			cmd.log(&#039;use pbx loc: &#039;+loc);&lt;br /&gt;
			&lt;br /&gt;
			// get user objects&lt;br /&gt;
			var regex = new RegExp(&#039;/\(loc=&#039;+loc+&#039;\)(.*)\(guid;bin=([0-9A-Za-z]+)\)/&#039;);&lt;br /&gt;
			for (var l = 0; l &amp;lt; lines.length; l++) {&lt;br /&gt;
				// skip if user is not from this pbx&lt;br /&gt;
				if (!lines[l].includes(&#039;(loc=&#039;+loc+&#039;)&#039;)) continue;&lt;br /&gt;
				&lt;br /&gt;
				var match = lines[l].match(/\(guid;bin=([0-9A-Za-z]+)\)/);&lt;br /&gt;
				if (!match) continue;&lt;br /&gt;
				cmd.log(&#039;user found: &#039;+match[1]);&lt;br /&gt;
				output[match[1]] = {cmd: &#039;PBX0/ADMIN/mod_cmd_login.xml?cmd=show&amp;amp;user-guid=&#039;+match[1]};&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			return output;&lt;br /&gt;
		}&lt;br /&gt;
	},&lt;br /&gt;
},&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Our goal is to get the xml output from the advanced ui for every pbx object. But there i no direct command to get this information. So we have to do it in multipe steps.&lt;br /&gt;
&lt;br /&gt;
In this sample, we request the following in the commands object:&lt;br /&gt;
# Execute our command &amp;quot;config&amp;quot; on PBXes the get the plain configuration file&lt;br /&gt;
# If the first request is done, the nested &amp;quot;commands&amp;quot; object should be called, and we get the result from the first command&lt;br /&gt;
## Now, inside the function &amp;lt;code&amp;gt;commands: function(cmd, result) {&amp;lt;/code&amp;gt; we can use some free-style code to do what we need, to build multiple following commands&lt;br /&gt;
&lt;br /&gt;
## Here we split the config file by lines breaks and iterate the whole config&lt;br /&gt;
## then we generate an empty return object to fill it later&lt;br /&gt;
### think about that is possible to add an new &amp;lt;code&amp;gt;commands: function(cmd, result) {&amp;lt;/code&amp;gt; inside the return to add a new level :-)&lt;br /&gt;
## If we have checked the pbx and the userobject we add with &amp;lt;code&amp;gt;output[match[1]] = {cmd: &#039;PBX0/ADMIN/mod_cmd_login.xml?cmd=show&amp;amp;user-guid=&#039;+match[1]};&amp;lt;/code&amp;gt; a specific command to the retunr value&lt;br /&gt;
&lt;br /&gt;
In the end, we have a big return object with multiple cmd&#039;s&lt;br /&gt;
In this case we will get all the results in the test() later and can do further stuff with the results.&lt;br /&gt;
&lt;br /&gt;
==== Executable method test() ====&lt;br /&gt;
The upper layer expects a method &amp;lt;code&amp;gt;test(cmd, results, storage)&amp;lt;/code&amp;gt; in your JavaScript object. This method has three parameters.&lt;br /&gt;
&lt;br /&gt;
;cmd&lt;br /&gt;
:An object that offers you a wide range of predefined functions and options. You can see it as a kind of library, which is documented at the [[#cmd object|cmd object]].&lt;br /&gt;
&lt;br /&gt;
;results&lt;br /&gt;
:An object of the results of your commands from the given &#039;&#039;command-objects&#039;&#039; in your test definition.&lt;br /&gt;
&amp;lt;spoiler show=&amp;quot;show sample strcuture of the results object&amp;quot; hide=&amp;quot;hide sample strcuture of the results object&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// structure of results object&lt;br /&gt;
{&lt;br /&gt;
  // your command is the property&lt;br /&gt;
  &#039;buffered_cdr0&#039; : {&lt;br /&gt;
    // the unique id of the device is the property&lt;br /&gt;
    &#039;1&#039;: &#039;QS messages: 0 max 2000 chars: 0 max 300000&#039;,&lt;br /&gt;
    &#039;4&#039;: &#039;QS messages: 0 max 2000 chars: 0 max 300000&#039;,&lt;br /&gt;
  },&lt;br /&gt;
  &#039;buffered_cdr1&#039; : {&lt;br /&gt;
    // the unique id of the device is the property&lt;br /&gt;
    &#039;1&#039;: &#039;QS messages: 0 max 2000 chars: 0 max 300000&#039;,&lt;br /&gt;
    &#039;4&#039;: &#039;QS messages: 0 max 2000 chars: 0 max 300000&#039;,&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/spoiler&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;spoiler show=&amp;quot;show best practice code to deal with the results object&amp;quot; hide=&amp;quot;hide best practice code to deal with the results object&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// you can use this inside your function &amp;quot;test: function (cmd, results, storage)&amp;quot; to iterate all commands over all affected devices&lt;br /&gt;
        &lt;br /&gt;
Object.keys(results).forEach(function(command) {&lt;br /&gt;
  log.push(&#039;command: &#039;+command);&lt;br /&gt;
  Object.keys(results[command]).forEach(function(device) {&lt;br /&gt;
    log.push(&#039;device: &#039;+device);&lt;br /&gt;
    var output = results[command][device];&lt;br /&gt;
  });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
// expected log array from the code above:&lt;br /&gt;
// $ command: buffered_cdr0&lt;br /&gt;
// $ device: 1&lt;br /&gt;
// $ device: 4&lt;br /&gt;
// $ command: buffered_cdr1&lt;br /&gt;
// $ device: 1&lt;br /&gt;
// $ device: 4&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/spoiler&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;storage&lt;br /&gt;
:If the test has written something to the test volatile memory during the last execution, you will get the last value back here. (Note that the storage is not available for one-time tests in the code editor. There you will always get an empty storage)&lt;br /&gt;
&lt;br /&gt;
===== return test result =====&lt;br /&gt;
Your test has to be return an object with your test result. The system expect an object with the following properties.&lt;br /&gt;
&lt;br /&gt;
; success&lt;br /&gt;
: boolean | indicates if your test was successful or not&lt;br /&gt;
; msg&lt;br /&gt;
: string | an optional short message that will be displayed in the UI as preview&lt;br /&gt;
; log&lt;br /&gt;
: array | an optional array with lines of logfile that you can use to display detailed information in the UI at your test result. Use &amp;lt;code&amp;gt;log.push()&amp;lt;/code&amp;gt; to fill up the logfile array. In the frontend, the log will be parsed and mac addresses &amp;lt;code&amp;gt;/(^|\W)([a-f0-9]{12})(\W|$)/i&amp;lt;/code&amp;gt; will be updated with an internal link to devices app. (If you want to create instead debug output to the app-instance logfile you can use &amp;lt;code&amp;gt;cmd.log()&amp;lt;/code&amp;gt;)&lt;br /&gt;
;storage&lt;br /&gt;
: string | an optional string, which can be json or similar, that is stored for this test. The next time the test is executed, the payload saved here is available inside the test again.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
test: function (cmd, results, storage) {&lt;br /&gt;
  // your stuff&lt;br /&gt;
  var count = 2;&lt;br /&gt;
 &lt;br /&gt;
  return {&lt;br /&gt;
    success: false,&lt;br /&gt;
    msg: &#039;There are &#039;+count+&#039; new/unassigned devices in your setup&#039;&lt;br /&gt;
  };&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== The full picture ====&lt;br /&gt;
===== Complete sample test to check buffered CDRs =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
tests_add.cdrs_buffered = tests_add.cdrs_buffered || {&lt;br /&gt;
    title: &#039;Buffered CDRs&#039;,&lt;br /&gt;
    description: &#039;This test will check if CDRs on a gateway was buffered and are not transmit to the CDR target yet&#039;,&lt;br /&gt;
    todo: &#039;Check the CDR target&#039;,&lt;br /&gt;
    author: &#039;slu@innovaphone.com&#039;,&lt;br /&gt;
    enabled: true,&lt;br /&gt;
    schedule: &#039;10m&#039;,&lt;br /&gt;
    &lt;br /&gt;
    commands: {&lt;br /&gt;
        cdr0: {&lt;br /&gt;
            cmd: &#039;!mod cmd CDR0 qs&#039;,&lt;br /&gt;
            cat: [&#039;gw&#039;],&lt;br /&gt;
        },&lt;br /&gt;
        cdr1: {&lt;br /&gt;
            cmd: &#039;!mod cmd CDR1 qs&#039;,&lt;br /&gt;
            cat: [&#039;gw&#039;],&lt;br /&gt;
        },&lt;br /&gt;
        cdr2: {&lt;br /&gt;
            cmd: &#039;!mod cmd CDR2 qs&#039;,&lt;br /&gt;
            cat: [&#039;gw&#039;],&lt;br /&gt;
        },&lt;br /&gt;
        cdr3: {&lt;br /&gt;
            cmd: &#039;!mod cmd CDR3 qs&#039;,&lt;br /&gt;
            cat: [&#039;gw&#039;],&lt;br /&gt;
        },&lt;br /&gt;
        cdr4: {&lt;br /&gt;
            cmd: &#039;!mod cmd CDR4 qs&#039;,&lt;br /&gt;
            cat: [&#039;gw&#039;],&lt;br /&gt;
        },&lt;br /&gt;
    },&lt;br /&gt;
    &lt;br /&gt;
    test: function (cmd, results, storage) {&lt;br /&gt;
        var log = [];&lt;br /&gt;
        var success = true;&lt;br /&gt;
        &lt;br /&gt;
        for (var n = 0; n &amp;lt; 5; n++) {&lt;br /&gt;
            Object.keys(results[&#039;cdr&#039;+n]).forEach(function(i){&lt;br /&gt;
                var check = calculate_cdrs(results[&#039;cdr&#039;+n][i]);&lt;br /&gt;
                // result was not good, lets create a human error message&lt;br /&gt;
                if (check !== true) {&lt;br /&gt;
                    log.push(cmd.get_device(i).product+&#039; / &#039;+cmd.get_device(i).hwId+&#039; / &#039;+check+&#039;% - &#039;+results[&#039;cdr&#039;+n][i]);&lt;br /&gt;
                    if (success) success = false;&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    &lt;br /&gt;
        return {&lt;br /&gt;
            success: success,&lt;br /&gt;
            msg: success ? &#039;&#039; : &#039;Devices with buffered CDRs exists&#039;,&lt;br /&gt;
            log: log&lt;br /&gt;
        };&lt;br /&gt;
    &lt;br /&gt;
        function calculate_cdrs(str) {&lt;br /&gt;
            // QS messages: 0 max 2000 chars: 0 max 300000&lt;br /&gt;
            var check = 0;&lt;br /&gt;
            str = str.split(&#039; &#039;);&lt;br /&gt;
            // log.push(str);&lt;br /&gt;
        &lt;br /&gt;
            var messages_current = str[2];&lt;br /&gt;
            var messages_max = str[4];&lt;br /&gt;
            var chars_current = str[6];&lt;br /&gt;
            var chars_max = str[8];&lt;br /&gt;
        &lt;br /&gt;
            // check messages&lt;br /&gt;
            check = cmd.percent(messages_current, messages_max);&lt;br /&gt;
            if (check &amp;gt;= 30) return check;&lt;br /&gt;
        &lt;br /&gt;
            // check chars&lt;br /&gt;
            check = cmd.percent(chars_current, chars_max);&lt;br /&gt;
            if (check &amp;gt;= 30) return check;&lt;br /&gt;
        &lt;br /&gt;
            return true;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Complete sample test to check firmware versions =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
tests_add.firmware_version = tests_add.firmware_version || {&lt;br /&gt;
    title: &#039;Supported firmware versions&#039;,&lt;br /&gt;
    description: &#039;Check if you have unsupported firmware version in use&#039;,&lt;br /&gt;
    todo: &#039;Update the firmware on affected devices&#039;,&lt;br /&gt;
    author: &#039;slu@innovaphone.com&#039;,&lt;br /&gt;
    schedule: &#039;1d&#039;,&lt;br /&gt;
    commands: {&lt;br /&gt;
        box_info: {&lt;br /&gt;
            cmd: &#039;CMD0/box_info.xml&#039;,&lt;br /&gt;
        },&lt;br /&gt;
    },&lt;br /&gt;
    &lt;br /&gt;
    test: function (cmd, results, storage) {&lt;br /&gt;
        var log = [];&lt;br /&gt;
        var success = true;&lt;br /&gt;
        var msg = &#039;&#039;;&lt;br /&gt;
        &lt;br /&gt;
        Object.keys(results.box_info).forEach(function(i){&lt;br /&gt;
            var xml = cmd.parse_xml(results.box_info[i]);&lt;br /&gt;
            if (typeof xml.info === &#039;undefined&#039;) return;&lt;br /&gt;
            if (typeof xml.info.sys === &#039;undefined&#039;) return;&lt;br /&gt;
            if (typeof xml.info.sys[&#039;@version&#039;] === &#039;undefined&#039;) return;&lt;br /&gt;
            &lt;br /&gt;
            if (&lt;br /&gt;
                xml.info.sys[&#039;@version&#039;].includes(&#039;6.00&#039;) ||&lt;br /&gt;
                xml.info.sys[&#039;@version&#039;].includes(&#039;7.00&#039;) ||&lt;br /&gt;
                xml.info.sys[&#039;@version&#039;].includes(&#039;8.00&#039;) ||&lt;br /&gt;
                xml.info.sys[&#039;@version&#039;].includes(&#039;9.00&#039;) ||&lt;br /&gt;
                xml.info.sys[&#039;@version&#039;].includes(&#039;10.00&#039;) ||&lt;br /&gt;
                xml.info.sys[&#039;@version&#039;].includes(&#039;11.00&#039;) ||&lt;br /&gt;
                xml.info.sys[&#039;@version&#039;].includes(&#039;11r1&#039;) ||&lt;br /&gt;
                xml.info.sys[&#039;@version&#039;].includes(&#039;12r1&#039;) ||&lt;br /&gt;
                xml.info.sys[&#039;@version&#039;].includes(&#039;13r1&#039;)&lt;br /&gt;
            ) {&lt;br /&gt;
                log.push(cmd.get_device(i).product+&#039; / &#039;+cmd.get_device(i).hwId+&#039; / &#039;+xml.info.sys[&#039;@version&#039;]);&lt;br /&gt;
                if (success) success = false;&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
        &lt;br /&gt;
        return {&lt;br /&gt;
            success: success,&lt;br /&gt;
            msg: success ? &#039;&#039; : &#039;You use old firmware which is no longer be supported&#039;,&lt;br /&gt;
            log: log&lt;br /&gt;
        };&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== cmd object ====&lt;br /&gt;
The &#039;&#039;&#039;cmd&#039;&#039;&#039; object provides you the following methods:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== get device information / system information =====&lt;br /&gt;
&lt;br /&gt;
====== get_build() : object ======&lt;br /&gt;
You will receive back the current version build of the app&lt;br /&gt;
&lt;br /&gt;
&amp;lt;spoiler show=&amp;quot;show sample code&amp;quot; hide=&amp;quot;hide sample code&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var build = cmd.get_build();&lt;br /&gt;
console.log(build);&lt;br /&gt;
// 15012456&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/spoiler&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== get_domains() : object ======&lt;br /&gt;
You will receive all existing domains&lt;br /&gt;
&lt;br /&gt;
&amp;lt;spoiler show=&amp;quot;show sample code&amp;quot; hide=&amp;quot;hide sample code&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var domains = cmd.get_domains();&lt;br /&gt;
console.log(domains);&lt;br /&gt;
{&lt;br /&gt;
 &amp;quot;1&amp;quot;: {&lt;br /&gt;
   &amp;quot;id&amp;quot;: 1,&lt;br /&gt;
   &amp;quot;name&amp;quot;: &amp;quot;slu.de&amp;quot;,&lt;br /&gt;
   &amp;quot;deployAdminPasswords&amp;quot;: true,&lt;br /&gt;
   &amp;quot;isInstanceDomain&amp;quot;: true,&lt;br /&gt;
   &amp;quot;categories&amp;quot;: [ ... ]&lt;br /&gt;
 }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/spoiler&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== get_devices() : object ======&lt;br /&gt;
You will receive all existing devices&lt;br /&gt;
&lt;br /&gt;
&amp;lt;spoiler show=&amp;quot;show sample code&amp;quot; hide=&amp;quot;hide sample code&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var devices = cmd.get_devices();&lt;br /&gt;
console.log(devices);&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;0_009033420623&amp;quot;: {&lt;br /&gt;
    &amp;quot;id&amp;quot;: &amp;quot;0_009033420623&amp;quot;,&lt;br /&gt;
    &amp;quot;hwId&amp;quot;: &amp;quot;009033420623&amp;quot;,&lt;br /&gt;
    &amp;quot;domainId&amp;quot;: 0,&lt;br /&gt;
    &amp;quot;product&amp;quot;: &amp;quot;IP0011&amp;quot;,&lt;br /&gt;
    &amp;quot;version&amp;quot;: &amp;quot;13r3 dvl [13.7526/132035/600]&amp;quot;,&lt;br /&gt;
    &amp;quot;type&amp;quot;: &amp;quot;GW&amp;quot;,&lt;br /&gt;
    &amp;quot;pbxActive&amp;quot;: false,&lt;br /&gt;
    &amp;quot;online&amp;quot;: true,&lt;br /&gt;
    &amp;quot;ethIfs&amp;quot;: [ ... ]&lt;br /&gt;
  },&lt;br /&gt;
  &amp;quot;1&amp;quot;: {&lt;br /&gt;
    &amp;quot;id&amp;quot;: 1,&lt;br /&gt;
    &amp;quot;hwId&amp;quot;: &amp;quot;009033420621&amp;quot;,&lt;br /&gt;
    &amp;quot;name&amp;quot;: &amp;quot;PBX - pbx.slu.de&amp;quot;,&lt;br /&gt;
    &amp;quot;domainId&amp;quot;: 1,&lt;br /&gt;
    &amp;quot;product&amp;quot;: &amp;quot;IP0011&amp;quot;,&lt;br /&gt;
    &amp;quot;version&amp;quot;: &amp;quot;13r3 beta4 [13.7688/137623/600]&amp;quot;,&lt;br /&gt;
    &amp;quot;type&amp;quot;: &amp;quot;GW&amp;quot;,&lt;br /&gt;
    &amp;quot;pbxActive&amp;quot;: true,&lt;br /&gt;
    &amp;quot;online&amp;quot;: true,&lt;br /&gt;
    &amp;quot;ethIfs&amp;quot;: [ ... ]&lt;br /&gt;
  },&lt;br /&gt;
  &amp;quot;2&amp;quot;: {&lt;br /&gt;
    &amp;quot;id&amp;quot;: 2,&lt;br /&gt;
    &amp;quot;hwId&amp;quot;: &amp;quot;029033420621&amp;quot;,&lt;br /&gt;
    &amp;quot;name&amp;quot;: &amp;quot;AP - apps.slu.de&amp;quot;,&lt;br /&gt;
    &amp;quot;domainId&amp;quot;: 1,&lt;br /&gt;
    &amp;quot;product&amp;quot;: &amp;quot;AppPlatform ARM&amp;quot;,&lt;br /&gt;
    &amp;quot;version&amp;quot;: &amp;quot;110002 dvl (13r3 137688 beta4 )&amp;quot;,&lt;br /&gt;
    &amp;quot;type&amp;quot;: &amp;quot;APP_PLATFORM&amp;quot;,&lt;br /&gt;
    &amp;quot;pbxActive&amp;quot;: false,&lt;br /&gt;
    &amp;quot;online&amp;quot;: true,&lt;br /&gt;
    &amp;quot;ethIfs&amp;quot;: [ ... ]&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/spoiler&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== get_devices_from_domain(int id) : object ======&lt;br /&gt;
You will receive all devices which are assigned to the given domain&lt;br /&gt;
&lt;br /&gt;
&amp;lt;spoiler show=&amp;quot;show sample code&amp;quot; hide=&amp;quot;hide sample code&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var devices = cmd.get_devices_from_domain(1);&lt;br /&gt;
console.log(devices);&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;1&amp;quot;: {&lt;br /&gt;
    &amp;quot;id&amp;quot;: 1,&lt;br /&gt;
    &amp;quot;hwId&amp;quot;: &amp;quot;009033420621&amp;quot;,&lt;br /&gt;
    &amp;quot;name&amp;quot;: &amp;quot;PBX - pbx.slu.de&amp;quot;,&lt;br /&gt;
    &amp;quot;domainId&amp;quot;: 1,&lt;br /&gt;
    &amp;quot;product&amp;quot;: &amp;quot;IP0011&amp;quot;,&lt;br /&gt;
    &amp;quot;version&amp;quot;: &amp;quot;13r3 beta4 [13.7688/137623/600]&amp;quot;,&lt;br /&gt;
    &amp;quot;type&amp;quot;: &amp;quot;GW&amp;quot;,&lt;br /&gt;
    &amp;quot;pbxActive&amp;quot;: true,&lt;br /&gt;
    &amp;quot;online&amp;quot;: true,&lt;br /&gt;
    &amp;quot;ethIfs&amp;quot;: [ ... ]&lt;br /&gt;
  },&lt;br /&gt;
  &amp;quot;2&amp;quot;: {&lt;br /&gt;
    &amp;quot;id&amp;quot;: 2,&lt;br /&gt;
    &amp;quot;hwId&amp;quot;: &amp;quot;029033420621&amp;quot;,&lt;br /&gt;
    &amp;quot;name&amp;quot;: &amp;quot;AP - apps.slu.de&amp;quot;,&lt;br /&gt;
    &amp;quot;domainId&amp;quot;: 1,&lt;br /&gt;
    &amp;quot;product&amp;quot;: &amp;quot;AppPlatform ARM&amp;quot;,&lt;br /&gt;
    &amp;quot;version&amp;quot;: &amp;quot;110002 dvl (13r3 137688 beta4 )&amp;quot;,&lt;br /&gt;
    &amp;quot;type&amp;quot;: &amp;quot;APP_PLATFORM&amp;quot;,&lt;br /&gt;
    &amp;quot;pbxActive&amp;quot;: false,&lt;br /&gt;
    &amp;quot;online&amp;quot;: true,&lt;br /&gt;
    &amp;quot;ethIfs&amp;quot;: [ ... ]&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/spoiler&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== get_device(int id) : object ======&lt;br /&gt;
You will receive a specific device&lt;br /&gt;
&lt;br /&gt;
&amp;lt;spoiler show=&amp;quot;show sample code&amp;quot; hide=&amp;quot;hide sample code&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var device = cmd.get_device(2);&lt;br /&gt;
console.log(device);&lt;br /&gt;
{&lt;br /&gt;
   &amp;quot;id&amp;quot;: 2,&lt;br /&gt;
   &amp;quot;hwId&amp;quot;: &amp;quot;029033420621&amp;quot;,&lt;br /&gt;
   &amp;quot;name&amp;quot;: &amp;quot;AP - apps.slu.de&amp;quot;,&lt;br /&gt;
   &amp;quot;domainId&amp;quot;: 1,&lt;br /&gt;
   &amp;quot;product&amp;quot;: &amp;quot;AppPlatform ARM&amp;quot;,&lt;br /&gt;
   &amp;quot;version&amp;quot;: &amp;quot;110002 dvl (13r3 137688 beta4 )&amp;quot;,&lt;br /&gt;
   &amp;quot;type&amp;quot;: &amp;quot;APP_PLATFORM&amp;quot;,&lt;br /&gt;
   &amp;quot;pbxActive&amp;quot;: false,&lt;br /&gt;
   &amp;quot;online&amp;quot;: true,&lt;br /&gt;
   &amp;quot;ethIfs&amp;quot;: [ ... ]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/spoiler&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== helper functions =====&lt;br /&gt;
&lt;br /&gt;
====== percent(int value, int total) : float ======&lt;br /&gt;
Returns the number of percent of value to total&lt;br /&gt;
&lt;br /&gt;
&amp;lt;spoiler show=&amp;quot;show sample code&amp;quot; hide=&amp;quot;hide sample code&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var check = cmd.percent(50, 100);&lt;br /&gt;
console.log(check);&lt;br /&gt;
50&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/spoiler&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== parse_xml(string xml, string element = &amp;lt;nowiki&amp;gt;&#039;&#039;&amp;lt;/nowiki&amp;gt;) : object ======&lt;br /&gt;
Returns an object/array representation of given XML string. Note that very large XML inputs cannot be converted directly because there are some restrictions in the duktape environment. If you receive an exception with &#039;&#039;Error: RangeError: regexp executor recursion limit&#039;&#039; you have to define which element do you want to converted (See the second example).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;spoiler show=&amp;quot;show sample code&amp;quot; hide=&amp;quot;hide sample code&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var json = cmd.parse_xml(&#039;&amp;lt;sample&amp;gt;&amp;lt;item property_1=&amp;quot;value_1&amp;quot; property_2=&amp;quot;value_2&amp;quot;&amp;gt;content of item&amp;lt;/item&amp;gt;&amp;lt;item_short prop_1=&amp;quot;value_prop_1&amp;quot; /&amp;gt;&amp;lt;/sample&amp;gt;&#039;);&lt;br /&gt;
console.log(json);&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;sample&amp;quot;: {&lt;br /&gt;
    &amp;quot;item&amp;quot;: {&lt;br /&gt;
      &amp;quot;@property_1&amp;quot;: &amp;quot;value_1&amp;quot;,&lt;br /&gt;
      &amp;quot;@property_2&amp;quot;: &amp;quot;value_2&amp;quot;,&lt;br /&gt;
      &amp;quot;#&amp;quot;: &amp;quot;content of item&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    &amp;quot;item_short&amp;quot;: {&lt;br /&gt;
      &amp;quot;@prop_1&amp;quot;: &amp;quot;value_prop_1&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/spoiler&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;spoiler show=&amp;quot;show sample code with large xml payload&amp;quot; hide=&amp;quot;hide sample code with large xml payload&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
var xml_registrations_on_big_pbx = &#039;\&lt;br /&gt;
  &amp;lt;show state=&amp;quot;up&amp;quot; time=&amp;quot;267993&amp;quot; loc=&amp;quot;pbx&amp;quot;&amp;gt;\&lt;br /&gt;
    &amp;lt;attrs&amp;gt;&amp;lt;/attrs&amp;gt;\&lt;br /&gt;
    &amp;lt;reg cn=&amp;quot;Fax&amp;quot; guid=&amp;quot;829a6aeec2a76401c62600155d50c817&amp;quot; h323=&amp;quot;fax&amp;quot; pwd=&amp;quot;********&amp;quot; pwdx=&amp;quot;********&amp;quot; prot=&amp;quot;JSON&amp;quot;&amp;gt;\&lt;br /&gt;
      &amp;lt;ep type=&amp;quot;gk&amp;quot; addr=&amp;quot;172.16.176.205&amp;quot; time=&amp;quot;10&amp;quot;/&amp;gt;\&lt;br /&gt;
      &amp;lt;pseudo-common lics=&amp;quot;.reporting.&amp;quot;/&amp;gt;\&lt;br /&gt;
      &amp;lt;pseudo type=&amp;quot;fax&amp;quot;/&amp;gt;\&lt;br /&gt;
    &amp;lt;/reg&amp;gt;\&lt;br /&gt;
    &amp;lt;reg cn=&amp;quot;Voicemail de&amp;quot; guid=&amp;quot;5ceb0ee7c2a76401bb2600155d50c817&amp;quot; h323=&amp;quot;voicemail-de&amp;quot; pwd=&amp;quot;********&amp;quot; pwdx=&amp;quot;********&amp;quot; prot=&amp;quot;JSON&amp;quot;&amp;gt;\&lt;br /&gt;
      &amp;lt;ep type=&amp;quot;gk&amp;quot; addr=&amp;quot;172.16.176.205&amp;quot; time=&amp;quot;10&amp;quot;/&amp;gt;\&lt;br /&gt;
      &amp;lt;pseudo-common lics=&amp;quot;.uc.voicemail.reporting.&amp;quot;/&amp;gt;\&lt;br /&gt;
      &amp;lt;pseudo type=&amp;quot;vm&amp;quot;/&amp;gt;\&lt;br /&gt;
    &amp;lt;/reg&amp;gt;\&lt;br /&gt;
    ... and so on ...\&lt;br /&gt;
  &amp;lt;/show&amp;gt;&#039;;&lt;br /&gt;
var json = cmd.parse_xml(xml_registrations_on_big_pbx, &#039;reg&#039;);&lt;br /&gt;
console.log(json);&lt;br /&gt;
[&lt;br /&gt;
  {&amp;quot;@cn&amp;quot;:&amp;quot;Fax&amp;quot;, &amp;quot;@guid&amp;quot;:&amp;quot;829a6aeec2a76401c62600155d50c817&amp;quot;, ... &amp;quot;ep&amp;quot;:{&amp;quot;@type&amp;quot;:&amp;quot;gk&amp;quot;,&amp;quot;@addr&amp;quot;:&amp;quot;172.16.176.205&amp;quot;,&amp;quot;@time&amp;quot;:&amp;quot;10&amp;quot;}, ...},&lt;br /&gt;
  {&amp;quot;@cn&amp;quot;:&amp;quot;Voicemail&amp;quot;, &amp;quot;@guid&amp;quot;:&amp;quot;5ceb0ee7c2a76401bb2600155d50c817&amp;quot;, ... &amp;quot;ep&amp;quot;:{&amp;quot;@type&amp;quot;:&amp;quot;gk&amp;quot;,&amp;quot;@addr&amp;quot;:&amp;quot;172.16.176.205&amp;quot;,&amp;quot;@time&amp;quot;:&amp;quot;10&amp;quot;}, ...},&lt;br /&gt;
  ...&lt;br /&gt;
]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/spoiler&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== is_supported_version(string version) : object ======&lt;br /&gt;
Return if the given Version string is supported according to [[Howto:Supported innovaphone versions]].&lt;br /&gt;
&amp;lt;spoiler show=&amp;quot;show sample code&amp;quot; hide=&amp;quot;hide sample code&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
cmd.is_supported_version(&#039;13r3 sr9 [13.7886/1000/0]&#039;); // return &amp;quot;true&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/spoiler&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== get_version_from_build(int build) : string ======&lt;br /&gt;
Return the named version from given build number. (13r3, 14r1 or similar)&lt;br /&gt;
&amp;lt;spoiler show=&amp;quot;show sample code&amp;quot; hide=&amp;quot;hide sample code&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
cmd.get_version_from_build(1410485); // return &amp;quot;14r1&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/spoiler&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== get_pbx_objects_from_config(string config) : array =====&lt;br /&gt;
Extract from a config file PBX Objects with support for different views, DynPBXes and the removal of marks-as-deleted objects&lt;br /&gt;
&amp;lt;spoiler show=&amp;quot;show sample code&amp;quot; hide=&amp;quot;hide sample code&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// &amp;quot;config&amp;quot; contains the result from your &amp;quot;cfg.txt&amp;quot;&lt;br /&gt;
cmd.get_pbx_objects_from_config(config); &lt;br /&gt;
// return &lt;br /&gt;
[&lt;br /&gt;
   &amp;quot;mod cmd FLASHDIR0 add-item 102 (cn=user-1)(h323=user-1)(e164=10)&amp;quot;,&lt;br /&gt;
   &amp;quot;mod cmd FLASHDIR0 add-item 102 (cn=user-2)(h323=user-2)(e164=20)&amp;quot;,&lt;br /&gt;
   &amp;quot;mod cmd FLASHDIR0 add-item 105 (cn=user-1-in-dynpbx)(h323=user-1-in-dynpbx)(e164=50)&amp;quot;,&lt;br /&gt;
]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/spoiler&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== debug =====&lt;br /&gt;
&lt;br /&gt;
====== log(string message) : void ======&lt;br /&gt;
You can write a logfile line to the app debug log&lt;br /&gt;
&lt;br /&gt;
&amp;lt;spoiler show=&amp;quot;show sample code&amp;quot; hide=&amp;quot;hide sample code&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var domains = cmd.log(&#039;my first logfile line&#039;);&lt;br /&gt;
07-26 07:58:33.179 TechAssist@slu.de (b0728708) | Test &amp;quot;sample_test&amp;quot; | my first logfile line&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/spoiler&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Secret knowledge for good tests ===&lt;br /&gt;
; use &amp;quot;get_pbx_objects_from_config()&amp;quot; to get Objects from PBX config&lt;br /&gt;
: To really get all the required objects (dyn PBXes, different views, deleted objects), there are a few things to consider. It is therefore advisable to always use this function in a test.&lt;br /&gt;
; bool PBX-Object config attributes&lt;br /&gt;
: You will find config attributes like &amp;lt;code&amp;gt;no-subscribe=&amp;quot;true&amp;quot;&amp;lt;/code&amp;gt; (this is from a Trunk Object) in the config. Please note that if the attribute is &#039;&#039;missing&#039;&#039; or the value is &#039;&#039;false&#039;&#039; it is false, otherwise it is &#039;&#039;true&#039;&#039;. For example, the value &amp;lt;code&amp;gt;no-subscribe=&amp;quot;on&amp;quot;&amp;lt;/code&amp;gt; is also true.&lt;br /&gt;
; bool Interface config attributes&lt;br /&gt;
: You will find config attributes like &amp;lt;code&amp;gt;/direct-sig on&amp;lt;/code&amp;gt; (this is from a SIP interface) in the config. Please note that they are exists bool-attribute which are &#039;&#039;true&#039;&#039; if the attribute is existing. In the case of bool-attribute the following value make no matter. For example, the attribute &amp;lt;code&amp;gt;/direct-sig off&amp;lt;/code&amp;gt; is also true.&lt;br /&gt;
&lt;br /&gt;
== Monitoring ==&lt;br /&gt;
The App supports a monitoring interface where well known IT-Monitoring Systems or other Statistics Services can connect and collect various data for the whole innovaphone installation.&lt;br /&gt;
&lt;br /&gt;
===Requirements===&lt;br /&gt;
* Only devices that are known by the &#039;&#039;Devices App&#039;&#039; will be included in the monitoring data&lt;br /&gt;
* Only devices that have a non-empty &amp;quot;Name&amp;quot; in the &#039;&#039;Devices App&#039;&#039; will be included in the monitoring data&lt;br /&gt;
* Depending on your monitoring system (to support the automatic host matching magic) it can be needed that all devices has the same &#039;&#039;Name&#039;&#039; in your &#039;&#039;Devices App&#039;&#039; and your external System (Usually the FQDN is used)&lt;br /&gt;
&lt;br /&gt;
===Configurations===&lt;br /&gt;
* In the Techassist Plugin in Settings (former PBX Manager), you have to configure the credentials for the HTTP authorization to get monitoring data&lt;br /&gt;
* In the TechAssist App in the settings area, you have to:&lt;br /&gt;
** enable/disable the whole monitoring feature. Default is disabled.&lt;br /&gt;
** select categories (PBXes, Gateways, AP Platforms, Apps, DECT, Phones) which should be included in the monitoring data&lt;br /&gt;
* For all app services that provide statistics, the TechAssist app object must have access rights to these apps (the apps must be checked in the &amp;quot;Apps&amp;quot; tab of the PBX object)&lt;br /&gt;
** All Metrics will be placed (in the monitoring output) at the AP where TechAssist is running&lt;br /&gt;
&lt;br /&gt;
===Internal Timers===&lt;br /&gt;
*The data for monitoring systems will be updated every 15 minutes by default. You can adjust this timer in the App Settings.&lt;br /&gt;
*App Metrics will be updated every 1 minute internally&lt;br /&gt;
*App Metrics for the TechAssist itself always have live values&lt;br /&gt;
&lt;br /&gt;
=== HTTP Response Codes ===&lt;br /&gt;
&lt;br /&gt;
* 501 - Monitoring feature is disabled...&lt;br /&gt;
* 503 - Service is starting... | You have to try it again later. The app service is starting.&lt;br /&gt;
* 503 - Data will be collected... | You have to try it again later. The first bunch of data will be collected at this moment.&lt;br /&gt;
&lt;br /&gt;
===Internal Cached Monitoring Data===&lt;br /&gt;
The monitoring data is cached internally. After starting the app, no monitoring data is processed at all to save resources if this function is not used.&lt;br /&gt;
If the first call is made to an interface, the data is prepared in Background and you will get a &amp;quot;503 - Data will be collected...&amp;quot;. This means that the first call fails. From then on, the app knows that monitoring data is being retrieved and prepares the data in a 1-minute interval so that a call to the monitoring system receives the cached data.&lt;br /&gt;
&lt;br /&gt;
===Supported Integrations===&lt;br /&gt;
We support various output formats over different interfaces. Your System can pull the information and append in the needed Interface/Format to the URL. &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Example: https://apps.slu.de/slu.de/techassist/monitoring/JSON (Here is &amp;quot;JSON&amp;quot; the used interface, see below)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you use an old/legacy system that only support http basic-auth instead of digest-auth you can add a &amp;quot;/basic&amp;quot; to the endpoint url. &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Example: https://&amp;lt;/nowiki&amp;gt;apps.slu.de/slu.de/techassist&#039;&#039;&#039;/basic&#039;&#039;&#039;/monitoring/JSON&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== RAW ====&lt;br /&gt;
The interface &amp;quot;/RAW&amp;quot; provides the internal TechAssist format as JSON.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;spoiler show=&amp;quot;show sample output&amp;quot; hide=&amp;quot;hide sample output&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
[&lt;br /&gt;
  {&lt;br /&gt;
    &amp;quot;id&amp;quot;: &amp;quot;1&amp;quot;,&lt;br /&gt;
    &amp;quot;title&amp;quot;: &amp;quot;pbx.domain.de&amp;quot;,&lt;br /&gt;
    &amp;quot;metrics&amp;quot;: [&lt;br /&gt;
      {&lt;br /&gt;
        &amp;quot;id&amp;quot;: &amp;quot;online&amp;quot;,&lt;br /&gt;
        &amp;quot;value&amp;quot;: 1,&lt;br /&gt;
        &amp;quot;valuePercent&amp;quot;: null,&lt;br /&gt;
        &amp;quot;comment&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
        &amp;quot;min&amp;quot;: null,&lt;br /&gt;
        &amp;quot;max&amp;quot;: null&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        &amp;quot;id&amp;quot;: &amp;quot;serialnumber&amp;quot;,&lt;br /&gt;
        &amp;quot;value&amp;quot;: &amp;quot;005056001338&amp;quot;,&lt;br /&gt;
        &amp;quot;valuePercent&amp;quot;: null,&lt;br /&gt;
        &amp;quot;comment&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
        &amp;quot;min&amp;quot;: null,&lt;br /&gt;
        &amp;quot;max&amp;quot;: null&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        &amp;quot;id&amp;quot;: &amp;quot;product&amp;quot;,&lt;br /&gt;
        &amp;quot;value&amp;quot;: &amp;quot;IPVA&amp;quot;,&lt;br /&gt;
        &amp;quot;valuePercent&amp;quot;: null,&lt;br /&gt;
        &amp;quot;comment&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
        &amp;quot;min&amp;quot;: null,&lt;br /&gt;
        &amp;quot;max&amp;quot;: null&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        &amp;quot;id&amp;quot;: &amp;quot;version&amp;quot;,&lt;br /&gt;
        &amp;quot;value&amp;quot;: &amp;quot;15r1 dvl [15.1.0130/1000/0]&amp;quot;,&lt;br /&gt;
        &amp;quot;valuePercent&amp;quot;: null,&lt;br /&gt;
        &amp;quot;comment&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
        &amp;quot;min&amp;quot;: null,&lt;br /&gt;
        &amp;quot;max&amp;quot;: null&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        &amp;quot;id&amp;quot;: &amp;quot;versionIsSupported&amp;quot;,&lt;br /&gt;
        &amp;quot;value&amp;quot;: 1,&lt;br /&gt;
        &amp;quot;valuePercent&amp;quot;: null,&lt;br /&gt;
        &amp;quot;comment&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
        &amp;quot;min&amp;quot;: null,&lt;br /&gt;
        &amp;quot;max&amp;quot;: null&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        &amp;quot;id&amp;quot;: &amp;quot;uptime&amp;quot;,&lt;br /&gt;
        &amp;quot;value&amp;quot;: 2747,&lt;br /&gt;
        &amp;quot;valuePercent&amp;quot;: null,&lt;br /&gt;
        &amp;quot;comment&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
        &amp;quot;min&amp;quot;: null,&lt;br /&gt;
        &amp;quot;max&amp;quot;: null&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        &amp;quot;id&amp;quot;: &amp;quot;CPU&amp;quot;,&lt;br /&gt;
        &amp;quot;value&amp;quot;: 1,&lt;br /&gt;
        &amp;quot;valuePercent&amp;quot;: 1,&lt;br /&gt;
        &amp;quot;comment&amp;quot;: null,&lt;br /&gt;
        &amp;quot;min&amp;quot;: 0,&lt;br /&gt;
        &amp;quot;max&amp;quot;: 100&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        &amp;quot;id&amp;quot;: &amp;quot;CPU-R&amp;quot;,&lt;br /&gt;
        &amp;quot;value&amp;quot;: 0,&lt;br /&gt;
        &amp;quot;valuePercent&amp;quot;: 0,&lt;br /&gt;
        &amp;quot;comment&amp;quot;: null,&lt;br /&gt;
        &amp;quot;min&amp;quot;: 0,&lt;br /&gt;
        &amp;quot;max&amp;quot;: 26000&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        &amp;quot;id&amp;quot;: &amp;quot;MEM&amp;quot;,&lt;br /&gt;
        &amp;quot;value&amp;quot;: 46,&lt;br /&gt;
        &amp;quot;valuePercent&amp;quot;: 0.09,&lt;br /&gt;
        &amp;quot;comment&amp;quot;: null,&lt;br /&gt;
        &amp;quot;min&amp;quot;: 0,&lt;br /&gt;
        &amp;quot;max&amp;quot;: 49793&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        &amp;quot;id&amp;quot;: &amp;quot;ETH0&amp;quot;,&lt;br /&gt;
        &amp;quot;value&amp;quot;: 10,&lt;br /&gt;
        &amp;quot;valuePercent&amp;quot;: 0,&lt;br /&gt;
        &amp;quot;comment&amp;quot;: null,&lt;br /&gt;
        &amp;quot;min&amp;quot;: 0,&lt;br /&gt;
        &amp;quot;max&amp;quot;: 1000000&lt;br /&gt;
      }&lt;br /&gt;
    ]&lt;br /&gt;
  },&lt;br /&gt;
  {&lt;br /&gt;
    &amp;quot;id&amp;quot;: &amp;quot;47&amp;quot;,&lt;br /&gt;
    &amp;quot;title&amp;quot;: &amp;quot;ap.domain.de&amp;quot;,&lt;br /&gt;
    &amp;quot;metrics&amp;quot;: [&lt;br /&gt;
      {&lt;br /&gt;
        &amp;quot;id&amp;quot;: &amp;quot;online&amp;quot;,&lt;br /&gt;
        &amp;quot;value&amp;quot;: 1,&lt;br /&gt;
        &amp;quot;valuePercent&amp;quot;: null,&lt;br /&gt;
        &amp;quot;comment&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
        &amp;quot;min&amp;quot;: null,&lt;br /&gt;
        &amp;quot;max&amp;quot;: null&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        &amp;quot;id&amp;quot;: &amp;quot;serialnumber&amp;quot;,&lt;br /&gt;
        &amp;quot;value&amp;quot;: &amp;quot;00155db3c306&amp;quot;,&lt;br /&gt;
        &amp;quot;valuePercent&amp;quot;: null,&lt;br /&gt;
        &amp;quot;comment&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
        &amp;quot;min&amp;quot;: null,&lt;br /&gt;
        &amp;quot;max&amp;quot;: null&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        &amp;quot;id&amp;quot;: &amp;quot;product&amp;quot;,&lt;br /&gt;
        &amp;quot;value&amp;quot;: &amp;quot;AppPlatform x86_64&amp;quot;,&lt;br /&gt;
        &amp;quot;valuePercent&amp;quot;: null,&lt;br /&gt;
        &amp;quot;comment&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
        &amp;quot;min&amp;quot;: null,&lt;br /&gt;
        &amp;quot;max&amp;quot;: null&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        &amp;quot;id&amp;quot;: &amp;quot;version&amp;quot;,&lt;br /&gt;
        &amp;quot;value&amp;quot;: &amp;quot;120010  (15r1 1510130 dvl )&amp;quot;,&lt;br /&gt;
        &amp;quot;valuePercent&amp;quot;: null,&lt;br /&gt;
        &amp;quot;comment&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
        &amp;quot;min&amp;quot;: null,&lt;br /&gt;
        &amp;quot;max&amp;quot;: null&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        &amp;quot;id&amp;quot;: &amp;quot;versionIsSupported&amp;quot;,&lt;br /&gt;
        &amp;quot;value&amp;quot;: 1,&lt;br /&gt;
        &amp;quot;valuePercent&amp;quot;: null,&lt;br /&gt;
        &amp;quot;comment&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
        &amp;quot;min&amp;quot;: null,&lt;br /&gt;
        &amp;quot;max&amp;quot;: null&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;&amp;quot;&lt;br /&gt;
    ]&lt;br /&gt;
  }&lt;br /&gt;
]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/spoiler&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== CSV ====&lt;br /&gt;
The interface &amp;quot;/CSV&amp;quot; provides a simple text based comma separated structure.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;spoiler show=&amp;quot;show sample output&amp;quot; hide=&amp;quot;hide sample output&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;Hostname&amp;gt;;&amp;lt;Metric&amp;gt;;&amp;lt;Value&amp;gt;;&amp;lt;Result&amp;gt;;&amp;lt;Comment&amp;gt;&lt;br /&gt;
pbx.domain.de;&amp;quot;online&amp;quot;;true;&lt;br /&gt;
pbx.domain.de;&amp;quot;serialnumber&amp;quot;;005056001338;&lt;br /&gt;
pbx.domain.de;&amp;quot;product&amp;quot;;IPVA;&lt;br /&gt;
pbx.domain.de;&amp;quot;version&amp;quot;;15r1 dvl [15.1.0130/1000/0];&lt;br /&gt;
pbx.domain.de;&amp;quot;versionIsSupported&amp;quot;;true;&lt;br /&gt;
pbx.domain.de;&amp;quot;uptime&amp;quot;;3050;&lt;br /&gt;
pbx.domain.de;&amp;quot;CPU&amp;quot;;2;null&lt;br /&gt;
pbx.domain.de;&amp;quot;CPU-R&amp;quot;;0;null&lt;br /&gt;
pbx.domain.de;&amp;quot;MEM&amp;quot;;0.09;null&lt;br /&gt;
pbx.domain.de;&amp;quot;ETH0&amp;quot;;18;null&lt;br /&gt;
ap.domain.de;&amp;quot;online&amp;quot;;true;&lt;br /&gt;
ap.domain.de;&amp;quot;serialnumber&amp;quot;;00155db3c306;&lt;br /&gt;
ap.domain.de;&amp;quot;product&amp;quot;;AppPlatform x86_64;&lt;br /&gt;
ap.domain.de;&amp;quot;version&amp;quot;;120010  (15r1 1510130 dvl );&lt;br /&gt;
ap.domain.de;&amp;quot;versionIsSupported&amp;quot;;true;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/spoiler&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== JSON ====&lt;br /&gt;
The interface &amp;quot;/JSON&amp;quot; provides a JSON formatted structure.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;spoiler show=&amp;quot;show sample output&amp;quot; hide=&amp;quot;hide sample output&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;pbx.domain.de&amp;quot;: [&lt;br /&gt;
    {&amp;quot;device&amp;quot;:&amp;quot;pbx.domain.de&amp;quot;,&amp;quot;metric&amp;quot;:&amp;quot;online&amp;quot;,&amp;quot;value&amp;quot;:&amp;quot;true&amp;quot;,&amp;quot;result&amp;quot;:true&amp;quot;comment&amp;quot;:&amp;quot;&amp;quot;},&lt;br /&gt;
    {&amp;quot;device&amp;quot;:&amp;quot;pbx.domain.de&amp;quot;,&amp;quot;metric&amp;quot;:&amp;quot;serialnumber&amp;quot;,&amp;quot;value&amp;quot;:005056001338,&amp;quot;comment&amp;quot;:&amp;quot;&amp;quot;},&lt;br /&gt;
    {&amp;quot;device&amp;quot;:&amp;quot;pbx.domain.de&amp;quot;,&amp;quot;metric&amp;quot;:&amp;quot;product&amp;quot;,&amp;quot;value&amp;quot;:IPVA,&amp;quot;comment&amp;quot;:&amp;quot;&amp;quot;},&lt;br /&gt;
    {&amp;quot;device&amp;quot;:&amp;quot;pbx.domain.de&amp;quot;,&amp;quot;metric&amp;quot;:&amp;quot;version&amp;quot;,&amp;quot;value&amp;quot;:15r1 dvl [15.1.0130/1000/0],&amp;quot;comment&amp;quot;:&amp;quot;&amp;quot;},&lt;br /&gt;
    {&amp;quot;device&amp;quot;:&amp;quot;pbx.domain.de&amp;quot;,&amp;quot;metric&amp;quot;:&amp;quot;versionIsSupported&amp;quot;,&amp;quot;value&amp;quot;:&amp;quot;true&amp;quot;,&amp;quot;result&amp;quot;:true&amp;quot;comment&amp;quot;:&amp;quot;&amp;quot;},&lt;br /&gt;
    {&amp;quot;device&amp;quot;:&amp;quot;pbx.domain.de&amp;quot;,&amp;quot;metric&amp;quot;:&amp;quot;uptime&amp;quot;,&amp;quot;value&amp;quot;:3050,&amp;quot;comment&amp;quot;:&amp;quot;&amp;quot;},&lt;br /&gt;
    {&amp;quot;device&amp;quot;:&amp;quot;pbx.domain.de&amp;quot;,&amp;quot;metric&amp;quot;:&amp;quot;CPU&amp;quot;,&amp;quot;value&amp;quot;:2,&amp;quot;comment&amp;quot;:&amp;quot;null&amp;quot;},&lt;br /&gt;
    {&amp;quot;device&amp;quot;:&amp;quot;pbx.domain.de&amp;quot;,&amp;quot;metric&amp;quot;:&amp;quot;CPU-R&amp;quot;,&amp;quot;value&amp;quot;:0,&amp;quot;comment&amp;quot;:&amp;quot;null&amp;quot;},&lt;br /&gt;
    {&amp;quot;device&amp;quot;:&amp;quot;pbx.domain.de&amp;quot;,&amp;quot;metric&amp;quot;:&amp;quot;MEM&amp;quot;,&amp;quot;value&amp;quot;:0.09,&amp;quot;comment&amp;quot;:&amp;quot;null&amp;quot;},&lt;br /&gt;
    {&amp;quot;device&amp;quot;:&amp;quot;pbx.domain.de&amp;quot;,&amp;quot;metric&amp;quot;:&amp;quot;ETH0&amp;quot;,&amp;quot;value&amp;quot;:18,&amp;quot;comment&amp;quot;:&amp;quot;null&amp;quot;}&lt;br /&gt;
  ],&lt;br /&gt;
  &amp;quot;ap.domain.de&amp;quot;: [&lt;br /&gt;
    {&amp;quot;device&amp;quot;:&amp;quot;ap.domain.de&amp;quot;,&amp;quot;metric&amp;quot;:&amp;quot;online&amp;quot;,&amp;quot;value&amp;quot;:&amp;quot;true&amp;quot;,&amp;quot;result&amp;quot;:true,&amp;quot;comment&amp;quot;:&amp;quot;&amp;quot;},&lt;br /&gt;
    {&amp;quot;device&amp;quot;:&amp;quot;ap.domain.de&amp;quot;,&amp;quot;metric&amp;quot;:&amp;quot;serialnumber&amp;quot;,&amp;quot;value&amp;quot;:00155db3c306,&amp;quot;comment&amp;quot;:&amp;quot;&amp;quot;},&lt;br /&gt;
    {&amp;quot;device&amp;quot;:&amp;quot;ap.domain.de&amp;quot;,&amp;quot;metric&amp;quot;:&amp;quot;product&amp;quot;,&amp;quot;value&amp;quot;:AppPlatform x86_64,&amp;quot;comment&amp;quot;:&amp;quot;&amp;quot;},&lt;br /&gt;
    {&amp;quot;device&amp;quot;:&amp;quot;ap.domain.de&amp;quot;,&amp;quot;metric&amp;quot;:&amp;quot;version&amp;quot;,&amp;quot;value&amp;quot;:120010  (15r1 1510130 dvl ),&amp;quot;comment&amp;quot;:&amp;quot;&amp;quot;},&lt;br /&gt;
    {&amp;quot;device&amp;quot;:&amp;quot;ap.domain.de&amp;quot;,&amp;quot;metric&amp;quot;:&amp;quot;versionIsSupported&amp;quot;,&amp;quot;value&amp;quot;:&amp;quot;true&amp;quot;,&amp;quot;result&amp;quot;:true,&amp;quot;comment&amp;quot;:&amp;quot;&amp;quot;},&lt;br /&gt;
  ]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/spoiler&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Checkmk ====&lt;br /&gt;
The interface &amp;quot;/Checkmk&amp;quot; provides a native integration to your Checkmk system with [https://docs.checkmk.com/latest/en/piggyback.html Piggyback] information for all known hosts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;spoiler show=&amp;quot;show sample output&amp;quot; hide=&amp;quot;hide sample output&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;&amp;lt;&amp;lt;&amp;lt;pbx.domain.de&amp;gt;&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;&amp;lt;&amp;lt;check_mk&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
AgentOS: innovaphone TechAssist&lt;br /&gt;
Hostname: pbx.domain.de&lt;br /&gt;
&amp;lt;&amp;lt;&amp;lt;uptime&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
3050&lt;br /&gt;
&amp;lt;&amp;lt;&amp;lt;kernel&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
util 0&lt;br /&gt;
cpu 1728891356864 0 0 1728891356960 0 0 0 0 0 0&lt;br /&gt;
&amp;lt;&amp;lt;&amp;lt;mem&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
MemTotal: 49793 kB&lt;br /&gt;
MemFree: 49747 kB&lt;br /&gt;
MemAvailable: 49747 kB&lt;br /&gt;
Buffers: 0 kB&lt;br /&gt;
Cached: 0 kB&lt;br /&gt;
SwapTotal: 0 kB&lt;br /&gt;
SwapFree: 0 kB&lt;br /&gt;
Dirty: 0 kB&lt;br /&gt;
Writeback: 0 kB&lt;br /&gt;
&amp;lt;&amp;lt;&amp;lt;lnx_thermal&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;&amp;lt;&amp;lt;local&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
0 &amp;quot;online&amp;quot; - online=1&lt;br /&gt;
0 &amp;quot;serialnumber&amp;quot; - serialnumber=005056001338&lt;br /&gt;
0 &amp;quot;product&amp;quot; - product=IPVA&lt;br /&gt;
0 &amp;quot;version&amp;quot; - version=15r1 dvl [15.1.0130/1000/0]&lt;br /&gt;
0 &amp;quot;versionIsSupported&amp;quot; - versionIsSupported=1&lt;br /&gt;
0 &amp;quot;CPU-R&amp;quot; - CPU-R=0&lt;br /&gt;
0 &amp;quot;ETH0&amp;quot; - ETH0=18&lt;br /&gt;
&amp;lt;&amp;lt;&amp;lt;innovaphone&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;&amp;lt;&amp;lt;&amp;lt;ap.domain.de&amp;gt;&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;&amp;lt;&amp;lt;check_mk&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
AgentOS: innovaphone TechAssist&lt;br /&gt;
Hostname: ap.domain.de&lt;br /&gt;
&amp;lt;&amp;lt;&amp;lt;uptime&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;&amp;lt;&amp;lt;kernel&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;&amp;lt;&amp;lt;mem&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;&amp;lt;&amp;lt;lnx_thermal&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;&amp;lt;&amp;lt;local&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
0 &amp;quot;online&amp;quot; - online=1&lt;br /&gt;
0 &amp;quot;serialnumber&amp;quot; - serialnumber=00155db3c306&lt;br /&gt;
0 &amp;quot;product&amp;quot; - product=AppPlatform x86_64&lt;br /&gt;
0 &amp;quot;version&amp;quot; - version=120010  (15r1 1510130 dvl )&lt;br /&gt;
0 &amp;quot;versionIsSupported&amp;quot; - versionIsSupported=1&lt;br /&gt;
&amp;lt;&amp;lt;&amp;lt;innovaphone&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/spoiler&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Configure your Checkmk installation =====&lt;br /&gt;
#Setup your Hosts in Checkmk&lt;br /&gt;
#*Make sure that &amp;quot;Checkmk agent / API integrations&amp;quot; in the Hostconfiguration of your Application Platform is set to &amp;quot;API integrations if configured, else Checkmk agent&amp;quot;, all other Hosts hat to bet set to &amp;quot;No API integrations, no Checkmk agent&amp;quot;.&lt;br /&gt;
#Create a new Rule for &amp;quot;Individual program call instead of agent access&amp;quot; in &amp;quot;Setup &amp;gt; Agents &amp;gt; Other integrations&amp;quot;&lt;br /&gt;
#*Command line to execute: &amp;lt;code&amp;gt;curl --digest -u &amp;quot;user:pass&amp;quot; https://ap.domain.tld/domain.de/techassist/monitoring/Checkmk&amp;lt;/code&amp;gt;&lt;br /&gt;
#*Explicit hosts: Set this to the Host of your Application Platform&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
After that, you can run the service discovery and receive new checks for your devices&lt;br /&gt;
&lt;br /&gt;
[[File:Checkmk new checks.png|frameless|500px|checkmk_new_checks.png/|checkmk_new_checks.png/]]&lt;br /&gt;
&lt;br /&gt;
==== Icinga ====&lt;br /&gt;
The interface &amp;quot;/Icinga&amp;quot; provides a native integration to your Icinga system for all known hosts.&lt;br /&gt;
&lt;br /&gt;
{{FIXME|reason=This interface is currently being researched, and it is being checked whether icinga can read such data as expected}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;spoiler show=&amp;quot;show sample output&amp;quot; hide=&amp;quot;hide sample output&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
[&lt;br /&gt;
  {&lt;br /&gt;
    &amp;quot;_host&amp;quot;: &amp;quot;pbx.domain.de&amp;quot;,&lt;br /&gt;
    &amp;quot;_ETH0_ipv4&amp;quot;: &amp;quot;10.0.102.7&amp;quot;,&lt;br /&gt;
    &amp;quot;online&amp;quot;:1,&lt;br /&gt;
    &amp;quot;serialnumber&amp;quot;:005056001338,&lt;br /&gt;
    &amp;quot;product&amp;quot;:IPVA,&lt;br /&gt;
    &amp;quot;version&amp;quot;:15r1 dvl [15.1.0130/1000/0],&lt;br /&gt;
    &amp;quot;versionIsSupported&amp;quot;:1,&lt;br /&gt;
    &amp;quot;uptime&amp;quot;:3353,&lt;br /&gt;
    &amp;quot;CPU&amp;quot;:1,&lt;br /&gt;
    &amp;quot;CPU-R&amp;quot;:0,&lt;br /&gt;
    &amp;quot;MEM&amp;quot;:0.09,&lt;br /&gt;
    &amp;quot;ETH0&amp;quot;:14&lt;br /&gt;
  },&lt;br /&gt;
  {&lt;br /&gt;
    &amp;quot;_host&amp;quot;: &amp;quot;ap.domain.de&amp;quot;,&lt;br /&gt;
    &amp;quot;_eth0_ipv4&amp;quot;: &amp;quot;10.0.102.8&amp;quot;,&lt;br /&gt;
    &amp;quot;_eth0_ipv6&amp;quot;: &amp;quot;2001:4090:e000:9a1::8&amp;quot;,&lt;br /&gt;
    &amp;quot;online&amp;quot;:1,&lt;br /&gt;
    &amp;quot;serialnumber&amp;quot;:00155db3c306,&lt;br /&gt;
    &amp;quot;product&amp;quot;:AppPlatform x86_64,&lt;br /&gt;
    &amp;quot;version&amp;quot;:120010  (15r1 1510130 dvl ),&lt;br /&gt;
    &amp;quot;versionIsSupported&amp;quot;:1&lt;br /&gt;
  }&lt;br /&gt;
]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/spoiler&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Configure your Icinga installation =====&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
=== Startup Logfile ===&lt;br /&gt;
If you enable the traceflag &#039;&#039;App&#039;&#039; in your App instance, you will find the following logs:&lt;br /&gt;
&lt;br /&gt;
 AppService::AppStart TechAssist@slu.de&lt;br /&gt;
 App instance started 14C1363 14C1363&lt;br /&gt;
 ...&lt;br /&gt;
 // App begins to load embedded tests&lt;br /&gt;
 JavaScript: Files tests/*&lt;br /&gt;
 ...&lt;br /&gt;
 // Scheduler begins to load all the tests&lt;br /&gt;
 scheduler init&lt;br /&gt;
 init test &amp;quot;firmware_version&amp;quot;&lt;br /&gt;
 firmware_version: Test added successful&lt;br /&gt;
 init test &amp;quot;pbx_mediarelay&amp;quot;&lt;br /&gt;
 pbx_mediarelay: Test added successful&lt;br /&gt;
&lt;br /&gt;
=== Websocket Connections ===&lt;br /&gt;
The App holds Websocket connections to various targets. To debug and follow these connections in the logfile you will find special log output for outgoing websocket connections.&lt;br /&gt;
&lt;br /&gt;
You can filter the logfile with &amp;lt;code&amp;gt;Websocket Log&amp;lt;/code&amp;gt; to get the Websocket flow. Then a good practice should be to click on these lines and check the lines before.&lt;br /&gt;
 C:\Users\slu\Downloads\techassist-x86_64-20241112-131349.txt (8 Treffer)&lt;br /&gt;
 Zeile   9: 11-12 13:13:46.288 techassist@slu.de Websocket Log - ServicesInfoApis::close | {...}&lt;br /&gt;
 Zeile  12: 11-12 13:13:46.288 techassist@slu.de Websocket Log - ServicesInfoApis::close | {...}&lt;br /&gt;
 Zeile  18: 11-12 13:13:46.288 techassist@slu.de Websocket Log - ServicesInfoApis::add | {...}&lt;br /&gt;
 Zeile  22: 11-12 13:13:46.288 techassist@slu.de Websocket Log - ServicesInfoApis::add | {...}&lt;br /&gt;
 Zeile  34: 11-12 13:13:46.290 techassist@slu.de Websocket Log - ServicesInfoApis::remove | {...}&lt;br /&gt;
 Zeile  41: 11-12 13:13:46.290 techassist@slu.de Websocket Log - ServicesInfoApis::remove | {...}&lt;br /&gt;
 Zeile  66: 11-12 13:13:46.307 techassist@slu.de Websocket Log - ServicesInfoApis::find | {...}&lt;br /&gt;
 Zeile 321: 11-12 13:13:46.324 techassist@slu.de Websocket Log - ServicesInfoApis::find | {...}&lt;/div&gt;</summary>
		<author><name>Tfu</name></author>
	</entry>
	<entry>
		<id>https://wiki.innovaphone.com/index.php?title=Reference16r1:Concept_App_Service_TechAssist&amp;diff=80616</id>
		<title>Reference16r1:Concept App Service TechAssist</title>
		<link rel="alternate" type="text/html" href="https://wiki.innovaphone.com/index.php?title=Reference16r1:Concept_App_Service_TechAssist&amp;diff=80616"/>
		<updated>2026-10-06T08:06:11Z</updated>

		<summary type="html">&lt;p&gt;Tfu: /* Configurations */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Concept|Apps]]&lt;br /&gt;
[[Category:Concept App Service TechAssist]]&lt;br /&gt;
&amp;lt;!-- techassist, ticket, analyze, debug, tests --&amp;gt;&lt;br /&gt;
== Applies To == &lt;br /&gt;
&lt;br /&gt;
* innovaphone PBX from version 15r1&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
The idea of the TechAssist app is to provide helpful tools for technicians, as well as to analyze static and runtime information of a system and check for problems and improvements. In this way, the app can help you find and solve problems and misconfigurations independently and quickly.&lt;br /&gt;
For this purpose, the app supports&lt;br /&gt;
* the execution of &#039;&#039;tests&#039;&#039;&lt;br /&gt;
** a bunch of manufacturer tests are supplied with the app&lt;br /&gt;
** you can create and save your own tests&lt;br /&gt;
** testresults can be downloaded to attach them to a support ticket&lt;br /&gt;
* a PBX license overview&lt;br /&gt;
&lt;br /&gt;
== Licensing ==&lt;br /&gt;
There are no licenses needed for this app&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
The TechAssist App is installed by default for every new installation and is accessible from the Config Admin template.&lt;br /&gt;
&lt;br /&gt;
=== With the PBX manager AP app installer plug-in === &lt;br /&gt;
[[File:Ap_app_installer.png|ap_app_installer.png/|ap_app_installer.png/]]&lt;br /&gt;
&lt;br /&gt;
Go to the PBX manager and open the &#039;&#039;&#039;&amp;quot;AP app installer&amp;quot;&#039;&#039;&#039; plugin. On the right panel, the App Store will be shown. &#039;&#039;Hint : if you access it for the first time, you will need to accept the &amp;quot;Terms of Use of the innovaphone App Store&amp;quot;&#039;&#039;&lt;br /&gt;
* In the search field located on the top right corner of the store, search for &#039;&#039;&#039;&amp;quot;Techassist&amp;quot;&#039;&#039;&#039; and click on it&lt;br /&gt;
* Select the proper firmware version, here &#039;&#039;&#039;&amp;quot;v14&amp;quot;&#039;&#039;&#039; and click on install&lt;br /&gt;
* Tick &amp;quot;I accept the terms of use&amp;quot; and continue by clicking on the install yellow button&lt;br /&gt;
* Wait until the install has been finished&lt;br /&gt;
* Close and open the PBX manager to refresh the list of the available colored AP plugin&lt;br /&gt;
* Click on the &#039;&#039;&#039;&amp;quot;AP techassist&amp;quot;&#039;&#039;&#039; and click on &#039;&#039;&#039;&amp;quot; + Add an App&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
* Enter a &#039;&#039;&#039;&amp;quot;Name&amp;quot;&#039;&#039;&#039; that is used as display name &#039;&#039;(all character allowed)&#039;&#039; for it and the &#039;&#039;&#039;&amp;quot;SIP&amp;quot;&#039;&#039;&#039; name that is the administrative field &#039;&#039;(no space, no capital letters)&#039;&#039;. &#039;&#039;e.g : Name: TechAssist, SIP: techassist&#039;&#039;&lt;br /&gt;
&#039;&#039;Hint : The App needs access-right to one devices-api. The access to &amp;quot;devices-api&amp;quot; will be set automatically. If you want to have another devices-apis working with techassist, you have to configure it manually in the advanced UI.&#039;&#039;&lt;br /&gt;
* Tick the appropriate template to distribute the App&lt;br /&gt;
* Click OK to save the settings and a green check mark will be shown to inform you that the configuration is good&lt;br /&gt;
&lt;br /&gt;
== Test Engine ==&lt;br /&gt;
=== Overview ===&lt;br /&gt;
==== Technical look inside ====&lt;br /&gt;
[[File:Concept_TechAssist.png|thumb|upright=1.0|right|concept_techassist.png/|concept_techassist.png/]]&lt;br /&gt;
The app service receives multiple incoming websocket connections of the app objects from the PBXes. By assigning rights to a to your desired &amp;quot;devices-apis&amp;quot; (in the Apps tab), the app service receives the corresponding rights to connect to the respectively activated DevicesApps. All managed domains and devices can then be read in via this connection. (One TechAssist can only connect with one device-api)&lt;br /&gt;
With this procedure, you can work with one DevicesApp instance and across all domains and devices in it.&lt;br /&gt;
&lt;br /&gt;
==== Submodules ====&lt;br /&gt;
The app contains various sub-modules in order to be able to carry out the tests provided by the manufacturer and also to be able to integrate custom tests created by yourself.&lt;br /&gt;
&lt;br /&gt;
;scheduler&lt;br /&gt;
: The scheduler initially loads all tests and performs a plausibility check of the individual tests. From this status onwards, the scheduler ensures that all tests are executed in the required time intervals.&lt;br /&gt;
: Inside the Scheduler the tick is 5000 milliseconds, and test are executed sequentially to prevent high system load&lt;br /&gt;
;cmd&lt;br /&gt;
: The cmd submodule (derived from &amp;quot;command&amp;quot;) can communicate with devices in the installation to query a status, the config or similar. The submodule takes care of all the information that tests from an installation want to have, consolidates them so that queries do not have to be executed multiple times and caches the results.&lt;br /&gt;
;test&lt;br /&gt;
: The test submodule is instantiated per test and provides all necessary functionalities within a test.&lt;br /&gt;
&lt;br /&gt;
==== UI Language ====&lt;br /&gt;
By design, only the app itself is available in multiple languages. The content of the tests and technical output is intentionally only available in english.&lt;br /&gt;
&lt;br /&gt;
==== Tests ====&lt;br /&gt;
The app contains a bunch of embedded test, but it is also possible to create and save your own tests.&lt;br /&gt;
&lt;br /&gt;
=== UI ===&lt;br /&gt;
&lt;br /&gt;
==== Tests ====&lt;br /&gt;
;Execute all&lt;br /&gt;
:This Button will trigger all tests. Keep in mind that this trigger used the cached version of commands.&lt;br /&gt;
;Execute all without cache&lt;br /&gt;
:This Button will trigger all tests but will clear the cache for all commands before&lt;br /&gt;
;Execute a dedicated test&lt;br /&gt;
: In this execution, no cache will be used&lt;br /&gt;
&lt;br /&gt;
==== Expert Mode ====&lt;br /&gt;
By default there are some expert information hidden in the left menu bar. You will find a switch for that in the left menu (non-mobile-view) to enable all menu items.&lt;br /&gt;
&lt;br /&gt;
==== Dealing with the Code Editor ====&lt;br /&gt;
The Code Editor is a tool for viewing the tests supplied and writing your own tests based on these tests.&lt;br /&gt;
&lt;br /&gt;
The editor is divided into 3 basic areas.&lt;br /&gt;
;Left - Code Editor&lt;br /&gt;
:This is the code editor where you can write your test code in the browser. When you close the app, the content in the editor is saved, so that the next time you open the app you will find your old code again.&lt;br /&gt;
&lt;br /&gt;
;Top right - Menu bar&lt;br /&gt;
:Here you will find the following functions:&lt;br /&gt;
:Selection of all existing Tests (predefined vendor Tests and your own custom Tests)&lt;br /&gt;
:Load the source code of the selected Test to the code editor&lt;br /&gt;
:Delete the selected test from the app (This is only possible for custom tests)&lt;br /&gt;
:Execute the source code (with or without cached commands in the service) in the Code Editor and show the result&lt;br /&gt;
:Clear the Code Editor&lt;br /&gt;
:Save the current Content from the code Editor as Test&lt;br /&gt;
::The title of your test is divided from the &#039;&#039;title&#039;&#039; property in your test (lower based without non-alphanumeric characters). This means: If you save another Test with the same &#039;&#039;title&#039;&#039; the value will be saved in the other test.&lt;br /&gt;
&lt;br /&gt;
;Top right - Results&lt;br /&gt;
:If you execute, save or delete a test you will get the response/results in this area&lt;br /&gt;
&lt;br /&gt;
=== Create your own Testscript ===&lt;br /&gt;
You can create your own Test scripts in a JavaScript based environment.&lt;br /&gt;
A test itself is a JavaScript object with some configurations properties and a section of &#039;&#039;freestyle&#039;&#039; code to use JavaScript habits to perform your test. If your test will be executed, an above layer will call your &#039;&#039;test()&#039;&#039; method and want to have a return object with your result.&lt;br /&gt;
&lt;br /&gt;
There already exists a global Object called &#039;&#039;&#039;tests_add&#039;&#039;&#039;. You can add your own Test as Property to this existing Object like:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
tests_add.my_new_test = tests_add.my_new_test || {&lt;br /&gt;
   title: &#039;Check for xyz&#039;,&lt;br /&gt;
   // configuration properties&lt;br /&gt;
   &lt;br /&gt;
   test: function (cmd, result, storage) {&lt;br /&gt;
       // your custom test code&lt;br /&gt;
&lt;br /&gt;
       return {&lt;br /&gt;
           success: false,&lt;br /&gt;
           msg: &#039;....&#039;&lt;br /&gt;
       };&lt;br /&gt;
   }&lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The way to add a test with &amp;lt;code&amp;gt;tests_add.my_new_test = tests_add.my_new_test || {}&amp;lt;/code&amp;gt; is important so that two tests do not overwrite each other. Please also pay attention to this. In this example, we have a &#039;&#039;logical condition&#039;&#039; in the first line. If the test &#039;&#039;my_new_test&#039;&#039; already exists in the object &#039;&#039;tests_add&#039;&#039; the left side from the &#039;&#039;OR-condition&#039;&#039; is &#039;&#039;true&#039;&#039;, and the existing test takes place. Otherwise, it is &#039;&#039;false&#039;&#039; and the right side (your new test object) will be written to &#039;&#039;tests_add.my_new_test&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==== Configuration Properties ====&lt;br /&gt;
You must configure certain properties in your test so that the scheduler knows exactly how to handle your test.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
tests_add.my_new_test = tests_add.my_new_test || {&lt;br /&gt;
  title: &#039;Unknown / New devices&#039;,&lt;br /&gt;
  description: &#039;Check for unassigned devices in your installation&#039;,&lt;br /&gt;
  todo: &#039;Please check the unknown devices in your installation and acceppt or delete the devices&#039;,&lt;br /&gt;
  author: &#039;slu@innovaphone.com&#039;,&lt;br /&gt;
  enabled: true,&lt;br /&gt;
  schedule: &#039;1h&#039;,&lt;br /&gt;
  commands: { ... },&lt;br /&gt;
&lt;br /&gt;
  test: function (cmd, result, storage) {&lt;br /&gt;
    // your custom test code&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Mandatory properties =====&lt;br /&gt;
&lt;br /&gt;
; title&lt;br /&gt;
: string | The title of your test, which is displayed in the UI&lt;br /&gt;
; description&lt;br /&gt;
: string | A short description of your test, which is displayed in the UI&lt;br /&gt;
; todo&lt;br /&gt;
: string | An instruction on what the user has to do if the check fails. It will be displayed above the logfile in failed tests. (You can use &#039;&#039;\r\n&#039;&#039; for line breaks)&lt;br /&gt;
: Variable &amp;lt;nowiki&amp;gt;{{VERSION}}&amp;lt;/nowiki&amp;gt; will be replaced to current Version of the app like &amp;quot;14r1&amp;quot;&lt;br /&gt;
; author&lt;br /&gt;
: string | The contact of the person who create the test&lt;br /&gt;
; schedule&lt;br /&gt;
: string | The time interval during which the test is to be carried out independently. The format is composed of a numerical value and interval value. This allows you to create combinations such as &amp;lt;code&amp;gt;5m (every 5 minutes), 10h (every 10 hours) or 1d (every day) &amp;lt;/code&amp;gt;. A special case which is also allowed is the value &#039;&#039;none&#039;&#039;. With a &#039;&#039;none&#039;&#039; value, your test will not be executed automatically, but is available in the app. So the user is able to execute your test manually.&lt;br /&gt;
: Possible interval values are:&lt;br /&gt;
: &amp;lt;code&amp;gt;s&amp;lt;/code&amp;gt; (seconds)&lt;br /&gt;
: &amp;lt;code&amp;gt;m&amp;lt;/code&amp;gt; (minutes)&lt;br /&gt;
: &amp;lt;code&amp;gt;h&amp;lt;/code&amp;gt; (hours)&lt;br /&gt;
: &amp;lt;code&amp;gt;d&amp;lt;/code&amp;gt; (days)&lt;br /&gt;
: &amp;lt;code&amp;gt;w&amp;lt;/code&amp;gt; (weeks)&lt;br /&gt;
: Please note that each execution of a test requires resources. For example, if you create a test with &#039;&#039;1m&#039;&#039; that is executed every minute, you may well create an unpleasant impact! The system automatically checks the execution time of your test against your specified interval. If your test runs for a longer time than your schedule, your &#039;&#039;schedule&#039;&#039; parameter is automatically doubled by the system.&lt;br /&gt;
: Please note the [[#Submodules|Submodule Scheduler]] with Tick and synchronous execution. For example, it is not possible to execute a test every second. &lt;br /&gt;
&lt;br /&gt;
===== Optional properties =====&lt;br /&gt;
&lt;br /&gt;
; commands&lt;br /&gt;
: object | An object in which you can list all the commands, values, etc. that you want to use later in your test. As soon as your test() method is called, the returns of these commands are passed in as parameters so that you can analyze them. For detailed documentation, please see the [[#Property_&amp;quot;commands&amp;quot;|commands-documentation]] below.&lt;br /&gt;
; minBuild&lt;br /&gt;
: int | The minimum build version of the app, that the Test will be executed.&lt;br /&gt;
; oneTime&lt;br /&gt;
: bool | If &#039;&#039;true&#039;&#039; the test will be self-deactivated after the first successful execution.&lt;br /&gt;
; enabled&lt;br /&gt;
: bool | If &#039;&#039;false&#039;&#039; the test will be loaded but not executed. The user will see the test in the list of test, and it is possible to enable it (default: &#039;&#039;true&#039;&#039;)&lt;br /&gt;
; hidden&lt;br /&gt;
: bool | If &#039;&#039;true&#039;&#039; the test will be skipped by the system and will not be loaded (default: &#039;&#039;false&#039;&#039;) &lt;br /&gt;
&lt;br /&gt;
==== Property &amp;quot;commands&amp;quot; ====&lt;br /&gt;
The property &#039;&#039;commands&#039;&#039; is an object where you can define innovaphone specific commands that are executed before your test will be executed. The results of the given commands will be passed to your test in the parameter &#039;&#039;results&#039;&#039;. Think about that, all your commands will be cached until the &#039;&#039;schedule&#039;&#039; timeout is exceeded. This means that you will only get a new result of the command after the schedule time has elapsed in relation to the time of your last execution. The only exceptions is when the user manually re-executes a test via the UI or caching has been explicitly disabled at the command&lt;br /&gt;
&lt;br /&gt;
You have to consider a special nested notation when creating your commands, so that you can use them later.&lt;br /&gt;
&lt;br /&gt;
===== outer commands-object =====&lt;br /&gt;
Let&#039;s start with some first basic rules:&lt;br /&gt;
* &#039;&#039;commands&#039;&#039; is an object with one property per command. At this moment we only list commands, we don&#039;t take care about specific devices, types of models or so on.&lt;br /&gt;
* Every child-property (let&#039;s call it &amp;quot;command-object&amp;quot;) is a new object which contains all needed information for this specific command&lt;br /&gt;
* The title of the property &amp;quot;command-object&amp;quot; is defined by yourself&lt;br /&gt;
** Spoiler: The title of your &amp;quot;command-object&amp;quot; should be used later if you want to read the result for a specific device&lt;br /&gt;
* You can list multiple &amp;quot;command-objects&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Up to here we have the following and can define it like this:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
commands: {&lt;br /&gt;
  my_command_one: {},&lt;br /&gt;
  my_command_two: {},&lt;br /&gt;
},&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== single command-object =====&lt;br /&gt;
&lt;br /&gt;
Then we have some new rules per &amp;quot;command-object&amp;quot;:&lt;br /&gt;
* A property called &#039;&#039;cmd&#039;&#039; is expected. This property contains the real command which shall be executed (Remember, at this moment we only list commands, we don&#039;t take care about specific devices, types of models or so on)&lt;br /&gt;
** Example 1: &amp;lt;code&amp;gt;cmd: &#039;CMD0/box_info.xml&#039;&amp;lt;/code&amp;gt; will give you the xml output of the general overview page&lt;br /&gt;
** Example 2: &amp;lt;code&amp;gt;cmd: &#039;!mod cmd CDR0 qs&#039;&amp;lt;/code&amp;gt; will give you the amount of buffered CDRs in the CDR0 interface&lt;br /&gt;
** Example 3: &amp;lt;code&amp;gt;cmd: &#039;cfg.txt&#039;&amp;lt;/code&amp;gt; will give you back the full configuration file&lt;br /&gt;
** If you are already firm with the innovaphone based command syntax, you will see that you can use any HTTP command which can be sent to an innovaphone device&lt;br /&gt;
* Some more properties can be defined optionally. See documentation below&lt;br /&gt;
&lt;br /&gt;
Up to here we have an idea of a specific &amp;quot;command-object&amp;quot; and can do the following now:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
commands: {&lt;br /&gt;
  buffered_cdr0: {&lt;br /&gt;
    cmd: &#039;!mod cmd CDR0 qs&#039;,&lt;br /&gt;
  },&lt;br /&gt;
  buffered_cdr1: {&lt;br /&gt;
    cmd: &#039;!mod cmd CDR1 qs&#039;,&lt;br /&gt;
  },&lt;br /&gt;
},&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With this command, we can collect the &amp;quot;buffered CDRs&amp;quot; on both CDR Interfaces in our boxes. Maybe you see it directly... This will not make really sense in a real setup because CDRs only generated by Gateways/PBXes. So we don&#039;t need to bother phones with these requests.&lt;br /&gt;
So from now on we take care about our defined command. There are optional parameters that we can also list inside a &amp;quot;command-object&amp;quot; to let the system know what is the to-do with this command.&lt;br /&gt;
&lt;br /&gt;
;cmd&lt;br /&gt;
: string | Any HTTP command you can send to an innovaphone device. There is a limit of 15 seconds for every http request. If your request exceeds this limit the request will be cancelled.&lt;br /&gt;
;cat&lt;br /&gt;
: array | An optional list of device types on which the command is to be executed. If &#039;&#039;cat&#039;&#039; is empty, it means all devices in your installation.&lt;br /&gt;
: You can define the following device categories:&lt;br /&gt;
: &amp;lt;code&amp;gt;pbx&amp;lt;/code&amp;gt; - all PBXes&lt;br /&gt;
: &amp;lt;code&amp;gt;gw&amp;lt;/code&amp;gt; - all Gateways&lt;br /&gt;
: &amp;lt;code&amp;gt;ap&amp;lt;/code&amp;gt; - all App Platforms &#039;&#039;(effect at the moement)&#039;&#039;&lt;br /&gt;
: &amp;lt;code&amp;gt;dect&amp;lt;/code&amp;gt; - all Dect Gateways&lt;br /&gt;
: &amp;lt;code&amp;gt;phone&amp;lt;/code&amp;gt; - all Phones&lt;br /&gt;
: &amp;lt;code&amp;gt;monitoring&amp;lt;/code&amp;gt; - all categories based on Monitoring settings&lt;br /&gt;
;cache&lt;br /&gt;
: bool | If you set it to &#039;&#039;false&#039;&#039; you will never get a cached value. Please use this option wisely and only if you really need it. (default: &#039;&#039;true&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
Now let&#039;s improve our example from above and get the bufferd CDRx information only from pbxes and gateways.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
commands: {&lt;br /&gt;
  buffered_cdr0: {&lt;br /&gt;
    cmd: &#039;!mod cmd CDR0 qs&#039;,&lt;br /&gt;
    cat: [&#039;pbx&#039;, &#039;gw&#039;],&lt;br /&gt;
  },&lt;br /&gt;
  buffered_cdr1: {&lt;br /&gt;
    cmd: &#039;!mod cmd CDR1 qs&#039;,&lt;br /&gt;
    cat: [&#039;pbx&#039;, &#039;gw&#039;],&lt;br /&gt;
  },&lt;br /&gt;
},&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== execution and results of commands =====&lt;br /&gt;
Up to now, we have only defined commands that are to be executed on certain devices. When your test is executed, the previously defined commands are executed and the system collects the returns in a corresponding object (called &amp;lt;code&amp;gt;results&amp;lt;/code&amp;gt;) which is passed into your &amp;lt;code&amp;gt;test(cmd, results)&amp;lt;/code&amp;gt; method. There you can access the results and do whatever you want to test/analyze or whatever with the return value. You will find an example and some sample-code how to use the results-object in the description of the &#039;&#039;test() method&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===== nested commands-objects =====&lt;br /&gt;
You can now send any commands and the results will be returned to you for evaluation.&lt;br /&gt;
As you may have already noticed, there is no possibility to place multiple commands in dependency. But this is the way to do this.&lt;br /&gt;
&lt;br /&gt;
For more complicated tests, it is necessary to execute several commands one after the other and to generate following commands dynamically on the basis of the result of the first command.&lt;br /&gt;
&lt;br /&gt;
For such tests, there is the possibility to specify an object &amp;quot;commands&amp;quot; within a &amp;quot;command-object&amp;quot;. From this level, you can define a dynamic function in which you can apply your own code based on the first result, and then return a new &#039;&#039;commands-object&#039;&#039;. In this return statement, you also have the option of returning another dynamic function in order to be able to create processes of any complexity. Please note that if you not return an &#039;&#039;object&#039;&#039; your return value will be discarded. The results of your nested &#039;&#039;command-objects&#039;&#039; will be passed to the &#039;&#039;test()&#039;&#039; method inside the &#039;&#039;results&#039;&#039; object.&lt;br /&gt;
&lt;br /&gt;
This is certainly not easy to understand. Therefore, let us take a closer look at it with an example.&lt;br /&gt;
&lt;br /&gt;
====== example: nested commands-object which generates the second command from the first result ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
commands: {&lt;br /&gt;
  certificates: {&lt;br /&gt;
    cmd: &#039;X509/mod_cmd.xml&#039;,&lt;br /&gt;
    cat: [&#039;pbx&#039;, &#039;gw&#039;, &#039;dect&#039;],&lt;br /&gt;
    commands: function(cmd, result) {&lt;br /&gt;
                // free style code to build the following commands&lt;br /&gt;
                var xml = cmd.parse_xml(result);&lt;br /&gt;
                //log(JSON.stringify(xml));&lt;br /&gt;
                &lt;br /&gt;
                var fingerprint;&lt;br /&gt;
                // get the fingerprint for single cert&lt;br /&gt;
                if (typeof xml.info.servercert.certificate[&#039;@fingerprint&#039;] !== &#039;undefined&#039;) {&lt;br /&gt;
                    fingerprint = xml.info.servercert.certificate[&#039;@fingerprint&#039;]&lt;br /&gt;
                }&lt;br /&gt;
                // use last certificates in case of multiple&lt;br /&gt;
                else {&lt;br /&gt;
                    fingerprint = xml.info.servercert.certificate[xml.info.servercert.certificate.length - 1][&#039;@fingerprint&#039;];&lt;br /&gt;
                }&lt;br /&gt;
                cmd.log(&#039;Fingerprint: &#039;+fingerprint);&lt;br /&gt;
                &lt;br /&gt;
                return {&lt;br /&gt;
                    certificate: {&lt;br /&gt;
                        cmd: &#039;X509/mod_cmd.xml?cmd=servercert-details&amp;amp;fingerprint=&#039;+fingerprint,&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    },&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Our goal is to check which key-length is used in the device certificate. But there i no direct command to get this information. So we have to do it in multipe steps.&lt;br /&gt;
&lt;br /&gt;
In this sample, we request the following in the commands object:&lt;br /&gt;
# Execute our command &amp;quot;certificates&amp;quot; on devices (pbx, gw, dect) the command &amp;quot;X509/mod_cmd.xml&amp;quot; which will give you back the xml payload of the page [[{{NAMESPACE}}:General/Certificates|Reference15r1:General/Certificates]]&lt;br /&gt;
# If the first request is done, the nested &amp;quot;commands&amp;quot; object should be called and we get the result from the first command&lt;br /&gt;
## Now, inside the function &amp;lt;code&amp;gt;commands: function(cmd, result) {&amp;lt;/code&amp;gt; we can use some free-style code to to what we need, to build a following command&lt;br /&gt;
## Here we convert xml to an object and extract the certificate fingerprint from the result of the first request&lt;br /&gt;
## then we return an object with &amp;quot;command-objects&amp;quot;&lt;br /&gt;
### think about that is possible to add an new &amp;lt;code&amp;gt;commands: function(cmd, result) {&amp;lt;/code&amp;gt; inside the return to add a new level :-)&lt;br /&gt;
## this second command will be executed to for every device and the xml payload contains the device certifcate of the current device. (like the popup in the UI if you click on a specific certificate)&lt;br /&gt;
#If all nested commands are processed, then your test() will be called, and you get all the results (in this case &amp;quot;certificates&amp;quot; and &amp;quot;certificate&amp;quot;) in the results-object&lt;br /&gt;
&lt;br /&gt;
====== example: nested commands-object which generates various commands from the first result ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
commands: {&lt;br /&gt;
	config: {&lt;br /&gt;
		cmd: &#039;cfg.txt&#039;,&lt;br /&gt;
		cat: [&#039;pbx&#039;],&lt;br /&gt;
		commands: function(cmd, result) {&lt;br /&gt;
			var lines = result.split(&amp;quot;\r\n&amp;quot;);&lt;br /&gt;
			var output = {};&lt;br /&gt;
			&lt;br /&gt;
			// get pbx loc&lt;br /&gt;
			var loc = false;&lt;br /&gt;
			for (var l = 0; l &amp;lt; lines.length; l++) {&lt;br /&gt;
				if (!lines[l].startsWith(&#039;config change PBX0&#039;)) continue; // skip non pbx line&lt;br /&gt;
				if (lines[l].includes(&#039;/mode standby&#039;)) continue; // skip slave pbxes&lt;br /&gt;
				&lt;br /&gt;
				var match = lines[l].match(/config change PBX0 (.*) \/loc ([^ ][^/]+)/);&lt;br /&gt;
				loc = match[2].substr(0, match[2].length-1);&lt;br /&gt;
				l = lines.length;&lt;br /&gt;
			}&lt;br /&gt;
			cmd.log(&#039;use pbx loc: &#039;+loc);&lt;br /&gt;
			&lt;br /&gt;
			// get user objects&lt;br /&gt;
			var regex = new RegExp(&#039;/\(loc=&#039;+loc+&#039;\)(.*)\(guid;bin=([0-9A-Za-z]+)\)/&#039;);&lt;br /&gt;
			for (var l = 0; l &amp;lt; lines.length; l++) {&lt;br /&gt;
				// skip if user is not from this pbx&lt;br /&gt;
				if (!lines[l].includes(&#039;(loc=&#039;+loc+&#039;)&#039;)) continue;&lt;br /&gt;
				&lt;br /&gt;
				var match = lines[l].match(/\(guid;bin=([0-9A-Za-z]+)\)/);&lt;br /&gt;
				if (!match) continue;&lt;br /&gt;
				cmd.log(&#039;user found: &#039;+match[1]);&lt;br /&gt;
				output[match[1]] = {cmd: &#039;PBX0/ADMIN/mod_cmd_login.xml?cmd=show&amp;amp;user-guid=&#039;+match[1]};&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			return output;&lt;br /&gt;
		}&lt;br /&gt;
	},&lt;br /&gt;
},&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Our goal is to get the xml output from the advanced ui for every pbx object. But there i no direct command to get this information. So we have to do it in multipe steps.&lt;br /&gt;
&lt;br /&gt;
In this sample, we request the following in the commands object:&lt;br /&gt;
# Execute our command &amp;quot;config&amp;quot; on PBXes the get the plain configuration file&lt;br /&gt;
# If the first request is done, the nested &amp;quot;commands&amp;quot; object should be called, and we get the result from the first command&lt;br /&gt;
## Now, inside the function &amp;lt;code&amp;gt;commands: function(cmd, result) {&amp;lt;/code&amp;gt; we can use some free-style code to do what we need, to build multiple following commands&lt;br /&gt;
&lt;br /&gt;
## Here we split the config file by lines breaks and iterate the whole config&lt;br /&gt;
## then we generate an empty return object to fill it later&lt;br /&gt;
### think about that is possible to add an new &amp;lt;code&amp;gt;commands: function(cmd, result) {&amp;lt;/code&amp;gt; inside the return to add a new level :-)&lt;br /&gt;
## If we have checked the pbx and the userobject we add with &amp;lt;code&amp;gt;output[match[1]] = {cmd: &#039;PBX0/ADMIN/mod_cmd_login.xml?cmd=show&amp;amp;user-guid=&#039;+match[1]};&amp;lt;/code&amp;gt; a specific command to the retunr value&lt;br /&gt;
&lt;br /&gt;
In the end, we have a big return object with multiple cmd&#039;s&lt;br /&gt;
In this case we will get all the results in the test() later and can do further stuff with the results.&lt;br /&gt;
&lt;br /&gt;
==== Executable method test() ====&lt;br /&gt;
The upper layer expects a method &amp;lt;code&amp;gt;test(cmd, results, storage)&amp;lt;/code&amp;gt; in your JavaScript object. This method has three parameters.&lt;br /&gt;
&lt;br /&gt;
;cmd&lt;br /&gt;
:An object that offers you a wide range of predefined functions and options. You can see it as a kind of library, which is documented at the [[#cmd object|cmd object]].&lt;br /&gt;
&lt;br /&gt;
;results&lt;br /&gt;
:An object of the results of your commands from the given &#039;&#039;command-objects&#039;&#039; in your test definition.&lt;br /&gt;
&amp;lt;spoiler show=&amp;quot;show sample strcuture of the results object&amp;quot; hide=&amp;quot;hide sample strcuture of the results object&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// structure of results object&lt;br /&gt;
{&lt;br /&gt;
  // your command is the property&lt;br /&gt;
  &#039;buffered_cdr0&#039; : {&lt;br /&gt;
    // the unique id of the device is the property&lt;br /&gt;
    &#039;1&#039;: &#039;QS messages: 0 max 2000 chars: 0 max 300000&#039;,&lt;br /&gt;
    &#039;4&#039;: &#039;QS messages: 0 max 2000 chars: 0 max 300000&#039;,&lt;br /&gt;
  },&lt;br /&gt;
  &#039;buffered_cdr1&#039; : {&lt;br /&gt;
    // the unique id of the device is the property&lt;br /&gt;
    &#039;1&#039;: &#039;QS messages: 0 max 2000 chars: 0 max 300000&#039;,&lt;br /&gt;
    &#039;4&#039;: &#039;QS messages: 0 max 2000 chars: 0 max 300000&#039;,&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/spoiler&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;spoiler show=&amp;quot;show best practice code to deal with the results object&amp;quot; hide=&amp;quot;hide best practice code to deal with the results object&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// you can use this inside your function &amp;quot;test: function (cmd, results, storage)&amp;quot; to iterate all commands over all affected devices&lt;br /&gt;
        &lt;br /&gt;
Object.keys(results).forEach(function(command) {&lt;br /&gt;
  log.push(&#039;command: &#039;+command);&lt;br /&gt;
  Object.keys(results[command]).forEach(function(device) {&lt;br /&gt;
    log.push(&#039;device: &#039;+device);&lt;br /&gt;
    var output = results[command][device];&lt;br /&gt;
  });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
// expected log array from the code above:&lt;br /&gt;
// $ command: buffered_cdr0&lt;br /&gt;
// $ device: 1&lt;br /&gt;
// $ device: 4&lt;br /&gt;
// $ command: buffered_cdr1&lt;br /&gt;
// $ device: 1&lt;br /&gt;
// $ device: 4&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/spoiler&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;storage&lt;br /&gt;
:If the test has written something to the test volatile memory during the last execution, you will get the last value back here. (Note that the storage is not available for one-time tests in the code editor. There you will always get an empty storage)&lt;br /&gt;
&lt;br /&gt;
===== return test result =====&lt;br /&gt;
Your test has to be return an object with your test result. The system expect an object with the following properties.&lt;br /&gt;
&lt;br /&gt;
; success&lt;br /&gt;
: boolean | indicates if your test was successful or not&lt;br /&gt;
; msg&lt;br /&gt;
: string | an optional short message that will be displayed in the UI as preview&lt;br /&gt;
; log&lt;br /&gt;
: array | an optional array with lines of logfile that you can use to display detailed information in the UI at your test result. Use &amp;lt;code&amp;gt;log.push()&amp;lt;/code&amp;gt; to fill up the logfile array. In the frontend, the log will be parsed and mac addresses &amp;lt;code&amp;gt;/(^|\W)([a-f0-9]{12})(\W|$)/i&amp;lt;/code&amp;gt; will be updated with an internal link to devices app. (If you want to create instead debug output to the app-instance logfile you can use &amp;lt;code&amp;gt;cmd.log()&amp;lt;/code&amp;gt;)&lt;br /&gt;
;storage&lt;br /&gt;
: string | an optional string, which can be json or similar, that is stored for this test. The next time the test is executed, the payload saved here is available inside the test again.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
test: function (cmd, results, storage) {&lt;br /&gt;
  // your stuff&lt;br /&gt;
  var count = 2;&lt;br /&gt;
 &lt;br /&gt;
  return {&lt;br /&gt;
    success: false,&lt;br /&gt;
    msg: &#039;There are &#039;+count+&#039; new/unassigned devices in your setup&#039;&lt;br /&gt;
  };&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== The full picture ====&lt;br /&gt;
===== Complete sample test to check buffered CDRs =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
tests_add.cdrs_buffered = tests_add.cdrs_buffered || {&lt;br /&gt;
    title: &#039;Buffered CDRs&#039;,&lt;br /&gt;
    description: &#039;This test will check if CDRs on a gateway was buffered and are not transmit to the CDR target yet&#039;,&lt;br /&gt;
    todo: &#039;Check the CDR target&#039;,&lt;br /&gt;
    author: &#039;slu@innovaphone.com&#039;,&lt;br /&gt;
    enabled: true,&lt;br /&gt;
    schedule: &#039;10m&#039;,&lt;br /&gt;
    &lt;br /&gt;
    commands: {&lt;br /&gt;
        cdr0: {&lt;br /&gt;
            cmd: &#039;!mod cmd CDR0 qs&#039;,&lt;br /&gt;
            cat: [&#039;gw&#039;],&lt;br /&gt;
        },&lt;br /&gt;
        cdr1: {&lt;br /&gt;
            cmd: &#039;!mod cmd CDR1 qs&#039;,&lt;br /&gt;
            cat: [&#039;gw&#039;],&lt;br /&gt;
        },&lt;br /&gt;
        cdr2: {&lt;br /&gt;
            cmd: &#039;!mod cmd CDR2 qs&#039;,&lt;br /&gt;
            cat: [&#039;gw&#039;],&lt;br /&gt;
        },&lt;br /&gt;
        cdr3: {&lt;br /&gt;
            cmd: &#039;!mod cmd CDR3 qs&#039;,&lt;br /&gt;
            cat: [&#039;gw&#039;],&lt;br /&gt;
        },&lt;br /&gt;
        cdr4: {&lt;br /&gt;
            cmd: &#039;!mod cmd CDR4 qs&#039;,&lt;br /&gt;
            cat: [&#039;gw&#039;],&lt;br /&gt;
        },&lt;br /&gt;
    },&lt;br /&gt;
    &lt;br /&gt;
    test: function (cmd, results, storage) {&lt;br /&gt;
        var log = [];&lt;br /&gt;
        var success = true;&lt;br /&gt;
        &lt;br /&gt;
        for (var n = 0; n &amp;lt; 5; n++) {&lt;br /&gt;
            Object.keys(results[&#039;cdr&#039;+n]).forEach(function(i){&lt;br /&gt;
                var check = calculate_cdrs(results[&#039;cdr&#039;+n][i]);&lt;br /&gt;
                // result was not good, lets create a human error message&lt;br /&gt;
                if (check !== true) {&lt;br /&gt;
                    log.push(cmd.get_device(i).product+&#039; / &#039;+cmd.get_device(i).hwId+&#039; / &#039;+check+&#039;% - &#039;+results[&#039;cdr&#039;+n][i]);&lt;br /&gt;
                    if (success) success = false;&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    &lt;br /&gt;
        return {&lt;br /&gt;
            success: success,&lt;br /&gt;
            msg: success ? &#039;&#039; : &#039;Devices with buffered CDRs exists&#039;,&lt;br /&gt;
            log: log&lt;br /&gt;
        };&lt;br /&gt;
    &lt;br /&gt;
        function calculate_cdrs(str) {&lt;br /&gt;
            // QS messages: 0 max 2000 chars: 0 max 300000&lt;br /&gt;
            var check = 0;&lt;br /&gt;
            str = str.split(&#039; &#039;);&lt;br /&gt;
            // log.push(str);&lt;br /&gt;
        &lt;br /&gt;
            var messages_current = str[2];&lt;br /&gt;
            var messages_max = str[4];&lt;br /&gt;
            var chars_current = str[6];&lt;br /&gt;
            var chars_max = str[8];&lt;br /&gt;
        &lt;br /&gt;
            // check messages&lt;br /&gt;
            check = cmd.percent(messages_current, messages_max);&lt;br /&gt;
            if (check &amp;gt;= 30) return check;&lt;br /&gt;
        &lt;br /&gt;
            // check chars&lt;br /&gt;
            check = cmd.percent(chars_current, chars_max);&lt;br /&gt;
            if (check &amp;gt;= 30) return check;&lt;br /&gt;
        &lt;br /&gt;
            return true;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Complete sample test to check firmware versions =====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
tests_add.firmware_version = tests_add.firmware_version || {&lt;br /&gt;
    title: &#039;Supported firmware versions&#039;,&lt;br /&gt;
    description: &#039;Check if you have unsupported firmware version in use&#039;,&lt;br /&gt;
    todo: &#039;Update the firmware on affected devices&#039;,&lt;br /&gt;
    author: &#039;slu@innovaphone.com&#039;,&lt;br /&gt;
    schedule: &#039;1d&#039;,&lt;br /&gt;
    commands: {&lt;br /&gt;
        box_info: {&lt;br /&gt;
            cmd: &#039;CMD0/box_info.xml&#039;,&lt;br /&gt;
        },&lt;br /&gt;
    },&lt;br /&gt;
    &lt;br /&gt;
    test: function (cmd, results, storage) {&lt;br /&gt;
        var log = [];&lt;br /&gt;
        var success = true;&lt;br /&gt;
        var msg = &#039;&#039;;&lt;br /&gt;
        &lt;br /&gt;
        Object.keys(results.box_info).forEach(function(i){&lt;br /&gt;
            var xml = cmd.parse_xml(results.box_info[i]);&lt;br /&gt;
            if (typeof xml.info === &#039;undefined&#039;) return;&lt;br /&gt;
            if (typeof xml.info.sys === &#039;undefined&#039;) return;&lt;br /&gt;
            if (typeof xml.info.sys[&#039;@version&#039;] === &#039;undefined&#039;) return;&lt;br /&gt;
            &lt;br /&gt;
            if (&lt;br /&gt;
                xml.info.sys[&#039;@version&#039;].includes(&#039;6.00&#039;) ||&lt;br /&gt;
                xml.info.sys[&#039;@version&#039;].includes(&#039;7.00&#039;) ||&lt;br /&gt;
                xml.info.sys[&#039;@version&#039;].includes(&#039;8.00&#039;) ||&lt;br /&gt;
                xml.info.sys[&#039;@version&#039;].includes(&#039;9.00&#039;) ||&lt;br /&gt;
                xml.info.sys[&#039;@version&#039;].includes(&#039;10.00&#039;) ||&lt;br /&gt;
                xml.info.sys[&#039;@version&#039;].includes(&#039;11.00&#039;) ||&lt;br /&gt;
                xml.info.sys[&#039;@version&#039;].includes(&#039;11r1&#039;) ||&lt;br /&gt;
                xml.info.sys[&#039;@version&#039;].includes(&#039;12r1&#039;) ||&lt;br /&gt;
                xml.info.sys[&#039;@version&#039;].includes(&#039;13r1&#039;)&lt;br /&gt;
            ) {&lt;br /&gt;
                log.push(cmd.get_device(i).product+&#039; / &#039;+cmd.get_device(i).hwId+&#039; / &#039;+xml.info.sys[&#039;@version&#039;]);&lt;br /&gt;
                if (success) success = false;&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
        &lt;br /&gt;
        return {&lt;br /&gt;
            success: success,&lt;br /&gt;
            msg: success ? &#039;&#039; : &#039;You use old firmware which is no longer be supported&#039;,&lt;br /&gt;
            log: log&lt;br /&gt;
        };&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== cmd object ====&lt;br /&gt;
The &#039;&#039;&#039;cmd&#039;&#039;&#039; object provides you the following methods:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== get device information / system information =====&lt;br /&gt;
&lt;br /&gt;
====== get_build() : object ======&lt;br /&gt;
You will receive back the current version build of the app&lt;br /&gt;
&lt;br /&gt;
&amp;lt;spoiler show=&amp;quot;show sample code&amp;quot; hide=&amp;quot;hide sample code&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var build = cmd.get_build();&lt;br /&gt;
console.log(build);&lt;br /&gt;
// 15012456&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/spoiler&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== get_domains() : object ======&lt;br /&gt;
You will receive all existing domains&lt;br /&gt;
&lt;br /&gt;
&amp;lt;spoiler show=&amp;quot;show sample code&amp;quot; hide=&amp;quot;hide sample code&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var domains = cmd.get_domains();&lt;br /&gt;
console.log(domains);&lt;br /&gt;
{&lt;br /&gt;
 &amp;quot;1&amp;quot;: {&lt;br /&gt;
   &amp;quot;id&amp;quot;: 1,&lt;br /&gt;
   &amp;quot;name&amp;quot;: &amp;quot;slu.de&amp;quot;,&lt;br /&gt;
   &amp;quot;deployAdminPasswords&amp;quot;: true,&lt;br /&gt;
   &amp;quot;isInstanceDomain&amp;quot;: true,&lt;br /&gt;
   &amp;quot;categories&amp;quot;: [ ... ]&lt;br /&gt;
 }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/spoiler&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== get_devices() : object ======&lt;br /&gt;
You will receive all existing devices&lt;br /&gt;
&lt;br /&gt;
&amp;lt;spoiler show=&amp;quot;show sample code&amp;quot; hide=&amp;quot;hide sample code&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var devices = cmd.get_devices();&lt;br /&gt;
console.log(devices);&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;0_009033420623&amp;quot;: {&lt;br /&gt;
    &amp;quot;id&amp;quot;: &amp;quot;0_009033420623&amp;quot;,&lt;br /&gt;
    &amp;quot;hwId&amp;quot;: &amp;quot;009033420623&amp;quot;,&lt;br /&gt;
    &amp;quot;domainId&amp;quot;: 0,&lt;br /&gt;
    &amp;quot;product&amp;quot;: &amp;quot;IP0011&amp;quot;,&lt;br /&gt;
    &amp;quot;version&amp;quot;: &amp;quot;13r3 dvl [13.7526/132035/600]&amp;quot;,&lt;br /&gt;
    &amp;quot;type&amp;quot;: &amp;quot;GW&amp;quot;,&lt;br /&gt;
    &amp;quot;pbxActive&amp;quot;: false,&lt;br /&gt;
    &amp;quot;online&amp;quot;: true,&lt;br /&gt;
    &amp;quot;ethIfs&amp;quot;: [ ... ]&lt;br /&gt;
  },&lt;br /&gt;
  &amp;quot;1&amp;quot;: {&lt;br /&gt;
    &amp;quot;id&amp;quot;: 1,&lt;br /&gt;
    &amp;quot;hwId&amp;quot;: &amp;quot;009033420621&amp;quot;,&lt;br /&gt;
    &amp;quot;name&amp;quot;: &amp;quot;PBX - pbx.slu.de&amp;quot;,&lt;br /&gt;
    &amp;quot;domainId&amp;quot;: 1,&lt;br /&gt;
    &amp;quot;product&amp;quot;: &amp;quot;IP0011&amp;quot;,&lt;br /&gt;
    &amp;quot;version&amp;quot;: &amp;quot;13r3 beta4 [13.7688/137623/600]&amp;quot;,&lt;br /&gt;
    &amp;quot;type&amp;quot;: &amp;quot;GW&amp;quot;,&lt;br /&gt;
    &amp;quot;pbxActive&amp;quot;: true,&lt;br /&gt;
    &amp;quot;online&amp;quot;: true,&lt;br /&gt;
    &amp;quot;ethIfs&amp;quot;: [ ... ]&lt;br /&gt;
  },&lt;br /&gt;
  &amp;quot;2&amp;quot;: {&lt;br /&gt;
    &amp;quot;id&amp;quot;: 2,&lt;br /&gt;
    &amp;quot;hwId&amp;quot;: &amp;quot;029033420621&amp;quot;,&lt;br /&gt;
    &amp;quot;name&amp;quot;: &amp;quot;AP - apps.slu.de&amp;quot;,&lt;br /&gt;
    &amp;quot;domainId&amp;quot;: 1,&lt;br /&gt;
    &amp;quot;product&amp;quot;: &amp;quot;AppPlatform ARM&amp;quot;,&lt;br /&gt;
    &amp;quot;version&amp;quot;: &amp;quot;110002 dvl (13r3 137688 beta4 )&amp;quot;,&lt;br /&gt;
    &amp;quot;type&amp;quot;: &amp;quot;APP_PLATFORM&amp;quot;,&lt;br /&gt;
    &amp;quot;pbxActive&amp;quot;: false,&lt;br /&gt;
    &amp;quot;online&amp;quot;: true,&lt;br /&gt;
    &amp;quot;ethIfs&amp;quot;: [ ... ]&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/spoiler&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== get_devices_from_domain(int id) : object ======&lt;br /&gt;
You will receive all devices which are assigned to the given domain&lt;br /&gt;
&lt;br /&gt;
&amp;lt;spoiler show=&amp;quot;show sample code&amp;quot; hide=&amp;quot;hide sample code&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var devices = cmd.get_devices_from_domain(1);&lt;br /&gt;
console.log(devices);&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;1&amp;quot;: {&lt;br /&gt;
    &amp;quot;id&amp;quot;: 1,&lt;br /&gt;
    &amp;quot;hwId&amp;quot;: &amp;quot;009033420621&amp;quot;,&lt;br /&gt;
    &amp;quot;name&amp;quot;: &amp;quot;PBX - pbx.slu.de&amp;quot;,&lt;br /&gt;
    &amp;quot;domainId&amp;quot;: 1,&lt;br /&gt;
    &amp;quot;product&amp;quot;: &amp;quot;IP0011&amp;quot;,&lt;br /&gt;
    &amp;quot;version&amp;quot;: &amp;quot;13r3 beta4 [13.7688/137623/600]&amp;quot;,&lt;br /&gt;
    &amp;quot;type&amp;quot;: &amp;quot;GW&amp;quot;,&lt;br /&gt;
    &amp;quot;pbxActive&amp;quot;: true,&lt;br /&gt;
    &amp;quot;online&amp;quot;: true,&lt;br /&gt;
    &amp;quot;ethIfs&amp;quot;: [ ... ]&lt;br /&gt;
  },&lt;br /&gt;
  &amp;quot;2&amp;quot;: {&lt;br /&gt;
    &amp;quot;id&amp;quot;: 2,&lt;br /&gt;
    &amp;quot;hwId&amp;quot;: &amp;quot;029033420621&amp;quot;,&lt;br /&gt;
    &amp;quot;name&amp;quot;: &amp;quot;AP - apps.slu.de&amp;quot;,&lt;br /&gt;
    &amp;quot;domainId&amp;quot;: 1,&lt;br /&gt;
    &amp;quot;product&amp;quot;: &amp;quot;AppPlatform ARM&amp;quot;,&lt;br /&gt;
    &amp;quot;version&amp;quot;: &amp;quot;110002 dvl (13r3 137688 beta4 )&amp;quot;,&lt;br /&gt;
    &amp;quot;type&amp;quot;: &amp;quot;APP_PLATFORM&amp;quot;,&lt;br /&gt;
    &amp;quot;pbxActive&amp;quot;: false,&lt;br /&gt;
    &amp;quot;online&amp;quot;: true,&lt;br /&gt;
    &amp;quot;ethIfs&amp;quot;: [ ... ]&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/spoiler&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== get_device(int id) : object ======&lt;br /&gt;
You will receive a specific device&lt;br /&gt;
&lt;br /&gt;
&amp;lt;spoiler show=&amp;quot;show sample code&amp;quot; hide=&amp;quot;hide sample code&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var device = cmd.get_device(2);&lt;br /&gt;
console.log(device);&lt;br /&gt;
{&lt;br /&gt;
   &amp;quot;id&amp;quot;: 2,&lt;br /&gt;
   &amp;quot;hwId&amp;quot;: &amp;quot;029033420621&amp;quot;,&lt;br /&gt;
   &amp;quot;name&amp;quot;: &amp;quot;AP - apps.slu.de&amp;quot;,&lt;br /&gt;
   &amp;quot;domainId&amp;quot;: 1,&lt;br /&gt;
   &amp;quot;product&amp;quot;: &amp;quot;AppPlatform ARM&amp;quot;,&lt;br /&gt;
   &amp;quot;version&amp;quot;: &amp;quot;110002 dvl (13r3 137688 beta4 )&amp;quot;,&lt;br /&gt;
   &amp;quot;type&amp;quot;: &amp;quot;APP_PLATFORM&amp;quot;,&lt;br /&gt;
   &amp;quot;pbxActive&amp;quot;: false,&lt;br /&gt;
   &amp;quot;online&amp;quot;: true,&lt;br /&gt;
   &amp;quot;ethIfs&amp;quot;: [ ... ]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/spoiler&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== helper functions =====&lt;br /&gt;
&lt;br /&gt;
====== percent(int value, int total) : float ======&lt;br /&gt;
Returns the number of percent of value to total&lt;br /&gt;
&lt;br /&gt;
&amp;lt;spoiler show=&amp;quot;show sample code&amp;quot; hide=&amp;quot;hide sample code&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var check = cmd.percent(50, 100);&lt;br /&gt;
console.log(check);&lt;br /&gt;
50&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/spoiler&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== parse_xml(string xml, string element = &amp;lt;nowiki&amp;gt;&#039;&#039;&amp;lt;/nowiki&amp;gt;) : object ======&lt;br /&gt;
Returns an object/array representation of given XML string. Note that very large XML inputs cannot be converted directly because there are some restrictions in the duktape environment. If you receive an exception with &#039;&#039;Error: RangeError: regexp executor recursion limit&#039;&#039; you have to define which element do you want to converted (See the second example).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;spoiler show=&amp;quot;show sample code&amp;quot; hide=&amp;quot;hide sample code&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var json = cmd.parse_xml(&#039;&amp;lt;sample&amp;gt;&amp;lt;item property_1=&amp;quot;value_1&amp;quot; property_2=&amp;quot;value_2&amp;quot;&amp;gt;content of item&amp;lt;/item&amp;gt;&amp;lt;item_short prop_1=&amp;quot;value_prop_1&amp;quot; /&amp;gt;&amp;lt;/sample&amp;gt;&#039;);&lt;br /&gt;
console.log(json);&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;sample&amp;quot;: {&lt;br /&gt;
    &amp;quot;item&amp;quot;: {&lt;br /&gt;
      &amp;quot;@property_1&amp;quot;: &amp;quot;value_1&amp;quot;,&lt;br /&gt;
      &amp;quot;@property_2&amp;quot;: &amp;quot;value_2&amp;quot;,&lt;br /&gt;
      &amp;quot;#&amp;quot;: &amp;quot;content of item&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    &amp;quot;item_short&amp;quot;: {&lt;br /&gt;
      &amp;quot;@prop_1&amp;quot;: &amp;quot;value_prop_1&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/spoiler&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;spoiler show=&amp;quot;show sample code with large xml payload&amp;quot; hide=&amp;quot;hide sample code with large xml payload&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
var xml_registrations_on_big_pbx = &#039;\&lt;br /&gt;
  &amp;lt;show state=&amp;quot;up&amp;quot; time=&amp;quot;267993&amp;quot; loc=&amp;quot;pbx&amp;quot;&amp;gt;\&lt;br /&gt;
    &amp;lt;attrs&amp;gt;&amp;lt;/attrs&amp;gt;\&lt;br /&gt;
    &amp;lt;reg cn=&amp;quot;Fax&amp;quot; guid=&amp;quot;829a6aeec2a76401c62600155d50c817&amp;quot; h323=&amp;quot;fax&amp;quot; pwd=&amp;quot;********&amp;quot; pwdx=&amp;quot;********&amp;quot; prot=&amp;quot;JSON&amp;quot;&amp;gt;\&lt;br /&gt;
      &amp;lt;ep type=&amp;quot;gk&amp;quot; addr=&amp;quot;172.16.176.205&amp;quot; time=&amp;quot;10&amp;quot;/&amp;gt;\&lt;br /&gt;
      &amp;lt;pseudo-common lics=&amp;quot;.reporting.&amp;quot;/&amp;gt;\&lt;br /&gt;
      &amp;lt;pseudo type=&amp;quot;fax&amp;quot;/&amp;gt;\&lt;br /&gt;
    &amp;lt;/reg&amp;gt;\&lt;br /&gt;
    &amp;lt;reg cn=&amp;quot;Voicemail de&amp;quot; guid=&amp;quot;5ceb0ee7c2a76401bb2600155d50c817&amp;quot; h323=&amp;quot;voicemail-de&amp;quot; pwd=&amp;quot;********&amp;quot; pwdx=&amp;quot;********&amp;quot; prot=&amp;quot;JSON&amp;quot;&amp;gt;\&lt;br /&gt;
      &amp;lt;ep type=&amp;quot;gk&amp;quot; addr=&amp;quot;172.16.176.205&amp;quot; time=&amp;quot;10&amp;quot;/&amp;gt;\&lt;br /&gt;
      &amp;lt;pseudo-common lics=&amp;quot;.uc.voicemail.reporting.&amp;quot;/&amp;gt;\&lt;br /&gt;
      &amp;lt;pseudo type=&amp;quot;vm&amp;quot;/&amp;gt;\&lt;br /&gt;
    &amp;lt;/reg&amp;gt;\&lt;br /&gt;
    ... and so on ...\&lt;br /&gt;
  &amp;lt;/show&amp;gt;&#039;;&lt;br /&gt;
var json = cmd.parse_xml(xml_registrations_on_big_pbx, &#039;reg&#039;);&lt;br /&gt;
console.log(json);&lt;br /&gt;
[&lt;br /&gt;
  {&amp;quot;@cn&amp;quot;:&amp;quot;Fax&amp;quot;, &amp;quot;@guid&amp;quot;:&amp;quot;829a6aeec2a76401c62600155d50c817&amp;quot;, ... &amp;quot;ep&amp;quot;:{&amp;quot;@type&amp;quot;:&amp;quot;gk&amp;quot;,&amp;quot;@addr&amp;quot;:&amp;quot;172.16.176.205&amp;quot;,&amp;quot;@time&amp;quot;:&amp;quot;10&amp;quot;}, ...},&lt;br /&gt;
  {&amp;quot;@cn&amp;quot;:&amp;quot;Voicemail&amp;quot;, &amp;quot;@guid&amp;quot;:&amp;quot;5ceb0ee7c2a76401bb2600155d50c817&amp;quot;, ... &amp;quot;ep&amp;quot;:{&amp;quot;@type&amp;quot;:&amp;quot;gk&amp;quot;,&amp;quot;@addr&amp;quot;:&amp;quot;172.16.176.205&amp;quot;,&amp;quot;@time&amp;quot;:&amp;quot;10&amp;quot;}, ...},&lt;br /&gt;
  ...&lt;br /&gt;
]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/spoiler&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== is_supported_version(string version) : object ======&lt;br /&gt;
Return if the given Version string is supported according to [[Howto:Supported innovaphone versions]].&lt;br /&gt;
&amp;lt;spoiler show=&amp;quot;show sample code&amp;quot; hide=&amp;quot;hide sample code&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
cmd.is_supported_version(&#039;13r3 sr9 [13.7886/1000/0]&#039;); // return &amp;quot;true&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/spoiler&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== get_version_from_build(int build) : string ======&lt;br /&gt;
Return the named version from given build number. (13r3, 14r1 or similar)&lt;br /&gt;
&amp;lt;spoiler show=&amp;quot;show sample code&amp;quot; hide=&amp;quot;hide sample code&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
cmd.get_version_from_build(1410485); // return &amp;quot;14r1&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/spoiler&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== get_pbx_objects_from_config(string config) : array =====&lt;br /&gt;
Extract from a config file PBX Objects with support for different views, DynPBXes and the removal of marks-as-deleted objects&lt;br /&gt;
&amp;lt;spoiler show=&amp;quot;show sample code&amp;quot; hide=&amp;quot;hide sample code&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
// &amp;quot;config&amp;quot; contains the result from your &amp;quot;cfg.txt&amp;quot;&lt;br /&gt;
cmd.get_pbx_objects_from_config(config); &lt;br /&gt;
// return &lt;br /&gt;
[&lt;br /&gt;
   &amp;quot;mod cmd FLASHDIR0 add-item 102 (cn=user-1)(h323=user-1)(e164=10)&amp;quot;,&lt;br /&gt;
   &amp;quot;mod cmd FLASHDIR0 add-item 102 (cn=user-2)(h323=user-2)(e164=20)&amp;quot;,&lt;br /&gt;
   &amp;quot;mod cmd FLASHDIR0 add-item 105 (cn=user-1-in-dynpbx)(h323=user-1-in-dynpbx)(e164=50)&amp;quot;,&lt;br /&gt;
]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/spoiler&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== debug =====&lt;br /&gt;
&lt;br /&gt;
====== log(string message) : void ======&lt;br /&gt;
You can write a logfile line to the app debug log&lt;br /&gt;
&lt;br /&gt;
&amp;lt;spoiler show=&amp;quot;show sample code&amp;quot; hide=&amp;quot;hide sample code&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
var domains = cmd.log(&#039;my first logfile line&#039;);&lt;br /&gt;
07-26 07:58:33.179 TechAssist@slu.de (b0728708) | Test &amp;quot;sample_test&amp;quot; | my first logfile line&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/spoiler&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Secret knowledge for good tests ===&lt;br /&gt;
; use &amp;quot;get_pbx_objects_from_config()&amp;quot; to get Objects from PBX config&lt;br /&gt;
: To really get all the required objects (dyn PBXes, different views, deleted objects), there are a few things to consider. It is therefore advisable to always use this function in a test.&lt;br /&gt;
; bool PBX-Object config attributes&lt;br /&gt;
: You will find config attributes like &amp;lt;code&amp;gt;no-subscribe=&amp;quot;true&amp;quot;&amp;lt;/code&amp;gt; (this is from a Trunk Object) in the config. Please note that if the attribute is &#039;&#039;missing&#039;&#039; or the value is &#039;&#039;false&#039;&#039; it is false, otherwise it is &#039;&#039;true&#039;&#039;. For example, the value &amp;lt;code&amp;gt;no-subscribe=&amp;quot;on&amp;quot;&amp;lt;/code&amp;gt; is also true.&lt;br /&gt;
; bool Interface config attributes&lt;br /&gt;
: You will find config attributes like &amp;lt;code&amp;gt;/direct-sig on&amp;lt;/code&amp;gt; (this is from a SIP interface) in the config. Please note that they are exists bool-attribute which are &#039;&#039;true&#039;&#039; if the attribute is existing. In the case of bool-attribute the following value make no matter. For example, the attribute &amp;lt;code&amp;gt;/direct-sig off&amp;lt;/code&amp;gt; is also true.&lt;br /&gt;
&lt;br /&gt;
== Monitoring ==&lt;br /&gt;
The App supports a monitoring interface where well known IT-Monitoring Systems or other Statistics Services can connect and collect various data for the whole innovaphone installation.&lt;br /&gt;
&lt;br /&gt;
===Requirements===&lt;br /&gt;
* Only devices that are known by the &#039;&#039;Devices App&#039;&#039; will be included in the monitoring data&lt;br /&gt;
* Only devices that have a non-empty &amp;quot;Name&amp;quot; in the &#039;&#039;Devices App&#039;&#039; will be included in the monitoring data&lt;br /&gt;
* Depending on your monitoring system (to support the automatic host matching magic) it can be needed that all devices has the same &#039;&#039;Name&#039;&#039; in your &#039;&#039;Devices App&#039;&#039; and your external System (Usually the FQDN is used)&lt;br /&gt;
&lt;br /&gt;
===Configurations===&lt;br /&gt;
* In Settings, you have to configure the credentials for the HTTP authorization to get monitoring data&lt;br /&gt;
* In the TechAssist App in the settings area, you have to:&lt;br /&gt;
** enable/disable the whole monitoring feature. Default is disabled.&lt;br /&gt;
** select categories (PBXes, Gateways, AP Platforms, Apps, DECT, Phones) which should be included in the monitoring data&lt;br /&gt;
* For all app services that provide statistics, the TechAssist app object must have access rights to these apps (the apps must be checked in the &amp;quot;Apps&amp;quot; tab of the PBX object)&lt;br /&gt;
** All Metrics will be placed (in the monitoring output) at the AP where TechAssist is running&lt;br /&gt;
&lt;br /&gt;
===Internal Timers===&lt;br /&gt;
*The data for monitoring systems will be updated every 15 minutes by default. You can adjust this timer in the App Settings.&lt;br /&gt;
*App Metrics will be updated every 1 minute internally&lt;br /&gt;
*App Metrics for the TechAssist itself always have live values&lt;br /&gt;
&lt;br /&gt;
=== HTTP Response Codes ===&lt;br /&gt;
&lt;br /&gt;
* 501 - Monitoring feature is disabled...&lt;br /&gt;
* 503 - Service is starting... | You have to try it again later. The app service is starting.&lt;br /&gt;
* 503 - Data will be collected... | You have to try it again later. The first bunch of data will be collected at this moment.&lt;br /&gt;
&lt;br /&gt;
===Internal Cached Monitoring Data===&lt;br /&gt;
The monitoring data is cached internally. After starting the app, no monitoring data is processed at all to save resources if this function is not used.&lt;br /&gt;
If the first call is made to an interface, the data is prepared in Background and you will get a &amp;quot;503 - Data will be collected...&amp;quot;. This means that the first call fails. From then on, the app knows that monitoring data is being retrieved and prepares the data in a 1-minute interval so that a call to the monitoring system receives the cached data.&lt;br /&gt;
&lt;br /&gt;
===Supported Integrations===&lt;br /&gt;
We support various output formats over different interfaces. Your System can pull the information and append in the needed Interface/Format to the URL. &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Example: https://apps.slu.de/slu.de/techassist/monitoring/JSON (Here is &amp;quot;JSON&amp;quot; the used interface, see below)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you use an old/legacy system that only support http basic-auth instead of digest-auth you can add a &amp;quot;/basic&amp;quot; to the endpoint url. &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Example: https://&amp;lt;/nowiki&amp;gt;apps.slu.de/slu.de/techassist&#039;&#039;&#039;/basic&#039;&#039;&#039;/monitoring/JSON&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== RAW ====&lt;br /&gt;
The interface &amp;quot;/RAW&amp;quot; provides the internal TechAssist format as JSON.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;spoiler show=&amp;quot;show sample output&amp;quot; hide=&amp;quot;hide sample output&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
[&lt;br /&gt;
  {&lt;br /&gt;
    &amp;quot;id&amp;quot;: &amp;quot;1&amp;quot;,&lt;br /&gt;
    &amp;quot;title&amp;quot;: &amp;quot;pbx.domain.de&amp;quot;,&lt;br /&gt;
    &amp;quot;metrics&amp;quot;: [&lt;br /&gt;
      {&lt;br /&gt;
        &amp;quot;id&amp;quot;: &amp;quot;online&amp;quot;,&lt;br /&gt;
        &amp;quot;value&amp;quot;: 1,&lt;br /&gt;
        &amp;quot;valuePercent&amp;quot;: null,&lt;br /&gt;
        &amp;quot;comment&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
        &amp;quot;min&amp;quot;: null,&lt;br /&gt;
        &amp;quot;max&amp;quot;: null&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        &amp;quot;id&amp;quot;: &amp;quot;serialnumber&amp;quot;,&lt;br /&gt;
        &amp;quot;value&amp;quot;: &amp;quot;005056001338&amp;quot;,&lt;br /&gt;
        &amp;quot;valuePercent&amp;quot;: null,&lt;br /&gt;
        &amp;quot;comment&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
        &amp;quot;min&amp;quot;: null,&lt;br /&gt;
        &amp;quot;max&amp;quot;: null&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        &amp;quot;id&amp;quot;: &amp;quot;product&amp;quot;,&lt;br /&gt;
        &amp;quot;value&amp;quot;: &amp;quot;IPVA&amp;quot;,&lt;br /&gt;
        &amp;quot;valuePercent&amp;quot;: null,&lt;br /&gt;
        &amp;quot;comment&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
        &amp;quot;min&amp;quot;: null,&lt;br /&gt;
        &amp;quot;max&amp;quot;: null&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        &amp;quot;id&amp;quot;: &amp;quot;version&amp;quot;,&lt;br /&gt;
        &amp;quot;value&amp;quot;: &amp;quot;15r1 dvl [15.1.0130/1000/0]&amp;quot;,&lt;br /&gt;
        &amp;quot;valuePercent&amp;quot;: null,&lt;br /&gt;
        &amp;quot;comment&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
        &amp;quot;min&amp;quot;: null,&lt;br /&gt;
        &amp;quot;max&amp;quot;: null&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        &amp;quot;id&amp;quot;: &amp;quot;versionIsSupported&amp;quot;,&lt;br /&gt;
        &amp;quot;value&amp;quot;: 1,&lt;br /&gt;
        &amp;quot;valuePercent&amp;quot;: null,&lt;br /&gt;
        &amp;quot;comment&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
        &amp;quot;min&amp;quot;: null,&lt;br /&gt;
        &amp;quot;max&amp;quot;: null&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        &amp;quot;id&amp;quot;: &amp;quot;uptime&amp;quot;,&lt;br /&gt;
        &amp;quot;value&amp;quot;: 2747,&lt;br /&gt;
        &amp;quot;valuePercent&amp;quot;: null,&lt;br /&gt;
        &amp;quot;comment&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
        &amp;quot;min&amp;quot;: null,&lt;br /&gt;
        &amp;quot;max&amp;quot;: null&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        &amp;quot;id&amp;quot;: &amp;quot;CPU&amp;quot;,&lt;br /&gt;
        &amp;quot;value&amp;quot;: 1,&lt;br /&gt;
        &amp;quot;valuePercent&amp;quot;: 1,&lt;br /&gt;
        &amp;quot;comment&amp;quot;: null,&lt;br /&gt;
        &amp;quot;min&amp;quot;: 0,&lt;br /&gt;
        &amp;quot;max&amp;quot;: 100&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        &amp;quot;id&amp;quot;: &amp;quot;CPU-R&amp;quot;,&lt;br /&gt;
        &amp;quot;value&amp;quot;: 0,&lt;br /&gt;
        &amp;quot;valuePercent&amp;quot;: 0,&lt;br /&gt;
        &amp;quot;comment&amp;quot;: null,&lt;br /&gt;
        &amp;quot;min&amp;quot;: 0,&lt;br /&gt;
        &amp;quot;max&amp;quot;: 26000&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        &amp;quot;id&amp;quot;: &amp;quot;MEM&amp;quot;,&lt;br /&gt;
        &amp;quot;value&amp;quot;: 46,&lt;br /&gt;
        &amp;quot;valuePercent&amp;quot;: 0.09,&lt;br /&gt;
        &amp;quot;comment&amp;quot;: null,&lt;br /&gt;
        &amp;quot;min&amp;quot;: 0,&lt;br /&gt;
        &amp;quot;max&amp;quot;: 49793&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        &amp;quot;id&amp;quot;: &amp;quot;ETH0&amp;quot;,&lt;br /&gt;
        &amp;quot;value&amp;quot;: 10,&lt;br /&gt;
        &amp;quot;valuePercent&amp;quot;: 0,&lt;br /&gt;
        &amp;quot;comment&amp;quot;: null,&lt;br /&gt;
        &amp;quot;min&amp;quot;: 0,&lt;br /&gt;
        &amp;quot;max&amp;quot;: 1000000&lt;br /&gt;
      }&lt;br /&gt;
    ]&lt;br /&gt;
  },&lt;br /&gt;
  {&lt;br /&gt;
    &amp;quot;id&amp;quot;: &amp;quot;47&amp;quot;,&lt;br /&gt;
    &amp;quot;title&amp;quot;: &amp;quot;ap.domain.de&amp;quot;,&lt;br /&gt;
    &amp;quot;metrics&amp;quot;: [&lt;br /&gt;
      {&lt;br /&gt;
        &amp;quot;id&amp;quot;: &amp;quot;online&amp;quot;,&lt;br /&gt;
        &amp;quot;value&amp;quot;: 1,&lt;br /&gt;
        &amp;quot;valuePercent&amp;quot;: null,&lt;br /&gt;
        &amp;quot;comment&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
        &amp;quot;min&amp;quot;: null,&lt;br /&gt;
        &amp;quot;max&amp;quot;: null&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        &amp;quot;id&amp;quot;: &amp;quot;serialnumber&amp;quot;,&lt;br /&gt;
        &amp;quot;value&amp;quot;: &amp;quot;00155db3c306&amp;quot;,&lt;br /&gt;
        &amp;quot;valuePercent&amp;quot;: null,&lt;br /&gt;
        &amp;quot;comment&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
        &amp;quot;min&amp;quot;: null,&lt;br /&gt;
        &amp;quot;max&amp;quot;: null&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        &amp;quot;id&amp;quot;: &amp;quot;product&amp;quot;,&lt;br /&gt;
        &amp;quot;value&amp;quot;: &amp;quot;AppPlatform x86_64&amp;quot;,&lt;br /&gt;
        &amp;quot;valuePercent&amp;quot;: null,&lt;br /&gt;
        &amp;quot;comment&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
        &amp;quot;min&amp;quot;: null,&lt;br /&gt;
        &amp;quot;max&amp;quot;: null&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        &amp;quot;id&amp;quot;: &amp;quot;version&amp;quot;,&lt;br /&gt;
        &amp;quot;value&amp;quot;: &amp;quot;120010  (15r1 1510130 dvl )&amp;quot;,&lt;br /&gt;
        &amp;quot;valuePercent&amp;quot;: null,&lt;br /&gt;
        &amp;quot;comment&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
        &amp;quot;min&amp;quot;: null,&lt;br /&gt;
        &amp;quot;max&amp;quot;: null&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        &amp;quot;id&amp;quot;: &amp;quot;versionIsSupported&amp;quot;,&lt;br /&gt;
        &amp;quot;value&amp;quot;: 1,&lt;br /&gt;
        &amp;quot;valuePercent&amp;quot;: null,&lt;br /&gt;
        &amp;quot;comment&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
        &amp;quot;min&amp;quot;: null,&lt;br /&gt;
        &amp;quot;max&amp;quot;: null&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;&amp;quot;&lt;br /&gt;
    ]&lt;br /&gt;
  }&lt;br /&gt;
]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/spoiler&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== CSV ====&lt;br /&gt;
The interface &amp;quot;/CSV&amp;quot; provides a simple text based comma separated structure.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;spoiler show=&amp;quot;show sample output&amp;quot; hide=&amp;quot;hide sample output&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;Hostname&amp;gt;;&amp;lt;Metric&amp;gt;;&amp;lt;Value&amp;gt;;&amp;lt;Result&amp;gt;;&amp;lt;Comment&amp;gt;&lt;br /&gt;
pbx.domain.de;&amp;quot;online&amp;quot;;true;&lt;br /&gt;
pbx.domain.de;&amp;quot;serialnumber&amp;quot;;005056001338;&lt;br /&gt;
pbx.domain.de;&amp;quot;product&amp;quot;;IPVA;&lt;br /&gt;
pbx.domain.de;&amp;quot;version&amp;quot;;15r1 dvl [15.1.0130/1000/0];&lt;br /&gt;
pbx.domain.de;&amp;quot;versionIsSupported&amp;quot;;true;&lt;br /&gt;
pbx.domain.de;&amp;quot;uptime&amp;quot;;3050;&lt;br /&gt;
pbx.domain.de;&amp;quot;CPU&amp;quot;;2;null&lt;br /&gt;
pbx.domain.de;&amp;quot;CPU-R&amp;quot;;0;null&lt;br /&gt;
pbx.domain.de;&amp;quot;MEM&amp;quot;;0.09;null&lt;br /&gt;
pbx.domain.de;&amp;quot;ETH0&amp;quot;;18;null&lt;br /&gt;
ap.domain.de;&amp;quot;online&amp;quot;;true;&lt;br /&gt;
ap.domain.de;&amp;quot;serialnumber&amp;quot;;00155db3c306;&lt;br /&gt;
ap.domain.de;&amp;quot;product&amp;quot;;AppPlatform x86_64;&lt;br /&gt;
ap.domain.de;&amp;quot;version&amp;quot;;120010  (15r1 1510130 dvl );&lt;br /&gt;
ap.domain.de;&amp;quot;versionIsSupported&amp;quot;;true;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/spoiler&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== JSON ====&lt;br /&gt;
The interface &amp;quot;/JSON&amp;quot; provides a JSON formatted structure.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;spoiler show=&amp;quot;show sample output&amp;quot; hide=&amp;quot;hide sample output&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;pbx.domain.de&amp;quot;: [&lt;br /&gt;
    {&amp;quot;device&amp;quot;:&amp;quot;pbx.domain.de&amp;quot;,&amp;quot;metric&amp;quot;:&amp;quot;online&amp;quot;,&amp;quot;value&amp;quot;:&amp;quot;true&amp;quot;,&amp;quot;result&amp;quot;:true&amp;quot;comment&amp;quot;:&amp;quot;&amp;quot;},&lt;br /&gt;
    {&amp;quot;device&amp;quot;:&amp;quot;pbx.domain.de&amp;quot;,&amp;quot;metric&amp;quot;:&amp;quot;serialnumber&amp;quot;,&amp;quot;value&amp;quot;:005056001338,&amp;quot;comment&amp;quot;:&amp;quot;&amp;quot;},&lt;br /&gt;
    {&amp;quot;device&amp;quot;:&amp;quot;pbx.domain.de&amp;quot;,&amp;quot;metric&amp;quot;:&amp;quot;product&amp;quot;,&amp;quot;value&amp;quot;:IPVA,&amp;quot;comment&amp;quot;:&amp;quot;&amp;quot;},&lt;br /&gt;
    {&amp;quot;device&amp;quot;:&amp;quot;pbx.domain.de&amp;quot;,&amp;quot;metric&amp;quot;:&amp;quot;version&amp;quot;,&amp;quot;value&amp;quot;:15r1 dvl [15.1.0130/1000/0],&amp;quot;comment&amp;quot;:&amp;quot;&amp;quot;},&lt;br /&gt;
    {&amp;quot;device&amp;quot;:&amp;quot;pbx.domain.de&amp;quot;,&amp;quot;metric&amp;quot;:&amp;quot;versionIsSupported&amp;quot;,&amp;quot;value&amp;quot;:&amp;quot;true&amp;quot;,&amp;quot;result&amp;quot;:true&amp;quot;comment&amp;quot;:&amp;quot;&amp;quot;},&lt;br /&gt;
    {&amp;quot;device&amp;quot;:&amp;quot;pbx.domain.de&amp;quot;,&amp;quot;metric&amp;quot;:&amp;quot;uptime&amp;quot;,&amp;quot;value&amp;quot;:3050,&amp;quot;comment&amp;quot;:&amp;quot;&amp;quot;},&lt;br /&gt;
    {&amp;quot;device&amp;quot;:&amp;quot;pbx.domain.de&amp;quot;,&amp;quot;metric&amp;quot;:&amp;quot;CPU&amp;quot;,&amp;quot;value&amp;quot;:2,&amp;quot;comment&amp;quot;:&amp;quot;null&amp;quot;},&lt;br /&gt;
    {&amp;quot;device&amp;quot;:&amp;quot;pbx.domain.de&amp;quot;,&amp;quot;metric&amp;quot;:&amp;quot;CPU-R&amp;quot;,&amp;quot;value&amp;quot;:0,&amp;quot;comment&amp;quot;:&amp;quot;null&amp;quot;},&lt;br /&gt;
    {&amp;quot;device&amp;quot;:&amp;quot;pbx.domain.de&amp;quot;,&amp;quot;metric&amp;quot;:&amp;quot;MEM&amp;quot;,&amp;quot;value&amp;quot;:0.09,&amp;quot;comment&amp;quot;:&amp;quot;null&amp;quot;},&lt;br /&gt;
    {&amp;quot;device&amp;quot;:&amp;quot;pbx.domain.de&amp;quot;,&amp;quot;metric&amp;quot;:&amp;quot;ETH0&amp;quot;,&amp;quot;value&amp;quot;:18,&amp;quot;comment&amp;quot;:&amp;quot;null&amp;quot;}&lt;br /&gt;
  ],&lt;br /&gt;
  &amp;quot;ap.domain.de&amp;quot;: [&lt;br /&gt;
    {&amp;quot;device&amp;quot;:&amp;quot;ap.domain.de&amp;quot;,&amp;quot;metric&amp;quot;:&amp;quot;online&amp;quot;,&amp;quot;value&amp;quot;:&amp;quot;true&amp;quot;,&amp;quot;result&amp;quot;:true,&amp;quot;comment&amp;quot;:&amp;quot;&amp;quot;},&lt;br /&gt;
    {&amp;quot;device&amp;quot;:&amp;quot;ap.domain.de&amp;quot;,&amp;quot;metric&amp;quot;:&amp;quot;serialnumber&amp;quot;,&amp;quot;value&amp;quot;:00155db3c306,&amp;quot;comment&amp;quot;:&amp;quot;&amp;quot;},&lt;br /&gt;
    {&amp;quot;device&amp;quot;:&amp;quot;ap.domain.de&amp;quot;,&amp;quot;metric&amp;quot;:&amp;quot;product&amp;quot;,&amp;quot;value&amp;quot;:AppPlatform x86_64,&amp;quot;comment&amp;quot;:&amp;quot;&amp;quot;},&lt;br /&gt;
    {&amp;quot;device&amp;quot;:&amp;quot;ap.domain.de&amp;quot;,&amp;quot;metric&amp;quot;:&amp;quot;version&amp;quot;,&amp;quot;value&amp;quot;:120010  (15r1 1510130 dvl ),&amp;quot;comment&amp;quot;:&amp;quot;&amp;quot;},&lt;br /&gt;
    {&amp;quot;device&amp;quot;:&amp;quot;ap.domain.de&amp;quot;,&amp;quot;metric&amp;quot;:&amp;quot;versionIsSupported&amp;quot;,&amp;quot;value&amp;quot;:&amp;quot;true&amp;quot;,&amp;quot;result&amp;quot;:true,&amp;quot;comment&amp;quot;:&amp;quot;&amp;quot;},&lt;br /&gt;
  ]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/spoiler&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Checkmk ====&lt;br /&gt;
The interface &amp;quot;/Checkmk&amp;quot; provides a native integration to your Checkmk system with [https://docs.checkmk.com/latest/en/piggyback.html Piggyback] information for all known hosts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;spoiler show=&amp;quot;show sample output&amp;quot; hide=&amp;quot;hide sample output&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;&amp;lt;&amp;lt;&amp;lt;pbx.domain.de&amp;gt;&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;&amp;lt;&amp;lt;check_mk&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
AgentOS: innovaphone TechAssist&lt;br /&gt;
Hostname: pbx.domain.de&lt;br /&gt;
&amp;lt;&amp;lt;&amp;lt;uptime&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
3050&lt;br /&gt;
&amp;lt;&amp;lt;&amp;lt;kernel&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
util 0&lt;br /&gt;
cpu 1728891356864 0 0 1728891356960 0 0 0 0 0 0&lt;br /&gt;
&amp;lt;&amp;lt;&amp;lt;mem&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
MemTotal: 49793 kB&lt;br /&gt;
MemFree: 49747 kB&lt;br /&gt;
MemAvailable: 49747 kB&lt;br /&gt;
Buffers: 0 kB&lt;br /&gt;
Cached: 0 kB&lt;br /&gt;
SwapTotal: 0 kB&lt;br /&gt;
SwapFree: 0 kB&lt;br /&gt;
Dirty: 0 kB&lt;br /&gt;
Writeback: 0 kB&lt;br /&gt;
&amp;lt;&amp;lt;&amp;lt;lnx_thermal&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;&amp;lt;&amp;lt;local&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
0 &amp;quot;online&amp;quot; - online=1&lt;br /&gt;
0 &amp;quot;serialnumber&amp;quot; - serialnumber=005056001338&lt;br /&gt;
0 &amp;quot;product&amp;quot; - product=IPVA&lt;br /&gt;
0 &amp;quot;version&amp;quot; - version=15r1 dvl [15.1.0130/1000/0]&lt;br /&gt;
0 &amp;quot;versionIsSupported&amp;quot; - versionIsSupported=1&lt;br /&gt;
0 &amp;quot;CPU-R&amp;quot; - CPU-R=0&lt;br /&gt;
0 &amp;quot;ETH0&amp;quot; - ETH0=18&lt;br /&gt;
&amp;lt;&amp;lt;&amp;lt;innovaphone&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;&amp;lt;&amp;lt;&amp;lt;ap.domain.de&amp;gt;&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;&amp;lt;&amp;lt;check_mk&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
AgentOS: innovaphone TechAssist&lt;br /&gt;
Hostname: ap.domain.de&lt;br /&gt;
&amp;lt;&amp;lt;&amp;lt;uptime&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;&amp;lt;&amp;lt;kernel&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;&amp;lt;&amp;lt;mem&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;&amp;lt;&amp;lt;lnx_thermal&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;&amp;lt;&amp;lt;local&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
0 &amp;quot;online&amp;quot; - online=1&lt;br /&gt;
0 &amp;quot;serialnumber&amp;quot; - serialnumber=00155db3c306&lt;br /&gt;
0 &amp;quot;product&amp;quot; - product=AppPlatform x86_64&lt;br /&gt;
0 &amp;quot;version&amp;quot; - version=120010  (15r1 1510130 dvl )&lt;br /&gt;
0 &amp;quot;versionIsSupported&amp;quot; - versionIsSupported=1&lt;br /&gt;
&amp;lt;&amp;lt;&amp;lt;innovaphone&amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/spoiler&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Configure your Checkmk installation =====&lt;br /&gt;
#Setup your Hosts in Checkmk&lt;br /&gt;
#*Make sure that &amp;quot;Checkmk agent / API integrations&amp;quot; in the Hostconfiguration of your Application Platform is set to &amp;quot;API integrations if configured, else Checkmk agent&amp;quot;, all other Hosts hat to bet set to &amp;quot;No API integrations, no Checkmk agent&amp;quot;.&lt;br /&gt;
#Create a new Rule for &amp;quot;Individual program call instead of agent access&amp;quot; in &amp;quot;Setup &amp;gt; Agents &amp;gt; Other integrations&amp;quot;&lt;br /&gt;
#*Command line to execute: &amp;lt;code&amp;gt;curl --digest -u &amp;quot;user:pass&amp;quot; https://ap.domain.tld/domain.de/techassist/monitoring/Checkmk&amp;lt;/code&amp;gt;&lt;br /&gt;
#*Explicit hosts: Set this to the Host of your Application Platform&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
After that, you can run the service discovery and receive new checks for your devices&lt;br /&gt;
&lt;br /&gt;
[[File:Checkmk new checks.png|frameless|500px|checkmk_new_checks.png/|checkmk_new_checks.png/]]&lt;br /&gt;
&lt;br /&gt;
==== Icinga ====&lt;br /&gt;
The interface &amp;quot;/Icinga&amp;quot; provides a native integration to your Icinga system for all known hosts.&lt;br /&gt;
&lt;br /&gt;
{{FIXME|reason=This interface is currently being researched, and it is being checked whether icinga can read such data as expected}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;spoiler show=&amp;quot;show sample output&amp;quot; hide=&amp;quot;hide sample output&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
[&lt;br /&gt;
  {&lt;br /&gt;
    &amp;quot;_host&amp;quot;: &amp;quot;pbx.domain.de&amp;quot;,&lt;br /&gt;
    &amp;quot;_ETH0_ipv4&amp;quot;: &amp;quot;10.0.102.7&amp;quot;,&lt;br /&gt;
    &amp;quot;online&amp;quot;:1,&lt;br /&gt;
    &amp;quot;serialnumber&amp;quot;:005056001338,&lt;br /&gt;
    &amp;quot;product&amp;quot;:IPVA,&lt;br /&gt;
    &amp;quot;version&amp;quot;:15r1 dvl [15.1.0130/1000/0],&lt;br /&gt;
    &amp;quot;versionIsSupported&amp;quot;:1,&lt;br /&gt;
    &amp;quot;uptime&amp;quot;:3353,&lt;br /&gt;
    &amp;quot;CPU&amp;quot;:1,&lt;br /&gt;
    &amp;quot;CPU-R&amp;quot;:0,&lt;br /&gt;
    &amp;quot;MEM&amp;quot;:0.09,&lt;br /&gt;
    &amp;quot;ETH0&amp;quot;:14&lt;br /&gt;
  },&lt;br /&gt;
  {&lt;br /&gt;
    &amp;quot;_host&amp;quot;: &amp;quot;ap.domain.de&amp;quot;,&lt;br /&gt;
    &amp;quot;_eth0_ipv4&amp;quot;: &amp;quot;10.0.102.8&amp;quot;,&lt;br /&gt;
    &amp;quot;_eth0_ipv6&amp;quot;: &amp;quot;2001:4090:e000:9a1::8&amp;quot;,&lt;br /&gt;
    &amp;quot;online&amp;quot;:1,&lt;br /&gt;
    &amp;quot;serialnumber&amp;quot;:00155db3c306,&lt;br /&gt;
    &amp;quot;product&amp;quot;:AppPlatform x86_64,&lt;br /&gt;
    &amp;quot;version&amp;quot;:120010  (15r1 1510130 dvl ),&lt;br /&gt;
    &amp;quot;versionIsSupported&amp;quot;:1&lt;br /&gt;
  }&lt;br /&gt;
]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/spoiler&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Configure your Icinga installation =====&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
=== Startup Logfile ===&lt;br /&gt;
If you enable the traceflag &#039;&#039;App&#039;&#039; in your App instance, you will find the following logs:&lt;br /&gt;
&lt;br /&gt;
 AppService::AppStart TechAssist@slu.de&lt;br /&gt;
 App instance started 14C1363 14C1363&lt;br /&gt;
 ...&lt;br /&gt;
 // App begins to load embedded tests&lt;br /&gt;
 JavaScript: Files tests/*&lt;br /&gt;
 ...&lt;br /&gt;
 // Scheduler begins to load all the tests&lt;br /&gt;
 scheduler init&lt;br /&gt;
 init test &amp;quot;firmware_version&amp;quot;&lt;br /&gt;
 firmware_version: Test added successful&lt;br /&gt;
 init test &amp;quot;pbx_mediarelay&amp;quot;&lt;br /&gt;
 pbx_mediarelay: Test added successful&lt;br /&gt;
&lt;br /&gt;
=== Websocket Connections ===&lt;br /&gt;
The App holds Websocket connections to various targets. To debug and follow these connections in the logfile you will find special log output for outgoing websocket connections.&lt;br /&gt;
&lt;br /&gt;
You can filter the logfile with &amp;lt;code&amp;gt;Websocket Log&amp;lt;/code&amp;gt; to get the Websocket flow. Then a good practice should be to click on these lines and check the lines before.&lt;br /&gt;
 C:\Users\slu\Downloads\techassist-x86_64-20241112-131349.txt (8 Treffer)&lt;br /&gt;
 Zeile   9: 11-12 13:13:46.288 techassist@slu.de Websocket Log - ServicesInfoApis::close | {...}&lt;br /&gt;
 Zeile  12: 11-12 13:13:46.288 techassist@slu.de Websocket Log - ServicesInfoApis::close | {...}&lt;br /&gt;
 Zeile  18: 11-12 13:13:46.288 techassist@slu.de Websocket Log - ServicesInfoApis::add | {...}&lt;br /&gt;
 Zeile  22: 11-12 13:13:46.288 techassist@slu.de Websocket Log - ServicesInfoApis::add | {...}&lt;br /&gt;
 Zeile  34: 11-12 13:13:46.290 techassist@slu.de Websocket Log - ServicesInfoApis::remove | {...}&lt;br /&gt;
 Zeile  41: 11-12 13:13:46.290 techassist@slu.de Websocket Log - ServicesInfoApis::remove | {...}&lt;br /&gt;
 Zeile  66: 11-12 13:13:46.307 techassist@slu.de Websocket Log - ServicesInfoApis::find | {...}&lt;br /&gt;
 Zeile 321: 11-12 13:13:46.324 techassist@slu.de Websocket Log - ServicesInfoApis::find | {...}&lt;/div&gt;</summary>
		<author><name>Tfu</name></author>
	</entry>
	<entry>
		<id>https://wiki.innovaphone.com/index.php?title=Main_Page&amp;diff=80506</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://wiki.innovaphone.com/index.php?title=Main_Page&amp;diff=80506"/>
		<updated>2026-09-16T13:35:46Z</updated>

		<summary type="html">&lt;p&gt;Tfu: /* Latest News */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&amp;lt;!-- Message of the day --&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;margin:0px; margin-right:10px; border:1px solid #58C4C3; background-color:#F4F4F4; padding:0em 1em 0em 1em;&amp;quot;&amp;gt;&lt;br /&gt;
== Remote Support ==&lt;br /&gt;
[[Image:RemoteControl-click.png|left|60px|RemoteControl.png/|Download Remote Control|link=https://store.innovaphone.com/release/download/software/remotecontrolwindowsportable/16r1/remoteControl.exe]]&lt;br /&gt;
innovaphone only carries out scheduled remote maintenance via our ticket system by prior consultation.&amp;lt;br/&amp;gt;&lt;br /&gt;
As Remote Support Tool, we use our own product Remote Control ([https://www.innovaphone.com/en/all-apps/apps-to-work-with/remote-control-app.html more info]).&lt;br /&gt;
&lt;br /&gt;
You can &#039;&#039;&#039;[https://store.innovaphone.com/alpha/download/software/remotecontrolwindowsportable/16r1/remoteControl.exe download]&#039;&#039;&#039; the Remote Control client already or use the support link received from our support team.&amp;lt;br/&amp;gt;&lt;br /&gt;
After installing and opening the client you can &#039;&#039;&#039;pass the shown ID&#039;&#039;&#039; or &#039;&#039;&#039;use the received link&#039;&#039;&#039; to request the support session.&lt;br /&gt;
&lt;br /&gt;
== Searching ==&lt;br /&gt;
Searching in wiki works, but is sometimes cumbersome.  However, you can have Google do the job for you.  Try [https://www.google.de/search?q=site%3Ainnovaphone.com+xml+documentation &amp;lt;code&amp;gt;site:innovaphone.com your search terms&amp;lt;/code&amp;gt;] to search the innovaphone sites for matches!&lt;br /&gt;
&lt;br /&gt;
If you still don&#039;t find what you are looking for, [mailto:presales@innovaphone.com drop us a message]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- latest news commented out, may be reactivated once there are new really --&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;margin:0px; margin-right:10px; margin-top:15px; border:1px solid #58C4C3; background-color:#F4F4F4; padding:0em 1em 0.5em 1em;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!-- please insert new message ON TOP and remove extraneous (more than 5) old messages --&amp;gt;&lt;br /&gt;
&amp;lt;!-- &amp;lt;nowiki&amp;gt; ~~~~ is replaced by your name and date automatically &amp;lt;/nowiki&amp;gt; --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Latest News ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p align=&amp;quot;right&amp;quot;&amp;gt;[[User:Tfu|Tfu]] 15:35, 16 September 2026 (CET)&amp;lt;/p&amp;gt;&lt;br /&gt;
[[Support:WinPDM_Software_3130115_(4.3.0)_released| WinPDM Software 3130115 (4.3.0)]] is now available from the [https://store.innovaphone.com/release/download.htm App store].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p align=&amp;quot;right&amp;quot;&amp;gt;[[User:Tfu|Tfu]] 14:41, 16 September 2026 (CEST)&amp;lt;/p&amp;gt;&lt;br /&gt;
[[Support:Wireless_Handset_Firmware_IP73_1015_(8.0.3)_released| Wireless Handset Firmware IP73 1015 (8.0.3) released]] is now available from the [https://store.innovaphone.com/release/download.htm App store].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p align=&amp;quot;right&amp;quot;&amp;gt;[[User:Lmi|Lmi]] ([[User talk:Lmi|talk]]) 15:40, 27 August 2026 (CEST)&amp;lt;/p&amp;gt; [[Support:Firmware V16r1 product/16r1/firmware 1610979 (sr4) available | Version 16r1 Service Release 4]] is now available from the [http://store.innovaphone.com/release/download.htm download page]. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;p align=&amp;quot;right&amp;quot;&amp;gt;[[User:Lmi|Lmi]] ([[User talk:Lmi|talk]]) 15:40, 27 August 2026 (CEST)&amp;lt;/p&amp;gt; [[Support:Firmware V15r1 product/15r1/firmware 1510781 (sr16) available | Version 15r1 Service Release 16]] is now available from the [http://store.innovaphone.com/release/download.htm download page].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p align=&amp;quot;right&amp;quot;&amp;gt;[[User:Lmi|Lmi]] ([[User talk:Lmi|talk]]) 15:40, 27 August 2026 (CEST)&amp;lt;/p&amp;gt; [[Support:Firmware V14r2 product/14r2/firmware 1420601 (sr24) available | Version 14r2 Service Release 24]] is now available from the [http://store.innovaphone.com/release/download.htm download page]. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;p align=&amp;quot;right&amp;quot;&amp;gt;[[User:Aer|Aer]] ([[User talk:Aer|talk]]) 17:16, 25 March 2026 (CET)&amp;lt;/p&amp;gt; [[Support:Firmware V13r3 product/13r3/firmware 138046 (sr 36) available | Version 13r3 Service Release 36]] is now available from the [http://store.innovaphone.com/release/download.htm download page].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p align=&amp;quot;right&amp;quot;&amp;gt;[[User:Tfu|Tfu]] 10:48, 24 February 2026 (CET)&amp;lt;/p&amp;gt;&lt;br /&gt;
[[Support:WinPDM Software 3130114 (4.2.1) released| WinPDM Software 3130113 (4.2.1)]] is now available from the [https://store.innovaphone.com/release/download.htm App store].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p align=&amp;quot;right&amp;quot;&amp;gt;[[User:Tfu|Tfu]] 15:28, 13 March 2025 (CEST)&amp;lt;/p&amp;gt;&lt;br /&gt;
[[Support:Wireless Handset Firmware IP73 1012 (6.1.13) released| Wireless Handset Firmware IP73 1012 (6.1.13) released]] is now available from the [https://store.innovaphone.com/release/download.htm App store].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p align=&amp;quot;right&amp;quot;&amp;gt;[[User:Msu|Msu]] ([[User talk:Msu&amp;amp;action=edit&amp;amp;redlink=1|talk]]) 15:54, 18 February 2025 (CEST)&amp;lt;/p&amp;gt;&lt;br /&gt;
[[Support:Wireless Handset Firmware IP64 10317 (4.3.2)/IP65 10122 (4.3.2) released| Wireless Handset Firmware IP64 10317 (4.3.2)/IP65 10122 (4.3.2)]] is now available from the [https://store.innovaphone.com/release/download.htm App store].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p align=&amp;quot;right&amp;quot;&amp;gt;[[User:Msu|Msu]] ([[User talk:Msu&amp;amp;action=edit&amp;amp;redlink=1|talk]]) 15:54, 18 February 2025 (CEST)&amp;lt;/p&amp;gt;&lt;br /&gt;
[[Support:Wireless Handset Firmware D83 10002 (2.0.5) released| Wireless Handset Firmware D83 10002 (2.0.5)]] is now available from the [https://store.innovaphone.com/release/download.htm App store].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p align=&amp;quot;right&amp;quot;&amp;gt;[[User:Afi|Afi]] 15:38, 6 February 2023 (CET)&amp;lt;/p&amp;gt;&lt;br /&gt;
[[Support:Wireless Handset Firmware IP62 3040621 (6.2.7) released| Wireless Handset Firmware IP62 3040621 (6.2.7)]] is now available from the [https://store.innovaphone.com/release/download.htm App store].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p align=&amp;quot;right&amp;quot;&amp;gt;[[User:Afi|Afi]] 12:46, 16 June 2021 (CEST))&amp;lt;/p&amp;gt;&lt;br /&gt;
[[Support:TAPI Service Provider 8188 (hotfix21) available|TAPI Service Provider 8188 (hotfix21)]] is now available from [https://store.innovaphone.com/release/download.htm the Software download area].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p align=&amp;quot;right&amp;quot;&amp;gt;[[User:Afi|Afi]] 18:21, 12 October 2020 (CEST)&amp;lt;/p&amp;gt;&lt;br /&gt;
[[Support:Wireless Handset Firmware IP61 3022811 (4.7.8)/IP63 3022912 (4.7.8) released| Wireless Handset Firmware IP61 3022811 (4.7.8)/IP63 3022912 (4.7.8)]] is now available from the [https://store.innovaphone.com/release/download.htm App store].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p align=&amp;quot;right&amp;quot;&amp;gt;[[User:Afi|Afi]] 21:30, 27 March 2020 (CET)&amp;lt;/p&amp;gt;&lt;br /&gt;
[[Support:Wireless Handset Firmware and Management Software product/9.00/wireless 100037 (hotfix19) available| Wireless Package hotfix 19]] is now available from the [http://download.innovaphone.com/ice/9.00#wireless V9 download area].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;margin:0px; margin-right:10px; margin-top:15px; border:1px solid #58C4C3; background-color:#F4F4F4; padding:0em 1em 0.5em 1em;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== New Articles ==&lt;br /&gt;
&amp;lt;!-- https://www.mediawiki.org/wiki/Extension:Newest_Pages --&amp;gt;&lt;br /&gt;
{{Special:Newestpages/all/20}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;margin:0px; margin-right:10px; margin-top:15px; border:1px solid #58C4C3; background-color:#F4F4F4; padding:0em 1em 0.5em 1em; font-size:1&amp;quot;&amp;gt;&lt;br /&gt;
== More innovaphone Ressources ==&lt;br /&gt;
* [http://www.innovaphone.com Home Page]&lt;br /&gt;
* [http://download.innovaphone.com Download Site ]&lt;br /&gt;
* [http://my.innovaphone.com my.innovaphone ]&lt;br /&gt;
* [http://mantis.innovaphone.com/ Ticketing System ]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>Tfu</name></author>
	</entry>
	<entry>
		<id>https://wiki.innovaphone.com/index.php?title=Main_Page&amp;diff=80497</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://wiki.innovaphone.com/index.php?title=Main_Page&amp;diff=80497"/>
		<updated>2026-09-16T12:52:05Z</updated>

		<summary type="html">&lt;p&gt;Tfu: /* Latest News */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&amp;lt;!-- Message of the day --&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;margin:0px; margin-right:10px; border:1px solid #58C4C3; background-color:#F4F4F4; padding:0em 1em 0em 1em;&amp;quot;&amp;gt;&lt;br /&gt;
== Remote Support ==&lt;br /&gt;
[[Image:RemoteControl-click.png|left|60px|RemoteControl.png/|Download Remote Control|link=https://store.innovaphone.com/release/download/software/remotecontrolwindowsportable/16r1/remoteControl.exe]]&lt;br /&gt;
innovaphone only carries out scheduled remote maintenance via our ticket system by prior consultation.&amp;lt;br/&amp;gt;&lt;br /&gt;
As Remote Support Tool, we use our own product Remote Control ([https://www.innovaphone.com/en/all-apps/apps-to-work-with/remote-control-app.html more info]).&lt;br /&gt;
&lt;br /&gt;
You can &#039;&#039;&#039;[https://store.innovaphone.com/alpha/download/software/remotecontrolwindowsportable/16r1/remoteControl.exe download]&#039;&#039;&#039; the Remote Control client already or use the support link received from our support team.&amp;lt;br/&amp;gt;&lt;br /&gt;
After installing and opening the client you can &#039;&#039;&#039;pass the shown ID&#039;&#039;&#039; or &#039;&#039;&#039;use the received link&#039;&#039;&#039; to request the support session.&lt;br /&gt;
&lt;br /&gt;
== Searching ==&lt;br /&gt;
Searching in wiki works, but is sometimes cumbersome.  However, you can have Google do the job for you.  Try [https://www.google.de/search?q=site%3Ainnovaphone.com+xml+documentation &amp;lt;code&amp;gt;site:innovaphone.com your search terms&amp;lt;/code&amp;gt;] to search the innovaphone sites for matches!&lt;br /&gt;
&lt;br /&gt;
If you still don&#039;t find what you are looking for, [mailto:presales@innovaphone.com drop us a message]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- latest news commented out, may be reactivated once there are new really --&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;margin:0px; margin-right:10px; margin-top:15px; border:1px solid #58C4C3; background-color:#F4F4F4; padding:0em 1em 0.5em 1em;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!-- please insert new message ON TOP and remove extraneous (more than 5) old messages --&amp;gt;&lt;br /&gt;
&amp;lt;!-- &amp;lt;nowiki&amp;gt; ~~~~ is replaced by your name and date automatically &amp;lt;/nowiki&amp;gt; --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Latest News ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p align=&amp;quot;right&amp;quot;&amp;gt;[[User:Tfu|Tfu]] ([[User talk:Tfu|talk]]) 15:28, 13 March 2025 (CEST)&amp;lt;/p&amp;gt;&lt;br /&gt;
[[Support:Wireless_Handset_Firmware_IP73_1015_(8.0.3)_released| Wireless Handset Firmware IP73 1015 (8.0.3) released]] is now available from the [https://store.innovaphone.com/release/download.htm App store].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p align=&amp;quot;right&amp;quot;&amp;gt;[[User:Lmi|Lmi]] ([[User talk:Lmi|talk]]) 15:40, 27 August 2026 (CEST)&amp;lt;/p&amp;gt; [[Support:Firmware V16r1 product/16r1/firmware 1610979 (sr4) available | Version 16r1 Service Release 4]] is now available from the [http://store.innovaphone.com/release/download.htm download page]. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;p align=&amp;quot;right&amp;quot;&amp;gt;[[User:Lmi|Lmi]] ([[User talk:Lmi|talk]]) 15:40, 27 August 2026 (CEST)&amp;lt;/p&amp;gt; [[Support:Firmware V15r1 product/15r1/firmware 1510781 (sr16) available | Version 15r1 Service Release 16]] is now available from the [http://store.innovaphone.com/release/download.htm download page].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p align=&amp;quot;right&amp;quot;&amp;gt;[[User:Lmi|Lmi]] ([[User talk:Lmi|talk]]) 15:40, 27 August 2026 (CEST)&amp;lt;/p&amp;gt; [[Support:Firmware V14r2 product/14r2/firmware 1420601 (sr24) available | Version 14r2 Service Release 24]] is now available from the [http://store.innovaphone.com/release/download.htm download page]. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;p align=&amp;quot;right&amp;quot;&amp;gt;[[User:Aer|Aer]] ([[User talk:Aer|talk]]) 17:16, 25 March 2026 (CET)&amp;lt;/p&amp;gt; [[Support:Firmware V13r3 product/13r3/firmware 138046 (sr 36) available | Version 13r3 Service Release 36]] is now available from the [http://store.innovaphone.com/release/download.htm download page].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p align=&amp;quot;right&amp;quot;&amp;gt;[[User:Tfu|Tfu]] 10:48, 24 February 2026 (CET)&amp;lt;/p&amp;gt;&lt;br /&gt;
[[Support:WinPDM Software 3130114 (4.2.1) released| WinPDM Software 3130113 (4.2.1)]] is now available from the [https://store.innovaphone.com/release/download.htm App store].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p align=&amp;quot;right&amp;quot;&amp;gt;[[User:Tfu|Tfu]] ([[User talk:Tfu|talk]]) 15:28, 13 March 2025 (CEST)&amp;lt;/p&amp;gt;&lt;br /&gt;
[[Support:Wireless Handset Firmware IP73 1012 (6.1.13) released| Wireless Handset Firmware IP73 1012 (6.1.13) released]] is now available from the [https://store.innovaphone.com/release/download.htm App store].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p align=&amp;quot;right&amp;quot;&amp;gt;[[User:Msu|Msu]] ([[User talk:Msu&amp;amp;action=edit&amp;amp;redlink=1|talk]]) 15:54, 18 February 2025 (CEST)&amp;lt;/p&amp;gt;&lt;br /&gt;
[[Support:Wireless Handset Firmware IP64 10317 (4.3.2)/IP65 10122 (4.3.2) released| Wireless Handset Firmware IP64 10317 (4.3.2)/IP65 10122 (4.3.2)]] is now available from the [https://store.innovaphone.com/release/download.htm App store].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p align=&amp;quot;right&amp;quot;&amp;gt;[[User:Msu|Msu]] ([[User talk:Msu&amp;amp;action=edit&amp;amp;redlink=1|talk]]) 15:54, 18 February 2025 (CEST)&amp;lt;/p&amp;gt;&lt;br /&gt;
[[Support:Wireless Handset Firmware D83 10002 (2.0.5) released| Wireless Handset Firmware D83 10002 (2.0.5)]] is now available from the [https://store.innovaphone.com/release/download.htm App store].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p align=&amp;quot;right&amp;quot;&amp;gt;[[User:Afi|Afi]] 15:38, 6 February 2023 (CET)&amp;lt;/p&amp;gt;&lt;br /&gt;
[[Support:Wireless Handset Firmware IP62 3040621 (6.2.7) released| Wireless Handset Firmware IP62 3040621 (6.2.7)]] is now available from the [https://store.innovaphone.com/release/download.htm App store].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p align=&amp;quot;right&amp;quot;&amp;gt;[[User:Afi|Afi]] 12:46, 16 June 2021 (CEST))&amp;lt;/p&amp;gt;&lt;br /&gt;
[[Support:TAPI Service Provider 8188 (hotfix21) available|TAPI Service Provider 8188 (hotfix21)]] is now available from [https://store.innovaphone.com/release/download.htm the Software download area].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p align=&amp;quot;right&amp;quot;&amp;gt;[[User:Afi|Afi]] 18:21, 12 October 2020 (CEST)&amp;lt;/p&amp;gt;&lt;br /&gt;
[[Support:Wireless Handset Firmware IP61 3022811 (4.7.8)/IP63 3022912 (4.7.8) released| Wireless Handset Firmware IP61 3022811 (4.7.8)/IP63 3022912 (4.7.8)]] is now available from the [https://store.innovaphone.com/release/download.htm App store].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p align=&amp;quot;right&amp;quot;&amp;gt;[[User:Afi|Afi]] 21:30, 27 March 2020 (CET)&amp;lt;/p&amp;gt;&lt;br /&gt;
[[Support:Wireless Handset Firmware and Management Software product/9.00/wireless 100037 (hotfix19) available| Wireless Package hotfix 19]] is now available from the [http://download.innovaphone.com/ice/9.00#wireless V9 download area].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;margin:0px; margin-right:10px; margin-top:15px; border:1px solid #58C4C3; background-color:#F4F4F4; padding:0em 1em 0.5em 1em;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== New Articles ==&lt;br /&gt;
&amp;lt;!-- https://www.mediawiki.org/wiki/Extension:Newest_Pages --&amp;gt;&lt;br /&gt;
{{Special:Newestpages/all/20}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;margin:0px; margin-right:10px; margin-top:15px; border:1px solid #58C4C3; background-color:#F4F4F4; padding:0em 1em 0.5em 1em; font-size:1&amp;quot;&amp;gt;&lt;br /&gt;
== More innovaphone Ressources ==&lt;br /&gt;
* [http://www.innovaphone.com Home Page]&lt;br /&gt;
* [http://download.innovaphone.com Download Site ]&lt;br /&gt;
* [http://my.innovaphone.com my.innovaphone ]&lt;br /&gt;
* [http://mantis.innovaphone.com/ Ticketing System ]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>Tfu</name></author>
	</entry>
	<entry>
		<id>https://wiki.innovaphone.com/index.php?title=Reference16r1:Concept_App_Service_Connector_for_Microsoft_365&amp;diff=80432</id>
		<title>Reference16r1:Concept App Service Connector for Microsoft 365</title>
		<link rel="alternate" type="text/html" href="https://wiki.innovaphone.com/index.php?title=Reference16r1:Concept_App_Service_Connector_for_Microsoft_365&amp;diff=80432"/>
		<updated>2026-09-01T14:50:48Z</updated>

		<summary type="html">&lt;p&gt;Tfu: Add Known Limitation: Contact Search does not cover subordinate/shared contact folders or the Global Address List - Co-Authored-By: Pi-Agent&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Concept|Apps]]&lt;br /&gt;
== Applies To == &lt;br /&gt;
&lt;br /&gt;
* Connector for Microsoft 365 from Version 16r1&lt;br /&gt;
&lt;br /&gt;
= Overview =&lt;br /&gt;
&lt;br /&gt;
Connector for Microsoft 365 synchronizes Microsoft Teams presences with the innovaphone PBX and back, and optionally additionally Calendar presence from Exchange Online (part of the Microsoft 365 Cloud Services).&lt;br /&gt;
It is also possible to search for your own contacts. &lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
* innovaphone PBX&lt;br /&gt;
* innovaphone Application Platform (minimum version 120004)&lt;br /&gt;
* V16r1&lt;br /&gt;
* App(Connector for Microsoft 365)&lt;br /&gt;
* PBX-App(innovaphone-microsoft365) license per user - order no. 02-00050-009&lt;br /&gt;
&lt;br /&gt;
== Concept ==&lt;br /&gt;
&lt;br /&gt;
=== User Presence ===&lt;br /&gt;
&lt;br /&gt;
==== Configuration ====&lt;br /&gt;
Please have a look into our [[Howto16r1:Configure User Presence Sync by Connector for Microsoft365|Howto guide for basic configuration aid on user presence synchronisation]].&lt;br /&gt;
&lt;br /&gt;
==== Technical Overview ====&lt;br /&gt;
If the Connector for Microsoft 365 app is fully configured, the app connects to Microsoft to obtain a token. With the token, the app gets the teams users (with a Teams license) through the Microsoft Graph API.&lt;br /&gt;
A presence subscription to Microsoft is started with the licensed users of the PBX to get presence changes in Microsoft Teams for these users. A user subscription is also started to get changes of the users (adding, deleting or update). If a user has changed, the Teams users are retrieved again. If the presence has changed, it is forwarded to the PBX. The presences of Teams are mapped to the presences of the PBX.&lt;br /&gt;
&lt;br /&gt;
* User subscriptions are renewed every 60 minutes.&lt;br /&gt;
* Presence subscriptions are renewed every 10 minutes.&lt;br /&gt;
* License Check is made periodically.&lt;br /&gt;
&lt;br /&gt;
The app synchronises the PBX presence with Teams through the Graph Api. The on-the-phone presence will be renewed every 5 minutes. The other presences have a lifetime of 1 day but the away has a lifetime of 7 days.&lt;br /&gt;
The lifetimes are described [https://learn.microsoft.com/en-us/graph/api/presence-setuserpreferredpresence?view=graph-rest-1.0&amp;amp;tabs=http here]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Please be aware:&#039;&#039;&#039; The actual change of presence or line state will be live, the above-mentioned subscriptions are needed to register against the Microsoft API for changes. &lt;br /&gt;
After successful subscription Microsoft will trigger the Connector for Microsoft 365 App every time a presence or line state for a user has changed.&lt;br /&gt;
The subscription will then be renewed in the above-mentioned time interval to receive further live updates.&lt;br /&gt;
&lt;br /&gt;
===== User Matching =====&lt;br /&gt;
You now can choose the fields used for user matching on either side from the following options:&lt;br /&gt;
* PBX&lt;br /&gt;
** CN (Long Name property from the PBX user object)&lt;br /&gt;
** h323 (Name property from the PBX user object)&lt;br /&gt;
* Azure Portal&lt;br /&gt;
** displayName&lt;br /&gt;
** mail&lt;br /&gt;
** mailNickname&lt;br /&gt;
** onPremisesDistinguishedName&lt;br /&gt;
** onPremisesSamAccountName&lt;br /&gt;
** onPremisesUserPrincipalName&lt;br /&gt;
** userPrincipalName&lt;br /&gt;
&lt;br /&gt;
Additionally, you have the possibility to remove a possibly contained domain from the Azure fields content. &amp;lt;br&amp;gt;&lt;br /&gt;
Example: &#039;user@domain.tld&#039; is transformed to &#039;user&#039;, if this option is checked.&lt;br /&gt;
&lt;br /&gt;
===== Mapping Table =====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Teams Presence&lt;br /&gt;
! PBX Presence&lt;br /&gt;
|-&lt;br /&gt;
| Away&lt;br /&gt;
| away&lt;br /&gt;
|-&lt;br /&gt;
| BeRightBack&lt;br /&gt;
| away&lt;br /&gt;
|-&lt;br /&gt;
| Busy&lt;br /&gt;
| busy&lt;br /&gt;
|-&lt;br /&gt;
| DoNotDisturb&lt;br /&gt;
| dnd&lt;br /&gt;
|-&lt;br /&gt;
| InACall&lt;br /&gt;
| on-the-phone&lt;br /&gt;
|-&lt;br /&gt;
| InAMeeting&lt;br /&gt;
| meeting&lt;br /&gt;
|-&lt;br /&gt;
| Inactive&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| PresenceUnknown&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| Available&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| Offline&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| Offwork&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| OutOfOffice&lt;br /&gt;
| away&lt;br /&gt;
|-&lt;br /&gt;
| UrgentInterruptionsOnly&lt;br /&gt;
| dnd&lt;br /&gt;
|-&lt;br /&gt;
| Presenting&lt;br /&gt;
| on-the-phone&lt;br /&gt;
|-&lt;br /&gt;
| InAConferenceCall&lt;br /&gt;
| on-the-phone&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The value &amp;quot;online&amp;quot; unsets the Teams presence in the PBX.&lt;br /&gt;
&lt;br /&gt;
===== Master/Slave =====&lt;br /&gt;
&lt;br /&gt;
For Master/Slave combination the &amp;quot;Connector for Microsoft 365&amp;quot; App has to be added to the slave (if no full replication is on). The slave websocket connection is needed to display &amp;quot;on-the-phone&amp;quot; presence.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Calendar Presence ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Configuration ====&lt;br /&gt;
Please have a look into our [[Howto16r1:Configure Calendar Presence Sync by Connector for Microsoft365|Howto guide for basic configuration aid on calendar presence synchronisation]].&lt;br /&gt;
&lt;br /&gt;
==== Technical Overview ====&lt;br /&gt;
Introduced in 15r1 the Connector for Microsoft 365 will offer a possibility to sync Azure Portal calendar events (Teams, Exchange online) via the Graph API with the PBX presence.&amp;lt;br&amp;gt;&lt;br /&gt;
For now the [https://wiki.innovaphone.com/index.php?title=Reference13r3:Concept_App_Service_Calendar Calendar App] is (along with other functions) also capable of syncing calendar events, but using the old EWS mechanism, which Microsoft announced as end of life starting from 2026.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Warning:&#039;&#039;&#039; Please make sure to not use both apps for syncing calendar events in parallel, this is not supported and will most likely lead to conflicts and unexpected behaviours.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
When the configuration of the connector for Microsoft 365 Calendar Presence Sync is complete, the app connects to Microsoft to receive a token with the calendar app registered in the Azure portal.&amp;lt;br&amp;gt;&lt;br /&gt;
With the token, the app can pick up the users from the Azure portal.&amp;lt;br&amp;gt;&lt;br /&gt;
These are matched against the users in the PBX, based on the configured &amp;quot;User Assignment&amp;quot; settings.&amp;lt;br&amp;gt;&lt;br /&gt;
For each matched user with a valid Connector for Microsoft 365 licence applied, a subscription for calendar events is created at Microsoft to receive event changes in Microsoft Calendar for these users.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
A user subscription is also started to receive user changes (add, delete or update).&amp;lt;br&amp;gt;&lt;br /&gt;
If a user has changed, the users are retrieved again. &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
If a calendar event has been started or ended, it is forwarded to the PBX.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* User subscriptions are renewed every 60 minutes.&lt;br /&gt;
* Event subscriptions are renewed every day.&lt;br /&gt;
* License Check is made every hour.&lt;br /&gt;
&lt;br /&gt;
=== Contact Search ===&lt;br /&gt;
&lt;br /&gt;
==== Configuration ====&lt;br /&gt;
Please have a look into our [[Howto16r1:Configure_Contact_Search_by_Connector_for_Microsoft365|Howto guide for basic configuration aid on contact search]].&lt;br /&gt;
&lt;br /&gt;
==== Technical Overview ====&lt;br /&gt;
Introduced in 16r1 the Connector for Microsoft 365 will offer a possibility to search for your own contacts (Teams, Exchange online) via the Graph API.&lt;br /&gt;
&lt;br /&gt;
When the configuration of the connector for Microsoft 365 Contact Search is complete, the app connects to Microsoft to receive a token with the contact search app registered in the Azure portal.&amp;lt;br&amp;gt;&lt;br /&gt;
With the token, the app can pick up the users from the Azure portal.&amp;lt;br&amp;gt;&lt;br /&gt;
These are matched against the users in the PBX, based on the configured &amp;quot;User Assignment&amp;quot; settings.&amp;lt;br&amp;gt;&lt;br /&gt;
For each matched user with a valid Connector for Microsoft 365 licence applied, the user can search with the Phone App, for example (a myApps search provider will be provided for all apps looking using search providers looking up contacts). The search string is made available to the Connector for Microsoft 365 via the microsoft365-api. The results are sent to the consumer, e.g. the Phone App and presented there.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
A user subscription is started to receive user changes (add, delete or update).&amp;lt;br&amp;gt;&lt;br /&gt;
If a user has changed, the users are retrieved again. &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* User subscriptions are renewed every 60 minutes.&lt;br /&gt;
* License Check is made every hour.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Be aware:&#039;&#039;&#039; Since the Connector for Microsoft 365 is an app in the Scope of myApps App Platform, IP Phones and other services not using Apps cannot benefit from this search service.&lt;br /&gt;
&lt;br /&gt;
== Related Articles ==&lt;br /&gt;
&lt;br /&gt;
=Known Limitation=&lt;br /&gt;
&lt;br /&gt;
== General ==&lt;br /&gt;
&#039;&#039;Applies to the User Presence and the Calendar Presence&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Synchronization Delay ===&lt;br /&gt;
In the official Graph-API documentation, Microsoft is providing an overview about expected latencies for change notifications.&amp;lt;br&amp;gt;&lt;br /&gt;
You can find a whole overview table here:&amp;lt;br&amp;gt;&lt;br /&gt;
https://learn.microsoft.com/en-us/graph/change-notifications-overview#latency&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
For the user presences the resource &amp;quot;presence&amp;quot; is used and an average latency of 10 seconds but a maximum up to 1 minute is provided.&amp;lt;br&amp;gt;&lt;br /&gt;
Such a delay in syncing changed presences from Teams down to the PBX are considered normal and are caused by the Microsoft Graph-API.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
In case of calendar events the average is provided as &amp;quot;less than 1 minute&amp;quot; and the maximum to 3 minutes.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== User Presence ==&lt;br /&gt;
=== Line states set by the PBX does not block calls in Teams ===&lt;br /&gt;
Line states set by a 3rd party application (like the Connector for Microsoft 365) through the graph API are currently &#039;&#039;&#039;only for display purpose and do not block new calls&#039;&#039;&#039; in Teams.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
https://techcommunity.microsoft.com/t5/teams-developer/ms-graph-setpresence-problems/m-p/2798805/highlight/true#M3957&amp;lt;br&amp;gt;&lt;br /&gt;
As you can see in the above linked discussion, there once existed a feature request on Microsoft Voice, which is no longer available since it was not voted.&lt;br /&gt;
=== Maximum number of supported users ===&lt;br /&gt;
The connector now supports multiple Microsoft Teams communication users, which is the prerequisite to subscribe for more than 650 users. There is a new ribbon (Manage Teams Accounts) that allows you to configure as many communication users as you need. Every configured communication user can be used to subscribe 650 users, for example:&lt;br /&gt;
&lt;br /&gt;
*3 configured communication users x 650 licensed users = 1950 users can be subscribed&lt;br /&gt;
&#039;&#039;&#039;Please be aware&#039;&#039;&#039;: Each communication user must have a Teams license applied.&lt;br /&gt;
&lt;br /&gt;
This limitation is caused by Microsoft.&amp;lt;br&amp;gt;&lt;br /&gt;
In the documentation of the Graph-API you will find a hint to this limitation:&amp;lt;br&amp;gt;&lt;br /&gt;
https://learn.microsoft.com/en-us/graph/changenotifications-for-presence#subscribe-to-multiple-users-presence&amp;lt;br&amp;gt;&lt;br /&gt;
Trying to subscribe more than 650 users (with one communication user) by using the presence subscription API will be declined by the graph API with an error message, that too many users are requested.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Communication User (UserSynctoPbx) ===&lt;br /&gt;
Users with multi-factor authentication (MFA) are not supported as technical communication users for the Connector.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;We recommend creating a dedicated user account for this purpose rather than using an existing user account.&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;This limitation applies only to technical users used for the Connector for Microsoft 365, not standard user accounts. MFA can be used for real users.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Multiple sites / instances require multiple communication users ===&lt;br /&gt;
Each instance or each site must have separate communication users, as Microsoft only allows one concurrent subscription per communication user. (otherwise an HTTP 409 conflict will occur)&lt;br /&gt;
&lt;br /&gt;
This means that if you want to subscribe to the same Azure Portal backend from two different sites (or instances), you will need to have multiple communication users (each with an applied Teams licence) in order to be able to subscribe from all endpoints.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Subscription Timeout ===&lt;br /&gt;
&lt;br /&gt;
==== Situation ====&lt;br /&gt;
Due to a current limitation in the Graph API it is not possible to cancel or delete an active presence subscription.&amp;lt;br&amp;gt;&lt;br /&gt;
As you can see in the [https://learn.microsoft.com/en-us/graph/api/subscription-delete?view=graph-rest-1.0&amp;amp;tabs=http|documentation of the current Graph API (1.0)] the “Delete subscription” chapter does not include presence subscriptions.&amp;lt;br&amp;gt;&lt;br /&gt;
It is also not possible to have multiple subscription in parallel. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To make sure to only request a new presence subscription when the old one is not valid anymore, the app will store the state of the presence subscription and the time until it is valid in the database.&amp;lt;br&amp;gt;&lt;br /&gt;
As mentioned in the chapter “Technical Overview” we are creating presence subscriptions with a validity of 10 minutes.&amp;lt;br&amp;gt;&lt;br /&gt;
The presence subscription will be renewed as soon as it is no longer valid which will be 10 minutes after initial subscription.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Impact ====&lt;br /&gt;
If settings are changed or the app instance is restarted it will check the corresponding database entry on startup.&amp;lt;br&amp;gt;&lt;br /&gt;
In case the last presence subscription was completed less than 10 minutes ago, there is still an active presence subscription and the app has to wait for it to become invalid. &amp;lt;br&amp;gt;&lt;br /&gt;
Some Changes (e.g., to the “Notification-URL”) will only take effect after a new created subscription. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The current Beta Version of the Graph API is already providing a function to delete presence subscriptions, so we hope we can improve this behavior in the future.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Contact Search ==&lt;br /&gt;
=== Limited scope of searchable contacts ===&lt;br /&gt;
The contact search only queries the default Contacts folder of the searching user&#039;s mailbox via the Microsoft Graph API (&#039;&#039;&#039;/users/{id}/contacts&#039;&#039;&#039;). The following are currently &#039;&#039;&#039;not&#039;&#039;&#039; included in the search results:&lt;br /&gt;
&lt;br /&gt;
* Custom/subordinate contact folders&lt;br /&gt;
* Contact folders of other mailboxes shared with the user&lt;br /&gt;
* The organizational Global Address List (GAL)&lt;br /&gt;
&lt;br /&gt;
Creating and managing custom contact folders is no longer available in Microsoft&#039;s own cloud-based Outlook (Outlook on the web / new Outlook). Contacts in folders created earlier are still displayed there, listed under a different category - but the standard Microsoft Graph API contact search used by the Connector does not find these contacts.&lt;br /&gt;
&lt;br /&gt;
Search of the organizational Global Address List (GAL) is currently not supported by the Connector.&lt;br /&gt;
&lt;br /&gt;
=Troubleshooting=&lt;br /&gt;
== General ==&lt;br /&gt;
&lt;br /&gt;
===Creating an app trace===&lt;br /&gt;
For further analysis and creating a support ticket it will be useful to have a suitable app trace. &amp;lt;br&amp;gt;&lt;br /&gt;
Before creating the trace please make sure the following trace flags are activated for the app instance:&lt;br /&gt;
* App&lt;br /&gt;
* App WebSocket&lt;br /&gt;
* Config&lt;br /&gt;
* Database&lt;br /&gt;
* HTTP client&lt;br /&gt;
* TCP&lt;br /&gt;
* TLS&lt;br /&gt;
* Webserver&lt;br /&gt;
&lt;br /&gt;
After setting the config flags, please make sure to&lt;br /&gt;
* stop the instance&lt;br /&gt;
* deleting the current instance log&lt;br /&gt;
* start the instance&lt;br /&gt;
&#039;&#039;&#039;Now please wait at least 5 Minutes before you save the log&#039;&#039;&#039;, otherwise we could not have the whole picture in the trace.&lt;br /&gt;
&lt;br /&gt;
The restart and deletion of the the old log is useful the see the complete initialization process right away.&lt;br /&gt;
&lt;br /&gt;
===SSL Certificate for notification URL===&lt;br /&gt;
It also is useful to make sure the notification URL has a valid and public signed certificate.&amp;lt;br&amp;gt;&lt;br /&gt;
You can do that, using an SSL-Checker, for example: https://www.sslshopper.com/ssl-checker.html &amp;lt;br&amp;gt;&lt;br /&gt;
Without a valid, public signed certificate, Microsoft will decline the connection since it will not be possible to establish a trust relationship for the SSL/TLS secure channel.&lt;br /&gt;
&lt;br /&gt;
===Correctness of notification URL===&lt;br /&gt;
You can try to open the notification URL in your Browser&amp;lt;br&amp;gt;&lt;br /&gt;
Most likely you will see a HTTP 404 (Not Found) error message, which is the expected behavior since we are not providing an HTML website, the HTTP GET request from the browser will not be answered with content.&amp;lt;br&amp;gt;&lt;br /&gt;
This is perfectly fine since Microsoft will send presence updates with HTTP POST and will not try to request content from our app.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
What you can find out by trying to open the URL in your browser are the two following things: &amp;lt;br&amp;gt;&lt;br /&gt;
* If you receive a HTTP 404 error message you are most likely connected to an App Platform, if not you need to check your DNS (and maybe also reverse proxy) settings.&lt;br /&gt;
* If the URL is modified and the used build number is added, an app has answered your request&lt;br /&gt;
** Example: &amp;lt;code&amp;gt;https://public.dns/your.domain/microsoft365/subscriptions&amp;lt;/code&amp;gt; is modified to &amp;lt;code&amp;gt;https://public.dns/your.domain/microsoft365/&amp;lt;b&amp;gt;1510411&amp;lt;/b&amp;gt;/subscriptions&amp;lt;/code&amp;gt;&lt;br /&gt;
** If this is not the case, your URL is wrong. (Be aware: The URL depends on the settings of the web server path of your app instance)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Be aware:&#039;&#039;&#039; The URL-Recognition in the Application Platform is &#039;&#039;&#039;case sensitive&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Activation of &amp;quot;Public client flow&amp;quot; for the registered app in Azure Portal===&lt;br /&gt;
If the subscription is not working at all, please make sure &amp;quot;Public client flow&amp;quot; is activated for the registered app in the Azure portal (as described in our [[Howto16r1:Configure User Presence Sync by Connector for Microsoft365#Create an App for syncing Teams to PBX|HowTo article]]).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
The App Service trace will contain the following message if this is not the case:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;AADSTS7000218: The request body must contain the following parameter: &#039;client_assertion&#039; or &#039;client_secret&#039;.&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== User Presence == &lt;br /&gt;
===GUI Feedback===&lt;br /&gt;
The app itself shows required states with green and red as connections to the Master PBX, Authentication and Presence Subscription to identify if there are problems. &amp;lt;br&amp;gt;&lt;br /&gt;
Sometimes it needs a little bit time until the states are changed. &amp;lt;br&amp;gt;&lt;br /&gt;
If the states remain, it is mandatory to enable logs on the app platform and check for more information. &amp;lt;br&amp;gt;&lt;br /&gt;
([[Howto13r3:Configure Connector for Microsoft365#Creating an app trace|Concept App Service Connector for Microsoft 365: Creating an app trace]])&lt;br /&gt;
&lt;br /&gt;
====No connection to Master PBX====&lt;br /&gt;
Check the MasterPBX name.&amp;lt;br&amp;gt;&lt;br /&gt;
The field must only contain the name [&amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;pbx&amp;lt;/span&amp;gt;], &#039;&#039;&#039;not the full domain&#039;&#039;&#039; [&amp;lt;span style=&amp;quot;color:red;text-decoration: line-through;&amp;quot;&amp;gt;pbx.domain.tld&amp;lt;/span&amp;gt;]. ([[Howto13r3:Configure Connector for Microsoft365#Synchronization from Teams to the PBX|Synchronization from Teams to the PBX - Master PBX field]])&lt;br /&gt;
&lt;br /&gt;
====Presence subscription failed====&lt;br /&gt;
There are many reasons why the &amp;quot;Presence subscription failed&amp;quot; message could be displayed.&amp;lt;br&amp;gt;&lt;br /&gt;
We try to list the most common reasons:&lt;br /&gt;
* The permission for the registered app in the Azure portal are not correctly set ([[Howto13r3:Configure Connector for Microsoft365#Create an App for syncing Teams to PBX|Howto: Create an App for syncing Teams to PBX]])&lt;br /&gt;
* The Notification URL is wrong ([[Reference13r3:Concept App Service Connector for Microsoft 365#Correctness of notification URL|Concept App Service Connector for Microsoft 365: Correctness of notification URL]] )&lt;br /&gt;
* The App service is not reachable from the internet ([[Reference13r3:Concept App Service Connector for Microsoft 365#Correctness of notification URL|Concept App Service Connector for Microsoft 365: Correctness of notification URL]] )&lt;br /&gt;
* The certificate for the public endpoint (e.g. reverse proxy) is not valid, or not publicly signed ([[Reference13r3:Concept App Service Connector for Microsoft 365#SSL Certificate for notification URL|Concept App Service Connector for Microsoft 365: SSL Certificate for notification URL]])&lt;br /&gt;
* The user from PBX and the Azure Portal cannot be matched ([[Reference13r3:Concept App Service Connector for Microsoft 365#User Matching|Concept App Service Connector for Microsoft 365: User Matching]])&lt;br /&gt;
* The App Platforms clock time is wrong ([[Reference13r3:Concept App Service Connector for Microsoft 365#App Platform clock time is wrong|Concept App Service Connector for Microsoft 365: App Platform clock time is wrong]])&lt;br /&gt;
* No user has a valid Connector for Microsoft 365 App license ([[Reference13r3:Concept App Service Connector for Microsoft 365#Requirements|Concept App Service Connector for Microsoft 365: Requirements]])&lt;br /&gt;
&lt;br /&gt;
===Teams License for communication user===&lt;br /&gt;
If presence subscription does not work, please check if all of the configured communication users have a Microsoft Teams license applied and no multifactor authentication is in use for this particular user. &amp;lt;br&amp;gt;&lt;br /&gt;
Also please make sure you can login with the configured credentials. (If you have set a password as an Administration, the user needs to change the password during the first login, therefore the given password will be invalid for API access).&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Sometimes, after changing setting or after the instance has restarted it can take up to 12 minutes until the presence subscription is working correctly. (Due to the subscription timeout)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
= Known Issues =&lt;br /&gt;
== Special Characters In Password ==&lt;br /&gt;
If you are using special characters (*, &amp;amp;, (, ), etc.) in your password you could run into a problem with the authentication of the communication user.&amp;lt;br&amp;gt;&lt;br /&gt;
The authentication failed status is being displayed. &amp;lt;br&amp;gt;&lt;br /&gt;
For the moment the only workaround is to eliminate special characters from your password.&lt;br /&gt;
&lt;br /&gt;
==App Platform clock time is wrong==&lt;br /&gt;
If the clock time at the App Platform is not correct, this will lead to an unstable behaviour of the Connector for Microsoft 365.&amp;lt;br&amp;gt;&lt;br /&gt;
Since the Connector for Microsoft 365 is using the Microsoft Graph APIs presence subscription function, it needs to provide in its request a precise time until the subscription validity will be expired.&amp;lt;br&amp;gt;&lt;br /&gt;
The app service is handling subscription and will automatically recreate a new subscription each time the previous one has expired.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A wrong clock time will lead to false expiration times and thus&lt;br /&gt;
*  the subscription will be expired earlier than expected (synchronisation is not working because there is no valid subscription)&lt;br /&gt;
*  the subscription will be valid longer than expected (the app service is trying to create a new subscription because it is expecting the previous one to be expired - will lead to a 409 conflict error, because only one subscription can be valid at a time)&lt;br /&gt;
&lt;br /&gt;
If you are not sure about the current time of the App Platform, you can login via SSH into the App Platform and execute the &amp;lt;code&amp;gt;date&amp;lt;/code&amp;gt; command to check the current time.&amp;lt;br&amp;gt;&lt;br /&gt;
You will receive an output like: &lt;br /&gt;
 Tue Mar 12 13:38:57 UTC 2024&lt;br /&gt;
Please be aware: The time is displayed in UTC, so please make sure to convert to your local time zone.&lt;br /&gt;
&lt;br /&gt;
==Geoblocking==&lt;br /&gt;
Since there might be no reliable country assignment for Microsoft addresses, all Microsoft addresses must be enabled on the upstream firewall in the event of geoblocking in order to ensure functionality of the Office365 Connector.&amp;lt;br&amp;gt;&lt;br /&gt;
As an alternative you might be able to configure your firewall to bypass the geoblocking for the configured notification URL.&lt;br /&gt;
&lt;br /&gt;
= Related Articles =&lt;br /&gt;
[[Howto16r1:Configure User Presence Sync by Connector for Microsoft365]] &amp;lt;br/&amp;gt;&lt;br /&gt;
[[Howto16r1:Configure Calendar Presence Sync by Connector for Microsoft365]] &amp;lt;br/&amp;gt;&lt;br /&gt;
[[Howto16r1:Configure Contact Search by Connector for Microsoft365]] &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Howto|{{PAGENAME}}]]&lt;/div&gt;</summary>
		<author><name>Tfu</name></author>
	</entry>
	<entry>
		<id>https://wiki.innovaphone.com/index.php?title=Reference16r1:Concept_App_Service_Connector_for_Microsoft_365&amp;diff=80064</id>
		<title>Reference16r1:Concept App Service Connector for Microsoft 365</title>
		<link rel="alternate" type="text/html" href="https://wiki.innovaphone.com/index.php?title=Reference16r1:Concept_App_Service_Connector_for_Microsoft_365&amp;diff=80064"/>
		<updated>2026-07-06T09:13:04Z</updated>

		<summary type="html">&lt;p&gt;Tfu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Concept|Apps]]&lt;br /&gt;
== Applies To == &lt;br /&gt;
&lt;br /&gt;
* Connector for Microsoft 365 from Version 16r1&lt;br /&gt;
&lt;br /&gt;
= Overview =&lt;br /&gt;
&lt;br /&gt;
Connector for Microsoft 365 synchronizes Microsoft Teams presences with the innovaphone PBX and back, and optionally additionally Calendar presence from Exchange Online (part of the Microsoft 365 Cloud Services).&lt;br /&gt;
It is also possible to search for your own contacts. &lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
* innovaphone PBX&lt;br /&gt;
* innovaphone Application Platform (minimum version 120004)&lt;br /&gt;
* V16r1&lt;br /&gt;
* App(Connector for Microsoft 365)&lt;br /&gt;
* PBX-App(innovaphone-microsoft365) license per user - order no. 02-00050-009&lt;br /&gt;
&lt;br /&gt;
== Concept ==&lt;br /&gt;
&lt;br /&gt;
=== User Presence ===&lt;br /&gt;
&lt;br /&gt;
==== Configuration ====&lt;br /&gt;
Please have a look into our [[Howto16r1:Configure User Presence Sync by Connector for Microsoft365|Howto guide for basic configuration aid]].&lt;br /&gt;
&lt;br /&gt;
==== Technical Overview ====&lt;br /&gt;
If the Connector for Microsoft 365 app is fully configured, the app connects to Microsoft to obtain a token. With the token, the app gets the teams users (with a Teams license) through the Microsoft Graph API.&lt;br /&gt;
A presence subscription to Microsoft is started with the licensed users of the PBX to get presence changes in Microsoft Teams for these users. A user subscription is also started to get changes of the users (adding, deleting or update). If a user has changed, the Teams users are retrieved again. If the presence has changed, it is forwarded to the PBX. The presences of Teams are mapped to the presences of the PBX.&lt;br /&gt;
&lt;br /&gt;
* User subscriptions are renewed every 60 minutes.&lt;br /&gt;
* Presence subscriptions are renewed every 10 minutes.&lt;br /&gt;
* License Check is made periodically.&lt;br /&gt;
&lt;br /&gt;
The app synchronises the PBX presence with Teams through the Graph Api. The on-the-phone presence will be renewed every 5 minutes. The other presences have a lifetime of 1 day but the away has a lifetime of 7 days.&lt;br /&gt;
The lifetimes are described [https://learn.microsoft.com/en-us/graph/api/presence-setuserpreferredpresence?view=graph-rest-1.0&amp;amp;tabs=http here]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Please be aware:&#039;&#039;&#039; The actual change of presence or line state will be live, the above-mentioned subscriptions are needed to register against the Microsoft API for changes. &lt;br /&gt;
After successful subscription Microsoft will trigger the Connector for Microsoft 365 App every time a presence or line state for a user has changed.&lt;br /&gt;
The subscription will then be renewed in the above-mentioned time interval to receive further live updates.&lt;br /&gt;
&lt;br /&gt;
===== User Matching =====&lt;br /&gt;
You now can choose the fields used for user matching on either side from the following options:&lt;br /&gt;
* PBX&lt;br /&gt;
** CN (Long Name property from the PBX user object)&lt;br /&gt;
** h323 (Name property from the PBX user object)&lt;br /&gt;
* Azure Portal&lt;br /&gt;
** displayName&lt;br /&gt;
** mail&lt;br /&gt;
** mailNickname&lt;br /&gt;
** onPremisesDistinguishedName&lt;br /&gt;
** onPremisesSamAccountName&lt;br /&gt;
** onPremisesUserPrincipalName&lt;br /&gt;
** userPrincipalName&lt;br /&gt;
&lt;br /&gt;
Additionally, you have the possibility to remove a possibly contained domain from the Azure fields content. &amp;lt;br&amp;gt;&lt;br /&gt;
Example: &#039;user@domain.tld&#039; is transformed to &#039;user&#039;, if this option is checked.&lt;br /&gt;
&lt;br /&gt;
===== Mapping Table =====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Teams Presence&lt;br /&gt;
! PBX Presence&lt;br /&gt;
|-&lt;br /&gt;
| Away&lt;br /&gt;
| away&lt;br /&gt;
|-&lt;br /&gt;
| BeRightBack&lt;br /&gt;
| away&lt;br /&gt;
|-&lt;br /&gt;
| Busy&lt;br /&gt;
| busy&lt;br /&gt;
|-&lt;br /&gt;
| DoNotDisturb&lt;br /&gt;
| dnd&lt;br /&gt;
|-&lt;br /&gt;
| InACall&lt;br /&gt;
| on-the-phone&lt;br /&gt;
|-&lt;br /&gt;
| InAMeeting&lt;br /&gt;
| meeting&lt;br /&gt;
|-&lt;br /&gt;
| Inactive&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| PresenceUnknown&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| Available&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| Offline&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| Offwork&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| OutOfOffice&lt;br /&gt;
| away&lt;br /&gt;
|-&lt;br /&gt;
| UrgentInterruptionsOnly&lt;br /&gt;
| dnd&lt;br /&gt;
|-&lt;br /&gt;
| Presenting&lt;br /&gt;
| on-the-phone&lt;br /&gt;
|-&lt;br /&gt;
| InAConferenceCall&lt;br /&gt;
| on-the-phone&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The value &amp;quot;online&amp;quot; unsets the Teams presence in the PBX.&lt;br /&gt;
&lt;br /&gt;
===== Master/Slave =====&lt;br /&gt;
&lt;br /&gt;
For Master/Slave combination the &amp;quot;Connector for Microsoft 365&amp;quot; App has to be added to the slave (if no full replication is on). The slave websocket connection is needed to display &amp;quot;on-the-phone&amp;quot; presence.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Calendar Presence ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Configuration ====&lt;br /&gt;
Please have a look into our [[Howto16r1:Configure Calendar Presence Sync by Connector for Microsoft365|Howto guide for basic configuration aid]].&lt;br /&gt;
&lt;br /&gt;
==== Technical Overview ====&lt;br /&gt;
Introduced in 15r1 the Connector for Microsoft 365 will offer a possibility to sync Azure Portal calendar events (Teams, Exchange online) via the Graph API with the PBX presence.&amp;lt;br&amp;gt;&lt;br /&gt;
For now the [https://wiki.innovaphone.com/index.php?title=Reference13r3:Concept_App_Service_Calendar Calendar App] is (along with other functions) also capable of syncing calendar events, but using the old EWS mechanism, which Microsoft announced as end of life starting from 2026.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Warning:&#039;&#039;&#039; Please make sure to not use both apps for syncing calendar events in parallel, this is not supported and will most likely lead to conflicts and unexpected behaviours.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
When the configuration of the connector for Microsoft 365 Calendar Presence Sync is complete, the app connects to Microsoft to receive a token with the calendar app registered in the Azure portal.&amp;lt;br&amp;gt;&lt;br /&gt;
With the token, the app can pick up the users from the Azure portal.&amp;lt;br&amp;gt;&lt;br /&gt;
These are matched against the users in the PBX, based on the configured &amp;quot;User Assignment&amp;quot; settings.&amp;lt;br&amp;gt;&lt;br /&gt;
For each matched user with a valid Connector for Microsoft 365 licence applied, a subscription for calendar events is created at Microsoft to receive event changes in Microsoft Calendar for these users.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
A user subscription is also started to receive user changes (add, delete or update).&amp;lt;br&amp;gt;&lt;br /&gt;
If a user has changed, the users are retrieved again. &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
If a calendar event has been started or ended, it is forwarded to the PBX.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* User subscriptions are renewed every 60 minutes.&lt;br /&gt;
* Event subscriptions are renewed every day.&lt;br /&gt;
* License Check is made every hour.&lt;br /&gt;
&lt;br /&gt;
=== Contact Search ===&lt;br /&gt;
&lt;br /&gt;
==== Configuration ====&lt;br /&gt;
Please have a look into our [[Howto16r1:Configure Calendar Presence Sync by Connector for Microsoft365|Howto guide for basic configuration aid]].&lt;br /&gt;
&lt;br /&gt;
==== Technical Overview ====&lt;br /&gt;
Introduced in 16r1 the Connector for Microsoft 365 will offer a possibility to search for your own contacts (Teams, Exchange online) via the Graph API.&lt;br /&gt;
&lt;br /&gt;
When the configuration of the connector for Microsoft 365 Contact Search is complete, the app connects to Microsoft to receive a token with the contact search app registered in the Azure portal.&amp;lt;br&amp;gt;&lt;br /&gt;
With the token, the app can pick up the users from the Azure portal.&amp;lt;br&amp;gt;&lt;br /&gt;
These are matched against the users in the PBX, based on the configured &amp;quot;User Assignment&amp;quot; settings.&amp;lt;br&amp;gt;&lt;br /&gt;
For each matched user with a valid Connector for Microsoft 365 licence applied, the user can search with the Phone App, for example (a myApps search provider will be provided for all apps looking using search providers looking up contacts). The search string is made available to the Connector for Microsoft 365 via the microsoft365-api. The results are sent to the consumer, e.g. the Phone App and presented there.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
A user subscription is started to receive user changes (add, delete or update).&amp;lt;br&amp;gt;&lt;br /&gt;
If a user has changed, the users are retrieved again. &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* User subscriptions are renewed every 60 minutes.&lt;br /&gt;
* License Check is made every hour.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Be aware:&#039;&#039;&#039; Since the Connector for Microsoft 365 is an app in the Scope of myApps App Platform, IP Phones and other services not using Apps cannot benefit from this search service.&lt;br /&gt;
&lt;br /&gt;
== Related Articles ==&lt;br /&gt;
&lt;br /&gt;
=Known Limitation=&lt;br /&gt;
&lt;br /&gt;
== General ==&lt;br /&gt;
&#039;&#039;Applies to the User Presence and the Calendar Presence&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Synchronization Delay ===&lt;br /&gt;
In the official Graph-API documentation, Microsoft is providing an overview about expected latencies for change notifications.&amp;lt;br&amp;gt;&lt;br /&gt;
You can find a whole overview table here:&amp;lt;br&amp;gt;&lt;br /&gt;
https://learn.microsoft.com/en-us/graph/change-notifications-overview#latency&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
For the user presences the resource &amp;quot;presence&amp;quot; is used and an average latency of 10 seconds but a maximum up to 1 minute is provided.&amp;lt;br&amp;gt;&lt;br /&gt;
Such a delay in syncing changed presences from Teams down to the PBX are considered normal and are caused by the Microsoft Graph-API.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
In case of calendar events the average is provided as &amp;quot;less than 1 minute&amp;quot; and the maximum to 3 minutes.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== User Presence ==&lt;br /&gt;
=== Line states set by the PBX does not block calls in Teams ===&lt;br /&gt;
Line states set by a 3rd party application (like the Connector for Microsoft 365) through the graph API are currently &#039;&#039;&#039;only for display purpose and do not block new calls&#039;&#039;&#039; in Teams.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
https://techcommunity.microsoft.com/t5/teams-developer/ms-graph-setpresence-problems/m-p/2798805/highlight/true#M3957&amp;lt;br&amp;gt;&lt;br /&gt;
As you can see in the above linked discussion, there once existed a feature request on Microsoft Voice, which is no longer available since it was not voted.&lt;br /&gt;
=== Maximum number of supported users ===&lt;br /&gt;
The connector now supports multiple Microsoft Teams communication users, which is the prerequisite to subscribe for more than 650 users. There is a new ribbon (Manage Teams Accounts) that allows you to configure as many communication users as you need. Every configured communication user can be used to subscribe 650 users, for example:&lt;br /&gt;
&lt;br /&gt;
*3 configured communication users x 650 licensed users = 1950 users can be subscribed&lt;br /&gt;
&#039;&#039;&#039;Please be aware&#039;&#039;&#039;: Each communication user must have a Teams license applied.&lt;br /&gt;
&lt;br /&gt;
This limitation is caused by Microsoft.&amp;lt;br&amp;gt;&lt;br /&gt;
In the documentation of the Graph-API you will find a hint to this limitation:&amp;lt;br&amp;gt;&lt;br /&gt;
https://learn.microsoft.com/en-us/graph/changenotifications-for-presence#subscribe-to-multiple-users-presence&amp;lt;br&amp;gt;&lt;br /&gt;
Trying to subscribe more than 650 users (with one communication user) by using the presence subscription API will be declined by the graph API with an error message, that too many users are requested.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Communication User (UserSynctoPbx) ===&lt;br /&gt;
Users with multi-factor authentication (MFA) are not supported as technical communication users for the Connector.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;We recommend creating a dedicated user account for this purpose rather than using an existing user account.&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;This limitation applies only to technical users used for the Connector for Microsoft 365, not standard user accounts. MFA can be used for real users.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Multiple sites / instances require multiple communication users ===&lt;br /&gt;
Each instance or each site must have separate communication users, as Microsoft only allows one concurrent subscription per communication user. (otherwise an HTTP 409 conflict will occur)&lt;br /&gt;
&lt;br /&gt;
This means that if you want to subscribe to the same Azure Portal backend from two different sites (or instances), you will need to have multiple communication users (each with an applied Teams licence) in order to be able to subscribe from all endpoints.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Subscription Timeout ===&lt;br /&gt;
&lt;br /&gt;
==== Situation ====&lt;br /&gt;
Due to a current limitation in the Graph API it is not possible to cancel or delete an active presence subscription.&amp;lt;br&amp;gt;&lt;br /&gt;
As you can see in the [https://learn.microsoft.com/en-us/graph/api/subscription-delete?view=graph-rest-1.0&amp;amp;tabs=http|documentation of the current Graph API (1.0)] the “Delete subscription” chapter does not include presence subscriptions.&amp;lt;br&amp;gt;&lt;br /&gt;
It is also not possible to have multiple subscription in parallel. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To make sure to only request a new presence subscription when the old one is not valid anymore, the app will store the state of the presence subscription and the time until it is valid in the database.&amp;lt;br&amp;gt;&lt;br /&gt;
As mentioned in the chapter “Technical Overview” we are creating presence subscriptions with a validity of 10 minutes.&amp;lt;br&amp;gt;&lt;br /&gt;
The presence subscription will be renewed as soon as it is no longer valid which will be 10 minutes after initial subscription.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Impact ====&lt;br /&gt;
If settings are changed or the app instance is restarted it will check the corresponding database entry on startup.&amp;lt;br&amp;gt;&lt;br /&gt;
In case the last presence subscription was completed less than 10 minutes ago, there is still an active presence subscription and the app has to wait for it to become invalid. &amp;lt;br&amp;gt;&lt;br /&gt;
Some Changes (e.g., to the “Notification-URL”) will only take effect after a new created subscription. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The current Beta Version of the Graph API is already providing a function to delete presence subscriptions, so we hope we can improve this behavior in the future.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Troubleshooting=&lt;br /&gt;
== General ==&lt;br /&gt;
&lt;br /&gt;
===Creating an app trace===&lt;br /&gt;
For further analysis and creating a support ticket it will be useful to have a suitable app trace. &amp;lt;br&amp;gt;&lt;br /&gt;
Before creating the trace please make sure the following trace flags are activated for the app instance:&lt;br /&gt;
* App&lt;br /&gt;
* App WebSocket&lt;br /&gt;
* Config&lt;br /&gt;
* Database&lt;br /&gt;
* HTTP client&lt;br /&gt;
* TCP&lt;br /&gt;
* TLS&lt;br /&gt;
* Webserver&lt;br /&gt;
&lt;br /&gt;
After setting the config flags, please make sure to&lt;br /&gt;
* stop the instance&lt;br /&gt;
* deleting the current instance log&lt;br /&gt;
* start the instance&lt;br /&gt;
&#039;&#039;&#039;Now please wait at least 5 Minutes before you save the log&#039;&#039;&#039;, otherwise we could not have the whole picture in the trace.&lt;br /&gt;
&lt;br /&gt;
The restart and deletion of the the old log is useful the see the complete initialization process right away.&lt;br /&gt;
&lt;br /&gt;
===SSL Certificate for notification URL===&lt;br /&gt;
It also is useful to make sure the notification URL has a valid and public signed certificate.&amp;lt;br&amp;gt;&lt;br /&gt;
You can do that, using an SSL-Checker, for example: https://www.sslshopper.com/ssl-checker.html &amp;lt;br&amp;gt;&lt;br /&gt;
Without a valid, public signed certificate, Microsoft will decline the connection since it will not be possible to establish a trust relationship for the SSL/TLS secure channel.&lt;br /&gt;
&lt;br /&gt;
===Correctness of notification URL===&lt;br /&gt;
You can try to open the notification URL in your Browser&amp;lt;br&amp;gt;&lt;br /&gt;
Most likely you will see a HTTP 404 (Not Found) error message, which is the expected behavior since we are not providing an HTML website, the HTTP GET request from the browser will not be answered with content.&amp;lt;br&amp;gt;&lt;br /&gt;
This is perfectly fine since Microsoft will send presence updates with HTTP POST and will not try to request content from our app.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
What you can find out by trying to open the URL in your browser are the two following things: &amp;lt;br&amp;gt;&lt;br /&gt;
* If you receive a HTTP 404 error message you are most likely connected to an App Platform, if not you need to check your DNS (and maybe also reverse proxy) settings.&lt;br /&gt;
* If the URL is modified and the used build number is added, an app has answered your request&lt;br /&gt;
** Example: &amp;lt;code&amp;gt;https://public.dns/your.domain/microsoft365/subscriptions&amp;lt;/code&amp;gt; is modified to &amp;lt;code&amp;gt;https://public.dns/your.domain/microsoft365/&amp;lt;b&amp;gt;1510411&amp;lt;/b&amp;gt;/subscriptions&amp;lt;/code&amp;gt;&lt;br /&gt;
** If this is not the case, your URL is wrong. (Be aware: The URL depends on the settings of the web server path of your app instance)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Be aware:&#039;&#039;&#039; The URL-Recognition in the Application Platform is &#039;&#039;&#039;case sensitive&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Activation of &amp;quot;Public client flow&amp;quot; for the registered app in Azure Portal===&lt;br /&gt;
If the subscription is not working at all, please make sure &amp;quot;Public client flow&amp;quot; is activated for the registered app in the Azure portal (as described in our [[Howto16r1:Configure User Presence Sync by Connector for Microsoft365#Create an App for syncing Teams to PBX|HowTo article]]).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
The App Service trace will contain the following message if this is not the case:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;AADSTS7000218: The request body must contain the following parameter: &#039;client_assertion&#039; or &#039;client_secret&#039;.&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== User Presence == &lt;br /&gt;
===GUI Feedback===&lt;br /&gt;
The app itself shows required states with green and red as connections to the Master PBX, Authentication and Presence Subscription to identify if there are problems. &amp;lt;br&amp;gt;&lt;br /&gt;
Sometimes it needs a little bit time until the states are changed. &amp;lt;br&amp;gt;&lt;br /&gt;
If the states remain, it is mandatory to enable logs on the app platform and check for more information. &amp;lt;br&amp;gt;&lt;br /&gt;
([[Howto13r3:Configure Connector for Microsoft365#Creating an app trace|Concept App Service Connector for Microsoft 365: Creating an app trace]])&lt;br /&gt;
&lt;br /&gt;
====No connection to Master PBX====&lt;br /&gt;
Check the MasterPBX name.&amp;lt;br&amp;gt;&lt;br /&gt;
The field must only contain the name [&amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;pbx&amp;lt;/span&amp;gt;], &#039;&#039;&#039;not the full domain&#039;&#039;&#039; [&amp;lt;span style=&amp;quot;color:red;text-decoration: line-through;&amp;quot;&amp;gt;pbx.domain.tld&amp;lt;/span&amp;gt;]. ([[Howto13r3:Configure Connector for Microsoft365#Synchronization from Teams to the PBX|Synchronization from Teams to the PBX - Master PBX field]])&lt;br /&gt;
&lt;br /&gt;
====Presence subscription failed====&lt;br /&gt;
There are many reasons why the &amp;quot;Presence subscription failed&amp;quot; message could be displayed.&amp;lt;br&amp;gt;&lt;br /&gt;
We try to list the most common reasons:&lt;br /&gt;
* The permission for the registered app in the Azure portal are not correctly set ([[Howto13r3:Configure Connector for Microsoft365#Create an App for syncing Teams to PBX|Howto: Create an App for syncing Teams to PBX]])&lt;br /&gt;
* The Notification URL is wrong ([[Reference13r3:Concept App Service Connector for Microsoft 365#Correctness of notification URL|Concept App Service Connector for Microsoft 365: Correctness of notification URL]] )&lt;br /&gt;
* The App service is not reachable from the internet ([[Reference13r3:Concept App Service Connector for Microsoft 365#Correctness of notification URL|Concept App Service Connector for Microsoft 365: Correctness of notification URL]] )&lt;br /&gt;
* The certificate for the public endpoint (e.g. reverse proxy) is not valid, or not publicly signed ([[Reference13r3:Concept App Service Connector for Microsoft 365#SSL Certificate for notification URL|Concept App Service Connector for Microsoft 365: SSL Certificate for notification URL]])&lt;br /&gt;
* The user from PBX and the Azure Portal cannot be matched ([[Reference13r3:Concept App Service Connector for Microsoft 365#User Matching|Concept App Service Connector for Microsoft 365: User Matching]])&lt;br /&gt;
* The App Platforms clock time is wrong ([[Reference13r3:Concept App Service Connector for Microsoft 365#App Platform clock time is wrong|Concept App Service Connector for Microsoft 365: App Platform clock time is wrong]])&lt;br /&gt;
* No user has a valid Connector for Microsoft 365 App license ([[Reference13r3:Concept App Service Connector for Microsoft 365#Requirements|Concept App Service Connector for Microsoft 365: Requirements]])&lt;br /&gt;
&lt;br /&gt;
===Teams License for communication user===&lt;br /&gt;
If presence subscription does not work, please check if all of the configured communication users have a Microsoft Teams license applied and no multifactor authentication is in use for this particular user. &amp;lt;br&amp;gt;&lt;br /&gt;
Also please make sure you can login with the configured credentials. (If you have set a password as an Administration, the user needs to change the password during the first login, therefore the given password will be invalid for API access).&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Sometimes, after changing setting or after the instance has restarted it can take up to 12 minutes until the presence subscription is working correctly. (Due to the subscription timeout)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
= Known Issues =&lt;br /&gt;
== Special Characters In Password ==&lt;br /&gt;
If you are using special characters (*, &amp;amp;, (, ), etc.) in your password you could run into a problem with the authentication of the communication user.&amp;lt;br&amp;gt;&lt;br /&gt;
The authentication failed status is being displayed. &amp;lt;br&amp;gt;&lt;br /&gt;
For the moment the only workaround is to eliminate special characters from your password.&lt;br /&gt;
&lt;br /&gt;
==App Platform clock time is wrong==&lt;br /&gt;
If the clock time at the App Platform is not correct, this will lead to an unstable behaviour of the Connector for Microsoft 365.&amp;lt;br&amp;gt;&lt;br /&gt;
Since the Connector for Microsoft 365 is using the Microsoft Graph APIs presence subscription function, it needs to provide in its request a precise time until the subscription validity will be expired.&amp;lt;br&amp;gt;&lt;br /&gt;
The app service is handling subscription and will automatically recreate a new subscription each time the previous one has expired.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A wrong clock time will lead to false expiration times and thus&lt;br /&gt;
*  the subscription will be expired earlier than expected (synchronisation is not working because there is no valid subscription)&lt;br /&gt;
*  the subscription will be valid longer than expected (the app service is trying to create a new subscription because it is expecting the previous one to be expired - will lead to a 409 conflict error, because only one subscription can be valid at a time)&lt;br /&gt;
&lt;br /&gt;
If you are not sure about the current time of the App Platform, you can login via SSH into the App Platform and execute the &amp;lt;code&amp;gt;date&amp;lt;/code&amp;gt; command to check the current time.&amp;lt;br&amp;gt;&lt;br /&gt;
You will receive an output like: &lt;br /&gt;
 Tue Mar 12 13:38:57 UTC 2024&lt;br /&gt;
Please be aware: The time is displayed in UTC, so please make sure to convert to your local time zone.&lt;br /&gt;
&lt;br /&gt;
==Geoblocking==&lt;br /&gt;
Since there might be no reliable country assignment for Microsoft addresses, all Microsoft addresses must be enabled on the upstream firewall in the event of geoblocking in order to ensure functionality of the Office365 Connector.&amp;lt;br&amp;gt;&lt;br /&gt;
As an alternative you might be able to configure your firewall to bypass the geoblocking for the configured notification URL.&lt;br /&gt;
&lt;br /&gt;
= Related Articles =&lt;br /&gt;
[[Howto16r1:Configure User Presence Sync by Connector for Microsoft365]] &amp;lt;br/&amp;gt;&lt;br /&gt;
[[Howto16r1:Configure Calendar Presence Sync by Connector for Microsoft365]] &amp;lt;br/&amp;gt;&lt;br /&gt;
[[Howto16r1:Configure Contact Search by Connector for Microsoft365]] &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Howto|{{PAGENAME}}]]&lt;/div&gt;</summary>
		<author><name>Tfu</name></author>
	</entry>
	<entry>
		<id>https://wiki.innovaphone.com/index.php?title=Reference16r1:Concept_App_Service_Connector_for_Microsoft_365&amp;diff=80063</id>
		<title>Reference16r1:Concept App Service Connector for Microsoft 365</title>
		<link rel="alternate" type="text/html" href="https://wiki.innovaphone.com/index.php?title=Reference16r1:Concept_App_Service_Connector_for_Microsoft_365&amp;diff=80063"/>
		<updated>2026-07-06T09:09:06Z</updated>

		<summary type="html">&lt;p&gt;Tfu: /* Communication User (UserSynctoPbx) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Concept|Apps]]&lt;br /&gt;
== Applies To == &lt;br /&gt;
&lt;br /&gt;
* Connector for Microsoft 365 from Version 16r1&lt;br /&gt;
&lt;br /&gt;
= Overview =&lt;br /&gt;
&lt;br /&gt;
Connector for Microsoft 365 synchronizes Microsoft Teams presences with the innovaphone PBX and back, and optionally additionally Calendar presence from Exchange Online (part of the Microsoft 365 Cloud Services).&lt;br /&gt;
It is also possible to search for your own contacts. &lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
* innovaphone PBX&lt;br /&gt;
* innovaphone Application Platform (minimum version 120004)&lt;br /&gt;
* V16r1&lt;br /&gt;
* App(Connector for Microsoft 365)&lt;br /&gt;
* PBX-App(innovaphone-microsoft365) license per user - order no. 02-00050-009&lt;br /&gt;
&lt;br /&gt;
== Concept ==&lt;br /&gt;
&lt;br /&gt;
=== User Presence ===&lt;br /&gt;
&lt;br /&gt;
==== Configuration ====&lt;br /&gt;
Please have a look into our [[Howto16r1:Configure User Presence Sync by Connector for Microsoft365|Howto guide for basic configuration aid]].&lt;br /&gt;
&lt;br /&gt;
==== Technical Overview ====&lt;br /&gt;
If the Connector for Microsoft 365 app is fully configured, the app connects to Microsoft to obtain a token. With the token, the app gets the teams users (with a Teams license) through the Microsoft Graph API.&lt;br /&gt;
A presence subscription to Microsoft is started with the licensed users of the PBX to get presence changes in Microsoft Teams for these users. A user subscription is also started to get changes of the users (adding, deleting or update). If a user has changed, the Teams users are retrieved again. If the presence has changed, it is forwarded to the PBX. The presences of Teams are mapped to the presences of the PBX.&lt;br /&gt;
&lt;br /&gt;
* User subscriptions are renewed every 60 minutes.&lt;br /&gt;
* Presence subscriptions are renewed every 10 minutes.&lt;br /&gt;
* License Check is made periodically.&lt;br /&gt;
&lt;br /&gt;
The app synchronises the PBX presence with Teams through the Graph Api. The on-the-phone presence will be renewed every 5 minutes. The other presences have a lifetime of 1 day but the away has a lifetime of 7 days.&lt;br /&gt;
The lifetimes are described [https://learn.microsoft.com/en-us/graph/api/presence-setuserpreferredpresence?view=graph-rest-1.0&amp;amp;tabs=http here]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Please be aware:&#039;&#039;&#039; The actual change of presence or line state will be live, the above-mentioned subscriptions are needed to register against the Microsoft API for changes. &lt;br /&gt;
After successful subscription Microsoft will trigger the Connector for Microsoft 365 App every time a presence or line state for a user has changed.&lt;br /&gt;
The subscription will then be renewed in the above-mentioned time interval to receive further live updates.&lt;br /&gt;
&lt;br /&gt;
===== User Matching =====&lt;br /&gt;
You now can choose the fields used for user matching on either side from the following options:&lt;br /&gt;
* PBX&lt;br /&gt;
** CN (Long Name property from the PBX user object)&lt;br /&gt;
** h323 (Name property from the PBX user object)&lt;br /&gt;
* Azure Portal&lt;br /&gt;
** displayName&lt;br /&gt;
** mail&lt;br /&gt;
** mailNickname&lt;br /&gt;
** onPremisesDistinguishedName&lt;br /&gt;
** onPremisesSamAccountName&lt;br /&gt;
** onPremisesUserPrincipalName&lt;br /&gt;
** userPrincipalName&lt;br /&gt;
&lt;br /&gt;
Additionally, you have the possibility to remove a possibly contained domain from the Azure fields content. &amp;lt;br&amp;gt;&lt;br /&gt;
Example: &#039;user@domain.tld&#039; is transformed to &#039;user&#039;, if this option is checked.&lt;br /&gt;
&lt;br /&gt;
===== Mapping Table =====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Teams Presence&lt;br /&gt;
! PBX Presence&lt;br /&gt;
|-&lt;br /&gt;
| Away&lt;br /&gt;
| away&lt;br /&gt;
|-&lt;br /&gt;
| BeRightBack&lt;br /&gt;
| away&lt;br /&gt;
|-&lt;br /&gt;
| Busy&lt;br /&gt;
| busy&lt;br /&gt;
|-&lt;br /&gt;
| DoNotDisturb&lt;br /&gt;
| dnd&lt;br /&gt;
|-&lt;br /&gt;
| InACall&lt;br /&gt;
| on-the-phone&lt;br /&gt;
|-&lt;br /&gt;
| InAMeeting&lt;br /&gt;
| meeting&lt;br /&gt;
|-&lt;br /&gt;
| Inactive&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| PresenceUnknown&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| Available&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| Offline&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| Offwork&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| OutOfOffice&lt;br /&gt;
| away&lt;br /&gt;
|-&lt;br /&gt;
| UrgentInterruptionsOnly&lt;br /&gt;
| dnd&lt;br /&gt;
|-&lt;br /&gt;
| Presenting&lt;br /&gt;
| on-the-phone&lt;br /&gt;
|-&lt;br /&gt;
| InAConferenceCall&lt;br /&gt;
| on-the-phone&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The value &amp;quot;online&amp;quot; unsets the Teams presence in the PBX.&lt;br /&gt;
&lt;br /&gt;
===== Master/Slave =====&lt;br /&gt;
&lt;br /&gt;
For Master/Slave combination the &amp;quot;Connector for Microsoft 365&amp;quot; App has to be added to the slave (if no full replication is on). The slave websocket connection is needed to display &amp;quot;on-the-phone&amp;quot; presence.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Calendar Presence ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Configuration ====&lt;br /&gt;
Please have a look into our [[Howto15r1:Configure Calendar Presence Sync by Connector for Microsoft365|Howto guide for basic configuration aid]].&lt;br /&gt;
&lt;br /&gt;
==== Technical Overview ====&lt;br /&gt;
Introduced in 15r1 the Connector for Microsoft 365 will offer a possibility to sync Azure Portal calendar events (Teams, Exchange online) via the Graph API with the PBX presence.&amp;lt;br&amp;gt;&lt;br /&gt;
For now the [https://wiki.innovaphone.com/index.php?title=Reference13r3:Concept_App_Service_Calendar Calendar App] is (along with other functions) also capable of syncing calendar events, but using the old EWS mechanism, which Microsoft announced as end of life starting from 2026.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Warning:&#039;&#039;&#039; Please make sure to not use both apps for syncing calendar events in parallel, this is not supported and will most likely lead to conflicts and unexpected behaviours.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
When the configuration of the connector for Microsoft 365 Calendar Presence Sync is complete, the app connects to Microsoft to receive a token with the calendar app registered in the Azure portal.&amp;lt;br&amp;gt;&lt;br /&gt;
With the token, the app can pick up the users from the Azure portal.&amp;lt;br&amp;gt;&lt;br /&gt;
These are matched against the users in the PBX, based on the configured &amp;quot;User Assignment&amp;quot; settings.&amp;lt;br&amp;gt;&lt;br /&gt;
For each matched user with a valid Connector for Microsoft 365 licence applied, a subscription for calendar events is created at Microsoft to receive event changes in Microsoft Calendar for these users.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
A user subscription is also started to receive user changes (add, delete or update).&amp;lt;br&amp;gt;&lt;br /&gt;
If a user has changed, the users are retrieved again. &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
If a calendar event has been started or ended, it is forwarded to the PBX.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* User subscriptions are renewed every 60 minutes.&lt;br /&gt;
* Event subscriptions are renewed every day.&lt;br /&gt;
* License Check is made every hour.&lt;br /&gt;
&lt;br /&gt;
=== Contact Search ===&lt;br /&gt;
&lt;br /&gt;
==== Configuration ====&lt;br /&gt;
Please have a look into our [[Howto16r1:Configure Calendar Presence Sync by Connector for Microsoft365|Howto guide for basic configuration aid]].&lt;br /&gt;
&lt;br /&gt;
==== Technical Overview ====&lt;br /&gt;
Introduced in 16r1 the Connector for Microsoft 365 will offer a possibility to search for your own contacts (Teams, Exchange online) via the Graph API.&lt;br /&gt;
&lt;br /&gt;
When the configuration of the connector for Microsoft 365 Contact Search is complete, the app connects to Microsoft to receive a token with the contact search app registered in the Azure portal.&amp;lt;br&amp;gt;&lt;br /&gt;
With the token, the app can pick up the users from the Azure portal.&amp;lt;br&amp;gt;&lt;br /&gt;
These are matched against the users in the PBX, based on the configured &amp;quot;User Assignment&amp;quot; settings.&amp;lt;br&amp;gt;&lt;br /&gt;
For each matched user with a valid Connector for Microsoft 365 licence applied, the user can search with the Phone App, for example (a myApps search provider will be provided for all apps looking using search providers looking up contacts). The search string is made available to the Connector for Microsoft 365 via the microsoft365-api. The results are sent to the consumer, e.g. the Phone App and presented there.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
A user subscription is started to receive user changes (add, delete or update).&amp;lt;br&amp;gt;&lt;br /&gt;
If a user has changed, the users are retrieved again. &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* User subscriptions are renewed every 60 minutes.&lt;br /&gt;
* License Check is made every hour.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Be aware:&#039;&#039;&#039; Since the Connector for Microsoft 365 is an app in the Scope of myApps App Platform, IP Phones and other services not using Apps cannot benefit from this search service.&lt;br /&gt;
&lt;br /&gt;
== Related Articles ==&lt;br /&gt;
&lt;br /&gt;
=Known Limitation=&lt;br /&gt;
&lt;br /&gt;
== General ==&lt;br /&gt;
&#039;&#039;Applies to the User Presence and the Calendar Presence&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Synchronization Delay ===&lt;br /&gt;
In the official Graph-API documentation, Microsoft is providing an overview about expected latencies for change notifications.&amp;lt;br&amp;gt;&lt;br /&gt;
You can find a whole overview table here:&amp;lt;br&amp;gt;&lt;br /&gt;
https://learn.microsoft.com/en-us/graph/change-notifications-overview#latency&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
For the user presences the resource &amp;quot;presence&amp;quot; is used and an average latency of 10 seconds but a maximum up to 1 minute is provided.&amp;lt;br&amp;gt;&lt;br /&gt;
Such a delay in syncing changed presences from Teams down to the PBX are considered normal and are caused by the Microsoft Graph-API.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
In case of calendar events the average is provided as &amp;quot;less than 1 minute&amp;quot; and the maximum to 3 minutes.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== User Presence ==&lt;br /&gt;
=== Line states set by the PBX does not block calls in Teams ===&lt;br /&gt;
Line states set by a 3rd party application (like the Connector for Microsoft 365) through the graph API are currently &#039;&#039;&#039;only for display purpose and do not block new calls&#039;&#039;&#039; in Teams.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
https://techcommunity.microsoft.com/t5/teams-developer/ms-graph-setpresence-problems/m-p/2798805/highlight/true#M3957&amp;lt;br&amp;gt;&lt;br /&gt;
As you can see in the above linked discussion, there once existed a feature request on Microsoft Voice, which is no longer available since it was not voted.&lt;br /&gt;
=== Maximum number of supported users ===&lt;br /&gt;
The connector now supports multiple Microsoft Teams communication users, which is the prerequisite to subscribe for more than 650 users. There is a new ribbon (Manage Teams Accounts) that allows you to configure as many communication users as you need. Every configured communication user can be used to subscribe 650 users, for example:&lt;br /&gt;
&lt;br /&gt;
*3 configured communication users x 650 licensed users = 1950 users can be subscribed&lt;br /&gt;
&#039;&#039;&#039;Please be aware&#039;&#039;&#039;: Each communication user must have a Teams license applied.&lt;br /&gt;
&lt;br /&gt;
This limitation is caused by Microsoft.&amp;lt;br&amp;gt;&lt;br /&gt;
In the documentation of the Graph-API you will find a hint to this limitation:&amp;lt;br&amp;gt;&lt;br /&gt;
https://learn.microsoft.com/en-us/graph/changenotifications-for-presence#subscribe-to-multiple-users-presence&amp;lt;br&amp;gt;&lt;br /&gt;
Trying to subscribe more than 650 users (with one communication user) by using the presence subscription API will be declined by the graph API with an error message, that too many users are requested.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Communication User (UserSynctoPbx) ===&lt;br /&gt;
Users with multi-factor authentication (MFA) are not supported as technical communication users for the Connector.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;We recommend creating a dedicated user account for this purpose rather than using an existing user account.&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;This limitation applies only to technical users used for the Connector for Microsoft 365, not standard user accounts. MFA can be used for real users.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Multiple sites / instances require multiple communication users ===&lt;br /&gt;
Each instance or each site must have separate communication users, as Microsoft only allows one concurrent subscription per communication user. (otherwise an HTTP 409 conflict will occur)&lt;br /&gt;
&lt;br /&gt;
This means that if you want to subscribe to the same Azure Portal backend from two different sites (or instances), you will need to have multiple communication users (each with an applied Teams licence) in order to be able to subscribe from all endpoints.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Subscription Timeout ===&lt;br /&gt;
&lt;br /&gt;
==== Situation ====&lt;br /&gt;
Due to a current limitation in the Graph API it is not possible to cancel or delete an active presence subscription.&amp;lt;br&amp;gt;&lt;br /&gt;
As you can see in the [https://learn.microsoft.com/en-us/graph/api/subscription-delete?view=graph-rest-1.0&amp;amp;tabs=http|documentation of the current Graph API (1.0)] the “Delete subscription” chapter does not include presence subscriptions.&amp;lt;br&amp;gt;&lt;br /&gt;
It is also not possible to have multiple subscription in parallel. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To make sure to only request a new presence subscription when the old one is not valid anymore, the app will store the state of the presence subscription and the time until it is valid in the database.&amp;lt;br&amp;gt;&lt;br /&gt;
As mentioned in the chapter “Technical Overview” we are creating presence subscriptions with a validity of 10 minutes.&amp;lt;br&amp;gt;&lt;br /&gt;
The presence subscription will be renewed as soon as it is no longer valid which will be 10 minutes after initial subscription.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Impact ====&lt;br /&gt;
If settings are changed or the app instance is restarted it will check the corresponding database entry on startup.&amp;lt;br&amp;gt;&lt;br /&gt;
In case the last presence subscription was completed less than 10 minutes ago, there is still an active presence subscription and the app has to wait for it to become invalid. &amp;lt;br&amp;gt;&lt;br /&gt;
Some Changes (e.g., to the “Notification-URL”) will only take effect after a new created subscription. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The current Beta Version of the Graph API is already providing a function to delete presence subscriptions, so we hope we can improve this behavior in the future.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Troubleshooting=&lt;br /&gt;
== General ==&lt;br /&gt;
&lt;br /&gt;
===Creating an app trace===&lt;br /&gt;
For further analysis and creating a support ticket it will be useful to have a suitable app trace. &amp;lt;br&amp;gt;&lt;br /&gt;
Before creating the trace please make sure the following trace flags are activated for the app instance:&lt;br /&gt;
* App&lt;br /&gt;
* App WebSocket&lt;br /&gt;
* Config&lt;br /&gt;
* Database&lt;br /&gt;
* HTTP client&lt;br /&gt;
* TCP&lt;br /&gt;
* TLS&lt;br /&gt;
* Webserver&lt;br /&gt;
&lt;br /&gt;
After setting the config flags, please make sure to&lt;br /&gt;
* stop the instance&lt;br /&gt;
* deleting the current instance log&lt;br /&gt;
* start the instance&lt;br /&gt;
&#039;&#039;&#039;Now please wait at least 5 Minutes before you save the log&#039;&#039;&#039;, otherwise we could not have the whole picture in the trace.&lt;br /&gt;
&lt;br /&gt;
The restart and deletion of the the old log is useful the see the complete initialization process right away.&lt;br /&gt;
&lt;br /&gt;
===SSL Certificate for notification URL===&lt;br /&gt;
It also is useful to make sure the notification URL has a valid and public signed certificate.&amp;lt;br&amp;gt;&lt;br /&gt;
You can do that, using an SSL-Checker, for example: https://www.sslshopper.com/ssl-checker.html &amp;lt;br&amp;gt;&lt;br /&gt;
Without a valid, public signed certificate, Microsoft will decline the connection since it will not be possible to establish a trust relationship for the SSL/TLS secure channel.&lt;br /&gt;
&lt;br /&gt;
===Correctness of notification URL===&lt;br /&gt;
You can try to open the notification URL in your Browser&amp;lt;br&amp;gt;&lt;br /&gt;
Most likely you will see a HTTP 404 (Not Found) error message, which is the expected behavior since we are not providing an HTML website, the HTTP GET request from the browser will not be answered with content.&amp;lt;br&amp;gt;&lt;br /&gt;
This is perfectly fine since Microsoft will send presence updates with HTTP POST and will not try to request content from our app.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
What you can find out by trying to open the URL in your browser are the two following things: &amp;lt;br&amp;gt;&lt;br /&gt;
* If you receive a HTTP 404 error message you are most likely connected to an App Platform, if not you need to check your DNS (and maybe also reverse proxy) settings.&lt;br /&gt;
* If the URL is modified and the used build number is added, an app has answered your request&lt;br /&gt;
** Example: &amp;lt;code&amp;gt;https://public.dns/your.domain/microsoft365/subscriptions&amp;lt;/code&amp;gt; is modified to &amp;lt;code&amp;gt;https://public.dns/your.domain/microsoft365/&amp;lt;b&amp;gt;1510411&amp;lt;/b&amp;gt;/subscriptions&amp;lt;/code&amp;gt;&lt;br /&gt;
** If this is not the case, your URL is wrong. (Be aware: The URL depends on the settings of the web server path of your app instance)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Be aware:&#039;&#039;&#039; The URL-Recognition in the Application Platform is &#039;&#039;&#039;case sensitive&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Activation of &amp;quot;Public client flow&amp;quot; for the registered app in Azure Portal===&lt;br /&gt;
If the subscription is not working at all, please make sure &amp;quot;Public client flow&amp;quot; is activated for the registered app in the Azure portal (as described in our [[Howto16r1:Configure User Presence Sync by Connector for Microsoft365#Create an App for syncing Teams to PBX|HowTo article]]).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
The App Service trace will contain the following message if this is not the case:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;AADSTS7000218: The request body must contain the following parameter: &#039;client_assertion&#039; or &#039;client_secret&#039;.&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== User Presence == &lt;br /&gt;
===GUI Feedback===&lt;br /&gt;
The app itself shows required states with green and red as connections to the Master PBX, Authentication and Presence Subscription to identify if there are problems. &amp;lt;br&amp;gt;&lt;br /&gt;
Sometimes it needs a little bit time until the states are changed. &amp;lt;br&amp;gt;&lt;br /&gt;
If the states remain, it is mandatory to enable logs on the app platform and check for more information. &amp;lt;br&amp;gt;&lt;br /&gt;
([[Howto13r3:Configure Connector for Microsoft365#Creating an app trace|Concept App Service Connector for Microsoft 365: Creating an app trace]])&lt;br /&gt;
&lt;br /&gt;
====No connection to Master PBX====&lt;br /&gt;
Check the MasterPBX name.&amp;lt;br&amp;gt;&lt;br /&gt;
The field must only contain the name [&amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;pbx&amp;lt;/span&amp;gt;], &#039;&#039;&#039;not the full domain&#039;&#039;&#039; [&amp;lt;span style=&amp;quot;color:red;text-decoration: line-through;&amp;quot;&amp;gt;pbx.domain.tld&amp;lt;/span&amp;gt;]. ([[Howto13r3:Configure Connector for Microsoft365#Synchronization from Teams to the PBX|Synchronization from Teams to the PBX - Master PBX field]])&lt;br /&gt;
&lt;br /&gt;
====Presence subscription failed====&lt;br /&gt;
There are many reasons why the &amp;quot;Presence subscription failed&amp;quot; message could be displayed.&amp;lt;br&amp;gt;&lt;br /&gt;
We try to list the most common reasons:&lt;br /&gt;
* The permission for the registered app in the Azure portal are not correctly set ([[Howto13r3:Configure Connector for Microsoft365#Create an App for syncing Teams to PBX|Howto: Create an App for syncing Teams to PBX]])&lt;br /&gt;
* The Notification URL is wrong ([[Reference13r3:Concept App Service Connector for Microsoft 365#Correctness of notification URL|Concept App Service Connector for Microsoft 365: Correctness of notification URL]] )&lt;br /&gt;
* The App service is not reachable from the internet ([[Reference13r3:Concept App Service Connector for Microsoft 365#Correctness of notification URL|Concept App Service Connector for Microsoft 365: Correctness of notification URL]] )&lt;br /&gt;
* The certificate for the public endpoint (e.g. reverse proxy) is not valid, or not publicly signed ([[Reference13r3:Concept App Service Connector for Microsoft 365#SSL Certificate for notification URL|Concept App Service Connector for Microsoft 365: SSL Certificate for notification URL]])&lt;br /&gt;
* The user from PBX and the Azure Portal cannot be matched ([[Reference13r3:Concept App Service Connector for Microsoft 365#User Matching|Concept App Service Connector for Microsoft 365: User Matching]])&lt;br /&gt;
* The App Platforms clock time is wrong ([[Reference13r3:Concept App Service Connector for Microsoft 365#App Platform clock time is wrong|Concept App Service Connector for Microsoft 365: App Platform clock time is wrong]])&lt;br /&gt;
* No user has a valid Connector for Microsoft 365 App license ([[Reference13r3:Concept App Service Connector for Microsoft 365#Requirements|Concept App Service Connector for Microsoft 365: Requirements]])&lt;br /&gt;
&lt;br /&gt;
===Teams License for communication user===&lt;br /&gt;
If presence subscription does not work, please check if all of the configured communication users have a Microsoft Teams license applied and no multifactor authentication is in use for this particular user. &amp;lt;br&amp;gt;&lt;br /&gt;
Also please make sure you can login with the configured credentials. (If you have set a password as an Administration, the user needs to change the password during the first login, therefore the given password will be invalid for API access).&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Sometimes, after changing setting or after the instance has restarted it can take up to 12 minutes until the presence subscription is working correctly. (Due to the subscription timeout)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
= Known Issues =&lt;br /&gt;
== Special Characters In Password ==&lt;br /&gt;
If you are using special characters (*, &amp;amp;, (, ), etc.) in your password you could run into a problem with the authentication of the communication user.&amp;lt;br&amp;gt;&lt;br /&gt;
The authentication failed status is being displayed. &amp;lt;br&amp;gt;&lt;br /&gt;
For the moment the only workaround is to eliminate special characters from your password.&lt;br /&gt;
&lt;br /&gt;
==App Platform clock time is wrong==&lt;br /&gt;
If the clock time at the App Platform is not correct, this will lead to an unstable behaviour of the Connector for Microsoft 365.&amp;lt;br&amp;gt;&lt;br /&gt;
Since the Connector for Microsoft 365 is using the Microsoft Graph APIs presence subscription function, it needs to provide in its request a precise time until the subscription validity will be expired.&amp;lt;br&amp;gt;&lt;br /&gt;
The app service is handling subscription and will automatically recreate a new subscription each time the previous one has expired.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A wrong clock time will lead to false expiration times and thus&lt;br /&gt;
*  the subscription will be expired earlier than expected (synchronisation is not working because there is no valid subscription)&lt;br /&gt;
*  the subscription will be valid longer than expected (the app service is trying to create a new subscription because it is expecting the previous one to be expired - will lead to a 409 conflict error, because only one subscription can be valid at a time)&lt;br /&gt;
&lt;br /&gt;
If you are not sure about the current time of the App Platform, you can login via SSH into the App Platform and execute the &amp;lt;code&amp;gt;date&amp;lt;/code&amp;gt; command to check the current time.&amp;lt;br&amp;gt;&lt;br /&gt;
You will receive an output like: &lt;br /&gt;
 Tue Mar 12 13:38:57 UTC 2024&lt;br /&gt;
Please be aware: The time is displayed in UTC, so please make sure to convert to your local time zone.&lt;br /&gt;
&lt;br /&gt;
==Geoblocking==&lt;br /&gt;
Since there might be no reliable country assignment for Microsoft addresses, all Microsoft addresses must be enabled on the upstream firewall in the event of geoblocking in order to ensure functionality of the Office365 Connector.&amp;lt;br&amp;gt;&lt;br /&gt;
As an alternative you might be able to configure your firewall to bypass the geoblocking for the configured notification URL.&lt;br /&gt;
&lt;br /&gt;
= Related Articles =&lt;br /&gt;
[[Howto16r1:Configure User Presence Sync by Connector for Microsoft365]] &amp;lt;br/&amp;gt;&lt;br /&gt;
[[Howto16r1:Configure Calendar Presence Sync by Connector for Microsoft365]] &amp;lt;br/&amp;gt;&lt;br /&gt;
[[Howto16r1:Configure Contact Search by Connector for Microsoft365]] &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Howto|{{PAGENAME}}]]&lt;/div&gt;</summary>
		<author><name>Tfu</name></author>
	</entry>
	<entry>
		<id>https://wiki.innovaphone.com/index.php?title=Howto16r1:Configure_OAuth2_E-Mail&amp;diff=79966</id>
		<title>Howto16r1:Configure OAuth2 E-Mail</title>
		<link rel="alternate" type="text/html" href="https://wiki.innovaphone.com/index.php?title=Howto16r1:Configure_OAuth2_E-Mail&amp;diff=79966"/>
		<updated>2026-06-10T07:30:08Z</updated>

		<summary type="html">&lt;p&gt;Tfu: /* Exchange admin center */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The innovaphone PBX and apps can be configured to send E-Mails for various subjects and purposes. Major E-Mail providers intent to discontinue the username/password authentication schemes in favour of OAuth2. PBX and Apps version 16r1 does support OAuth2 authentication for SMTP. Here is a step by step guide how to set up OAuth2 support in Microsoft 365 through the Azure Portal and how to set it up on a Google Gmail account in the Google Cloud Console.&lt;br /&gt;
&lt;br /&gt;
== General Information ==&lt;br /&gt;
Most of the large email providers offer the possibility to define an app that is allowed to gain access of a certain scope like SMTP. &amp;lt;br&amp;gt;&lt;br /&gt;
It assigns a Client ID / Client Secret.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Authorization for sending from the mail account needs to be given one time either:&amp;lt;br&amp;gt;&lt;br /&gt;
* By providing resource owner username/password. Sending this to the token endpoint results in an access token and long term refresh token.&lt;br /&gt;
* By interactive authorization via a popup dialogue that is loaded from the authorization endpoint. After the credentials are verified, the dialogue redirects to the redirect URI with an authorization code that is traded to an access token and refresh token.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
The access token is sent for authentication in SMTP. It needs regular refresh, which will be done automatically.&lt;br /&gt;
&lt;br /&gt;
=== Modes ===&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Exchange&#039;&#039;&#039;: Microsoft, with interactive authorization&lt;br /&gt;
* &#039;&#039;&#039;Microsoft 365&#039;&#039;&#039;: Microsoft, without interactive authorization (Resource owner and password has to be filled)&lt;br /&gt;
* &#039;&#039;&#039;Gmail&#039;&#039;&#039;: Google, with interactive authorization&lt;br /&gt;
* &#039;&#039;&#039;Google Service Account&#039;&#039;&#039;:  Google, without interactive authorization (Client e-mail, Private Key ID and Private Key of the service account must be provided)&lt;br /&gt;
* &#039;&#039;&#039;Client secret post&#039;&#039;&#039;: Generic configuration where all parameters of the client secret post OAuth2 flow can be set.&lt;br /&gt;
* &#039;&#039;&#039;Private key jwt&#039;&#039;&#039;: Generic configuration where all parameters of the private key jwt OAuth2 flow can be set.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Example Redirect URIs ===&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;PBX&#039;&#039;&#039;: &amp;lt;nowiki&amp;gt;https://example-pbx.domain.com/OAUTH2-CLIENT/auth.htm&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Reporting&#039;&#039;&#039;: &amp;lt;nowiki&amp;gt;https://example-ap.domain.com/domain.com/reporting/auth.htm&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Fax&#039;&#039;&#039;: &amp;lt;nowiki&amp;gt;https://example-ap.domain.com/domain.com/fax/auth.htm&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Users&#039;&#039;&#039;: &amp;lt;nowiki&amp;gt;https://example-ap.domain.com/domain.com/usersapp/auth.htm&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Connect&#039;&#039;&#039;: &amp;lt;nowiki&amp;gt;https://example-ap.domain.com/domain.com/messages/auth.htm&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;AP Manager&#039;&#039;&#039;: &amp;lt;nowiki&amp;gt;https://example-ap.domain.com/manager/auth.htm&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Microsoft 365 ==&lt;br /&gt;
=== Azure Portal ===&lt;br /&gt;
Log in to Microsoft Azure Portal (https://portal.azure.com) and go to Microsoft Entra ID.&lt;br /&gt;
[[File:AzureMicrosoftEntraID.png|none|thumb|600x600px|/AzureMicrosoftEntraID.png|/AzureMicrosoftEntraID.png]]&lt;br /&gt;
Add a new app registration to create client credentials.&lt;br /&gt;
[[File:AzureAddAppRegistration.png|none|thumb|600x600px|/AzureAddAppRegistration.png|/AzureAddAppRegistration.png]]&lt;br /&gt;
Register the application and maybe already fill in the redirect URI for Web based application type to path OAUTH2-CLIENT/auth.htm at the PBX.&lt;br /&gt;
[[File:AzureRegisterAnApplication.png|none|thumb|600x600px|/AzureRegisterAnApplication.png|/AzureRegisterAnApplication.png]]&lt;br /&gt;
App registration is complete. Client ID and tenant needs to be configured at the PBX and every app that will be sending e-mails.&lt;br /&gt;
[[File:AzureApp.png|none|thumb|600x600px|/AzureApp.png|/AzureApp.png]]&lt;br /&gt;
Create a client secret. Note that expiry is limited to no longer than 2 years. The client secret must be renewed before expiry and the new secret configured and interactive authorisation carried out again to ensure continuous operation.&lt;br /&gt;
[[File:AzureAddClientSecret.png|none|thumb|600x600px|/AzureAddClientSecret.png|/AzureAddClientSecret.png]]&lt;br /&gt;
Copy the client secret. It also needs to be configured at the PBX and every app that will be sending e-mails.&lt;br /&gt;
[[File:AzureCopyClientSecret.png|none|thumb|600x600px|/AzureCopyClientSecret.png|/AzureCopyClientSecret.png]]&lt;br /&gt;
Add permissions located in APIs my organization uses.&lt;br /&gt;
[[File:AzureAddApiPermissionMyOrganization.png|none|thumb|600x600px|/AzureAddApiPermissionMyOrganization.png|/AzureAddApiPermissionMyOrganization.png]]&lt;br /&gt;
More precisely located in Office 365 Exchange Online.&lt;br /&gt;
[[File:AzureAddApiPermissionExchange.png|none|thumb|600x600px|/AzureAddApiPermissionExchange.png|/AzureAddApiPermissionExchange.png]]&lt;br /&gt;
And there in the application permissions.&lt;br /&gt;
[[File:AzureAddApiExchangeApplication.png|none|thumb|600x600px|/AzureAddApiExchangeApplication.png|/AzureAddApiExchangeApplication.png]]&lt;br /&gt;
Namely SMTP Mail.Send.&lt;br /&gt;
[[File:AzureAddApiSendMailAsUser.png|none|thumb|600x600px|/AzureAddApiSendMailAsUser.png|/AzureAddApiSendMailAsUser.png]]&lt;br /&gt;
Grant admin permission for Mail.Send.&lt;br /&gt;
[[File:AzureGrantApiPermissions.png|none|thumb|600x600px|/AzureGrantApiPermissions.png|/AzureGrantApiPermissions.png]]&lt;br /&gt;
API permissions are now granted.&lt;br /&gt;
[[File:AzureApiPermissionsGranted.png|none|thumb|600x600px|/AzureApiPermissionsGranted.png|/AzureApiPermissionsGranted.png]]&lt;br /&gt;
Tell all redirect URIs that the PBX and the apps will be using during interactive authorization.&lt;br /&gt;
[[File:AzureRedirectUris.png|none|thumb|600x600px|/AzureRedirectUris.png|/AzureRedirectUris.png]]&lt;br /&gt;
Allow public client flows of OAuth2. Resource Owner Password Credentials Flow has the advantage that it doesn&#039;t need interactive authorization.&lt;br /&gt;
[[File:AzureAllowPublicClientFlows.png|none|thumb|600x600px|/AzureAllowPublicClientFlows.png|/AzureAllowPublicClientFlows.png]]&lt;br /&gt;
&lt;br /&gt;
=== Microsoft 365 admin center ===&lt;br /&gt;
Log in to the Microsoft 365 admin center (https://admin.cloud.microsoft).&lt;br /&gt;
[[File:MS365AdminCenter.png|none|thumb|600x600px|/MS365AdminCenter.png|/MS365AdminCenter.png]]&lt;br /&gt;
Make sure that Microsoft 365 licenses are assigned to your user.&lt;br /&gt;
[[File:MS365UserLicenses.png|none|thumb|600x600px|/MS365UserLicenses.png|/MS365UserLicenses.png]]&lt;br /&gt;
Set your user active.&lt;br /&gt;
[[File:MS365ActiveUsers.png|none|thumb|600x600px|/MS365ActiveUsers.png|/MS365ActiveUsers.png]]&lt;br /&gt;
Locate the Mail tab of your user.&lt;br /&gt;
[[File:MS365UserEMail.png|none|thumb|600x600px|/MS365UserEMail.png|/MS365UserEMail.png]]&lt;br /&gt;
Allow authenticated SMTP.&lt;br /&gt;
[[File:MS365AuthenticatedSMTP.png|none|thumb|600x600px|/MS365AuthenticatedSMTP.png|/MS365AuthenticatedSMTP.png]]&lt;br /&gt;
&lt;br /&gt;
=== PBX Example configuration === &lt;br /&gt;
With this Microsoft setup the OAuth2 configuration for the resource owner password credentials flow can be filled in as follows. &lt;br /&gt;
[[File:OAuth2ResourceOwnerPasswordCredentials.png|none|thumb|600x600px|/OAuth2ResourceOwnerPasswordCredentials.png|/OAuth2ResourceOwnerPasswordCredentials.png]]&lt;br /&gt;
For interactive authorization this is the OAuth2 configuration. Authorize e-mail access one time and send a test mail to verify everything went well.&lt;br /&gt;
[[File:OAuth2InteractiveAuthorization.png|none|thumb|600x600px|/OAuth2InteractiveAuthorization.png|/OAuth2InteractiveAuthorization.png]]&lt;br /&gt;
&lt;br /&gt;
== Gmail ==&lt;br /&gt;
=== Preparations === &lt;br /&gt;
Login to the Google Cloud Console (https://console.cloud.google.com), select a project, New project.&lt;br /&gt;
[[File:GoogleSelectProject.png|none|thumb|600x600px|/GoogleSelectProject.png|/GoogleSelectProject.png]]&lt;br /&gt;
Create the project.&lt;br /&gt;
[[File:GoogleCreateProject.png|none|thumb|600x600px|/GoogleCreateProject.png|/GoogleCreateProject.png]]&lt;br /&gt;
Client credentials will be created in this project.&lt;br /&gt;
[[File:GoogleProjectCreated.png|none|thumb|600x600px|/GoogleProjectCreated.png|/GoogleProjectCreated.png]]&lt;br /&gt;
From the library specify the APIs needed to access.&lt;br /&gt;
[[File:GoogleApisServicesFromLibrary.png|none|thumb|600x600px|/GoogleApisServicesFromLibrary.png|/GoogleApisServicesFromLibrary.png]]&lt;br /&gt;
These are in the Gmail API.&lt;br /&gt;
[[File:GoogleApisServicesApiLibrary.png|none|thumb|600x600px|/GoogleApisServicesApiLibrary.png|/GoogleApisServicesApiLibrary.png]]&lt;br /&gt;
Choose the Gmail API and enable it.&lt;br /&gt;
[[File:GoogleGmailApis.png|none|thumb|600x600px|/GoogleGmailApis.png|/GoogleGmailApis.png]]&lt;br /&gt;
Credentials need to be created.&lt;br /&gt;
[[File:GoogleGmailApiAdded.png|none|thumb|600x600px|/GoogleGmailApiAdded.png|/GoogleGmailApiAdded.png]]&lt;br /&gt;
Invoke the help me choose wizard.&lt;br /&gt;
[[File:GoogleCreateCredentialsHelpMeChoose.png|none|thumb|600x600px|/GoogleCreateCredentialsHelpMeChoose.png|/GoogleCreateCredentialsHelpMeChoose.png]]&lt;br /&gt;
User data access is needed.&lt;br /&gt;
[[File:GoogleCredentialsUserData.png|none|thumb|600x600px|/GoogleCredentialsUserData.png|/GoogleCredentialsUserData.png]]&lt;br /&gt;
Configure the consent screen of the interactive authorization.&lt;br /&gt;
[[File:GoogleOAuthConsentScreen.png|none|thumb|600x600px|/GoogleOAuthConsentScreen.png|/GoogleOAuthConsentScreen.png]]&lt;br /&gt;
Specify the permissions that need to be authorized by the user.&lt;br /&gt;
[[File:GoogleOAuthScopes.png|none|thumb|600x600px|/GoogleOAuthScopes.png|/GoogleOAuthScopes.png]]&lt;br /&gt;
Its mail.google.com in general.&lt;br /&gt;
[[File:GoogleScopeMailGoogleCom.png|none|thumb|600x600px|/GoogleScopeMailGoogleCom.png|/GoogleScopeMailGoogleCom.png]]&lt;br /&gt;
And its to send email on the users behalf.&lt;br /&gt;
[[File:GoogleScopeAuthGmailSend.png|none|thumb|600x600px|/GoogleScopeAuthGmailSend.png|/GoogleScopeAuthGmailSend.png]]&lt;br /&gt;
These are the scopes needed.&lt;br /&gt;
[[File:GoogleScopes.png|none|thumb|600x600px|/GoogleScopes.png|/GoogleScopes.png]]&lt;br /&gt;
Ask client credentials for Web type application.&lt;br /&gt;
[[File:GoogleOAuthClientID.png|none|thumb|600x600px|/GoogleOAuthClientID.png|/GoogleOAuthClientID.png]]&lt;br /&gt;
Tell all redirect URIs that the PBX and the apps will be using during interactive authorization.&lt;br /&gt;
[[File:GoogleRedirectURIs.png|none|thumb|600x600px|/GoogleRedirectURIs.png|/GoogleRedirectURIs.png]]&lt;br /&gt;
Download the credentials. This json file contains all information for OAuth2 configuration.&lt;br /&gt;
[[File:GoogleClientCredentialsDownload.png|none|thumb|600x600px|/GoogleClientCredentialsDownload.png|/GoogleClientCredentialsDownload.png]]&lt;br /&gt;
Customize the OAuth consent screen&lt;br /&gt;
[[File:GoogleOAuthConsentScreenSettings.png|none|thumb|600x600px|/GoogleOAuthConsentScreenSettings.png|/GoogleOAuthConsentScreenSettings.png]]&lt;br /&gt;
Start the customization wizard.&lt;br /&gt;
[[File:GoogleConsentScreenWizard.png|none|thumb|600x600px|/GoogleConsentScreenWizard.png|/GoogleConsentScreenWizard.png]]&lt;br /&gt;
Choose which users may authorize.&lt;br /&gt;
[[File:GoogleAudienceExternal.png|none|thumb|600x600px|/GoogleAudienceExternal.png|/GoogleAudienceExternal.png]]&lt;br /&gt;
Google workspace users may choose internal audience. Users not in Google workspace proceed with external.&lt;br /&gt;
[[File:GoogleContactInformation.png|none|thumb|600x600px|/GoogleContactInformation.png|/GoogleContactInformation.png]]&lt;br /&gt;
Add a test user.&lt;br /&gt;
[[File:GoogleTestUserAdded.png|none|thumb|600x600px|/GoogleTestUserAdded.png|/GoogleTestUserAdded.png]]&lt;br /&gt;
&lt;br /&gt;
=== PBX Example configuration === &lt;br /&gt;
The OAuth2 parameters can be filled in with the information from the json file downloaded above. Authorize e-mail access one time and send a test mail to verify everything went well.&lt;br /&gt;
[[File:OAuth2InteractiveGmail.png|none|thumb|600x600px|/OAuth2InteractiveGmail.png|/OAuth2InteractiveGmail.png]]&lt;br /&gt;
&lt;br /&gt;
== Generic ==&lt;br /&gt;
&lt;br /&gt;
For other e-mail providers the client secret post OAuth2 flow may be configured in a generic way. Details need to be supplied by the e-mail provider.&lt;br /&gt;
&lt;br /&gt;
For the Microsoft 365 setup above it would be as follows with Token endpoint &#039;&#039;&amp;lt;nowiki&amp;gt;https://login.microsoftonline.com/af326a34-169c-469e-946b-1ef57925306b/oauth2/v2.0/token&amp;lt;/nowiki&amp;gt;&#039;&#039; Authorization URL &#039;&#039;&amp;lt;nowiki&amp;gt;https://login.microsoftonline.com/af326a34-169c-469e-946b-1ef57925306b/oauth2/v2.0/authorize?scope=https://outlook.office.com/SMTP.Send&amp;lt;/nowiki&amp;gt; offline_access&#039;&#039; The configuration appends &#039;&#039;&amp;amp;response_type=code&amp;amp;prompt=consent&amp;amp;login_hint=...&amp;amp;redirect_uri=...&amp;amp;client_id=...&#039;&#039; automatically.[[File:OAuth2ClientSecretPost.png|none|thumb|600x600px|/OAuth2ClientSecretPost.png|/OAuth2ClientSecretPost.png]]&lt;br /&gt;
For the Gmail example above the generic confguration would be like this with Token endpoint &#039;&#039;&amp;lt;nowiki&amp;gt;https://oauth2.googleapis.com/token&amp;lt;/nowiki&amp;gt;&#039;&#039; Authorization URL &#039;&#039;&amp;lt;nowiki&amp;gt;https://accounts.google.com/o/oauth2/auth?access_type=offline&amp;amp;scope=https://mail.google.com/&amp;lt;/nowiki&amp;gt;&#039;&#039; The configuration appends &#039;&#039;&amp;amp;response_type=code&amp;amp;prompt=consent&amp;amp;login_hint=...&amp;amp;redirect_uri=...&amp;amp;client_id=...&#039;&#039; automatically.&lt;br /&gt;
[[File:OAith2ClientSecretPostGmail.png|none|thumb|600x600px|/OAith2ClientSecretPostGmail.png|/OAith2ClientSecretPostGmail.png]]&lt;br /&gt;
The private key jwt OAuth2 flow can be configured generically as well.[[File:OAuth2PrivateKeyJWT.png|none|thumb|600x600px|/OAuth2PrivateKeyJWT.png|/OAuth2PrivateKeyJWT.png]]&lt;br /&gt;
&lt;br /&gt;
== Related Articles ==&lt;br /&gt;
* [[Reference16r1:PBX/Config/Authentication]]&lt;br /&gt;
* [[Reference16r1:Apps/PbxManager/Email]]&lt;br /&gt;
* [[Reference16r1:Concept App Connect#E-Mail configuration]]&lt;br /&gt;
* [[Reference16r1:Concept App Service Fax#Mail Configuration (SMTP_Server)]]&lt;br /&gt;
* [[Reference16r1:Concept App Service Reports#Configuration]]&lt;br /&gt;
* [[Reference16r1:Concept App Service Users#Users Admin App (innovaphone-usersadmin)]]&lt;br /&gt;
* [[Reference16r1:Concept App Platform#SMTP]]&lt;/div&gt;</summary>
		<author><name>Tfu</name></author>
	</entry>
	<entry>
		<id>https://wiki.innovaphone.com/index.php?title=Courseware:IT_Plus_Overview&amp;diff=79851</id>
		<title>Courseware:IT Plus Overview</title>
		<link rel="alternate" type="text/html" href="https://wiki.innovaphone.com/index.php?title=Courseware:IT_Plus_Overview&amp;diff=79851"/>
		<updated>2026-05-19T08:14:24Z</updated>

		<summary type="html">&lt;p&gt;Tfu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;innovaphone Plus&#039;&#039; is a series of courses, each covering advanced aspects of the configuration of innovaphone devices in separate topics.  Each topic can be worked through on individually or in any order.  Further topics will be added over time.  Each topic is based on the latest firmware at the time of creation.  All topics based on the same firmware version (e.g. 14r2) are included in the same course of the series.  &lt;br /&gt;
&lt;br /&gt;
Access to &#039;&#039;innovaphone Plus&#039;&#039; requires a valid innovaphone &#039;&#039;Plus&#039;&#039; corporate subscription. See [https://www.innovaphone.com/en/partner/training/innovaphone-plus-training.html innovaphone Plus Training] for details.&lt;br /&gt;
&lt;br /&gt;
The rest of this article gives you an overview of the topics covered and in which course they can be found. &lt;br /&gt;
__NOEDITSECTION__ &lt;br /&gt;
{{#invoke-url: https://class.innovaphone.com/moodle-debug/itplus-overview.php?wiki=true}}&lt;/div&gt;</summary>
		<author><name>Tfu</name></author>
	</entry>
	<entry>
		<id>https://wiki.innovaphone.com/index.php?title=Howto16r1:Configure_Contact_Search_by_Connector_for_Microsoft365&amp;diff=79595</id>
		<title>Howto16r1:Configure Contact Search by Connector for Microsoft365</title>
		<link rel="alternate" type="text/html" href="https://wiki.innovaphone.com/index.php?title=Howto16r1:Configure_Contact_Search_by_Connector_for_Microsoft365&amp;diff=79595"/>
		<updated>2026-04-24T15:34:07Z</updated>

		<summary type="html">&lt;p&gt;Tfu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
==Applies To==&lt;br /&gt;
This information applies to&lt;br /&gt;
Connector for Microsoft 365 from version 16r1&lt;br /&gt;
&lt;br /&gt;
==More Information==&lt;br /&gt;
&lt;br /&gt;
This article outlines a configuration scheme for Connector for Microsoft365 functionality.&amp;lt;br&amp;gt;&lt;br /&gt;
In preparation, you first will need to configure one Application in your Azure Portal. &amp;lt;br&amp;gt;&lt;br /&gt;
After that, you will install the App in your Application Platform, and configure everything.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===System Requirements===&lt;br /&gt;
&lt;br /&gt;
* Licenses &#039;&#039;&#039;innovaphone Connector for Microsoft 365&#039;&#039;&#039; per user who wants to use the innovaphone myApps Connector for Microsoft 365.&lt;br /&gt;
* &#039;&#039;&#039;account in Azure Portal of Microsoft&#039;&#039;&#039; (for each of the technical communication users, no permission role needed)&amp;lt;br&amp;gt;&lt;br /&gt;
* Must have access from the internet to your App Platform&lt;br /&gt;
** This can be done by using a reverse proxy or other firewall&lt;br /&gt;
* The public endpoint &#039;&#039;&#039;must have &#039;&#039;&#039; a &#039;&#039;&#039;valid, public signed certificate&#039;&#039;&#039; (in order to make a trusted SSL connection from the Azure cloud to the Application Platform possible)&lt;br /&gt;
** A valid certificate is required in all involved network entities - at least in the App Platform and if used in the Reverse Proxy; to ensure transmission of MS365 HTTPS POST requests to the app service in order to send notifications.&lt;br /&gt;
* Admin account for Azure Portal (only necessary for granting needed permission for registered app during setup)&lt;br /&gt;
&lt;br /&gt;
==Installation==&lt;br /&gt;
&lt;br /&gt;
===Configuration in Azure Portal===&lt;br /&gt;
&lt;br /&gt;
====Create an App to search for contacts====&lt;br /&gt;
* &#039;&#039;&#039;In the Azure Portal of Microsoft you have to add an app registration&#039;&#039;&#039; &lt;br /&gt;
* &#039;&#039;&#039;You only have to give a name for the app&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[Image:App_Registration_Connector_for_Microsoft365.png|thumb|none|600px|App Registration|app_registration_connector_for_microsoft365.png/]]&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Switch to Certificates &amp;amp; Secrets on the left&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;You only have to configure a client secret and save the value for the configuration of the app&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[Image:Authentication_Connector_for_Microsoft365_Calendar.png|thumb|none|600px|authentication_connector_for_microsoft365_calendar.png/]]&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Switch to api permissions on the left&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;You have to configure application permission (Contacts.Read) and (User.Read.All) as shown in the picture&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;Grant access to the api permissions, if not possible you have to ask an admin&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[Image:Azure_Select_Api-Permission.png|thumb|none|600px|azure_select_api-permission.png/]]&lt;br /&gt;
[[Image:Azure_Select_Api-Permission_Application.png|thumb|none|600px|azure_select_api-permission_application.png/]]&lt;br /&gt;
[[Image:APIPermission Connector for Microsoft365 ContactSearch.png|thumb|none|600px|APIPermission Connector for Microsoft365 ContactSearch/]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Installing and configuring App Platform and PBX===&lt;br /&gt;
====Installing the connector app====&lt;br /&gt;
* First you need to install the connector app from the App Store:&lt;br /&gt;
[[Image:Microsoft365_install_app_1.png|thumb|none|600px|microsoft365_install_app_1.png/]]&lt;br /&gt;
* Install the app by selecting&lt;br /&gt;
# All apps&lt;br /&gt;
# innovaphone AG&lt;br /&gt;
# innovaphone myApps Connector for Microsoft 365&lt;br /&gt;
# select the current Version &lt;br /&gt;
# Click install&lt;br /&gt;
[[Image:Microsoft365_install_app_2.png|thumb|none|600px|microsoft365_install_app_2.png/]]&lt;br /&gt;
====Creating an instance for the connector app====&lt;br /&gt;
* For creating an Instance, in the AP Manager you need to &lt;br /&gt;
# select &#039;&#039;&#039;innovaphone myApps Connector for Microsoft 365&#039;&#039;&#039;&lt;br /&gt;
# click &#039;&#039;&#039;add&#039;&#039;&#039;&lt;br /&gt;
[[Image:Microsoft365_create_instance_1.png|thumb|none|600px|microsoft365_create_instance_1.png/]]&lt;br /&gt;
* Insert the following information and save&lt;br /&gt;
# The technical Instance Name (we suggest microsoft365)&lt;br /&gt;
# Your Domain (This should be the domain you have already configured in your PBX and your Application Platform)&lt;br /&gt;
# define a password for the communication between the PBX and the app instance&lt;br /&gt;
# define a password for the communication between the app instance and the database&lt;br /&gt;
&#039;&#039;All other fields should be filled automatically&#039;&#039;&lt;br /&gt;
[[Image:Microsoft365_create_instance_2.png|thumb|none|600px|microsoft365_create_instance_2.png/]]&lt;br /&gt;
&lt;br /&gt;
====Creating the PBX app object using the PBX Manager Plugin====&lt;br /&gt;
* Open the PBX Manager and &lt;br /&gt;
# select the &#039;&#039;&#039;AP &amp;lt;code&amp;gt;InstanceName&amp;lt;/code&amp;gt;&#039;&#039;&#039; Tile&lt;br /&gt;
# Click &#039;&#039;&#039;Add an app&#039;&#039;&#039;&lt;br /&gt;
# Click &#039;&#039;&#039;Microsoft365 App&#039;&#039;&#039;&lt;br /&gt;
[[Image:Microsoft365_pbx_manager_1.png|thumb|none|600px|microsoft365_pbx_manager_1.png/]]&lt;br /&gt;
* Specify the &#039;&#039;&#039;Name&#039;&#039;&#039; and the &#039;&#039;&#039;SIP&#039;&#039;&#039; (We suggest using &#039;&#039;&#039;&amp;lt;code&amp;gt;microsoft365&amp;lt;/code&amp;gt;&#039;&#039;&#039; for this technical names)&lt;br /&gt;
[[Image:Microsoft365_pbx_manager_2.png|thumb|none|600px|microsoft365_pbx_manager_2.png/]]&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;Important:&#039;&#039;&#039; Please also add the &#039;&#039;&#039;microsoft365-api&#039;&#039;&#039; to a suitable Config-Template: Every user who should be able to search via the Connector for Microsoft 365 has to have access to the &#039;&#039;&#039;microsoft365-api&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
====Creating the API object using the PBX Manager Plugin====&lt;br /&gt;
* Open the PBX Manager and &lt;br /&gt;
# select the &#039;&#039;&#039;AP &amp;lt;code&amp;gt;InstanceName&amp;lt;/code&amp;gt;&#039;&#039;&#039; Tile&lt;br /&gt;
# Click &#039;&#039;&#039;Add an app&#039;&#039;&#039;&lt;br /&gt;
# Click &#039;&#039;&#039;Microsoft365 API&#039;&#039;&#039;&lt;br /&gt;
[[Image:Microsoft365_pbx_manager_1.png|thumb|none|600px|microsoft365_pbx_manager_1.png/]]&lt;br /&gt;
* The &#039;&#039;&#039;Name&#039;&#039;&#039; and &#039;&#039;&#039;SIP&#039;&#039;&#039; has to be &#039;&#039;&#039;&amp;lt;code&amp;gt;microsoft365-api&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
[[Image:Microsoft_365_Settings_API.png|thumb|none|600px|microsoft_365_Settings_API.png/]]&lt;br /&gt;
&lt;br /&gt;
====Add the admin app to a user or a template====&lt;br /&gt;
To be able to configure the connector app, you need users to have access to the admin app.&amp;lt;br&amp;gt;&lt;br /&gt;
You can achieve this by adding the app to a user, or to a template. &amp;lt;br&amp;gt;&lt;br /&gt;
In this Howto - as an example - we will add the app to the &amp;lt;code&amp;gt;Config Admin&amp;lt;/code&amp;gt; template. &amp;lt;br&amp;gt;&lt;br /&gt;
* In the PBX Manager &lt;br /&gt;
# select the &amp;lt;code&amp;gt;Templates&amp;lt;/code&amp;gt; tile &lt;br /&gt;
# click on the &amp;lt;code&amp;gt;Config Admin&amp;lt;/code&amp;gt; template&lt;br /&gt;
[[Image:Microsoft365_template_1.png|thumb|none|600px|microsoft365_template_1.png/]]&lt;br /&gt;
* In the &amp;lt;code&amp;gt;Config Admin&amp;lt;/code&amp;gt; template&lt;br /&gt;
# open Apps&lt;br /&gt;
# Check the &amp;lt;code&amp;gt;app name&amp;lt;/code&amp;gt; checkbox&lt;br /&gt;
# Save the changes&lt;br /&gt;
[[Image:Microsoft365_template_2.png|thumb|none|600px|microsoft365_template_2.png/]]&lt;br /&gt;
&lt;br /&gt;
====Configure the connector with the admin app====&lt;br /&gt;
Now your admins (designated groups or configured user) should have access to the connector admin app. &amp;lt;br&amp;gt;&lt;br /&gt;
* A user with access to the app can now see a new tile in the &#039;&#039;&#039;All Apps&#039;&#039;&#039; area&lt;br /&gt;
* The name depends on the configured &amp;lt;code&amp;gt;app name&amp;lt;/code&amp;gt; from the PBX Manager plugin&lt;br /&gt;
[[Image:Microsoft365_admin_app_1.png|thumb|none|600px|microsoft365_admin_app_1.png/]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====Configuration of the Contact Search=====&lt;br /&gt;
* For the contact search you select &#039;&#039;&#039;Configuration for Contact Search&#039;&#039;&#039; in the admin app&lt;br /&gt;
# &#039;&#039;&#039;ClientIDContactSearch&#039;&#039;&#039; - Please insert the Application ID (Client ID) from Azure Portal from the in preparation created Contact Search app&lt;br /&gt;
# &#039;&#039;&#039;TenantContactSearch&#039;&#039;&#039; - Please insert the Directory ID (Tenant) from Azure Portal from the in preparation created Contact Search app&lt;br /&gt;
# &#039;&#039;&#039;ClientSecretContactSearch&#039;&#039;&#039; - Please insert the shared secret from the in preparation created Contact Search app&lt;br /&gt;
# &#039;&#039;&#039;NotificationURL&#039;&#039;&#039; - You need to specify the address Microsoft can send presence updates to&lt;br /&gt;
## You need to make sure that you define a URL where you can reach your App Platform from the public internet &amp;lt;code&amp;gt;public.dns&amp;lt;/code&amp;gt;&lt;br /&gt;
## Next you need the domain you have configured in the app instance before (3.2.2) &amp;lt;code&amp;gt;your.domain&amp;lt;/code&amp;gt;&lt;br /&gt;
## Next you need the name of the instance you have configured before (3.2.2) &amp;lt;code&amp;gt;microsoft365&amp;lt;/code&amp;gt;&lt;br /&gt;
## The URL will always be terminated by &amp;lt;code&amp;gt;subscriptions&amp;lt;/code&amp;gt;&lt;br /&gt;
##* &amp;lt;code&amp;gt;https://public.dns/your.domain/microsoft365/subscriptions&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Related Articles==&lt;br /&gt;
[[Reference16r1:Concept App Service Connector for Microsoft 365|Concept App Service Connector for Microsoft 365]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Howto16r1:Configure User Presence Sync by Connector for Microsoft365]] &amp;lt;br/&amp;gt;&lt;br /&gt;
[[Howto16r1:Configure Calendar Presence Sync by Connector for Microsoft365]] &amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Howto|{{PAGENAME}}]]&lt;/div&gt;</summary>
		<author><name>Tfu</name></author>
	</entry>
	<entry>
		<id>https://wiki.innovaphone.com/index.php?title=Reference16r1:Concept_App_Service_Connector_for_Microsoft_365&amp;diff=79594</id>
		<title>Reference16r1:Concept App Service Connector for Microsoft 365</title>
		<link rel="alternate" type="text/html" href="https://wiki.innovaphone.com/index.php?title=Reference16r1:Concept_App_Service_Connector_for_Microsoft_365&amp;diff=79594"/>
		<updated>2026-04-24T15:33:52Z</updated>

		<summary type="html">&lt;p&gt;Tfu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Concept|Apps]]&lt;br /&gt;
== Applies To == &lt;br /&gt;
&lt;br /&gt;
* Connector for Microsoft 365 from Version 16r1&lt;br /&gt;
&lt;br /&gt;
= Overview =&lt;br /&gt;
&lt;br /&gt;
Connector for Microsoft 365 synchronizes Microsoft Teams presences with the innovaphone PBX and back, and optionally additionally Calendar presence from Exchange Online (part of the Microsoft 365 Cloud Services).&lt;br /&gt;
It is also possible to search for your own contacts. &lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
* innovaphone PBX&lt;br /&gt;
* innovaphone Application Platform (minimum version 120004)&lt;br /&gt;
* V16r1&lt;br /&gt;
* App(Connector for Microsoft 365)&lt;br /&gt;
* PBX-App(innovaphone-microsoft365) license per user - order no. 02-00050-009&lt;br /&gt;
&lt;br /&gt;
== Concept ==&lt;br /&gt;
&lt;br /&gt;
=== User Presence ===&lt;br /&gt;
&lt;br /&gt;
==== Configuration ====&lt;br /&gt;
Please have a look into our [[Howto15r1:Configure User Presence Sync by Connector for Microsoft365|Howto guide for basic configuration aid]].&lt;br /&gt;
&lt;br /&gt;
==== Technical Overview ====&lt;br /&gt;
If the Connector for Microsoft 365 app is fully configured, the app connects to Microsoft to obtain a token. With the token, the app gets the teams users (with a Teams license) through the Microsoft Graph API.&lt;br /&gt;
A presence subscription to Microsoft is started with the licensed users of the PBX to get presence changes in Microsoft Teams for these users. A user subscription is also started to get changes of the users (adding, deleting or update). If a user has changed, the Teams users are retrieved again. If the presence has changed, it is forwarded to the PBX. The presences of Teams are mapped to the presences of the PBX.&lt;br /&gt;
&lt;br /&gt;
* User subscriptions are renewed every 60 minutes.&lt;br /&gt;
* Presence subscriptions are renewed every 10 minutes.&lt;br /&gt;
* License Check is made periodically.&lt;br /&gt;
&lt;br /&gt;
The app synchronises the PBX presence with Teams through the Graph Api. The on-the-phone presence will be renewed every 5 minutes. The other presences have a lifetime of 1 day but the away has a lifetime of 7 days.&lt;br /&gt;
The lifetimes are described [https://learn.microsoft.com/en-us/graph/api/presence-setuserpreferredpresence?view=graph-rest-1.0&amp;amp;tabs=http here]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Please be aware:&#039;&#039;&#039; The actual change of presence or line state will be live, the above-mentioned subscriptions are needed to register against the Microsoft API for changes. &lt;br /&gt;
After successful subscription Microsoft will trigger the Connector for Microsoft 365 App every time a presence or line state for a user has changed.&lt;br /&gt;
The subscription will then be renewed in the above-mentioned time interval to receive further live updates.&lt;br /&gt;
&lt;br /&gt;
===== User Matching =====&lt;br /&gt;
You now can choose the fields used for user matching on either side from the following options:&lt;br /&gt;
* PBX&lt;br /&gt;
** CN (Long Name property from the PBX user object)&lt;br /&gt;
** h323 (Name property from the PBX user object)&lt;br /&gt;
* Azure Portal&lt;br /&gt;
** displayName&lt;br /&gt;
** mail&lt;br /&gt;
** mailNickname&lt;br /&gt;
** onPremisesDistinguishedName&lt;br /&gt;
** onPremisesSamAccountName&lt;br /&gt;
** onPremisesUserPrincipalName&lt;br /&gt;
** userPrincipalName&lt;br /&gt;
&lt;br /&gt;
Additionally, you have the possibility to remove a possibly contained domain from the Azure fields content. &amp;lt;br&amp;gt;&lt;br /&gt;
Example: &#039;user@domain.tld&#039; is transformed to &#039;user&#039;, if this option is checked.&lt;br /&gt;
&lt;br /&gt;
===== Mapping Table =====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Teams Presence&lt;br /&gt;
! PBX Presence&lt;br /&gt;
|-&lt;br /&gt;
| Away&lt;br /&gt;
| away&lt;br /&gt;
|-&lt;br /&gt;
| BeRightBack&lt;br /&gt;
| away&lt;br /&gt;
|-&lt;br /&gt;
| Busy&lt;br /&gt;
| busy&lt;br /&gt;
|-&lt;br /&gt;
| DoNotDisturb&lt;br /&gt;
| dnd&lt;br /&gt;
|-&lt;br /&gt;
| InACall&lt;br /&gt;
| on-the-phone&lt;br /&gt;
|-&lt;br /&gt;
| InAMeeting&lt;br /&gt;
| meeting&lt;br /&gt;
|-&lt;br /&gt;
| Inactive&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| PresenceUnknown&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| Available&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| Offline&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| Offwork&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| OutOfOffice&lt;br /&gt;
| away&lt;br /&gt;
|-&lt;br /&gt;
| UrgentInterruptionsOnly&lt;br /&gt;
| dnd&lt;br /&gt;
|-&lt;br /&gt;
| Presenting&lt;br /&gt;
| on-the-phone&lt;br /&gt;
|-&lt;br /&gt;
| InAConferenceCall&lt;br /&gt;
| on-the-phone&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The value &amp;quot;online&amp;quot; unsets the Teams presence in the PBX.&lt;br /&gt;
&lt;br /&gt;
===== Master/Slave =====&lt;br /&gt;
&lt;br /&gt;
For Master/Slave combination the &amp;quot;Connector for Microsoft 365&amp;quot; App has to be added to the slave (if no full replication is on). The slave websocket connection is needed to display &amp;quot;on-the-phone&amp;quot; presence.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Calendar Presence ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Configuration ====&lt;br /&gt;
Please have a look into our [[Howto15r1:Configure_Calendar_Presence_Sync_by_Connector_for_Microsoft365|Howto guide for basic configuration aid]].&lt;br /&gt;
&lt;br /&gt;
==== Technical Overview ====&lt;br /&gt;
Introduced in 15r1 the Connector for Microsoft 365 will offer a possibility to sync Azure Portal calendar events (Teams, Exchange online) via the Graph API with the PBX presence.&amp;lt;br&amp;gt;&lt;br /&gt;
For now the [https://wiki.innovaphone.com/index.php?title=Reference13r3:Concept_App_Service_Calendar Calendar App] is (along with other functions) also capable of syncing calendar events, but using the old EWS mechanism, which Microsoft announced as end of life starting from 2026.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Warning:&#039;&#039;&#039; Please make sure to not use both apps for syncing calendar events in parallel, this is not supported and will most likely lead to conflicts and unexpected behaviours.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
When the configuration of the connector for Microsoft 365 Calendar Presence Sync is complete, the app connects to Microsoft to receive a token with the calendar app registered in the Azure portal.&amp;lt;br&amp;gt;&lt;br /&gt;
With the token, the app can pick up the users from the Azure portal.&amp;lt;br&amp;gt;&lt;br /&gt;
These are matched against the users in the PBX, based on the configured &amp;quot;User Assignment&amp;quot; settings.&amp;lt;br&amp;gt;&lt;br /&gt;
For each matched user with a valid Connector for Microsoft 365 licence applied, a subscription for calendar events is created at Microsoft to receive event changes in Microsoft Calendar for these users.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
A user subscription is also started to receive user changes (add, delete or update).&amp;lt;br&amp;gt;&lt;br /&gt;
If a user has changed, the users are retrieved again. &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
If a calendar event has been started or ended, it is forwarded to the PBX.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* User subscriptions are renewed every 60 minutes.&lt;br /&gt;
* Event subscriptions are renewed every day.&lt;br /&gt;
* License Check is made every hour.&lt;br /&gt;
&lt;br /&gt;
=== Contact Search ===&lt;br /&gt;
&lt;br /&gt;
==== Configuration ====&lt;br /&gt;
Please have a look into our [[Howto16r1:Configure Calendar Presence Sync by Connector for Microsoft365|Howto guide for basic configuration aid]].&lt;br /&gt;
&lt;br /&gt;
==== Technical Overview ====&lt;br /&gt;
Introduced in 16r1 the Connector for Microsoft 365 will offer a possibility to search for your own contacts (Teams, Exchange online) via the Graph API.&lt;br /&gt;
&lt;br /&gt;
When the configuration of the connector for Microsoft 365 Contact Search is complete, the app connects to Microsoft to receive a token with the contact search app registered in the Azure portal.&amp;lt;br&amp;gt;&lt;br /&gt;
With the token, the app can pick up the users from the Azure portal.&amp;lt;br&amp;gt;&lt;br /&gt;
These are matched against the users in the PBX, based on the configured &amp;quot;User Assignment&amp;quot; settings.&amp;lt;br&amp;gt;&lt;br /&gt;
For each matched user with a valid Connector for Microsoft 365 licence applied, the user can search with the Phone App, for example (a myApps search provider will be provided for all apps looking using search providers looking up contacts). The search string is made available to the Connector for Microsoft 365 via the microsoft365-api. The results are sent to the consumer, e.g. the Phone App and presented there.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
A user subscription is started to receive user changes (add, delete or update).&amp;lt;br&amp;gt;&lt;br /&gt;
If a user has changed, the users are retrieved again. &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* User subscriptions are renewed every 60 minutes.&lt;br /&gt;
* License Check is made every hour.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Be aware:&#039;&#039;&#039; Since the Connector for Microsoft 365 is an app in the Scope of myApps App Platform, IP Phones and other services not using Apps cannot benefit from this search service.&lt;br /&gt;
&lt;br /&gt;
== Related Articles ==&lt;br /&gt;
&lt;br /&gt;
=Known Limitation=&lt;br /&gt;
&lt;br /&gt;
== General ==&lt;br /&gt;
&#039;&#039;Applies to the User Presence and the Calendar Presence&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Synchronization Delay ===&lt;br /&gt;
In the official Graph-API documentation, Microsoft is providing an overview about expected latencies for change notifications.&amp;lt;br&amp;gt;&lt;br /&gt;
You can find a whole overview table here:&amp;lt;br&amp;gt;&lt;br /&gt;
https://learn.microsoft.com/en-us/graph/change-notifications-overview#latency&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
For the user presences the resource &amp;quot;presence&amp;quot; is used and an average latency of 10 seconds but a maximum up to 1 minute is provided.&amp;lt;br&amp;gt;&lt;br /&gt;
Such a delay in syncing changed presences from Teams down to the PBX are considered normal and are caused by the Microsoft Graph-API.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
In case of calendar events the average is provided as &amp;quot;less than 1 minute&amp;quot; and the maximum to 3 minutes.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== User Presence ==&lt;br /&gt;
=== Line states set by the PBX does not block calls in Teams ===&lt;br /&gt;
Line states set by a 3rd party application (like the Connector for Microsoft 365) through the graph API are currently &#039;&#039;&#039;only for display purpose and do not block new calls&#039;&#039;&#039; in Teams.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
https://techcommunity.microsoft.com/t5/teams-developer/ms-graph-setpresence-problems/m-p/2798805/highlight/true#M3957&amp;lt;br&amp;gt;&lt;br /&gt;
As you can see in the above linked discussion, there once existed a feature request on Microsoft Voice, which is no longer available since it was not voted.&lt;br /&gt;
=== Maximum number of supported users ===&lt;br /&gt;
The connector now supports multiple Microsoft Teams communication users, which is the prerequisite to subscribe for more than 650 users. There is a new ribbon (Manage Teams Accounts) that allows you to configure as many communication users as you need. Every configured communication user can be used to subscribe 650 users, for example:&lt;br /&gt;
&lt;br /&gt;
*3 configured communication users x 650 licensed users = 1950 users can be subscribed&lt;br /&gt;
&#039;&#039;&#039;Please be aware&#039;&#039;&#039;: Each communication user must have a Teams license applied.&lt;br /&gt;
&lt;br /&gt;
This limitation is caused by Microsoft.&amp;lt;br&amp;gt;&lt;br /&gt;
In the documentation of the Graph-API you will find a hint to this limitation:&amp;lt;br&amp;gt;&lt;br /&gt;
https://learn.microsoft.com/en-us/graph/changenotifications-for-presence#subscribe-to-multiple-users-presence&amp;lt;br&amp;gt;&lt;br /&gt;
Trying to subscribe more than 650 users (with one communication user) by using the presence subscription API will be declined by the graph API with an error message, that too many users are requested.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Communication User (UserSynctoPbx) ===&lt;br /&gt;
Users with MFA (multi-factor-authentication) are not supported as technical communication user for the Connector.&lt;br /&gt;
&lt;br /&gt;
=== Multiple sites / instances require multiple communication users ===&lt;br /&gt;
Each instance or each site must have separate communication users, as Microsoft only allows one concurrent subscription per communication user. (otherwise an HTTP 409 conflict will occur)&lt;br /&gt;
&lt;br /&gt;
This means that if you want to subscribe to the same Azure Portal backend from two different sites (or instances), you will need to have multiple communication users (each with an applied Teams licence) in order to be able to subscribe from all endpoints.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Subscription Timeout ===&lt;br /&gt;
&lt;br /&gt;
==== Situation ====&lt;br /&gt;
Due to a current limitation in the Graph API it is not possible to cancel or delete an active presence subscription.&amp;lt;br&amp;gt;&lt;br /&gt;
As you can see in the [https://learn.microsoft.com/en-us/graph/api/subscription-delete?view=graph-rest-1.0&amp;amp;tabs=http|documentation of the current Graph API (1.0)] the “Delete subscription” chapter does not include presence subscriptions.&amp;lt;br&amp;gt;&lt;br /&gt;
It is also not possible to have multiple subscription in parallel. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To make sure to only request a new presence subscription when the old one is not valid anymore, the app will store the state of the presence subscription and the time until it is valid in the database.&amp;lt;br&amp;gt;&lt;br /&gt;
As mentioned in the chapter “Technical Overview” we are creating presence subscriptions with a validity of 10 minutes.&amp;lt;br&amp;gt;&lt;br /&gt;
The presence subscription will be renewed as soon as it is no longer valid which will be 10 minutes after initial subscription.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Impact ====&lt;br /&gt;
If settings are changed or the app instance is restarted it will check the corresponding database entry on startup.&amp;lt;br&amp;gt;&lt;br /&gt;
In case the last presence subscription was completed less than 10 minutes ago, there is still an active presence subscription and the app has to wait for it to become invalid. &amp;lt;br&amp;gt;&lt;br /&gt;
Some Changes (e.g., to the “Notification-URL”) will only take effect after a new created subscription. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The current Beta Version of the Graph API is already providing a function to delete presence subscriptions, so we hope we can improve this behavior in the future.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Troubleshooting=&lt;br /&gt;
== General ==&lt;br /&gt;
&lt;br /&gt;
===Creating an app trace===&lt;br /&gt;
For further analysis and creating a support ticket it will be useful to have a suitable app trace. &amp;lt;br&amp;gt;&lt;br /&gt;
Before creating the trace please make sure the following trace flags are activated for the app instance:&lt;br /&gt;
* App&lt;br /&gt;
* Database&lt;br /&gt;
* HTTP client&lt;br /&gt;
* TLS&lt;br /&gt;
* TCP&lt;br /&gt;
* App WebSocket&lt;br /&gt;
* Config&lt;br /&gt;
* Webserver&lt;br /&gt;
&lt;br /&gt;
After setting the config flags, please make sure to&lt;br /&gt;
* stop the instance&lt;br /&gt;
* deleting the current instance log&lt;br /&gt;
* start the instance&lt;br /&gt;
&#039;&#039;&#039;Now please wait at least 5 Minutes before you save the log&#039;&#039;&#039;, otherwise we could not have the whole picture in the trace.&lt;br /&gt;
&lt;br /&gt;
The restart and deletion of the the old log is useful the see the complete initialization process right away.&lt;br /&gt;
&lt;br /&gt;
===SSL Certificate for notification URL===&lt;br /&gt;
It also is useful to make sure the notification URL has a valid and public signed certificate.&amp;lt;br&amp;gt;&lt;br /&gt;
You can do that, using an SSL-Checker, for example: https://www.sslshopper.com/ssl-checker.html &amp;lt;br&amp;gt;&lt;br /&gt;
Without a valid, public signed certificate, Microsoft will decline the connection since it will not be possible to establish a trust relationship for the SSL/TLS secure channel.&lt;br /&gt;
&lt;br /&gt;
===Correctness of notification URL===&lt;br /&gt;
You can try to open the notification URL in your Browser&amp;lt;br&amp;gt;&lt;br /&gt;
Most likely you will see a HTTP 404 (Not Found) error message, which is the expected behavior since we are not providing an HTML website, the HTTP GET request from the browser will not be answered with content.&amp;lt;br&amp;gt;&lt;br /&gt;
This is perfectly fine since Microsoft will send presence updates with HTTP POST and will not try to request content from our app.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
What you can find out by trying to open the URL in your browser are the two following things: &amp;lt;br&amp;gt;&lt;br /&gt;
* If you receive a HTTP 404 error message you are most likely connected to an App Platform, if not you need to check your DNS (and maybe also reverse proxy) settings.&lt;br /&gt;
* If the URL is modified and the used build number is added, an app has answered your request&lt;br /&gt;
** Example: &amp;lt;code&amp;gt;https://public.dns/your.domain/microsoft365/subscriptions&amp;lt;/code&amp;gt; is modified to &amp;lt;code&amp;gt;https://public.dns/your.domain/microsoft365/&amp;lt;b&amp;gt;1510411&amp;lt;/b&amp;gt;/subscriptions&amp;lt;/code&amp;gt;&lt;br /&gt;
** If this is not the case, your URL is wrong. (Be aware: The URL depends on the settings of the web server path of your app instance)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Be aware:&#039;&#039;&#039; The URL-Recognition in the Application Platform is &#039;&#039;&#039;case sensitive&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Activation of &amp;quot;Public client flow&amp;quot; for the registered app in Azure Portal===&lt;br /&gt;
If the subscription is not working at all, please make sure &amp;quot;Public client flow&amp;quot; is activated for the registered app in the Azure portal (as described in our [[Howto16r1:Configure User Presence Sync by Connector for Microsoft365#Create_an_App_for_syncing_Teams_to_PBX|HowTo article]]).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
The App Service trace will contain the following message if this is not the case:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;AADSTS7000218: The request body must contain the following parameter: &#039;client_assertion&#039; or &#039;client_secret&#039;.&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== User Presence == &lt;br /&gt;
===GUI Feedback===&lt;br /&gt;
The app itself shows required states with green and red as connections to the Master PBX, Authentication and Presence Subscription to identify if there are problems. &amp;lt;br&amp;gt;&lt;br /&gt;
Sometimes it needs a little bit time until the states are changed. &amp;lt;br&amp;gt;&lt;br /&gt;
If the states remain, it is mandatory to enable logs on the app platform and check for more information. &amp;lt;br&amp;gt;&lt;br /&gt;
([[Howto13r3:Configure Connector for Microsoft365#Creating an app trace|Concept App Service Connector for Microsoft 365: Creating an app trace]])&lt;br /&gt;
&lt;br /&gt;
====No connection to Master PBX====&lt;br /&gt;
Check the MasterPBX name.&amp;lt;br&amp;gt;&lt;br /&gt;
The field must only contain the name [&amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;pbx&amp;lt;/span&amp;gt;], &#039;&#039;&#039;not the full domain&#039;&#039;&#039; [&amp;lt;span style=&amp;quot;color:red;text-decoration: line-through;&amp;quot;&amp;gt;pbx.domain.tld&amp;lt;/span&amp;gt;]. ([[Howto13r3:Configure Connector for Microsoft365#Synchronization from Teams to the PBX|Synchronization from Teams to the PBX - Master PBX field]])&lt;br /&gt;
&lt;br /&gt;
====Presence subscription failed====&lt;br /&gt;
There are many reasons why the &amp;quot;Presence subscription failed&amp;quot; message could be displayed.&amp;lt;br&amp;gt;&lt;br /&gt;
We try to list the most common reasons:&lt;br /&gt;
* The permission for the registered app in the Azure portal are not correctly set ([[Howto13r3:Configure Connector for Microsoft365#Create an App for syncing Teams to PBX|Howto: Create an App for syncing Teams to PBX]])&lt;br /&gt;
* The Notification URL is wrong ([[Reference13r3:Concept App Service Connector for Microsoft 365#Correctness of notification URL|Concept App Service Connector for Microsoft 365: Correctness of notification URL]] )&lt;br /&gt;
* The App service is not reachable from the internet ([[Reference13r3:Concept App Service Connector for Microsoft 365#Correctness of notification URL|Concept App Service Connector for Microsoft 365: Correctness of notification URL]] )&lt;br /&gt;
* The certificate for the public endpoint (e.g. reverse proxy) is not valid, or not publicly signed ([[Reference13r3:Concept App Service Connector for Microsoft 365#SSL Certificate for notification URL|Concept App Service Connector for Microsoft 365: SSL Certificate for notification URL]])&lt;br /&gt;
* The user from PBX and the Azure Portal cannot be matched ([[Reference13r3:Concept App Service Connector for Microsoft 365#User Matching|Concept App Service Connector for Microsoft 365: User Matching]])&lt;br /&gt;
* The App Platforms clock time is wrong ([[Reference13r3:Concept App Service Connector for Microsoft 365#App Platform clock time is wrong|Concept App Service Connector for Microsoft 365: App Platform clock time is wrong]])&lt;br /&gt;
* No user has a valid Connector for Microsoft 365 App license ([[Reference13r3:Concept App Service Connector for Microsoft 365#Requirements|Concept App Service Connector for Microsoft 365: Requirements]])&lt;br /&gt;
&lt;br /&gt;
===Teams License for communication user===&lt;br /&gt;
If presence subscription does not work, please check if all of the configured communication users have a Microsoft Teams license applied and no multifactor authentication is in use for this particular user. &amp;lt;br&amp;gt;&lt;br /&gt;
Also please make sure you can login with the configured credentials. (If you have set a password as an Administration, the user needs to change the password during the first login, therefore the given password will be invalid for API access).&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Sometimes, after changing setting or after the instance has restarted it can take up to 12 minutes until the presence subscription is working correctly. (Due to the subscription timeout)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
= Known Issues =&lt;br /&gt;
== Special Characters In Password ==&lt;br /&gt;
If you are using special characters (*, &amp;amp;, (, ), etc.) in your password you could run into a problem with the authentication of the communication user.&amp;lt;br&amp;gt;&lt;br /&gt;
The authentication failed status is being displayed. &amp;lt;br&amp;gt;&lt;br /&gt;
For the moment the only workaround is to eliminate special characters from your password.&lt;br /&gt;
&lt;br /&gt;
==App Platform clock time is wrong==&lt;br /&gt;
If the clock time at the App Platform is not correct, this will lead to an unstable behaviour of the Connector for Microsoft 365.&amp;lt;br&amp;gt;&lt;br /&gt;
Since the Connector for Microsoft 365 is using the Microsoft Graph APIs presence subscription function, it needs to provide in its request a precise time until the subscription validity will be expired.&amp;lt;br&amp;gt;&lt;br /&gt;
The app service is handling subscription and will automatically recreate a new subscription each time the previous one has expired.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A wrong clock time will lead to false expiration times and thus&lt;br /&gt;
*  the subscription will be expired earlier than expected (synchronisation is not working because there is no valid subscription)&lt;br /&gt;
*  the subscription will be valid longer than expected (the app service is trying to create a new subscription because it is expecting the previous one to be expired - will lead to a 409 conflict error, because only one subscription can be valid at a time)&lt;br /&gt;
&lt;br /&gt;
If you are not sure about the current time of the App Platform, you can login via SSH into the App Platform and execute the &amp;lt;code&amp;gt;date&amp;lt;/code&amp;gt; command to check the current time.&amp;lt;br&amp;gt;&lt;br /&gt;
You will receive an output like: &lt;br /&gt;
 Tue Mar 12 13:38:57 UTC 2024&lt;br /&gt;
Please be aware: The time is displayed in UTC, so please make sure to convert to your local time zone.&lt;br /&gt;
&lt;br /&gt;
==Geoblocking==&lt;br /&gt;
Since there might be no reliable country assignment for Microsoft addresses, all Microsoft addresses must be enabled on the upstream firewall in the event of geoblocking in order to ensure functionality of the Office365 Connector.&amp;lt;br&amp;gt;&lt;br /&gt;
As an alternative you might be able to configure your firewall to bypass the geoblocking for the configured notification URL.&lt;br /&gt;
&lt;br /&gt;
= Related Articles =&lt;br /&gt;
[[Howto16r1:Configure User Presence Sync by Connector for Microsoft365]] &amp;lt;br/&amp;gt;&lt;br /&gt;
[[Howto16r1:Configure Calendar Presence Sync by Connector for Microsoft365]] &amp;lt;br/&amp;gt;&lt;br /&gt;
[[Howto16r1:Configure Contact Search by Connector for Microsoft365]] &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Howto|{{PAGENAME}}]]&lt;/div&gt;</summary>
		<author><name>Tfu</name></author>
	</entry>
	<entry>
		<id>https://wiki.innovaphone.com/index.php?title=Reference16r1:Concept_myApps_platform_services&amp;diff=79526</id>
		<title>Reference16r1:Concept myApps platform services</title>
		<link rel="alternate" type="text/html" href="https://wiki.innovaphone.com/index.php?title=Reference16r1:Concept_myApps_platform_services&amp;diff=79526"/>
		<updated>2026-04-21T09:12:06Z</updated>

		<summary type="html">&lt;p&gt;Tfu: /* Device handling */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Concept|myApps]]&lt;br /&gt;
&lt;br /&gt;
myApps platform services provide various operating system specific services which can be used by other &#039;&#039;Apps&#039;&#039; running in the [[{{NAMESPACE}}:Concept myApps|myApps client]]. Those services typically are not available in the browser&#039;s JavaScript environment and hence must be implemented in native platform code. Therefore, the platform services are installed as native executable on the respective platform.&lt;br /&gt;
&lt;br /&gt;
When myApps is started in a web browser (and hence has no access to the platform services), some Apps will use [https://en.wikipedia.org/wiki/WebRTC WebRTC] services implemented by the browser instead.  For ease of reference, features available in this scenario are also described here.&lt;br /&gt;
&lt;br /&gt;
On windows, the platform services also come with their own web browser in which the myApps web App will be started then.  This browser is based on google&#039;s [https://en.wikipedia.org/wiki/Chromium_(web_browser) Chromium] open source software.&lt;br /&gt;
= Applies To =&lt;br /&gt;
&lt;br /&gt;
* [[{{NAMESPACE}}:Concept myApps|myApps]]&lt;br /&gt;
* myApps for Windows&lt;br /&gt;
* myApps for macOS&lt;br /&gt;
* myApps for iOS&lt;br /&gt;
* myApps for Android&lt;br /&gt;
* myApps Web App (WebRTC)&lt;br /&gt;
* myApps for IP270&lt;br /&gt;
version 16r1&lt;br /&gt;
&lt;br /&gt;
=Features=&lt;br /&gt;
Not all features are available or required on all platforms.&lt;br /&gt;
{|&lt;br /&gt;
! style=&amp;quot;text-align: left; font-weight: bold&amp;quot; | Feature&lt;br /&gt;
! style=&amp;quot;text-align: left; font-weight: bold&amp;quot; | Description&lt;br /&gt;
! style=&amp;quot;text-align: left; font-weight: bold&amp;quot;| Availability&lt;br /&gt;
|-&lt;br /&gt;
| || || Windows || iOS || Android || macOS || Browser&amp;lt;ref&amp;gt;This refers to the myApps web application running in a browser with no platform services available&amp;lt;/ref&amp;gt;&lt;br /&gt;
|IP270&lt;br /&gt;
|-&lt;br /&gt;
| [[#Device handling|Audio Devices]]|| manage local audio devices to record and playback audio conversations || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; (audio available but devices managed by web browser) || &amp;amp;#10004;&lt;br /&gt;
|-&lt;br /&gt;
| Video || manage local displays and cameras to capture and render video live stream || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; (video available but devices managed by web browser) || &amp;amp;#10004;&lt;br /&gt;
|-&lt;br /&gt;
| Ringer || manage local ringing device || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004;&lt;br /&gt;
|-&lt;br /&gt;
| [[#Application sharing|Application sharing]]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;amp;nbsp; presenter || share an application || &amp;amp;#10004; || &amp;amp;#10007; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;amp;nbsp; consumer  || view an application shared by the peer || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004;&lt;br /&gt;
|-&lt;br /&gt;
| [[#Hot keys|Hot keys]]|| capture key presses for quick invocation of phone apps (e.g. dial selected number) || &amp;amp;#10004; || &amp;amp;#10007; || &amp;amp;#10007; || &amp;amp;#10004; || &amp;amp;#10007; || &amp;amp;#10007;&lt;br /&gt;
|-&lt;br /&gt;
| [[#URL Handler|tel: and sip: URI handler]]|| intercept clicks on tel: and sip: links in web sites to invoke phone apps || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10007; || &amp;amp;#10007;&lt;br /&gt;
|-&lt;br /&gt;
| [[#User activity|User activity]]|| set presence state according to user activity ||  &amp;amp;#10004; || &amp;amp;#10007; || &amp;amp;#10007; || &amp;amp;#10004; || &amp;amp;#10004;&amp;lt;ref&amp;gt;limited, see [[#User activity|User activity]] below&amp;lt;/ref&amp;gt; || &amp;amp;#10004;&lt;br /&gt;
|-&lt;br /&gt;
| Docking || myApps can be docked persistently to the right or left edge of your screens ||  &amp;amp;#10004;  || &amp;amp;#10007; || &amp;amp;#10007; || &amp;amp;#10007; || &amp;amp;#10007; || &amp;amp;#10007;&lt;br /&gt;
|-&lt;br /&gt;
| Multi-windowing || Apps can be launched in separate windows||  &amp;amp;#10004;  || &amp;amp;#10007; || &amp;amp;#10007; || &amp;amp;#10004; || &amp;amp;#10007; || &amp;amp;#10007;&lt;br /&gt;
|-&lt;br /&gt;
| [[#Recording|Recording]]|| Calls can be recorded to recording app||  &amp;amp;#10004;  || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10007; || &amp;amp;#10004;&lt;br /&gt;
|-&lt;br /&gt;
| [[#Notifications|Notifications]]|| ||&lt;br /&gt;
|-&lt;br /&gt;
| &amp;amp;nbsp; display notifications || display notifications with OS standard mechanism ||  &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10007;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;amp;nbsp; push notifications || receive push notifications while myApps is not running  ||  &amp;amp;#10007; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004;&amp;lt;ref&amp;gt;The browser needs to be running in order to receive push notifications.&amp;lt;/ref&amp;gt; || &amp;amp;#10007;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;amp;nbsp; chat and apps || display notifications for chat and other apps  ||  &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10007;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;amp;nbsp; calls || display notifications for incoming calls  ||  &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10007;&amp;lt;ref&amp;gt;Call notifications are only displayed locally while the phone or softphone app is started.&amp;lt;/ref&amp;gt; || &amp;amp;#10007;&lt;br /&gt;
|-&lt;br /&gt;
| [[#Local phonebook access|Local phonebook]]|| access local phone book ||  &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10007; || &amp;amp;#10007;&lt;br /&gt;
|-&lt;br /&gt;
| [[#Microsoft Office Integration|Office presence provider]]|| maps PBX presence state to Microsoft office presence state ||  &amp;amp;#10004;  || &amp;amp;#10007; || &amp;amp;#10007; || &amp;amp;#10007; || &amp;amp;#10007; || &amp;amp;#10007;&lt;br /&gt;
|-&lt;br /&gt;
| [[#Call an external application for calls|External application start]]|| start arbitrary external applications for calls || &amp;amp;#10004; || &amp;amp;#10007; || &amp;amp;#10007; || &amp;amp;#10004; || &amp;amp;#10007; || &amp;amp;#10007;&lt;br /&gt;
|-&lt;br /&gt;
| [[#App Proxy|App Proxy]]|| a caching proxy that provides app persistence  || &amp;amp;#10004;  || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10007; || &amp;amp;#10007;&lt;br /&gt;
|-&lt;br /&gt;
| [[#Auto update|Auto update]]|| automatically updates myApps platform services to the same version the PBX has || &amp;amp;#10004;  || &amp;amp;#10004; || &amp;amp;#10007; || &amp;amp;#10004; || &amp;amp;#10004;&amp;lt;ref&amp;gt;The then-current web app is always loaded from the PBX upon startup and hence up-to-date by definition&amp;lt;/ref&amp;gt; || &amp;amp;#10004;&lt;br /&gt;
|-&lt;br /&gt;
| Three party conference || initiate 3-pty-conference using Softphone-App || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10007; || &amp;amp;#10004;&lt;br /&gt;
|-&lt;br /&gt;
| Exclude VPN || disable use of VPN connections for audio and appsharing || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10007; || &amp;amp;#10007;&lt;br /&gt;
|-&lt;br /&gt;
| Screen lock || myApps screen lock against unauthorised use || &amp;amp;#10007; || &amp;amp;#10007; || &amp;amp;#10007; || &amp;amp;#10007; || &amp;amp;#10007; || &amp;amp;#10004;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Requirements=&lt;br /&gt;
* innovaphone PBX 16r1 and up&lt;br /&gt;
&lt;br /&gt;
== Hardware ==&lt;br /&gt;
Recommended hardware requirements&lt;br /&gt;
* Processor: Dual-core 2Ghz or higher&lt;br /&gt;
* RAM: 4 Gb&lt;br /&gt;
&lt;br /&gt;
== myApps for Windows ==&lt;br /&gt;
* Windows 11 and up&lt;br /&gt;
* Windows Server 2016 and later versions&lt;br /&gt;
&lt;br /&gt;
=== 32 &amp;amp; 64 bit Windows ===&lt;br /&gt;
* 32 bit Windows: install the myAppsSetup32.msi from the App Store&lt;br /&gt;
* 64 bit Windows: install the myAppsSetup.msi from the App Store&lt;br /&gt;
** the 64 bit variant still installs into Program Files (x86), as the main myApps.exe is still a 32bit application&lt;br /&gt;
** the 64 bit variant just contains an additional 64 bit binary for the outlook search&lt;br /&gt;
&lt;br /&gt;
=== Windows N editions ===&lt;br /&gt;
&lt;br /&gt;
Windows N editions are missing the &#039;&#039;Media Feature Pack&#039;&#039; which is pre installed on other Windows versions.&lt;br /&gt;
&lt;br /&gt;
Please install the pack from [https://www.microsoft.com/en-us/software-download/mediafeaturepack Microsoft (Windows 10 pack)] before you install myApps. The installer will check if the file &amp;lt;code&amp;gt;C:\Windows\SysWOW64\mfplat.dll&amp;lt;/code&amp;gt; exist on your system.&lt;br /&gt;
&lt;br /&gt;
Make sure to install the correct pack depending on your Windows version! There are different packs for Windows 10 1703, 1803, 1809 and 32bit or 64bit etc.&lt;br /&gt;
&lt;br /&gt;
NB: Sometimes the myApps installation will not work even though the media pack is already installed. This is because the installer has no read access to check if the package is already installed. If the above-mentioned file exists and the installer asks to install the Windows Media Feature Pack nevertheless, you have to start the myApps install with administrative rights.&lt;br /&gt;
&lt;br /&gt;
=== Terminal Server environments ===&lt;br /&gt;
&lt;br /&gt;
Audio driver was removed if myApps discovers that it is running in a terminal server environment like Citrix.&lt;br /&gt;
&lt;br /&gt;
The audio driver is needed for the Softphone App but the Softphone App should not use an audio driver at the server side because the audio devices are plugged locally and there would be a delay sending and receiving audio data with the server.&lt;br /&gt;
&lt;br /&gt;
If a customer wants to use the Softphone App at the server side he needs to make use of the myApps Plugin for virtual desktops solution:&lt;br /&gt;
&lt;br /&gt;
[[{{NAMESPACE}}:MyApps_Plugin_for_Virtual_Desktops|Reference15r1:MyApps_Plugin_for_Virtual_Desktops]]&lt;br /&gt;
&lt;br /&gt;
== myApps for macOS ==&lt;br /&gt;
* macOS 13 or higher&lt;br /&gt;
&lt;br /&gt;
== myApps for iOS ==&lt;br /&gt;
* iOS 16 or higher&lt;br /&gt;
&lt;br /&gt;
== myApps for Android ==&lt;br /&gt;
* Android 13 or higher.&lt;br /&gt;
&lt;br /&gt;
== myApps for IP270 ==&lt;br /&gt;
Exclusively used in IP270.&lt;br /&gt;
&lt;br /&gt;
= Licenses =&lt;br /&gt;
* No license needed for myApps platform services&lt;br /&gt;
&lt;br /&gt;
= Overview =&lt;br /&gt;
myApps platform services is a native executable that is installed using the standard mechanisms on the respective operating system. It provides various advanced services which can be used by the myApps web client code as well as the Apps running in the myApps context. &lt;br /&gt;
&lt;br /&gt;
Also, on Windows, the platform services come with their own, dedicated browser to run myApps in.  This browser is based on [https://en.wikipedia.org/wiki/Chromium_(web_browser) Chromium].  On iOS, macOS and Android, it is based upon native embedded web view facilities (such as WKWebView) instead.&lt;br /&gt;
== Components ==&lt;br /&gt;
&lt;br /&gt;
=== RTP service for audio and appsharing ===&lt;br /&gt;
The RTP service provides audio and appsharing as a video stream. VoIP RTP endpoints (e.g. for softphones).  It supports STUN, TURN, ICE, SRTP, DTLS. Note however that unlike WebRTC, these endpoints do not &#039;&#039;require&#039;&#039; ICE and DTLS. In other words, they can communicate also with non-compliant (i.e. older) VoIP devices.&lt;br /&gt;
&lt;br /&gt;
Note that the available capabilities when not running the myApps platform services depend on the used browser&#039;s WebRTC implementation. See your browser documentation for details.&lt;br /&gt;
&lt;br /&gt;
Apps can request RTP channels using the [https://sdk.innovaphone.com/doc/launcher/Media.htm Media Protocol]&#039;s &#039;&#039;AllocChannel&#039;&#039; message.&lt;br /&gt;
&lt;br /&gt;
==== RTP ports ====&lt;br /&gt;
{|&lt;br /&gt;
|  audio || 50000 -&amp;gt; 50099&lt;br /&gt;
|-&lt;br /&gt;
| video (app sharing) || 50100 -&amp;gt; 50199&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The RTP service will enumerate all local interfaces and create local HOST candidates for ICE.  There is an option however to disregard VPN interfaces (more precisely such interfaces with type of &#039;&#039;IF_TYPE_PPP&#039;&#039; or &#039;&#039;IF_TYPE_TUNNEL&#039;&#039;).  This can eliminate quality issues when RTP data is transmitted through TCP based VPN tunnels.&lt;br /&gt;
&lt;br /&gt;
SRFLX and RELAY candidates are obtained using the STUN and TURN server configuration passed by the App (e.g the &#039;&#039;softphone&#039;&#039; App) as part of the &#039;&#039;AllocChannel&#039;&#039; request.&lt;br /&gt;
&amp;lt;code&amp;gt;{&amp;quot;mt&amp;quot;:&amp;quot;AllocChannel&amp;quot;,&amp;quot;channel&amp;quot;:&amp;quot;81429cba-396d-43de-8a76-ec020ba8796e&amp;quot;,&amp;quot;iceServers&amp;quot;:[{&amp;quot;urls&amp;quot;:&amp;quot;turn:myturn.domaincom:4077?transport=udp&amp;quot;,&amp;quot;username&amp;quot;:&amp;quot;turnuser&amp;quot;,&amp;quot;credential&amp;quot;:&amp;quot;pwd&amp;quot;,&amp;quot;credentialType&amp;quot;:&amp;quot;password&amp;quot;},{&amp;quot;urls&amp;quot;:&amp;quot;stun:mystun.domain.com:4077&amp;quot;}],&amp;quot;dn&amp;quot;:&amp;quot;Foo Bar&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;RemoteRtp&amp;quot;,&amp;quot;kind&amp;quot;:&amp;quot;video&amp;quot;}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Codecs ====&lt;br /&gt;
The installed myApps launchers provide codecs that can be used by softphone apps for media streams. When running in a web browser the codecs depend on the browser version and operating system. See the documentation of your browser for details.&lt;br /&gt;
&lt;br /&gt;
The following codecs are supported:&lt;br /&gt;
{|&lt;br /&gt;
!style=&amp;quot;text-align:left;width:100px;&amp;quot;|Codec&lt;br /&gt;
!style=&amp;quot;width:100px&amp;quot;|Windows-Launcher&lt;br /&gt;
!style=&amp;quot;width:100px&amp;quot;|Android&lt;br /&gt;
!style=&amp;quot;width:100px&amp;quot;|iOS&lt;br /&gt;
!style=&amp;quot;width:100px&amp;quot;|macOS&lt;br /&gt;
!style=&amp;quot;width:100px&amp;quot;|Firefox (Browser)&lt;br /&gt;
!style=&amp;quot;width:100px&amp;quot;|Chrome (Browser)&lt;br /&gt;
!style=&amp;quot;width:100px&amp;quot;|Edge (Browser)&lt;br /&gt;
!style=&amp;quot;width:100px&amp;quot;|Safari (Browser)&lt;br /&gt;
!style=&amp;quot;width:100px&amp;quot;|Opera (Browser)&lt;br /&gt;
!style=&amp;quot;width:100px&amp;quot;|IP270&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:left; background-color:lightgray&amp;quot; colspan=&amp;quot;11&amp;quot;|Audio&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|G711A&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|-&lt;br /&gt;
|G711u&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|-&lt;br /&gt;
|G722&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|-&lt;br /&gt;
|[https://caniuse.com/#search=Opus OPUS-NB]&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|-&lt;br /&gt;
|[https://caniuse.com/#search=Opus OPUS-WB]&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;11&amp;quot; style=&amp;quot;text-align:left; background-color:lightgray&amp;quot; |Video&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[https://caniuse.com/#search=VP8 VP8]&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
|[https://caniuse.com/#search=VP9 VP9]&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔**&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔**&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔**&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔**&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔**&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔**&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔**&lt;br /&gt;
|-&lt;br /&gt;
|[https://caniuse.com/#search=H264 H264]&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔**&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:left; background-color:lightgray&amp;quot; colspan=&amp;quot;11&amp;quot;|Application Sharing&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|Share&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|-&lt;br /&gt;
|Watch&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔*&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔*&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔*&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;* small presentation only&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;** only for 1:1 calls, not for conferences&lt;br /&gt;
&lt;br /&gt;
==== Video capture ====&lt;br /&gt;
The default resolution for video capture is 1920x1080 if available.  Otherwise, 1280x720, 640x480, 352x288 or 320x240 will be used.  The frame rate is 30 fps if available, otherwise 15 fps. The resulting average bandwidth could reach 1 Mbps.&lt;br /&gt;
&lt;br /&gt;
==== Application sharing ====&lt;br /&gt;
Screen content will be transmitted as video stream by the presenter&lt;br /&gt;
&lt;br /&gt;
==== Device handling ====&lt;br /&gt;
The RTP service enumerates microphones, loudspeaker, cameras and ringing devices and notifies apps when devices come and go. It is up to the apps using the devices to store preferences.&lt;br /&gt;
&lt;br /&gt;
The RTP service also enables some extended features (such as hook switch or volume control) for supported USB headsets or Bluetooth headsets connected to myApps.&lt;br /&gt;
The supported headset-SDKs determine which headset vendors are recommended to be used with the myApps softphone app. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For this to work, the following vendor specific development kits are integrated in our myApps client. Be aware that the SDK are updated within our Service release :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! SDK Vendor !! Supported OS !! SDK Version !! innovaphone Service Release&lt;br /&gt;
|-&lt;br /&gt;
| Jabra|| MacOS || 1.16.4.0 || 14r2sr11&lt;br /&gt;
|-&lt;br /&gt;
||| Windows || 1.16.4.0 || 15r1sr3&lt;br /&gt;
|-&lt;br /&gt;
| Epos &#039;&#039;(formerly Sennheiser)&#039;&#039; || MacOS || 12.4.0.5478 || 14r1sr3&lt;br /&gt;
|-&lt;br /&gt;
||| Windows || n.a. - [[Support:13r3 sr10 MyApps Windows Client - Epos/Sennheiser-Headsets require installed Epos-Connect Software|to be installed separately]]|| 13r3sr10&lt;br /&gt;
|-&lt;br /&gt;
| Poly &#039;&#039;(formerly Plantronics)&#039;&#039; || MacOS || 3.25.53799.37131 || 13r3sr9&lt;br /&gt;
|-&lt;br /&gt;
||| Windows || 3.25.53800.37131 || 13r3sr10&lt;br /&gt;
|-&lt;br /&gt;
| Yealink || MacOS || 3.1.1.23 || 14r2sr1&lt;br /&gt;
|-&lt;br /&gt;
||| Windows || 3.1.1.23 || 14r2sr2&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
* It is possible to inhibit the start of the Sennheiser SDK (SenncomSDK.exe) using the &amp;lt;code&amp;gt;DISABLEHEADSETS&amp;lt;/code&amp;gt; directive of the installer (see [[#MSI Parameters and install options|  MSI parameters]]  below).&lt;br /&gt;
&lt;br /&gt;
* Starting with V13r3sr10, the Epos-SDK needs to be installed separately using the Epos Connect software to ensure full compatibility between current Epos headset models and native myApps-Windows client. For details [[Support:13r3 sr10 MyApps Windows Client - Epos/Sennheiser-Headsets require installed Epos-Connect Software|refer to this article]].&lt;br /&gt;
&amp;lt;!--Keywords: myapps softphone supported headsets sdk--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
myApps-IP270 supports use of [[Reference9:Concept USB Headset|USB devices known for innovpahone desk phones]].&lt;br /&gt;
&lt;br /&gt;
==== Ring tones ====&lt;br /&gt;
Ring tones can be played. Apps can choose the tone from a pre-defined list of ring tones.&lt;br /&gt;
&lt;br /&gt;
On Windows, custom ring tones can be uploaded as .mp3 files to the &amp;lt;code&amp;gt;ringtones&amp;lt;/code&amp;gt; sub-directory of myApps&#039; roaming directory (which usually is in &amp;lt;code&amp;gt;%appdata%\innovaphone\myApps\ringtones&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
On Android, custom ring tones can be added to the system via Android settings.&lt;br /&gt;
&lt;br /&gt;
On iOS, custom ring tones can be uploaded as .mp3 files to the &amp;lt;code&amp;gt;Ringtones&amp;lt;/code&amp;gt; subdirectory of the myApps file share that is available in iTunes if the iPhone has been connected via USB.&lt;br /&gt;
&lt;br /&gt;
On macOS, custom ring tones can be uploaded as .mp3 files to &amp;lt;code&amp;gt;~/Library/Containers/com.innovaphone.client-macos/Data/Documents/Ringtones&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Debugging ====&lt;br /&gt;
For extended debugging, turn on the &#039;&#039;Audio&#039;&#039;, &#039;&#039;Media&#039;&#039; and &#039;&#039;AppSharing&#039;&#039; traces in myApps.&lt;br /&gt;
=== Hot keys ===&lt;br /&gt;
On Windows and macOS systems, myApps platform services can listen for hot keys and invoke certain functions. Invocation is done by sending API messages to myApps which passes it to an appropriate API provider (in the cases described here, this will be a &#039;&#039;phone&#039;&#039; or &#039;&#039;softphone&#039;&#039; or &#039;&#039;rcc&#039;&#039; App typically.  See [[{{NAMESPACE}}:Concept_myApps#Client_APIs_and_default_apps | Client APIs and default apps]] for more details about this mechanism.&lt;br /&gt;
&lt;br /&gt;
The hot keys can be specified using the &#039;&#039;advanced settings&#039;&#039; user interface (see [[#UI elements| UI elements]] below. Any of the function keys F1 to F11 (optionally combined with up to two modifier keys &#039;&#039;alt&#039;&#039;, &#039;&#039;ctrl&#039;&#039;, &#039;&#039;shift&#039;&#039; or &#039;&#039;win&#039;&#039;) can be chosen for each function. If you do not want to start the call with &amp;quot;Hotkey+Enter&amp;quot; because you would have to wait for the focus, the hotkey can also be pressed twice and the number is dialled directly.&lt;br /&gt;
&lt;br /&gt;
; dial selected number : Initiates a call using the currently selected text as target.&lt;br /&gt;
&lt;br /&gt;
: A &#039;&#039;PrepareCall&#039;&#039; message with the &#039;&#039;text&#039;&#039; argument set to the selected text and the &#039;&#039;adjust&#039;&#039; argument set to &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; will be sent to the [http://sdk.innovaphone.com/web1/com.innovaphone.phone/com.innovaphone.phone.htm &#039;&#039;com.innovaphone.phone&#039;&#039; API].&lt;br /&gt;
&lt;br /&gt;
:: &amp;lt;code&amp;gt;{&amp;quot;mt&amp;quot;:&amp;quot;ApiRequest&amp;quot;,&amp;quot;apiId&amp;quot;:&amp;quot;com.innovaphone.phone&amp;quot;,&amp;quot;consumer&amp;quot;:&amp;quot;@local-ae2fc2ab74-3f1e-4ab9-b215-d42f213520317&amp;quot;,&amp;quot;msg&amp;quot;:&amp;quot;mt&amp;quot;:&amp;quot;PrepareCall&amp;quot;,&amp;quot;text&amp;quot;:&amp;quot;13&amp;quot;,&amp;quot;adjust&amp;quot;:true}}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; accept call : Accepts a currently alerting call.&lt;br /&gt;
&lt;br /&gt;
: A &#039;&#039;ConnectCall&#039;&#039; message will be sent to the [http://sdk.innovaphone.com/web1/com.innovaphone.phone/com.innovaphone.phone.htm &#039;&#039;com.innovaphone.phone&#039;&#039; API].&lt;br /&gt;
&lt;br /&gt;
:: &amp;lt;code&amp;gt;{&amp;quot;mt&amp;quot;:&amp;quot;ApiRequest&amp;quot;,&amp;quot;apiId&amp;quot;:&amp;quot;com.innovaphone.phone&amp;quot;,&amp;quot;consumer&amp;quot;:&amp;quot;@local-ae2fc2ab74-3f1e-4ab9-b215-d42f213520317&amp;quot;,&amp;quot;msg&amp;quot;:{&amp;quot;mt&amp;quot;:&amp;quot;ConnectCall&amp;quot;}}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; reject/disconnect call : Rejects a currently alerting call or disconnects an active call.&lt;br /&gt;
&lt;br /&gt;
: A &#039;&#039;DisconnectCall&#039;&#039; message will be sent to the [http://sdk.innovaphone.com/web1/com.innovaphone.phone/com.innovaphone.phone.htm &#039;&#039;com.innovaphone.phone&#039;&#039; API].&lt;br /&gt;
&lt;br /&gt;
:: &amp;lt;code&amp;gt;{&amp;quot;mt&amp;quot;:&amp;quot;ApiRequest&amp;quot;,&amp;quot;apiId&amp;quot;:&amp;quot;com.innovaphone.phone&amp;quot;,&amp;quot;consumer&amp;quot;:&amp;quot;@local-ae2fc2ab74-3f1e-4ab9-b215-d42f213520317&amp;quot;,&amp;quot;msg&amp;quot;:{&amp;quot;mt&amp;quot;:&amp;quot;DisconnectCall&amp;quot;}}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== URL Handler ===&lt;br /&gt;
&lt;br /&gt;
On Windows systems, two URI-handler are installed with the myApps platform services.  Windows will call up this URI handler when a user clicks on an appropriate link, for example in a web site.&lt;br /&gt;
&lt;br /&gt;
The handler will the send an API message to myApps which passes it to an appropriate API provider (in the cases described here, this will be a &#039;&#039;phone&#039;&#039; or &#039;&#039;softphone&#039;&#039; or &#039;&#039;rcc&#039;&#039; App typically.  See [[{{NAMESPACE}}:Concept_myApps#Client_APIs_and_default_apps | Client APIs and default apps]] for more details about this mechanism.&lt;br /&gt;
&lt;br /&gt;
; tel URI : call a number, e.g. &amp;lt;code&amp;gt;tel:4711&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: A &#039;&#039;PrepareCall&#039;&#039; message with the &#039;&#039;num&#039;&#039; argument set to the selected text and the &#039;&#039;adjust&#039;&#039; argument set to &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; will be sent to the [http://sdk.innovaphone.com/web1/com.innovaphone.phone/com.innovaphone.phone.htm &#039;&#039;com.innovaphone.phone&#039;&#039; API].&lt;br /&gt;
:: &amp;lt;code&amp;gt;{&amp;quot;mt&amp;quot;:&amp;quot;ApiRequest&amp;quot;,&amp;quot;apiId&amp;quot;:&amp;quot;com.innovaphone.phone&amp;quot;,&amp;quot;consumer&amp;quot;:&amp;quot;@local-ae2fc2ab74-3f1e-4ab9-b215-d42f213520317&amp;quot;,&amp;quot;msg&amp;quot;:{&amp;quot;mt&amp;quot;:&amp;quot;StartCall&amp;quot;,&amp;quot;num&amp;quot;:&amp;quot;4711&amp;quot;,&amp;quot;adjust&amp;quot;:true}}&amp;lt;/code&amp;gt;&lt;br /&gt;
; sip URI : call a SIP name, e.g. &amp;lt;code&amp;gt;sip:zkl@innovaphone.com&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: A &#039;&#039;PrepareCall&#039;&#039; message with the &#039;&#039;sip&#039;&#039; argument set to the selected text and the &#039;&#039;adjust&#039;&#039; argument set to &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; will be sent to the [http://sdk.innovaphone.com/web1/com.innovaphone.phone/com.innovaphone.phone.htm &#039;&#039;com.innovaphone.phone&#039;&#039; API].&lt;br /&gt;
:: &amp;lt;code&amp;gt;{&amp;quot;mt&amp;quot;:&amp;quot;ApiRequest&amp;quot;,&amp;quot;apiId&amp;quot;:&amp;quot;com.innovaphone.phone&amp;quot;,&amp;quot;consumer&amp;quot;:&amp;quot;@local-ae2fc2ab74-3f1e-4ab9-b215-d42f213520317&amp;quot;,&amp;quot;msg&amp;quot;:{&amp;quot;mt&amp;quot;:&amp;quot;StartCall&amp;quot;,&amp;quot;sip&amp;quot;:&amp;quot;zkl@innovaphone.com&amp;quot;,&amp;quot;adjust&amp;quot;:true}}&amp;lt;/code&amp;gt;&lt;br /&gt;
; im URI : start chat with SIP name, e.g. &amp;lt;code&amp;gt;im:zkl@innovaphone.com&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: A &#039;&#039;StartChat&#039;&#039; message with the &#039;&#039;sip&#039;&#039; argument set to the selected text will be sent to the [http://sdk.innovaphone.com/web1/com.innovaphone.chat/com.innovaphone.chat.htm &#039;&#039;com.innovaphone.chat&#039;&#039; API].&lt;br /&gt;
:: &amp;lt;code&amp;gt;{&amp;quot;mt&amp;quot;:&amp;quot;ApiRequest&amp;quot;,&amp;quot;apiId&amp;quot;:&amp;quot;com.innovaphone.chat&amp;quot;,&amp;quot;consumer&amp;quot;:&amp;quot;@local-ae2fc2ab74-3f1e-4ab9-b215-d42f213520317&amp;quot;,&amp;quot;msg&amp;quot;:{&amp;quot;mt&amp;quot;:&amp;quot;StartChat&amp;quot;,&amp;quot;sip&amp;quot;:&amp;quot;zkl@innovaphone.com&amp;quot;}}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On macOS systems myApps might be made the default application to handle tel URI e.g. &amp;lt;code&amp;gt;tel:4711&amp;lt;/code&amp;gt; via Apple FaceTime. Open the &amp;quot;FaceTime&amp;quot; menu &amp;quot;Settings...&amp;quot; and select myApps as &amp;quot;Default for phone calls&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
On iOS &#039;&#039;tel&#039;&#039; URIs are always dialed via GSM. Therefore myApps iOS also reacts to URI schemes &#039;&#039;com.innovaphone.tel&#039;&#039;, &#039;&#039;com.innovaphone.sip&#039;&#039; and &#039;&#039;com.innovaphone.im&#039;&#039;, e.g. &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;com.innovaphone.tel:4711&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;com.innovaphone.sip:zkl@innovaphone.com&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;com.innovaphone.im:zkl@innovaphone.com&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== User activity ===&lt;br /&gt;
On Windows and macOS systems, the myApps platform services can monitor user keyboard/mouse activity and change the user&#039;s presence state after a certain amount of inactivity.  The timeout can be specified using the &#039;&#039;advanced settings&#039;&#039; user interface (see [[#UI elements| UI elements]] below.&lt;br /&gt;
&lt;br /&gt;
myApps will then send a [https://sdk.innovaphone.com/doc/appwebsocket/myApps.htm#SetUserActivity&#039;&#039;SetUserActivity&#039;&#039;] message to the PBX using the &#039;&#039;myApps&#039;&#039; protocol.&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;code&amp;gt;{&amp;quot;mt&amp;quot;:&amp;quot;SetUserActivity&amp;quot;,&amp;quot;inactive&amp;quot;:true}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will change the &#039;&#039;status&#039;&#039; property of the &#039;&#039;im:&#039;&#039; contact for the user&#039;s own presence and hence result in a presence update from the PBX to myApps&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;code&amp;gt;{&amp;quot;mt&amp;quot;:&amp;quot;UpdateOwnPresence&amp;quot;,&amp;quot;presence&amp;quot;:[{...},{&amp;quot;contact&amp;quot;:&amp;quot;im:&amp;quot;,&amp;quot;activity&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;status&amp;quot;:&amp;quot;closed&amp;quot;}]}&amp;lt;/code&amp;gt;&lt;br /&gt;
The &#039;&#039;closed&#039;&#039; status is reflected in the grey status color when displaying a contact [[Image:myapps-inactive.png|myapps-inactive.png/|myapps-inactive.png/]].&lt;br /&gt;
&lt;br /&gt;
On iOS and Android, the state is set to &#039;&#039;inactive&#039;&#039; as soon as the App is brought to background.&lt;br /&gt;
When myApps platform services are not available (i.e. when running the web application in a browser solely) a limited user activity monitoring is available: the state is set to active when the web page is not used for more than 5 minutes.&lt;br /&gt;
&lt;br /&gt;
=== Recording ===&lt;br /&gt;
&lt;br /&gt;
The new launcher offers the possibility to record the audio of incoming and outgoing calls. In order to activate that functionality the URL of the recording instance must be configured in either the PBX (PBX-&amp;gt;myApps-&amp;gt;Config: Recording URL) or the softphone App (Settings-&amp;gt;Audio Recording (URL)) &lt;br /&gt;
&lt;br /&gt;
[[Image:PBX-Recording-Settings.png|pbx-recording-settings.png/|pbx-recording-settings.png/]] [[Image:Recording-Softphone-Settings.png|recording-softphone-settings.png/|recording-softphone-settings.png/]]. &lt;br /&gt;
&lt;br /&gt;
As long as that URL is configured the audio data of all calls are stored as pcap-files under that URL.&lt;br /&gt;
If the URL points to a CF device in the PBX, write access must be granted for that URL (PBX-&amp;gt;Services-&amp;gt;HTTP-&amp;gt;Server:Public compact flash access) and if the URL points to the recording app, the files can be accessed via the recording app [[{{NAMESPACE}}:Concept_App_Service_Recordings|recording]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Under PBX-&amp;gt;myApps the administrator can set a certain default behaviour of the audio recording like whether or not the recording should start automatically at the beginning of the call (Recording by Default ON/OFF), only calls with external numbers should be recorded (Record external calls only) or whether or not the user should be able to start/stop the recording himself (Allow user incall recording control). Except for the last parameter these parameters can also be modified by the user in its softphone settings if the administrator doesn&#039;t set the FORCE flag.&lt;br /&gt;
&lt;br /&gt;
If the user was allowed by the admin to control the recording a recording switch is active during the call when the &amp;quot;Media&amp;quot; Panel is opened. There the audio recording may be stopped and continued at will. A red recording notice is shown in the top right corner when the recording actually takes place.&lt;br /&gt;
 &lt;br /&gt;
[[Image:Recording-incall-switch.png|recording-incall-switch.png/|recording-incall-switch.png/]]&lt;br /&gt;
&lt;br /&gt;
=== Notifications ===&lt;br /&gt;
&lt;br /&gt;
The myApps platform services can use the OS specific notification mechanism (e.g. &#039;&#039;desktop notifications&#039;&#039; on Windows) to display messages (e.g. &#039;&#039;incoming new chat message&#039;&#039;) to the user.&lt;br /&gt;
&lt;br /&gt;
Note that the actual rendering of the notification is under control of the OS.  Therefore, myApps must be allowed to show notifications and its appearance can be restricted by OS native settings.&lt;br /&gt;
&lt;br /&gt;
==== Microsoft Windows Notifications ====&lt;br /&gt;
&lt;br /&gt;
Microsoft Windows Server editions (2016, 2019, 2022) are just capable of showing a single &#039;&#039;IncomingCall&#039;&#039; notification at the same time (we couldn&#039;t find a workaround for this limitation).&amp;lt;br/&amp;gt;&lt;br /&gt;
An &#039;&#039;IncomingCall&#039;&#039; notification is visible the whole time instead of being moved to the action center after a certain time.&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
A notification about a missed call uses the &#039;&#039;IncomingCall&#039;&#039; type so that this notification is visible until the user returns.&amp;lt;br/&amp;gt;&lt;br /&gt;
Due to the above limitation, on a new arriving call such a missed call notification is transformed to a default notification which will be moved to the action center automatically.&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
On non server editions, you can have multiple IncomingCall notifications at the same time (so two parallel incoming calls will be indeed notified at the same time), but the missed call notification handling is the same on both platforms!&lt;br /&gt;
&lt;br /&gt;
 Thus there will be always just &#039;&#039;&#039;one&#039;&#039;&#039; missed call notification visible and previous missed calls can be found inside your action center!&lt;br /&gt;
&lt;br /&gt;
To see myApps notifications, ensure:&lt;br /&gt;
* System -&amp;gt; Notifications &lt;br /&gt;
** enable notifications&lt;br /&gt;
** disable &amp;quot;Do not disturb&amp;quot; or allow myApps as priority application while &amp;quot;Do not disturb&amp;quot; is active&lt;br /&gt;
** enable notifications for myApps in the list of applications&lt;br /&gt;
* System -&amp;gt; Focus &lt;br /&gt;
** if a focus session is active and the &amp;quot;Do not disturb&amp;quot; is activated during a focus session, make sure that myApps is a priority application (see above)&lt;br /&gt;
&lt;br /&gt;
==== macOS Notifications ====&lt;br /&gt;
Notifications are the same as on Windows.&lt;br /&gt;
The difference is, that for macOS, notifications need to be allowed in the system settings.&lt;br /&gt;
Go to Notifications - myApps, select Banner and enable all check marks.&lt;br /&gt;
&lt;br /&gt;
=== Local phonebook access ===&lt;br /&gt;
&#039;&#039;&#039;Contact Search:&#039;&#039;&#039; The myApps platform services implement an &#039;&#039;API provider&#039;&#039; for the [http://sdk.innovaphone.com/web1/com.innovaphone.search/lib1_api_search.htm &#039;&#039;com.innovaphone.search&#039;&#039; API]]. They perform search capabilities on the OS&#039; local phone books which can be used by Apps like the &#039;&#039;phoneapp&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Apps would send a &#039;&#039;Search&#039;&#039; request to the API:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;code&amp;gt;{&amp;quot;mt&amp;quot;:&amp;quot;ApiRequest&amp;quot;,&amp;quot;consumer&amp;quot;:&amp;quot;dev:SwPh_zkl_5e42e884&amp;quot;,&amp;quot;provider&amp;quot;:&amp;quot;*&amp;quot;,&amp;quot;src&amp;quot;:&amp;quot;4&amp;quot;,&amp;quot;msg&amp;quot;:{&amp;quot;mt&amp;quot;:&amp;quot;Search&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;contact&amp;quot;,&amp;quot;search&amp;quot;:&amp;quot;john doe&amp;quot;},&amp;quot;apiId&amp;quot;:&amp;quot;com.innovaphone.search&amp;quot;}&amp;lt;/code&amp;gt;&lt;br /&gt;
Search results are delivered as &#039;&#039;SearchInfo&#039;&#039; messages:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;code&amp;gt;{&amp;quot;mt&amp;quot;:&amp;quot;ApiResult&amp;quot;,&amp;quot;src&amp;quot;:&amp;quot;3&amp;quot;,&amp;quot;provider&amp;quot;:&amp;quot;@local-8125d22e37-519d-4056-bfe5-c52ef2ae8fabb0&amp;quot;,&amp;quot;consumer&amp;quot;:&amp;quot;dev:SwPh_zkl_5e42e884&amp;quot;,&amp;quot;client&amp;quot;:&amp;quot;@client-f62702dd86-be3f-47fc-b4bc-7a21627b75b2ea&amp;quot;,&amp;quot;msg&amp;quot;:{&amp;quot;mt&amp;quot;:&amp;quot;SearchInfo&amp;quot;,&amp;quot;relevance&amp;quot;:2000,&amp;quot;adjust&amp;quot;:true,&amp;quot;type&amp;quot;:&amp;quot;contact&amp;quot;,&amp;quot;contact&amp;quot;:{&amp;quot;givenname&amp;quot;:&amp;quot;John&amp;quot;,&amp;quot;sn&amp;quot;:&amp;quot;Doe&amp;quot;,&amp;quot;company&amp;quot;:&amp;quot;ACME&amp;quot;,&amp;quot;position&amp;quot;:&amp;quot;Head of everything&amp;quot;,&amp;quot;telephonenumber&amp;quot;:[&amp;quot;11111&amp;quot;,&amp;quot;22222&amp;quot;],&amp;quot;homephone&amp;quot;:[&amp;quot;+4944444&amp;quot;,&amp;quot;33333&amp;quot;],&amp;quot;mobile&amp;quot;:[&amp;quot;+49 (123) 55555&amp;quot;]}},&amp;quot;api&amp;quot;:&amp;quot;com.innovaphone.search&amp;quot;}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Reverse Lookup:&#039;&#039;&#039; The myApps platform services implement an &#039;&#039;API provider&#039;&#039; for the [http://sdk.innovaphone.com/web1/com.innovaphone.phonelookup/lib1_api_phonelookup.htm &#039;&#039;com.innovaphone.phonelookup&#039;&#039; API]. They perform search capabilities on the OS&#039; local phone books which can be used by Apps like the &#039;&#039;phoneapp&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Apps would send a &#039;&#039;Lookup&#039;&#039; request to the API: &lt;br /&gt;
&lt;br /&gt;
: &amp;lt;code&amp;gt;{&amp;quot;mt&amp;quot;:&amp;quot;ApiRequest&amp;quot;,&amp;quot;consumer&amp;quot;:&amp;quot;dev:SwPh_zkl_5e42e884&amp;quot;,&amp;quot;provider&amp;quot;:&amp;quot;*&amp;quot;,&amp;quot;src&amp;quot;:&amp;quot;4&amp;quot;,&amp;quot;msg&amp;quot;:{ mt: &amp;quot;Lookup&amp;quot;, prefixIntl: &amp;quot;000&amp;quot;, prefixNtl: &amp;quot;00&amp;quot;, prefixExt:&amp;quot;0&amp;quot;, area: &amp;quot;7031&amp;quot;, country: &amp;quot;49&amp;quot;, lookup: &amp;quot;0004970311234567&amp;quot; },&amp;quot;apiId&amp;quot;:&amp;quot;com.innovaphone.lookup&amp;quot;}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Search results are delivered as &#039;&#039;LookupInfo&#039;&#039; messages:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;code&amp;gt;{&amp;quot;mt&amp;quot;:&amp;quot;ApiResult&amp;quot;,&amp;quot;src&amp;quot;:&amp;quot;3&amp;quot;,&amp;quot;provider&amp;quot;:&amp;quot;@local-8125d22e37-519d-4056-bfe5-c52ef2ae8fabb0&amp;quot;,&amp;quot;consumer&amp;quot;:&amp;quot;dev:SwPh_zkl_5e42e884&amp;quot;,&amp;quot;client&amp;quot;:&amp;quot;@client-f62702dd86-be3f-47fc-b4bc-7a21627b75b2ea&amp;quot;,&amp;quot;msg&amp;quot;:{mt: &amp;quot;LookupInfo&amp;quot;, dn: &amp;quot;Jake Blues&amp;quot;, contact: { telephonenumber: [&amp;quot;0004970311234567&amp;quot;], givenname: &amp;quot;Jake&amp;quot;, sn: &amp;quot;Blues&amp;quot;, company: &amp;quot;Blues Brothers&amp;quot; &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Windows ====&lt;br /&gt;
On Windows, the search and lookup are performed in all of the user&#039;s Outlook contact folders.  As opposed to the search implemented in the &#039;&#039;Contacts&#039;&#039; and &#039;&#039;Users&#039;&#039; App, all items are returned which match any of the search words (i.e. searching for &#039;&#039;a b&#039;&#039; will return items matching either &#039;&#039;a&#039;&#039; or &#039;&#039;b&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
; searched properties : firstname, lastname&lt;br /&gt;
; returned properties : Following Outlook contact phone number properties are returned  (if available):&lt;br /&gt;
&lt;br /&gt;
:* OFFICE_TELEPHONE_NUMBER as &#039;&#039;telephonenumber&#039;&#039;&lt;br /&gt;
:* OFFICE2_TELEPHONE_NUMBER as &#039;&#039;telephonenumber&#039;&#039;&lt;br /&gt;
:* HOME_TELEPHONE_NUMBER as &#039;&#039;homephone&#039;&#039;&lt;br /&gt;
:* HOME2_TELEPHONE_NUMBER as &#039;&#039;homephone&#039;&#039;&lt;br /&gt;
:* MOBILE_TELEPHONE_NUMBER as &#039;&#039;mobile&#039;&#039;&lt;br /&gt;
:* BUSINESS_FAX_NUMBER as &#039;&#039;facsimiletelephonenumber&#039;&#039;&lt;br /&gt;
Note that contact information is cached in the search provider.  Updated contacts may therefore become effective after a while only.&lt;br /&gt;
Outlook search will create its own trace file &amp;lt;code&amp;gt;myAppsOutlookSearch-&amp;lt;/code&amp;gt;&#039;&#039;date-time&#039;&#039;&amp;lt;code&amp;gt;.txt&amp;lt;/code&amp;gt; in the standard trace directory.&lt;br /&gt;
&lt;br /&gt;
This search provider is always installed and can be disabled.  There is no need (nor possibility) to enable it in the &#039;&#039;Apps&#039;&#039; tab of the PBX&#039;s user object.  Also, no &#039;&#039;App&#039;&#039; object needs to be created for it.&lt;br /&gt;
&lt;br /&gt;
==== Android/iOS ====&lt;br /&gt;
The search and lookup are performed in the contacts.&lt;br /&gt;
&lt;br /&gt;
==== macOS ====&lt;br /&gt;
The search and lookup are performed in the contacts. If you wish to disable local contact lookup, go to system settings - Security &amp;amp; Privacy and disable the access to contacts for myapps.&lt;br /&gt;
=== Microsoft Office integration ===&lt;br /&gt;
&lt;br /&gt;
The myApps platform services has a &#039;&#039;office presence provider&#039;&#039; that can provide the user&#039;s presence state to Office applications.  See [[{{NAMESPACE}}:Concept_myApps_Office_Integration|myApps Office Integration]] for details.&lt;br /&gt;
&lt;br /&gt;
This feature is installed by default.  However, it can be disabled using the &#039;&#039;OFFICEPRESENCE&#039;&#039; MSI Parameter.  Also, a check-mark is available in the setup dialog.&lt;br /&gt;
&lt;br /&gt;
=== Call an external application for calls ===&lt;br /&gt;
&lt;br /&gt;
Phone Apps (such as the phoneapp or softphone) can initiate the start of an external application when a new call appears (either incoming or outgoing).  The actual spawning of the application is done by the myApps platform service.  Also, the application properties (such as e.g. the executable&#039;s path) is configured in the myApps platform services (see [[#UI elements|Advanced settings]] in the &#039;&#039;UI elements&#039;&#039; section below).&lt;br /&gt;
&lt;br /&gt;
A number of arguments can be passed to the application by substituting $-variables in the &#039;&#039;Parameter&#039;&#039; field:&lt;br /&gt;
&lt;br /&gt;
; $n : phone number as dialed (called party number for outgoing calls) or received (calling party number for incoming calls)&lt;br /&gt;
&lt;br /&gt;
; $N : called or calling party number in &#039;&#039;national&#039;&#039; format (e.g. 07031730090)&lt;br /&gt;
&lt;br /&gt;
; $I : called or calling party number in &#039;&#039;international&#039;&#039; format (e.g. +497031730090)&lt;br /&gt;
&lt;br /&gt;
: note that both $N and $I only work if $n includes both subscriber number and area code (e.g. 07031730090). Otherwise they are equal to $n&lt;br /&gt;
&lt;br /&gt;
; $d : display name of peer (if known)&lt;br /&gt;
&lt;br /&gt;
; $u : URI name of the peer (if available eg with a federation call)&lt;br /&gt;
&lt;br /&gt;
; $c : conference id&lt;br /&gt;
&lt;br /&gt;
: this is a globally unique ID for this call and may be used to relate the call to the &#039;&#039;guid&#039;&#039; found in the CallInfo structure in the [http://wiki.innovaphone.com/index.php?title=Reference10:SOAP_API#CallInfo SOAP-API] and [http://sdk.innovaphone.com/doc/appwebsocket/RCC.htm RCC-API ].  Also, corresponding [[Reference10:Call Detail Record CDR PBX|CDRs]] can be related using the &#039;&#039;event&#039;&#039; tag&#039;s &#039;&#039;conf&#039;&#039; attribute.&lt;br /&gt;
The start of an external application can be requested using the &#039;&#039;com.innovaphone.externalapps&#039;&#039; API.&lt;br /&gt;
&lt;br /&gt;
Some setup examples are [[Howto:Integrate External Apps in innovaphone UC clients|shown here]].&lt;br /&gt;
&lt;br /&gt;
=== Push ===&lt;br /&gt;
&lt;br /&gt;
Mobile operating systems usually inhibit network operation of apps which run in the background or are closed by the user.  This is done in order to reduce battery consumption.  Unfortunately, this also stops such apps to maintain a registration by regularly sending &#039;&#039;keep alive&#039;&#039; messages to a server (in our case to the PBX).  As a result, myApps will be disconnected from the PBX.   When the PBX determines that there is an event for the application which needs a response, it needs to wake up the app using a dedicated channel provided by the operating system.  This mechanism is know as &#039;&#039;push&#039;&#039;. When running on iOS or Android, myApps supports &#039;&#039;push&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
For &#039;&#039;push&#039;&#039; to work, a [[{{NAMESPACE}}:PBX/Objects/Push|&#039;&#039;push object&#039;&#039;]] needs to be configured in the PBX .  Also, it needs to be enabled on the mobile phone for the myApps app.&lt;br /&gt;
This mechanism is quite similar in v12 and v13, so you can refer to [[{{NAMESPACE}}:Concept_Push_Notifications_for_iOS_and_Android|the concept for push notifications for iOS and Android]] for more details. &lt;br /&gt;
&lt;br /&gt;
Also, helpful hints can be found in [[Howto:Troubleshoot v13 Push with myApps for Android and iOS]].&lt;br /&gt;
&lt;br /&gt;
=== App Proxy ===&lt;br /&gt;
&lt;br /&gt;
myApps runs further &#039;&#039;Apps&#039;&#039; (such as e.g. the &#039;&#039;phoneapp&#039;&#039;) as a web page in an IFRAME of the browser myApps is running in.  The App&#039;s page code is loaded either from the PBX or from an &#039;&#039;application platform&#039;&#039; (AP).   This however would mean that the App&#039;s IFRAME would remain empty (a dead white screen) when the PBX or AP is not available. To make sure the App can start-up anyway, the myApps platform services feature the so-called &#039;&#039;App Proxy&#039;&#039;.  This is a caching proxy that caches all the App code so it is available even in case of network failure. When myApps runs in the context of the platform services, Apps are therefore not loaded from the App source directly, but from the local App proxy. &lt;br /&gt;
&lt;br /&gt;
The cached files are stored in the PCs local file system in the &amp;lt;code&amp;gt;%LOCALAPPDATA%\innovaphone\myApps\appproxy&amp;lt;/path&amp;gt;&amp;lt;/code&amp;gt;.  There is no configuration required.  However, if myApps seems to run with outdated or corrupt cached copies of the App, you can safely delete the entire directory.&lt;br /&gt;
&lt;br /&gt;
=== Auto update ===&lt;br /&gt;
&lt;br /&gt;
On Windows and on macOS, the myApps platform services can auto-update themselves to a common version.  This is controlled by the [[{{NAMESPACE}}:PBX/Config/myApps#Launcher_Software_Update | &#039;&#039;Launcher Software Update&#039;&#039;]] settings under &#039;&#039;PBX/Config/myApps&#039;&#039; in the PBX. &lt;br /&gt;
&lt;br /&gt;
When myApps is started or the user logs in or myApps needs to re-connect to the PBX, the platform services will use the [http://sdk.innovaphone.com/web1/com.innovaphone.client/lib1_api_client.htm com.innovaphone.client API] to learn the desired version (&#039;&#039;launcherUpdateBuild&#039;&#039;, which is part of the API&#039;s &#039;&#039;model&#039;&#039;). If this differs from the current version, the platform services will try to download the respective new version. &lt;br /&gt;
&lt;br /&gt;
 {&lt;br /&gt;
    &amp;quot;mt&amp;quot;: &amp;quot;ApiUpdate&amp;quot;,&lt;br /&gt;
    &amp;quot;apis&amp;quot;: {&lt;br /&gt;
        &amp;quot;com.innovaphone.client&amp;quot;: {&lt;br /&gt;
            &amp;quot;@client&amp;quot;: {&lt;br /&gt;
                &amp;quot;title&amp;quot;: &amp;quot;innovaphone myApps&amp;quot;,&lt;br /&gt;
                &amp;quot;model&amp;quot;: {&lt;br /&gt;
                    &amp;quot;launcher&amp;quot;: true,&lt;br /&gt;
                    &amp;quot;launcherUpdateBuild&amp;quot;: &amp;quot;134906&amp;quot;,&lt;br /&gt;
                    &amp;quot;appStoreUrl&amp;quot;: &amp;quot;http://store.innovaphone.com/release/download/&amp;quot;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
The installation of the downloaded version is done by the &#039;&#039;innovaphonemyAppsUpdateService&#039;&#039;. This service is installed and enabled during the initial installation of the myApps platform services.  To disable auto-update, either leave the &#039;&#039;Launcher Software Update&#039;&#039; settings empty or set the service&#039;s start mode to &#039;&#039;disabled&#039;&#039; in the Windows &#039;&#039;services control panel&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Note that on Windows the update service does not work on terminal servers. Administrators must do myApps base services updates using standard windows mechanisms.&lt;br /&gt;
&lt;br /&gt;
Note that on macOS if myApps has been installed from the Apple Store it is assumed that auto update from the PBX is not desired and disabled therefore.&lt;br /&gt;
&lt;br /&gt;
On Android/iOS/macOS updates can be downloaded from the respective app store.&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;Devices&#039;&#039; app can not update software installed on Windows PCs directly. However, when the PBX is updated using an &#039;&#039;update job&#039;&#039; in the &#039;&#039;Devices&#039;&#039; App, the &#039;&#039;Launcher Software Update&#039;&#039; settings will be updated accordingly and hence the myApps base services will ultimately also be updated to the same version.&lt;br /&gt;
&lt;br /&gt;
==== Auto update flow on Windows ====&lt;br /&gt;
&lt;br /&gt;
* On start of myApps, myApps checks if an update is available and ready for installation&lt;br /&gt;
** if yes, the update is installed directly, without user interaction (a popup is shown during the installation)&lt;br /&gt;
** if not, myApps starts&lt;br /&gt;
* if an update is available while myApps is already running, an update notification will be shown which let&#039;s the user choose to install the update now or later (the notification will then popup again after one hour)&lt;br /&gt;
&lt;br /&gt;
==UI elements ==&lt;br /&gt;
There are a few user interfaces provided by the platform services:&lt;br /&gt;
===tray-icon (Windows only) ===&lt;br /&gt;
::[[Image:myapps-tray.png|myapps-tray.png/|myapps-tray.png/]]&lt;br /&gt;
:Allows to&lt;br /&gt;
:* terminate myApps&lt;br /&gt;
:* toggle the &#039;&#039;autostart&#039;&#039; state&lt;br /&gt;
:* toggle the &#039;&#039;show in task bar&#039;&#039; state&lt;br /&gt;
:* open the trace folder&lt;br /&gt;
:&lt;br /&gt;
=== PBX connect form===&lt;br /&gt;
:: [[Image:myapps-connect.png|myapps-connect.png/|myapps-connect.png/]]&lt;br /&gt;
: Allows the user to specify the connect data for the PBX (i.e. IP address or DNS name)&lt;br /&gt;
:&lt;br /&gt;
=== Advanced settings===&lt;br /&gt;
::[[Image:myapps-settings0.png|myapps-settings0.png/|myapps-settings0.png/]]&lt;br /&gt;
::[[Image:myapps-settings.png|myapps-settings.png/|myapps-settings.png/]] [[Image:myapps-settings2.png|myapps-settings2.png/|myapps-settings2.png/]] [[Image:myapps-settings3.png|myapps-settings3.png/|myapps-settings3.png/]]&lt;br /&gt;
&lt;br /&gt;
: Allows to modify various platform dependant settings (such as e.g. the hotkey selection on Windows)&lt;br /&gt;
&lt;br /&gt;
== Interfaces ==&lt;br /&gt;
=== Provided APIs ===&lt;br /&gt;
&lt;br /&gt;
; [http://sdk.innovaphone.com/web1/com.innovaphone.search/lib1_api_search.htm com.innovaphone.search] : access to local phone book entries by the [[#Local phonebook access|Local phonebook access]] component.&lt;br /&gt;
; [http://sdk.innovaphone.com/web1/com.innovaphone.launcher/com.innovaphone.launcher.htm com.innovaphone.launcher] : display of OS specific user notifications and receipt of related user actions&lt;br /&gt;
; com.innovaphone.notificationhandler : reports back click on a notification.&lt;br /&gt;
; com.innovaphone.externalapps : to start external applications, see [[#Call an external application for calls|Call an external application for calls]]  above&lt;br /&gt;
&lt;br /&gt;
=== Used APIs ===&lt;br /&gt;
&lt;br /&gt;
; [http://sdk.innovaphone.com/web1/com.innovaphone.phone/com.innovaphone.phone.htm com.innovaphone.phone] : used to initiate new or manipulate existing calls by the [[#Hot keys|Hot keys]] and [[#URL handler|URL handler]] components.&lt;br /&gt;
&lt;br /&gt;
; [http://sdk.innovaphone.com/web1/com.innovaphone.chat/com.innovaphone.chat.htm com.innovaphone.chat] : used to start a new chat by the [[#URL handler|URL handler]] component.&lt;br /&gt;
&lt;br /&gt;
; [http://sdk.innovaphone.com/web1/com.innovaphone.client/lib1_api_client.htm com.innovaphone.client] : the model is used to learn the update settings, see [[#Auto update|Auto update]] above&lt;br /&gt;
&lt;br /&gt;
=== Protocols ===&lt;br /&gt;
&lt;br /&gt;
; [https://sdk.innovaphone.com/doc/launcher/Media.htm Media Protocol] : used by apps to allocate RTP channels, see [[#RTP service for audio.2C video and data|RTP service for audio, video and data]] above&lt;br /&gt;
&lt;br /&gt;
== Related App Services ==&lt;br /&gt;
&lt;br /&gt;
none&lt;br /&gt;
&lt;br /&gt;
== Known limitations ==&lt;br /&gt;
; Incoming call as banner on myApps for iOS : Since iOS 14 the iOS CallKit presents incoming calls as a banner leaving the original green answer button of myApps visible. Use only the blue button of the banner to accept the call or change iPhone Settings, App &amp;quot;Phone&amp;quot;, &amp;quot;Incoming Calls&amp;quot; to &amp;quot;Full Screen&amp;quot; to hide the myApps user interface again during call answering.&lt;br /&gt;
&lt;br /&gt;
; Call answer in speakerphone mode even with active Bluetooth headset on myApps for iOS : This causes unwanted speakerphone operation if the smartphone is used with a Bluetooth car audio system. The behaviour can be changed by selecting &#039;&#039;Bluetooth Headset&#039;&#039; in this setting:&lt;br /&gt;
:&#039;&#039;iOS Settings-&amp;gt;Accessibility-&amp;gt;Touch-&amp;gt;Call Audio Routing: Automatic / Bluetooth Headset / Speaker&#039;&#039;&lt;br /&gt;
:&#039;&#039;iOS Einstellungen-&amp;gt;Bedienungshilfen-&amp;gt;Tippen-&amp;gt;Anrufaudioausgabe: Automatisch / Bluetooth-Headset / Lautsprecher&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
; Windows Server 2016 (Windows 10 Build 1607) : windows just shows the first notification. Further notifications aren&#039;t displayed until the previous ones are removed from the notification center. Current windows builds do not show this behaviour anymore.&lt;br /&gt;
&lt;br /&gt;
; Problems on Mac computers with Yealink USB headsets&lt;br /&gt;
: we have received reports that myApps quits unexpectedly on some Mac computers when a Yealink headset is plugged in.  Unfortunately, we could not find out the cause yet.  If you use Yealink USB headsets and have a similar issue, please open a support ticket and send myApps traces.&lt;br /&gt;
&lt;br /&gt;
; Poly / Plantronics headset buttons only functional if myApps is started with Rosetta&lt;br /&gt;
: myApps macOS supports Apple M1/M2 hardware natively. However, the Poly / Plantronics headset SDK is only available for Intel platform and thus myApps needs to be started via Apple&#039;s Intel emulator Rosetta if a Poly / Plantronics headset is used. This is done with right-click on the myApps executable, &#039;&#039;Information&#039;&#039;, &#039;&#039;Open with Rosetta&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
; Windows surface devices may not work correctly&lt;br /&gt;
: Chromium does not get touch keyboard events. USB Keyboards may not be recognized either.&lt;br /&gt;
&lt;br /&gt;
= Installation =&lt;br /&gt;
&lt;br /&gt;
== Windows ==&lt;br /&gt;
&lt;br /&gt;
myApps platform services are installed on Windows using the .msi file found in the &#039;&#039;myApps Windows&#039;&#039; package from [https://store.innovaphone.com/release/download.htm store.innovaphone.com].&lt;br /&gt;
&lt;br /&gt;
myApps can update itself automatically, see [[#Auto update|Auto update]] above.&lt;br /&gt;
&lt;br /&gt;
=== MSI Parameters and install options ===&lt;br /&gt;
&lt;br /&gt;
The MSI installer of myApps for Windows supports the following parameters and can be edited with [https://docs.microsoft.com/en-us/windows/win32/msi/orca-exe Microsoft Orca]. You can add your parameters in the table &#039;&#039;property&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
; SERVER (REG_SZ): the PBX&#039;s server address (without protocol like https://)&lt;br /&gt;
; OFFICEPRESENCE (REG_DWORD): &#039;&#039;&#039;false&#039;&#039;&#039; to disable presence integration in Microsoft Office&lt;br /&gt;
: this is also available as a check-mark when running the install manually&lt;br /&gt;
&lt;br /&gt;
; DISABLEHEADSETS (REG_DWORD): &#039;&#039;&#039;true&#039;&#039;&#039; to disable headsets support, see [[#Device handling|Device handling]] above&lt;br /&gt;
&lt;br /&gt;
; EXTERNALAPPS (REG_SZ): pre-define external applications, see [[#Call an external application for calls|Call an external application for calls]] above&lt;br /&gt;
: e.g. &amp;lt;code&amp;gt;&amp;quot;{&amp;quot;&amp;quot;externalApps&amp;quot;&amp;quot;:[{&amp;quot;&amp;quot;id&amp;quot;&amp;quot;:0,&amp;quot;&amp;quot;name&amp;quot;&amp;quot;:&amp;quot;&amp;quot;Wireshark&amp;quot;&amp;quot;,&amp;quot;&amp;quot;path&amp;quot;&amp;quot;:&amp;quot;&amp;quot;C:\\Program Files\\Wireshark\\Wireshark.exe&amp;quot;&amp;quot;,&amp;quot;&amp;quot;param&amp;quot;&amp;quot;:&amp;quot;&amp;quot;test $I&amp;quot;&amp;quot;}]}&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; FORCERESTART (REG_DWORD): &#039;&#039;&#039;true&#039;&#039;&#039; (or any string ...) kills myApps during the installation and restarts it for the currently logged in user, if it was running&lt;br /&gt;
&lt;br /&gt;
; DISABLELOCALHOST (REG_DWORD): &#039;&#039;&#039;true&#039;&#039;&#039; to disable use of &#039;&#039;&#039;localhost&#039;&#039;&#039; string to access the local webserver. Use &#039;&#039;&#039;127.0.0.1&#039;&#039;&#039; instead&lt;br /&gt;
&lt;br /&gt;
; EXCLUDEINTERFACES (REG_SZ): some VPN interfaces are not detected by Windows as IF_TYPE_PPP or IF_TYPE_TUNNEL and therefore the &#039;&#039;&#039;media outside VPN&#039;&#039;&#039; setting is not taking effect. With this option interfaces can be pre-defined that will not be used for media. Interfaces must be comma separated&lt;br /&gt;
: e.g. &amp;lt;code&amp;gt;EXCLUDEINTERFACES=&amp;quot;172,192.168,10.10&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; FASTERDOWNLOADS (REG_DWORD): &#039;&#039;&#039;true&#039;&#039;&#039; to have faster downloads without artificially slowing down the download of an update (which is done to avoid audio lags if clients have slow networks).&lt;br /&gt;
&lt;br /&gt;
Current settings are stored in the registry at &amp;lt;code&amp;gt;Computer\HKEY_CURRENT_USER\Software\innovaphone\myApps&amp;lt;/code&amp;gt; or at &amp;lt;code&amp;gt;Computer\HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\innovaphone\myApps&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Boolean values like OfficePresence are stored in registry entries with type REG_DWORD and values 1 or 0. 0 disables the setting and 1 enables it.&lt;br /&gt;
&lt;br /&gt;
== iOS ==&lt;br /&gt;
&lt;br /&gt;
myApps platform services are installed on iOS by loading &#039;&#039;innovaphone myApps&#039;&#039; from the &#039;&#039;App Store&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Configuration via MDM ===&lt;br /&gt;
&lt;br /&gt;
the PBX&#039;s server URL can be pre-configured by specifying this dictionary in the MDM&lt;br /&gt;
 &amp;lt;plist&amp;gt;&lt;br /&gt;
   &amp;lt;dict&amp;gt;&lt;br /&gt;
     &amp;lt;key&amp;gt;server&amp;lt;/key&amp;gt;&lt;br /&gt;
     &amp;lt;string&amp;gt;pbx.example.com&amp;lt;/string&amp;gt;&lt;br /&gt;
   &amp;lt;/dict&amp;gt;&lt;br /&gt;
 &amp;lt;/plist&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== macOS ==&lt;br /&gt;
&lt;br /&gt;
myApps platform services might be installed directly from the Apple store. An installer package &amp;lt;code&amp;gt;myapps.pkg&amp;lt;/code&amp;gt; and a disk image &amp;lt;code&amp;gt;myapps.dmg&amp;lt;/code&amp;gt; is also available from the innovaphone app store. Install &amp;lt;code&amp;gt;myapps.pkg&amp;lt;/code&amp;gt; by double-click on the file and follow the instructions of the installer. myApps becomes available in the Applications folder and can be opened by double-click. Or download and open &amp;lt;code&amp;gt;myapps.dmg&amp;lt;/code&amp;gt; and double klick myApps. If desired integrate it into the app dock by right click, &#039;&#039;Options, Keep in the dock&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
If installed from the innovaphone app store, myApps can update itself automatically, see [[#Auto update|Auto update]] above.&lt;br /&gt;
&lt;br /&gt;
If installed from the Apple store, macOS notifies about updates on the Apple store. myApps [[#Auto update|Auto update]] is disabled then.&lt;br /&gt;
&lt;br /&gt;
If a clean-install of the client is necessary, the folder &amp;quot;/Users/username/Library/Containers/myapps&amp;quot; needs to be deleted. To be on the safe side also delete it from the trash bin.&lt;br /&gt;
&lt;br /&gt;
=== Configuration via MDM ===&lt;br /&gt;
&lt;br /&gt;
the PBX&#039;s server URL can be pre-configured by specifying this dictionary in the MDM&lt;br /&gt;
 &amp;lt;plist&amp;gt;&lt;br /&gt;
   &amp;lt;dict&amp;gt;&lt;br /&gt;
     &amp;lt;key&amp;gt;server&amp;lt;/key&amp;gt;&lt;br /&gt;
     &amp;lt;string&amp;gt;pbx.example.com&amp;lt;/string&amp;gt;&lt;br /&gt;
   &amp;lt;/dict&amp;gt;&lt;br /&gt;
 &amp;lt;/plist&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Preferences ===&lt;br /&gt;
&lt;br /&gt;
macOS supports preference settings that can be set via a shell command or via Mac remote management&lt;br /&gt;
&lt;br /&gt;
 defaults write com.innovaphone.client-ios-14r1 server &amp;quot;PBX-server-URL&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The following parameters and can be set through this method:&lt;br /&gt;
&lt;br /&gt;
; server: the PBX&#039;s server URL&lt;br /&gt;
&lt;br /&gt;
=== Setting myApps as Default App for SIP-URLs ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|defaults write com.apple.LaunchServices/com.apple.launchservices.secure LSHandlers -array-add &#039;{&lt;br /&gt;
   LSHandlerURLScheme = sip;&lt;br /&gt;
   LSHandlerRoleAll = &amp;quot;&amp;lt;CFBundleIdentifier&amp;gt;&amp;quot;;&lt;br /&gt;
}&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
To find the “CFBundleIdentifier”, proceed as follows:&lt;br /&gt;
* In the Finder under “Applications”, search for the desired myApps client that you want to set as the default app.&lt;br /&gt;
* Right-click on “Show package contents” -&amp;gt; you will find the “CFBundleIdentifier” in the Info.plist file.&lt;br /&gt;
&lt;br /&gt;
A restart of the MAC is required.&lt;br /&gt;
&lt;br /&gt;
=== Using Sennheiser headsets ===&lt;br /&gt;
If you use Sennheiser headsets, you should also install the then-current &amp;lt;code&amp;gt;DSEA_SDK_v&amp;lt;/code&amp;gt;&#039;&#039;version&#039;&#039;&amp;lt;code&amp;gt;.pkg&amp;lt;/code&amp;gt; package, after you installed the myApps client.  Without that, audio will still work, but not the controls on the headset.  You will need to keep that up-to-date yourself, as it is not updated by myApps&#039;s auto-update function.&lt;br /&gt;
&lt;br /&gt;
== Android ==&lt;br /&gt;
&lt;br /&gt;
myApps platform services are installed on Android by loading &#039;&#039;innovaphone myApps&#039;&#039; from the &#039;&#039;Play Store&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Configuration via MDM ===&lt;br /&gt;
&lt;br /&gt;
the PBX&#039;s server URL can be pre-configured by specifying a property &amp;quot;server&amp;quot; with string value &amp;quot;pbx.example.com&amp;quot; in the MDM.&lt;br /&gt;
&lt;br /&gt;
== IP270 ==&lt;br /&gt;
For configuration instructions, refer to the [[Reference16r1:Concept IP270|IP270 concept article]].&lt;br /&gt;
&lt;br /&gt;
= Configuration =&lt;br /&gt;
&lt;br /&gt;
== Server configuration ==&lt;br /&gt;
When opening myApps for the first time, the user is prompted for the Server. Usually only the hostname (DNS host name or IP address) needs to be configured.&lt;br /&gt;
&lt;br /&gt;
But there are more options for special PBX configurations.&lt;br /&gt;
&lt;br /&gt;
; Non-standard HTTPS port&lt;br /&gt;
: If the PBX uses a non-standard HTTPS port, it must be appended to the host name separated by a colon (&amp;lt;code&amp;gt;:&amp;lt;/code&amp;gt;).&lt;br /&gt;
: Example: &amp;lt;code&amp;gt;pbx.example.com:4444&amp;lt;/code&amp;gt; (expands to &amp;lt;code&amp;gt;https://pbx.example.com:4444/PBX0/APPCLIENT/appclient.htm&amp;lt;/code&amp;gt;)&lt;br /&gt;
; DynPBX module name&lt;br /&gt;
: If the PBX is a DynPBX, the module id must be appended to PBX0 separated - (&amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt;).&lt;br /&gt;
: Example: &amp;lt;code&amp;gt;pbx.example.com/PBX0-1&amp;lt;/code&amp;gt; (expands to &amp;lt;code&amp;gt;https://pbx.example.com/PBX0-1/APPCLIENT/appclient.htm&amp;lt;/code&amp;gt;)&lt;br /&gt;
; Softphone physical location&lt;br /&gt;
: If user defined physical location shall be used for softphone, you can append it using a parameter &amp;lt;code&amp;gt;#phys=&amp;lt;/code&amp;gt;.&lt;br /&gt;
: Example: &amp;lt;code&amp;gt;pbx.example.com#phys=slave&amp;lt;/code&amp;gt; (expands to &amp;lt;code&amp;gt;https://pbx.example.com/PBX0/APPCLIENT/appclient.htm#phys=slave&amp;lt;/code&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Example 1: PBX pbx.example.com with standard configuration&lt;br /&gt;
 pbx.example.com&lt;br /&gt;
&lt;br /&gt;
Example 2: PBX slave.example with DynPBX module ID 1, HTTPS port 4444 and physical location master&lt;br /&gt;
 slave.example.com:4444/PBX0-1#phys=master&lt;br /&gt;
&lt;br /&gt;
=== HTTP proxy support ===&lt;br /&gt;
&lt;br /&gt;
myApps platform services do support operation via HTTP proxy now. If one or more proxies have been configured in the network settings of the operating system for the active network connection, HTTP CONNECT tunnels are established.&lt;br /&gt;
&lt;br /&gt;
On Windows user name and password can be specified for the tunnel servers as generic credentials in the credentials manager (Anmeldeinformationsverwaltung). The name of the credentials must be the tunnel server hostname.&lt;br /&gt;
&lt;br /&gt;
On Android user name and password can be specified through Android &#039;&#039;Settings, Accounts&#039;&#039; by adding a myApps &#039;&#039;HTTP Proxy Credentials&#039;&#039; account. The name of the account must be the tunnel server hostname.&lt;br /&gt;
&lt;br /&gt;
== Platform specific settings ==&lt;br /&gt;
When myApps runs under the myApps platform services, it will show various platform specific settings as part of its &#039;&#039;burger menu&#039;&#039;, so the user can set them.  See &#039;&#039;Advanced settings&#039;&#039; in [[#UI elements|UI elements]] above.&lt;br /&gt;
&lt;br /&gt;
Some options can also be set globally for all myApps clients in the PBX&#039;s [[{{NAMESPACE}}:PBX/Config/myApps#Client_Settings|PBX/Config/myApps &#039;&#039;Client Settings&#039;&#039;]]&lt;br /&gt;
{|&lt;br /&gt;
! style=&amp;quot;text-align: left; font-weight: bold&amp;quot; | Option&lt;br /&gt;
&lt;br /&gt;
! style=&amp;quot;text-align: left; font-weight: bold&amp;quot; | Description&lt;br /&gt;
&lt;br /&gt;
! style=&amp;quot;text-align: left; font-weight: bold&amp;quot; | Where to set&lt;br /&gt;
&lt;br /&gt;
!&lt;br /&gt;
! style=&amp;quot;text-align: left; font-weight: bold&amp;quot;| Availability&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| || || User menu || PBX &#039;&#039;Client Settings&#039;&#039; || Windows || iOS || Android || macOS&lt;br /&gt;
|IP270&amp;lt;ref&amp;gt;myApps-IP270 offers device specific settings explained in [[Reference16r1:Concept IP270|IP270 concept article]]&amp;lt;/ref&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Autostart || Launch myApps on login || &amp;amp;#10004; ||&amp;amp;#10004; ||&amp;amp;#10004; || &amp;amp;#10007; || &amp;amp;#10007; || &amp;amp;#10004;&lt;br /&gt;
|&amp;amp;#10007;&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| Appear offline after || controls after which idle time a user is considered &#039;&#039;inactive&#039;&#039;. See [[#User activity|User activity]] above || &amp;amp;#10004; ||&amp;amp;#10004; ||&amp;amp;#10004; || &amp;amp;#10007; || &amp;amp;#10007; || &amp;amp;#10004;&lt;br /&gt;
|&amp;amp;#10007;&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| Hotkeys || Hotkeys for call dial, accept, reject. See [[#Hot keys|Hot keys]] above || &amp;amp;#10004; ||&amp;amp;#10004; ||&amp;amp;#10004; || &amp;amp;#10007; || &amp;amp;#10007; || &amp;amp;#10004;&lt;br /&gt;
|&amp;amp;#10007;&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| Docking || Docking mode (left, right, none). See [[#???|??]] above || &amp;amp;#10004; ||&amp;amp;#10004; ||&amp;amp;#10004; || &amp;amp;#10007; || &amp;amp;#10007; || &amp;amp;#10007;&lt;br /&gt;
|&amp;amp;#10007;&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| Desktop notifications|| Turn on/off platform notifications. See [[#Notifications|  Notifications]] above || &amp;amp;#10004; ||&amp;amp;#10004; ||&amp;amp;#10004; || &amp;amp;#10007; || &amp;amp;#10007; || &amp;amp;#10004;&lt;br /&gt;
|&amp;amp;#10007;&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| VPN || Disable VPN address for ICE candidate selection. See [[#RTP ports| RTP ports]] above || &amp;amp;#10004; ||&amp;amp;#10004; ||&amp;amp;#10004; || &amp;amp;#10007; || &amp;amp;#10004; || &amp;amp;#10004;&lt;br /&gt;
|&amp;amp;#10007;&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| Show in taskbar|| Show myApps in the taskbar in addition to it&#039;s tray icon.  || &amp;amp;#10004; ||&amp;amp;#10007; ||&amp;amp;#10004; || &amp;amp;#10007; || &amp;amp;#10007; || &amp;amp;#10007;&lt;br /&gt;
|&amp;amp;#10007;&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| Log flags || turn on/off certain trace levels. See [[#Troubleshooting|Troubleshooting]] below.  || &amp;amp;#10004; ||&amp;amp;#10004; ||&amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004;&lt;br /&gt;
|&amp;amp;#10004;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| External applications || define the applications available for Apps to be started. See [[#Call an external application for calls|Call an external application for calls]] above.  || &amp;amp;#10004; ||&amp;amp;#10007; ||&amp;amp;#10004; || &amp;amp;#10007; || &amp;amp;#10007; || &amp;amp;#10004;&lt;br /&gt;
|&amp;amp;#10007;&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| Ring in headset || send ring tone for incoming to headset instead of loudspeaker.  || &amp;amp;#10004; ||&amp;amp;#10007; ||&amp;amp;#10004; || &amp;amp;#10007; || &amp;amp;#10007; || &amp;amp;#10007;&lt;br /&gt;
|&amp;amp;#10007;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Start parameters for Windows ==&lt;br /&gt;
&lt;br /&gt;
On Windows, it is not possible to pass start parameters from the [https://www.chromium.org/developers Chromium documentation] to the myApps process.&lt;br /&gt;
&lt;br /&gt;
== OS Settings for Windows ==&lt;br /&gt;
Windows settings can influence the display of &#039;&#039;Desktop notifications&#039;&#039;. See [https://support.microsoft.com/en-us/help/4028678/windows-10-change-notification-settings Change notification settings in Windows 10/11] for details.&lt;br /&gt;
&lt;br /&gt;
=== Windows 11 ===&lt;br /&gt;
&lt;br /&gt;
* Windows 11 has a feature &amp;quot;do not disturb&amp;quot;. This hides notifications if enabled.&lt;br /&gt;
* Windows 11 has a feature &amp;quot;focus&amp;quot;. This enables &amp;quot;do not disturb&amp;quot; and thus hides notifications too.&lt;br /&gt;
* Windows 11 has priority settings for notifications. Ensure that VoIP notifications for calls are allowed any maybe also include myApps as an App which is allowed to show notifications.&lt;br /&gt;
&lt;br /&gt;
== OS settings for Android ==&lt;br /&gt;
; Events : The appearance of notifications can be controlled here.&lt;br /&gt;
&lt;br /&gt;
; Call accounts : For proper incoming call signaling, the call account &#039;&#039;myApps&#039;&#039; needs to be enabled. Note that on Samsung smartphones the call account switch likely toggles back and a few tries may need to be done until it persists. Please double-check the state.&lt;br /&gt;
&lt;br /&gt;
; Preferred Calling Account : Choose which calling account (myApps/SIM/..) should be used for outgoing calls initiated from within the native phone app / phone book.&lt;br /&gt;
&lt;br /&gt;
; Background data, unlimited data usage : Grant background data use to enable &#039;&#039;myApps&#039;&#039; to connect to the PBX immediately on an incoming call.&lt;br /&gt;
&lt;br /&gt;
; Overlaying : This setting is not needed if call account &#039;&#039;myApps&#039;&#039; has been enabled. Should there be a reason for not enabling call account &#039;&#039;myApps&#039;&#039;, the permission for overlaying needs to be granted on Android 10 or higher for proper call signaling.&lt;br /&gt;
&lt;br /&gt;
Note: If no SIM card is installed some Android smartphones exhibit a problem dialing from the smartphone contacts. The contacts app shows a choice &#039;&#039;Select SIM card for this call&#039;&#039; but all possible dialers are greyed out. In this case make myApps the default phone app in Android settings &#039;&#039;Apps, Default apps, Telephony&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== OS settings for iOS ==&lt;br /&gt;
; Notifications : The appearance of notifications can be controlled in iOS &#039;&#039;Settings, myApps&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== OS settings for macOS ==&lt;br /&gt;
&lt;br /&gt;
; Notifications : The appearance of notifications can be controlled in macOS &#039;&#039;Preferences, Notifications, myApps&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=Troubleshooting=&lt;br /&gt;
&lt;br /&gt;
myApps platform services can write various traces for debugging.  Trace can be turned on and off selectively in the [[#Advanced settings|Advanced settings]].&lt;br /&gt;
&lt;br /&gt;
The following trace flags can be set:&lt;br /&gt;
&lt;br /&gt;
(&#039;&#039;Recommended trace options are: &#039;&#039;&#039;App, Browser, ICE, TURN, Signaling and Audio&#039;&#039;&#039;. Please do not activate other flags unless innovaphone support says otherwise&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
!style=&amp;quot;text-align: left; font-weight: bold&amp;quot; |  Abbreviation&lt;br /&gt;
&lt;br /&gt;
!style=&amp;quot;text-align: left; font-weight: bold&amp;quot; |code&lt;br /&gt;
&lt;br /&gt;
!style=&amp;quot;text-align: left; font-weight: bold&amp;quot; | description&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| App||0x000000001|| logs from the App Service itself&lt;br /&gt;
|-&lt;br /&gt;
| DNS||0x000000008|| logs DNS requests and results&lt;br /&gt;
|-&lt;br /&gt;
| HTTP client||0x000000080|| http client logs&lt;br /&gt;
|-&lt;br /&gt;
| TLS||0x000000400|| TLS logs&lt;br /&gt;
|-&lt;br /&gt;
| TCP||0x000000800|| TCP logs&lt;br /&gt;
|-&lt;br /&gt;
| LDS||0x000001000|| local domain sockets&lt;br /&gt;
|-&lt;br /&gt;
| WebSocket client||0x000004000|| logs outgoing websocket connections&lt;br /&gt;
|-&lt;br /&gt;
| App WebSocket||0x000008000|| logs app websocket connections (e.g. from PBX objects to an App Service or from the UI to the App Service)&lt;br /&gt;
|-&lt;br /&gt;
| UDP||0x000200000|| UDP logs&lt;br /&gt;
|-&lt;br /&gt;
| DTLS||0x000400000|| logs DTLS handshake and messages&lt;br /&gt;
|-&lt;br /&gt;
| Media||0x000800000|| logs media events&lt;br /&gt;
|-&lt;br /&gt;
| Media channel||0x001000000|| logs RTP/SCTP media connections&lt;br /&gt;
|-&lt;br /&gt;
| ICE||0x002000000|| logs ICE messages between peers&lt;br /&gt;
|-&lt;br /&gt;
| TURN||0x004000000|| logs TURN messages between peers&lt;br /&gt;
|-&lt;br /&gt;
| AppSharing||0x008000000|| logs AppSharing connection&lt;br /&gt;
|-&lt;br /&gt;
| Audio||0x010000000|| logs Audio connection and headset events&lt;br /&gt;
|-&lt;br /&gt;
| Video||0x020000000|| logs video connection and webcam events&lt;br /&gt;
|-&lt;br /&gt;
| Browser||0x040000000|| logs Chromium events&lt;br /&gt;
|-&lt;br /&gt;
| AppProxy||0x080000000|| logs requests which are proxied between the local webserver and the remote server&lt;br /&gt;
|-&lt;br /&gt;
| Webserver ||0x200000000|| enables webserver specific logs&lt;br /&gt;
|-&lt;br /&gt;
| Browser Console ||0x400000000|| logs browser console events&lt;br /&gt;
|-&lt;br /&gt;
| Signaling||0x800000000|| enables logs in the signaling module for debugging calls&lt;br /&gt;
|}&lt;br /&gt;
&#039;&#039;code&#039;&#039; can be or&#039;ed and used as value for the &#039;&#039;Log flags&#039;&#039; field in [[{{NAMESPACE}}:PBX/Config/myApps#Client_Settings|PBX/Config/myApps/Client Settings]].&lt;br /&gt;
&lt;br /&gt;
; Windows :On Windows, traces are written to the &amp;lt;code&amp;gt;%LOCALAPPDATA%\innovaphone\myApps&amp;lt;/code&amp;gt; directory. If you start myApps with --log-size as parameter, you can define the maximum size of a log file (e.g. --log-size=100000000 would be 100MB for each file)&lt;br /&gt;
&lt;br /&gt;
:* myApps-&#039;&#039;date-time&#039;&#039;.txt : main log file for the platform services&lt;br /&gt;
&lt;br /&gt;
:* myAppsOutlookSearch-&#039;&#039;date-time&#039;&#039;.txt : log file for the Outlook phone book access&lt;br /&gt;
&lt;br /&gt;
:* myAppsHookController-&#039;&#039;date-time&#039;&#039;.txt : log file for the hot-key interceptor (see [[#Hot keys|Hot keys]])&lt;br /&gt;
&lt;br /&gt;
; :myApps update installation traces are written to the &amp;lt;code&amp;gt;%windir%\temp\&amp;lt;/code&amp;gt; directory.&lt;br /&gt;
:* myAppsInstall.txt: MSI installation file&lt;br /&gt;
&lt;br /&gt;
; :myApps update service traces are written to the &amp;lt;code&amp;gt;%ProgramData%\innovaphone\myAppsUpdateService&amp;lt;/code&amp;gt; directory.&lt;br /&gt;
:* myAppsUpdateService-&#039;&#039;date-time&#039;&#039;.txt: myApps update service traces&lt;br /&gt;
&lt;br /&gt;
;Android : traces can be sent by e-mail.&lt;br /&gt;
: also, an Android device might also be connected to a PC via an USB cable to get the traces. The files can be found in &amp;lt;code&amp;gt;Android/data/com.innovaphone.clientandroid/files&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; iOS : traces can be sent by e-mail.&lt;br /&gt;
&lt;br /&gt;
; macOS : traces can be sent by e-mail.&lt;br /&gt;
: also, the files can be found in &amp;lt;code&amp;gt;~/Library/Containers/com.innovaphone.client-ios/Data/Documents/&amp;lt;/code&amp;gt;. Press &#039;&#039;Alt+N&#039;&#039; followed by space to get tilde &#039;&#039;~&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
; IP270 : Refer to the [[Reference16r1:Concept IP270#Troubleshooting|IP270 concept article section troubleshooting]].&lt;br /&gt;
&lt;br /&gt;
= Known Problems =&lt;br /&gt;
[[:Category:Problem myApps platform services|Known Problems]]&lt;br /&gt;
&lt;br /&gt;
= Related Articles =&lt;br /&gt;
* [[{{NAMESPACE}}:Concept_myApps]]&lt;br /&gt;
* [[{{NAMESPACE}}:Concept_myApps_Redundancy|Concept myApps Redundancy]]&lt;br /&gt;
* [[{{NAMESPACE}}:Concept_myApps_Office_Integration|Concept myApps Office Integration]]&lt;br /&gt;
* [[{{NAMESPACE}}:Concept_myAPPs_Search_in_local-Outlook_Contacts|Concept myAPPs Search in local Outlook Contacts]]&lt;br /&gt;
* [[{{NAMESPACE}}:Call_Detail_Record_CDR_PBX|Call Detail Records]]&lt;br /&gt;
* [[{{NAMESPACE}}:Concept Push Notifications for myPBX iOS and Android|Concept Push Notifications for myPBX iOS and Android]]&lt;br /&gt;
* [[Howto:Troubleshoot v13 Push with myApps for Android and iOS]]&lt;br /&gt;
* [[{{NAMESPACE}}:PBX/Config/myApps|Reference16r1:PBX/Config/myApps]]&lt;br /&gt;
* [[{{NAMESPACE}}:Concept_IP270|IP270 concept article]]&lt;br /&gt;
[[Category:Concept myApps platform services]]&lt;/div&gt;</summary>
		<author><name>Tfu</name></author>
	</entry>
	<entry>
		<id>https://wiki.innovaphone.com/index.php?title=Reference15r1:Concept_myApps_platform_services&amp;diff=79525</id>
		<title>Reference15r1:Concept myApps platform services</title>
		<link rel="alternate" type="text/html" href="https://wiki.innovaphone.com/index.php?title=Reference15r1:Concept_myApps_platform_services&amp;diff=79525"/>
		<updated>2026-04-21T09:11:24Z</updated>

		<summary type="html">&lt;p&gt;Tfu: /* Device handling */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Concept|myApps]]&lt;br /&gt;
&lt;br /&gt;
myApps platform services provide various operating system specific services which can be used by other &#039;&#039;Apps&#039;&#039; running in the [[{{NAMESPACE}}:Concept myApps|myApps client]]. Those services typically are not available in the browser&#039;s JavaScript environment and hence must be implemented in native platform code. Therefore, the platform services are installed as native executable on the respective platform.&lt;br /&gt;
&lt;br /&gt;
When myApps is started in a web browser (and hence has no access to the platform services), some Apps will use [https://en.wikipedia.org/wiki/WebRTC WebRTC] services implemented by the browser instead.  For ease of reference, features available in this scenario are also described here.&lt;br /&gt;
&lt;br /&gt;
On windows, the platform services also come with their own web browser in which the myApps web App will be started then.  This browser is based on google&#039;s [https://en.wikipedia.org/wiki/Chromium_(web_browser) Chromium] open source software.&lt;br /&gt;
= Applies To =&lt;br /&gt;
&lt;br /&gt;
* [[{{NAMESPACE}}:Concept myApps|myApps]]&lt;br /&gt;
* myApps for Windows&lt;br /&gt;
* myApps for macOS&lt;br /&gt;
* myApps for iOS&lt;br /&gt;
* myApps for Android&lt;br /&gt;
&lt;br /&gt;
* myApps Web App (WebRTC)&lt;br /&gt;
version 14r2&lt;br /&gt;
&lt;br /&gt;
=Features=&lt;br /&gt;
Not all features are available or required on all platforms.&lt;br /&gt;
 {|&lt;br /&gt;
! style=&amp;quot;text-align: left; font-weight: bold&amp;quot; | Feature&lt;br /&gt;
&lt;br /&gt;
! style=&amp;quot;text-align: left; font-weight: bold&amp;quot; | Description&lt;br /&gt;
&lt;br /&gt;
! style=&amp;quot;text-align: left; font-weight: bold&amp;quot;| Availability&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| || || Windows || iOS || Android || macOS || Browser&amp;lt;ref&amp;gt;This refers to the myApps web application running in a browser with no platform services available&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| audio || manage local audio devices to record and playback audio conversations || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; (audio available but devices managed by web browser)&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| video || manage local displays and cameras to capture and render video live stream || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; (video available but devices managed by web browser)&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| ringer || manage local ringing device || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004;&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| application sharing&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| &amp;amp;nbsp; presenter || share an application || &amp;amp;#10004; || &amp;amp;#10007; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004;&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| &amp;amp;nbsp; consumer  || view an application shared by the peer || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| hot keys || capture key presses for quick invocation of phone apps (e.g. dial selected number) || &amp;amp;#10004; || &amp;amp;#10007; || &amp;amp;#10007; || &amp;amp;#10004; || &amp;amp;#10007;&lt;br /&gt;
|-&lt;br /&gt;
| tel: and sip: URI handler || intercept clicks on tel: and sip: links in web sites to invoke phone apps || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10007;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| user activity || set presence state according to user activity ||  &amp;amp;#10004; || &amp;amp;#10007; || &amp;amp;#10007; || &amp;amp;#10004; || &amp;amp;#10004;&amp;lt;ref&amp;gt;limited, see [[#User activity|User activity]] below&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| docking || myApps can be docked persistently to the right or left edge of your screens ||  &amp;amp;#10004;  || &amp;amp;#10007; || &amp;amp;#10007; || &amp;amp;#10007; || &amp;amp;#10007;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| multi-windowing|| Apps can be launched in separate windows||  &amp;amp;#10004;  || &amp;amp;#10007; || &amp;amp;#10007; || &amp;amp;#10004; || &amp;amp;#10007;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| recording|| Calls can be recorded to recording app||  &amp;amp;#10004;  || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10007;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| notifications || ||&lt;br /&gt;
|-&lt;br /&gt;
| &amp;amp;nbsp; display notifications || display notifications with OS standard mechanism ||  &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;amp;nbsp; push notifications || receive push notifications while myApps is not running  ||  &amp;amp;#10007; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004;&amp;lt;ref&amp;gt;The browser needs to be running in order to receive push notifications.&amp;lt;/ref&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;amp;nbsp; chat and apps || display notifications for chat and other apps  ||  &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;amp;nbsp; calls || display notifications for incoming calls  ||  &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10007;&amp;lt;ref&amp;gt;Call notifications are only displayed locally while the phone or softphone app is started.&amp;lt;/ref&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| phone book access || access local phone book ||  &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10007;&lt;br /&gt;
|-&lt;br /&gt;
| office presence provider || maps PBX presence state to Microsoft office presence state ||  &amp;amp;#10004;  || &amp;amp;#10007; || &amp;amp;#10007; || &amp;amp;#10007; || &amp;amp;#10007;&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| external application start || start arbitrary external applications for calls || &amp;amp;#10004; || &amp;amp;#10007; || &amp;amp;#10007; || &amp;amp;#10004; || &amp;amp;#10007;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| app proxy|| a caching proxy that provides app persistence  || &amp;amp;#10004;  || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10007;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| auto update || automatically updates myApps platform services to the same version the PBX has || &amp;amp;#10004;  || &amp;amp;#10004; || &amp;amp;#10007; || &amp;amp;#10004; || &amp;amp;#10004;&amp;lt;ref&amp;gt;The then-current web app is always loaded from the PBX upon startup and hence up-to-date by definition&amp;lt;/ref&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| three party conference || initiate 3-pty-conference using Softphone-App || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10007;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| exclude VPN || disable use of VPN connections for audio and appsharing || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10007;&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Requirements=&lt;br /&gt;
* innovaphone PBX 14r2 and up&lt;br /&gt;
&lt;br /&gt;
== Hardware ==&lt;br /&gt;
Recommended hardware requirements&lt;br /&gt;
* Processor: Dual-core 2Ghz or higher&lt;br /&gt;
* RAM: 4 Gb&lt;br /&gt;
&lt;br /&gt;
== myApps for Windows ==&lt;br /&gt;
* Windows 10 and up&lt;br /&gt;
* Windows Server 2016 and later versions&lt;br /&gt;
&lt;br /&gt;
=== 32 &amp;amp; 64 bit Windows ===&lt;br /&gt;
* 32 bit Windows: install the myAppsSetup32.msi from the App Store&lt;br /&gt;
* 64 bit Windows: install the myAppsSetup.msi from the App Store&lt;br /&gt;
** the 64 bit variant still installs into Program Files (x86), as the main myApps.exe is still a 32bit application&lt;br /&gt;
** the 64 bit variant just contains an additional 64 bit binary for the outlook search&lt;br /&gt;
&lt;br /&gt;
=== Windows N editions ===&lt;br /&gt;
&lt;br /&gt;
Windows N editions are missing the &#039;&#039;Media Feature Pack&#039;&#039; which is pre installed on other Windows versions.&lt;br /&gt;
&lt;br /&gt;
Please install the pack from [https://www.microsoft.com/en-us/software-download/mediafeaturepack Microsoft (Windows 10 pack)] before you install myApps. The installer will check if the file &amp;lt;code&amp;gt;C:\Windows\SysWOW64\mfplat.dll&amp;lt;/code&amp;gt; exist on your system.&lt;br /&gt;
&lt;br /&gt;
Make sure to install the correct pack depending on your Windows version! There are different packs for Windows 10 1703, 1803, 1809 and 32bit or 64bit etc.&lt;br /&gt;
&lt;br /&gt;
NB: Sometimes the myApps installation will not work even though the media pack is already installed. This is because the installer has no read access to check if the package is already installed. If the above-mentioned file exists and the installer asks to install the Windows Media Feature Pack nevertheless, you have to start the myApps install with administrative rights.&lt;br /&gt;
&lt;br /&gt;
=== Terminal Server environments ===&lt;br /&gt;
&lt;br /&gt;
Audio driver was removed if myApps discovers that it is running in a terminal server environment like Citrix.&lt;br /&gt;
&lt;br /&gt;
The audio driver is needed for the Softphone App but the Softphone App should not use an audio driver at the server side because the audio devices are plugged locally and there would be a delay sending and receiving audio data with the server.&lt;br /&gt;
&lt;br /&gt;
If a customer wants to use the Softphone App at the server side he needs to make use of the myApps Plugin for virtual desktops solution:&lt;br /&gt;
&lt;br /&gt;
[[{{NAMESPACE}}:MyApps_Plugin_for_Virtual_Desktops|Reference15r1:MyApps_Plugin_for_Virtual_Desktops]]&lt;br /&gt;
&lt;br /&gt;
== myApps for macOS ==&lt;br /&gt;
* macOS 10.13 or higher&lt;br /&gt;
&lt;br /&gt;
== myApps for iOS ==&lt;br /&gt;
* iOS 13 or higher&lt;br /&gt;
&lt;br /&gt;
== myApps for Android ==&lt;br /&gt;
* Android 6.0 or higher. Android 6.x may need an update of the Chrome browser.&lt;br /&gt;
&lt;br /&gt;
= Licenses =&lt;br /&gt;
* No license needed for myApps platform services&lt;br /&gt;
&lt;br /&gt;
= Overview =&lt;br /&gt;
myApps platform services is a native executable that is installed using the standard mechanisms on the respective operating system. It provides various advanced services which can be used by the myApps web client code as well as the Apps running in the myApps context. &lt;br /&gt;
&lt;br /&gt;
Also, on Windows, the platform services come with their own, dedicated browser to run myApps in.  This browser is based on [https://en.wikipedia.org/wiki/Chromium_(web_browser) Chromium].  On iOS, macOS and Android, it is based upon native embedded web view facilities (such as WKWebView) instead.&lt;br /&gt;
== Components ==&lt;br /&gt;
&lt;br /&gt;
=== RTP service for audio and appsharing ===&lt;br /&gt;
The RTP service provides audio and appsharing as a video stream. VoIP RTP endpoints (e.g. for softphones).  It supports STUN, TURN, ICE, SRTP, DTLS. Note however that unlike WebRTC, these endpoints do not &#039;&#039;require&#039;&#039; ICE and DTLS. In other words, they can communicate also with non-compliant (i.e. older) VoIP devices.&lt;br /&gt;
&lt;br /&gt;
Note that the available capabilities when not running the myApps platform services depend on the used browser&#039;s WebRTC implementation. See your browser documentation for details.&lt;br /&gt;
&lt;br /&gt;
Apps can request RTP channels using the [https://sdk.innovaphone.com/doc/launcher/Media.htm Media Protocol]&#039;s &#039;&#039;AllocChannel&#039;&#039; message.&lt;br /&gt;
&lt;br /&gt;
===== RTP ports=====&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|  audio || 50000 -&amp;gt; 50099&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| video (app sharing) || 50100 -&amp;gt; 50199&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The RTP service will enumerate all local interfaces and create local HOST candidates for ICE.  There is an option however to disregard VPN interfaces (more precisely such interfaces with type of &#039;&#039;IF_TYPE_PPP&#039;&#039; or &#039;&#039;IF_TYPE_TUNNEL&#039;&#039;).  This can eliminate quality issues when RTP data is transmitted through TCP based VPN tunnels.&lt;br /&gt;
&lt;br /&gt;
SRFLX and RELAY candidates are obtained using the STUN and TURN server configuration passed by the App (e.g the &#039;&#039;softphone&#039;&#039; App) as part of the &#039;&#039;AllocChannel&#039;&#039; request.&lt;br /&gt;
&amp;lt;code&amp;gt;{&amp;quot;mt&amp;quot;:&amp;quot;AllocChannel&amp;quot;,&amp;quot;channel&amp;quot;:&amp;quot;81429cba-396d-43de-8a76-ec020ba8796e&amp;quot;,&amp;quot;iceServers&amp;quot;:[{&amp;quot;urls&amp;quot;:&amp;quot;turn:myturn.domaincom:4077?transport=udp&amp;quot;,&amp;quot;username&amp;quot;:&amp;quot;turnuser&amp;quot;,&amp;quot;credential&amp;quot;:&amp;quot;pwd&amp;quot;,&amp;quot;credentialType&amp;quot;:&amp;quot;password&amp;quot;},{&amp;quot;urls&amp;quot;:&amp;quot;stun:mystun.domain.com:4077&amp;quot;}],&amp;quot;dn&amp;quot;:&amp;quot;Foo Bar&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;RemoteRtp&amp;quot;,&amp;quot;kind&amp;quot;:&amp;quot;video&amp;quot;}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Codecs =====&lt;br /&gt;
&lt;br /&gt;
The installed myApps launchers provide codecs that can be used by softphone apps for media streams. When running in a web browser the codecs depend on the browser version and operating system. See the documentation of your browser for details.&lt;br /&gt;
&lt;br /&gt;
The following codecs are supported:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
!style=&amp;quot;text-align:left;width:100px;&amp;quot;|Codec&lt;br /&gt;
!style=&amp;quot;width:100px&amp;quot;|Windows-Launcher&lt;br /&gt;
!style=&amp;quot;width:100px&amp;quot;|Android&lt;br /&gt;
!style=&amp;quot;width:100px&amp;quot;|iOS&lt;br /&gt;
!style=&amp;quot;width:100px&amp;quot;|macOS&lt;br /&gt;
!style=&amp;quot;width:100px&amp;quot;|Firefox (Browser)&lt;br /&gt;
!style=&amp;quot;width:100px&amp;quot;|Chrome (Browser)&lt;br /&gt;
!style=&amp;quot;width:100px&amp;quot;|Edge (Browser)&lt;br /&gt;
!style=&amp;quot;width:100px&amp;quot;|Safari (Browser)&lt;br /&gt;
!style=&amp;quot;width:100px&amp;quot;|Opera (Browser)&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:left; background-color:lightgray&amp;quot; colspan=&amp;quot;10&amp;quot;|Audio&lt;br /&gt;
|-&lt;br /&gt;
|G711A&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|-&lt;br /&gt;
|G711u&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|-&lt;br /&gt;
|G722&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|-&lt;br /&gt;
|G729&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|-&lt;br /&gt;
|G729A&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|-&lt;br /&gt;
|G729B&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|-&lt;br /&gt;
|G729AB&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|-&lt;br /&gt;
|[https://caniuse.com/#search=Opus OPUS-NB]&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|-&lt;br /&gt;
|[https://caniuse.com/#search=Opus OPUS-WB]&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:left; background-color:lightgray&amp;quot; colspan=&amp;quot;10&amp;quot;|Video&lt;br /&gt;
|-&lt;br /&gt;
|[https://caniuse.com/#search=VP8 VP8]&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
|[https://caniuse.com/#search=VP9 VP9]&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔**&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔**&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔**&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔**&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔**&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔**&lt;br /&gt;
|-&lt;br /&gt;
|[https://caniuse.com/#search=H264 H264]&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔**&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:left; background-color:lightgray&amp;quot; colspan=&amp;quot;10&amp;quot;|Application Sharing&lt;br /&gt;
|-&lt;br /&gt;
|Share&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|-&lt;br /&gt;
|Watch&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔*&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔*&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;* small presentation only&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;** only for 1:1 calls, not for conferences&lt;br /&gt;
&lt;br /&gt;
===== Video capture =====&lt;br /&gt;
&lt;br /&gt;
The default resolution for video capture is 1920x1080 if available.  Otherwise, 1280x720, 640x480, 352x288 or 320x240 will be used.  The frame rate is 30 fps if available, otherwise 15 fps. The resulting average bandwidth could reach 1 Mbps.&lt;br /&gt;
&lt;br /&gt;
===== Application sharing =====&lt;br /&gt;
&lt;br /&gt;
Screen content will be transmitted as video stream by the presenter&lt;br /&gt;
&lt;br /&gt;
===== Device handling =====&lt;br /&gt;
&lt;br /&gt;
The RTP service enumerates microphones, loudspeaker, cameras and ringing devices and notifies apps when devices come and go. It is up to the apps using the devices to store preferences.&lt;br /&gt;
&lt;br /&gt;
The RTP service also enables some extended features (such as hook switch or volume control) for supported USB headsets or Bluetooth headsets connected to myApps.&lt;br /&gt;
The supported headset-SDKs determine which headset vendors are recommended to be used with the myApps softphone app. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For this to work, the following vendor specific development kits are integrated in our myApps client. Be aware that the SDK are updated within our Service release :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! SDK Vendor !! Supported OS !! SDK Version !! innovaphone Service Release&lt;br /&gt;
|-&lt;br /&gt;
| Jabra|| MacOS || 1.16.4.0 || 14r2sr11&lt;br /&gt;
|-&lt;br /&gt;
||| Windows || 1.16.4.0 || 15r1sr3&lt;br /&gt;
|-&lt;br /&gt;
| Epos &#039;&#039;(formerly Sennheiser)&#039;&#039; || MacOS || 12.4.0.5478 || 14r1sr3&lt;br /&gt;
|-&lt;br /&gt;
||| Windows || n.a. - [[Support:13r3 sr10 MyApps Windows Client - Epos/Sennheiser-Headsets require installed Epos-Connect Software|to be installed separately]]|| 13r3sr10&lt;br /&gt;
|-&lt;br /&gt;
| Poly &#039;&#039;(formerly Plantronics)&#039;&#039; || MacOS || 3.25.53799.37131 || 13r3sr9&lt;br /&gt;
|-&lt;br /&gt;
||| Windows || 3.25.53800.37131 || 13r3sr10&lt;br /&gt;
|-&lt;br /&gt;
| Yealink || MacOS || 3.1.1.23 || 14r2sr1&lt;br /&gt;
|-&lt;br /&gt;
||| Windows || 3.1.1.23 || 14r2sr2&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
* It is possible to inhibit the start of the Sennheiser SDK (SenncomSDK.exe) using the &amp;lt;code&amp;gt;DISABLEHEADSETS&amp;lt;/code&amp;gt; directive of the installer (see [[#MSI Parameters and install options|  MSI parameters]]  below).&lt;br /&gt;
&lt;br /&gt;
* Starting with V13r3sr10, the Epos-SDK needs to be installed separately using the Epos Connect software to ensure full compatibility between current Epos headset models and native myApps-Windows client. For details [[Support:13r3 sr10 MyApps Windows Client - Epos/Sennheiser-Headsets require installed Epos-Connect Software|refer to this article]].&lt;br /&gt;
&amp;lt;!--Keywords: myapps softphone supported headsets sdk--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Ring tones =====&lt;br /&gt;
&lt;br /&gt;
Ring tones can be played. Apps can choose the tone from a pre-defined list of ring tones.&lt;br /&gt;
&lt;br /&gt;
On Windows, custom ring tones can be uploaded as .mp3 files to the &amp;lt;code&amp;gt;ringtones&amp;lt;/code&amp;gt; sub-directory of myApps&#039; roaming directory (which usually is in &amp;lt;code&amp;gt;%appdata%\innovaphone\myApps\ringtones&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
On Android, custom ring tones can be added to the system via Android settings.&lt;br /&gt;
&lt;br /&gt;
On iOS, custom ring tones can be uploaded as .mp3 files to the &amp;lt;code&amp;gt;Ringtones&amp;lt;/code&amp;gt; subdirectory of the myApps file share that is available in iTunes if the iPhone has been connected via USB.&lt;br /&gt;
&lt;br /&gt;
On macOS, custom ring tones can be uploaded as .mp3 files to &amp;lt;code&amp;gt;~/Library/Containers/com.innovaphone.client-macos/Data/Documents/Ringtones&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===== Debugging =====&lt;br /&gt;
For extended debugging, turn on the &#039;&#039;Audio&#039;&#039;, &#039;&#039;Media&#039;&#039; and &#039;&#039;AppSharing&#039;&#039; traces in myApps.&lt;br /&gt;
&lt;br /&gt;
=== Hot keys ===&lt;br /&gt;
On Windows and macOS systems, myApps platform services can listen for hot keys and invoke certain functions. Invocation is done by sending API messages to myApps which passes it to an appropriate API provider (in the cases described here, this will be a &#039;&#039;phone&#039;&#039; or &#039;&#039;softphone&#039;&#039; or &#039;&#039;rcc&#039;&#039; App typically.  See [[{{NAMESPACE}}:Concept_myApps#Client_APIs_and_default_apps | Client APIs and default apps]] for more details about this mechanism.&lt;br /&gt;
&lt;br /&gt;
The hot keys can be specified using the &#039;&#039;advanced settings&#039;&#039; user interface (see [[#UI elements| UI elements]] below. Any of the function keys F1 to F11 (optionally combined with up to two modifier keys &#039;&#039;alt&#039;&#039;, &#039;&#039;ctrl&#039;&#039;, &#039;&#039;shift&#039;&#039; or &#039;&#039;win&#039;&#039;) can be chosen for each function. If you do not want to start the call with &amp;quot;Hotkey+Enter&amp;quot; because you would have to wait for the focus, the hotkey can also be pressed twice and the number is dialled directly.&lt;br /&gt;
&lt;br /&gt;
; dial selected number : Initiates a call using the currently selected text as target.&lt;br /&gt;
&lt;br /&gt;
: A &#039;&#039;PrepareCall&#039;&#039; message with the &#039;&#039;text&#039;&#039; argument set to the selected text and the &#039;&#039;adjust&#039;&#039; argument set to &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; will be sent to the [http://sdk.innovaphone.com/web1/com.innovaphone.phone/com.innovaphone.phone.htm &#039;&#039;com.innovaphone.phone&#039;&#039; API].&lt;br /&gt;
&lt;br /&gt;
:: &amp;lt;code&amp;gt;{&amp;quot;mt&amp;quot;:&amp;quot;ApiRequest&amp;quot;,&amp;quot;apiId&amp;quot;:&amp;quot;com.innovaphone.phone&amp;quot;,&amp;quot;consumer&amp;quot;:&amp;quot;@local-ae2fc2ab74-3f1e-4ab9-b215-d42f213520317&amp;quot;,&amp;quot;msg&amp;quot;:&amp;quot;mt&amp;quot;:&amp;quot;PrepareCall&amp;quot;,&amp;quot;text&amp;quot;:&amp;quot;13&amp;quot;,&amp;quot;adjust&amp;quot;:true}}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; accept call : Accepts a currently alerting call.&lt;br /&gt;
&lt;br /&gt;
: A &#039;&#039;ConnectCall&#039;&#039; message will be sent to the [http://sdk.innovaphone.com/web1/com.innovaphone.phone/com.innovaphone.phone.htm &#039;&#039;com.innovaphone.phone&#039;&#039; API].&lt;br /&gt;
&lt;br /&gt;
:: &amp;lt;code&amp;gt;{&amp;quot;mt&amp;quot;:&amp;quot;ApiRequest&amp;quot;,&amp;quot;apiId&amp;quot;:&amp;quot;com.innovaphone.phone&amp;quot;,&amp;quot;consumer&amp;quot;:&amp;quot;@local-ae2fc2ab74-3f1e-4ab9-b215-d42f213520317&amp;quot;,&amp;quot;msg&amp;quot;:{&amp;quot;mt&amp;quot;:&amp;quot;ConnectCall&amp;quot;}}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; reject/disconnect call : Rejects a currently alerting call or disconnects an active call.&lt;br /&gt;
&lt;br /&gt;
: A &#039;&#039;DisconnectCall&#039;&#039; message will be sent to the [http://sdk.innovaphone.com/web1/com.innovaphone.phone/com.innovaphone.phone.htm &#039;&#039;com.innovaphone.phone&#039;&#039; API].&lt;br /&gt;
&lt;br /&gt;
:: &amp;lt;code&amp;gt;{&amp;quot;mt&amp;quot;:&amp;quot;ApiRequest&amp;quot;,&amp;quot;apiId&amp;quot;:&amp;quot;com.innovaphone.phone&amp;quot;,&amp;quot;consumer&amp;quot;:&amp;quot;@local-ae2fc2ab74-3f1e-4ab9-b215-d42f213520317&amp;quot;,&amp;quot;msg&amp;quot;:{&amp;quot;mt&amp;quot;:&amp;quot;DisconnectCall&amp;quot;}}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== URL Handler ===&lt;br /&gt;
&lt;br /&gt;
On Windows systems, two URI-handler are installed with the myApps platform services.  Windows will call up this URI handler when a user clicks on an appropriate link, for example in a web site.&lt;br /&gt;
&lt;br /&gt;
The handler will the send an API message to myApps which passes it to an appropriate API provider (in the cases described here, this will be a &#039;&#039;phone&#039;&#039; or &#039;&#039;softphone&#039;&#039; or &#039;&#039;rcc&#039;&#039; App typically.  See [[{{NAMESPACE}}:Concept_myApps#Client_APIs_and_default_apps | Client APIs and default apps]] for more details about this mechanism.&lt;br /&gt;
&lt;br /&gt;
; tel URI : call a number, e.g. &amp;lt;code&amp;gt;tel:4711&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: A &#039;&#039;PrepareCall&#039;&#039; message with the &#039;&#039;num&#039;&#039; argument set to the selected text and the &#039;&#039;adjust&#039;&#039; argument set to &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; will be sent to the [http://sdk.innovaphone.com/web1/com.innovaphone.phone/com.innovaphone.phone.htm &#039;&#039;com.innovaphone.phone&#039;&#039; API].&lt;br /&gt;
:: &amp;lt;code&amp;gt;{&amp;quot;mt&amp;quot;:&amp;quot;ApiRequest&amp;quot;,&amp;quot;apiId&amp;quot;:&amp;quot;com.innovaphone.phone&amp;quot;,&amp;quot;consumer&amp;quot;:&amp;quot;@local-ae2fc2ab74-3f1e-4ab9-b215-d42f213520317&amp;quot;,&amp;quot;msg&amp;quot;:{&amp;quot;mt&amp;quot;:&amp;quot;StartCall&amp;quot;,&amp;quot;num&amp;quot;:&amp;quot;4711&amp;quot;,&amp;quot;adjust&amp;quot;:true}}&amp;lt;/code&amp;gt;&lt;br /&gt;
; sip URI : call a SIP name, e.g. &amp;lt;code&amp;gt;sip:zkl@innovaphone.com&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: A &#039;&#039;PrepareCall&#039;&#039; message with the &#039;&#039;sip&#039;&#039; argument set to the selected text and the &#039;&#039;adjust&#039;&#039; argument set to &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; will be sent to the [http://sdk.innovaphone.com/web1/com.innovaphone.phone/com.innovaphone.phone.htm &#039;&#039;com.innovaphone.phone&#039;&#039; API].&lt;br /&gt;
:: &amp;lt;code&amp;gt;{&amp;quot;mt&amp;quot;:&amp;quot;ApiRequest&amp;quot;,&amp;quot;apiId&amp;quot;:&amp;quot;com.innovaphone.phone&amp;quot;,&amp;quot;consumer&amp;quot;:&amp;quot;@local-ae2fc2ab74-3f1e-4ab9-b215-d42f213520317&amp;quot;,&amp;quot;msg&amp;quot;:{&amp;quot;mt&amp;quot;:&amp;quot;StartCall&amp;quot;,&amp;quot;sip&amp;quot;:&amp;quot;zkl@innovaphone.com&amp;quot;,&amp;quot;adjust&amp;quot;:true}}&amp;lt;/code&amp;gt;&lt;br /&gt;
; im URI : start chat with SIP name, e.g. &amp;lt;code&amp;gt;im:zkl@innovaphone.com&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: A &#039;&#039;StartChat&#039;&#039; message with the &#039;&#039;sip&#039;&#039; argument set to the selected text will be sent to the [http://sdk.innovaphone.com/web1/com.innovaphone.chat/com.innovaphone.chat.htm &#039;&#039;com.innovaphone.chat&#039;&#039; API].&lt;br /&gt;
:: &amp;lt;code&amp;gt;{&amp;quot;mt&amp;quot;:&amp;quot;ApiRequest&amp;quot;,&amp;quot;apiId&amp;quot;:&amp;quot;com.innovaphone.chat&amp;quot;,&amp;quot;consumer&amp;quot;:&amp;quot;@local-ae2fc2ab74-3f1e-4ab9-b215-d42f213520317&amp;quot;,&amp;quot;msg&amp;quot;:{&amp;quot;mt&amp;quot;:&amp;quot;StartChat&amp;quot;,&amp;quot;sip&amp;quot;:&amp;quot;zkl@innovaphone.com&amp;quot;}}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On macOS systems myApps might be made the default application to handle tel URI e.g. &amp;lt;code&amp;gt;tel:4711&amp;lt;/code&amp;gt; via Apple FaceTime. Open the &amp;quot;FaceTime&amp;quot; menu &amp;quot;Settings...&amp;quot; and select myApps as &amp;quot;Default for phone calls&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
On iOS &#039;&#039;tel&#039;&#039; URIs are always dialed via GSM. Therefore myApps iOS also reacts to URI schemes &#039;&#039;com.innovaphone.tel&#039;&#039;, &#039;&#039;com.innovaphone.sip&#039;&#039; and &#039;&#039;com.innovaphone.im&#039;&#039;, e.g. &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;com.innovaphone.tel:4711&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;com.innovaphone.sip:zkl@innovaphone.com&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;com.innovaphone.im:zkl@innovaphone.com&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== User activity ===&lt;br /&gt;
On Windows and macOS systems, the myApps platform services can monitor user keyboard/mouse activity and change the user&#039;s presence state after a certain amount of inactivity.  The timeout can be specified using the &#039;&#039;advanced settings&#039;&#039; user interface (see [[#UI elements| UI elements]] below.&lt;br /&gt;
&lt;br /&gt;
myApps will then send a [https://sdk.innovaphone.com/doc/appwebsocket/myApps.htm#SetUserActivity&#039;&#039;SetUserActivity&#039;&#039;] message to the PBX using the &#039;&#039;myApps&#039;&#039; protocol.&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;code&amp;gt;{&amp;quot;mt&amp;quot;:&amp;quot;SetUserActivity&amp;quot;,&amp;quot;inactive&amp;quot;:true}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will change the &#039;&#039;status&#039;&#039; property of the &#039;&#039;im:&#039;&#039; contact for the user&#039;s own presence and hence result in a presence update from the PBX to myApps&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;code&amp;gt;{&amp;quot;mt&amp;quot;:&amp;quot;UpdateOwnPresence&amp;quot;,&amp;quot;presence&amp;quot;:[{...},{&amp;quot;contact&amp;quot;:&amp;quot;im:&amp;quot;,&amp;quot;activity&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;status&amp;quot;:&amp;quot;closed&amp;quot;}]}&amp;lt;/code&amp;gt;&lt;br /&gt;
The &#039;&#039;closed&#039;&#039; status is reflected in the grey status color when displaying a contact [[Image:myapps-inactive.png|myapps-inactive.png/|myapps-inactive.png/]].&lt;br /&gt;
&lt;br /&gt;
On iOS and Android, the state is set to &#039;&#039;inactive&#039;&#039; as soon as the App is brought to background.&lt;br /&gt;
When myApps platform services are not available (i.e. when running the web application in a browser solely) a limited user activity monitoring is available: the state is set to active when the web page is not used for more than 5 minutes.&lt;br /&gt;
&lt;br /&gt;
=== Recording ===&lt;br /&gt;
&lt;br /&gt;
The new launcher offers the possibility to record the audio of incoming and outgoing calls. In order to activate that functionality the URL of the recording instance must be configured in either the PBX (PBX-&amp;gt;myApps-&amp;gt;Config: Recording URL) or the softphone App (Settings-&amp;gt;Audio Recording (URL)) &lt;br /&gt;
&lt;br /&gt;
[[Image:PBX-Recording-Settings.png|pbx-recording-settings.png/|pbx-recording-settings.png/]] [[Image:Recording-Softphone-Settings.png|recording-softphone-settings.png/|recording-softphone-settings.png/]]. &lt;br /&gt;
&lt;br /&gt;
As long as that URL is configured the audio data of all calls are stored as pcap-files under that URL.&lt;br /&gt;
If the URL points to a CF device in the PBX, write access must be granted for that URL (PBX-&amp;gt;Services-&amp;gt;HTTP-&amp;gt;Server:Public compact flash access) and if the URL points to the recording app, the files can be accessed via the recording app [[{{NAMESPACE}}:Concept_App_Service_Recordings|recording]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Under PBX-&amp;gt;myApps the administrator can set a certain default behaviour of the audio recording like whether or not the recording should start automatically at the beginning of the call (Recording by Default ON/OFF), only calls with external numbers should be recorded (Record external calls only) or whether or not the user should be able to start/stop the recording himself (Allow user incall recording control). Except for the last parameter these parameters can also be modified by the user in its softphone settings if the administrator doesn&#039;t set the FORCE flag.&lt;br /&gt;
&lt;br /&gt;
If the user was allowed by the admin to control the recording a recording switch is active during the call when the &amp;quot;Media&amp;quot; Panel is opened. There the audio recording may be stopped and continued at will. A red recording notice is shown in the top right corner when the recording actually takes place.&lt;br /&gt;
 &lt;br /&gt;
[[Image:Recording-incall-switch.png|recording-incall-switch.png/|recording-incall-switch.png/]]&lt;br /&gt;
&lt;br /&gt;
=== Notifications ===&lt;br /&gt;
&lt;br /&gt;
The myApps platform services can use the OS specific notification mechanism (e.g. &#039;&#039;desktop notifications&#039;&#039; on Windows) to display messages (e.g. &#039;&#039;incoming new chat message&#039;&#039;) to the user.&lt;br /&gt;
&lt;br /&gt;
Note that the actual rendering of the notification is under control of the OS.  Therefore, myApps must be allowed to show notifications and its appearance can be restricted by OS native settings.&lt;br /&gt;
&lt;br /&gt;
==== Microsoft Windows Notifications ====&lt;br /&gt;
&lt;br /&gt;
Microsoft Windows Server editions (2016, 2019, 2022) are just capable of showing a single &#039;&#039;IncomingCall&#039;&#039; notification at the same time (we couldn&#039;t find a workaround for this limitation).&amp;lt;br/&amp;gt;&lt;br /&gt;
An &#039;&#039;IncomingCall&#039;&#039; notification is visible the whole time instead of being moved to the action center after a certain time.&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
A notification about a missed call uses the &#039;&#039;IncomingCall&#039;&#039; type so that this notification is visible until the user returns.&amp;lt;br/&amp;gt;&lt;br /&gt;
Due to the above limitation, on a new arriving call such a missed call notification is transformed to a default notification which will be moved to the action center automatically.&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
On non server editions, you can have multiple IncomingCall notifications at the same time (so two parallel incoming calls will be indeed notified at the same time), but the missed call notification handling is the same on both platforms!&lt;br /&gt;
&lt;br /&gt;
 Thus there will be always just &#039;&#039;&#039;one&#039;&#039;&#039; missed call notification visible and previous missed calls can be found inside your action center!&lt;br /&gt;
&lt;br /&gt;
To see myApps notifications, ensure:&lt;br /&gt;
* System -&amp;gt; Notifications &lt;br /&gt;
** enable notifications&lt;br /&gt;
** disable &amp;quot;Do not disturb&amp;quot; or allow myApps as priority application while &amp;quot;Do not disturb&amp;quot; is active&lt;br /&gt;
** enable notifications for myApps in the list of applications&lt;br /&gt;
* System -&amp;gt; Focus &lt;br /&gt;
** if a focus session is active and the &amp;quot;Do not disturb&amp;quot; is activated during a focus session, make sure that myApps is a priority application (see above)&lt;br /&gt;
&lt;br /&gt;
==== macOS Notifications ====&lt;br /&gt;
Notifications are the same as on Windows.&lt;br /&gt;
The difference is, that for macOS, notifications need to be allowed in the system settings.&lt;br /&gt;
Go to Notifications - myApps, select Banner and enable all check marks.&lt;br /&gt;
&lt;br /&gt;
=== Local phonebook access ===&lt;br /&gt;
&#039;&#039;&#039;Contact Search:&#039;&#039;&#039; The myApps platform services implement an &#039;&#039;API provider&#039;&#039; for the [http://sdk.innovaphone.com/web1/com.innovaphone.search/lib1_api_search.htm &#039;&#039;com.innovaphone.search&#039;&#039; API]]. They perform search capabilities on the OS&#039; local phone books which can be used by Apps like the &#039;&#039;phoneapp&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Apps would send a &#039;&#039;Search&#039;&#039; request to the API:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;code&amp;gt;{&amp;quot;mt&amp;quot;:&amp;quot;ApiRequest&amp;quot;,&amp;quot;consumer&amp;quot;:&amp;quot;dev:SwPh_zkl_5e42e884&amp;quot;,&amp;quot;provider&amp;quot;:&amp;quot;*&amp;quot;,&amp;quot;src&amp;quot;:&amp;quot;4&amp;quot;,&amp;quot;msg&amp;quot;:{&amp;quot;mt&amp;quot;:&amp;quot;Search&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;contact&amp;quot;,&amp;quot;search&amp;quot;:&amp;quot;john doe&amp;quot;},&amp;quot;apiId&amp;quot;:&amp;quot;com.innovaphone.search&amp;quot;}&amp;lt;/code&amp;gt;&lt;br /&gt;
Search results are delivered as &#039;&#039;SearchInfo&#039;&#039; messages:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;code&amp;gt;{&amp;quot;mt&amp;quot;:&amp;quot;ApiResult&amp;quot;,&amp;quot;src&amp;quot;:&amp;quot;3&amp;quot;,&amp;quot;provider&amp;quot;:&amp;quot;@local-8125d22e37-519d-4056-bfe5-c52ef2ae8fabb0&amp;quot;,&amp;quot;consumer&amp;quot;:&amp;quot;dev:SwPh_zkl_5e42e884&amp;quot;,&amp;quot;client&amp;quot;:&amp;quot;@client-f62702dd86-be3f-47fc-b4bc-7a21627b75b2ea&amp;quot;,&amp;quot;msg&amp;quot;:{&amp;quot;mt&amp;quot;:&amp;quot;SearchInfo&amp;quot;,&amp;quot;relevance&amp;quot;:2000,&amp;quot;adjust&amp;quot;:true,&amp;quot;type&amp;quot;:&amp;quot;contact&amp;quot;,&amp;quot;contact&amp;quot;:{&amp;quot;givenname&amp;quot;:&amp;quot;John&amp;quot;,&amp;quot;sn&amp;quot;:&amp;quot;Doe&amp;quot;,&amp;quot;company&amp;quot;:&amp;quot;ACME&amp;quot;,&amp;quot;position&amp;quot;:&amp;quot;Head of everything&amp;quot;,&amp;quot;telephonenumber&amp;quot;:[&amp;quot;11111&amp;quot;,&amp;quot;22222&amp;quot;],&amp;quot;homephone&amp;quot;:[&amp;quot;+4944444&amp;quot;,&amp;quot;33333&amp;quot;],&amp;quot;mobile&amp;quot;:[&amp;quot;+49 (123) 55555&amp;quot;]}},&amp;quot;api&amp;quot;:&amp;quot;com.innovaphone.search&amp;quot;}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Reverse Lookup:&#039;&#039;&#039; The myApps platform services implement an &#039;&#039;API provider&#039;&#039; for the [http://sdk.innovaphone.com/web1/com.innovaphone.phonelookup/lib1_api_phonelookup.htm &#039;&#039;com.innovaphone.phonelookup&#039;&#039; API]. They perform search capabilities on the OS&#039; local phone books which can be used by Apps like the &#039;&#039;phoneapp&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Apps would send a &#039;&#039;Lookup&#039;&#039; request to the API: &lt;br /&gt;
&lt;br /&gt;
: &amp;lt;code&amp;gt;{&amp;quot;mt&amp;quot;:&amp;quot;ApiRequest&amp;quot;,&amp;quot;consumer&amp;quot;:&amp;quot;dev:SwPh_zkl_5e42e884&amp;quot;,&amp;quot;provider&amp;quot;:&amp;quot;*&amp;quot;,&amp;quot;src&amp;quot;:&amp;quot;4&amp;quot;,&amp;quot;msg&amp;quot;:{ mt: &amp;quot;Lookup&amp;quot;, prefixIntl: &amp;quot;000&amp;quot;, prefixNtl: &amp;quot;00&amp;quot;, prefixExt:&amp;quot;0&amp;quot;, area: &amp;quot;7031&amp;quot;, country: &amp;quot;49&amp;quot;, lookup: &amp;quot;0004970311234567&amp;quot; },&amp;quot;apiId&amp;quot;:&amp;quot;com.innovaphone.lookup&amp;quot;}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Search results are delivered as &#039;&#039;LookupInfo&#039;&#039; messages:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;code&amp;gt;{&amp;quot;mt&amp;quot;:&amp;quot;ApiResult&amp;quot;,&amp;quot;src&amp;quot;:&amp;quot;3&amp;quot;,&amp;quot;provider&amp;quot;:&amp;quot;@local-8125d22e37-519d-4056-bfe5-c52ef2ae8fabb0&amp;quot;,&amp;quot;consumer&amp;quot;:&amp;quot;dev:SwPh_zkl_5e42e884&amp;quot;,&amp;quot;client&amp;quot;:&amp;quot;@client-f62702dd86-be3f-47fc-b4bc-7a21627b75b2ea&amp;quot;,&amp;quot;msg&amp;quot;:{mt: &amp;quot;LookupInfo&amp;quot;, dn: &amp;quot;Jake Blues&amp;quot;, contact: { telephonenumber: [&amp;quot;0004970311234567&amp;quot;], givenname: &amp;quot;Jake&amp;quot;, sn: &amp;quot;Blues&amp;quot;, company: &amp;quot;Blues Brothers&amp;quot; &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Windows ====&lt;br /&gt;
On Windows, the search and lookup are performed in all of the user&#039;s Outlook contact folders.  As opposed to the search implemented in the &#039;&#039;Contacts&#039;&#039; and &#039;&#039;Users&#039;&#039; App, all items are returned which match any of the search words (i.e. searching for &#039;&#039;a b&#039;&#039; will return items matching either &#039;&#039;a&#039;&#039; or &#039;&#039;b&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
; searched properties : firstname, lastname&lt;br /&gt;
; returned properties : Following Outlook contact phone number properties are returned  (if available):&lt;br /&gt;
&lt;br /&gt;
:* OFFICE_TELEPHONE_NUMBER as &#039;&#039;telephonenumber&#039;&#039;&lt;br /&gt;
:* OFFICE2_TELEPHONE_NUMBER as &#039;&#039;telephonenumber&#039;&#039;&lt;br /&gt;
:* HOME_TELEPHONE_NUMBER as &#039;&#039;homephone&#039;&#039;&lt;br /&gt;
:* HOME2_TELEPHONE_NUMBER as &#039;&#039;homephone&#039;&#039;&lt;br /&gt;
:* MOBILE_TELEPHONE_NUMBER as &#039;&#039;mobile&#039;&#039;&lt;br /&gt;
:* BUSINESS_FAX_NUMBER as &#039;&#039;facsimiletelephonenumber&#039;&#039;&lt;br /&gt;
Note that contact information is cached in the search provider.  Updated contacts may therefore become effective after a while only.&lt;br /&gt;
Outlook search will create its own trace file &amp;lt;code&amp;gt;myAppsOutlookSearch-&amp;lt;/code&amp;gt;&#039;&#039;date-time&#039;&#039;&amp;lt;code&amp;gt;.txt&amp;lt;/code&amp;gt; in the standard trace directory.&lt;br /&gt;
&lt;br /&gt;
This search provider is always installed and can be disabled.  There is no need (nor possibility) to enable it in the &#039;&#039;Apps&#039;&#039; tab of the PBX&#039;s user object.  Also, no &#039;&#039;App&#039;&#039; object needs to be created for it.&lt;br /&gt;
&lt;br /&gt;
==== Android/iOS ====&lt;br /&gt;
The search and lookup are performed in the contacts.&lt;br /&gt;
&lt;br /&gt;
==== macOS ====&lt;br /&gt;
The search and lookup are performed in the contacts. If you wish to disable local contact lookup, go to system settings - Security &amp;amp; Privacy and disable the access to contacts for myapps.&lt;br /&gt;
&lt;br /&gt;
=== Microsoft Office integration ===&lt;br /&gt;
&lt;br /&gt;
The myApps platform services has a &#039;&#039;office presence provider&#039;&#039; that can provide the user&#039;s presence state to Office applications.  See [[{{NAMESPACE}}:Concept_myApps_Office_Integration|myApps Office Integration]] for details.&lt;br /&gt;
&lt;br /&gt;
This feature is installed by default.  However, it can be disabled using the &#039;&#039;OFFICEPRESENCE&#039;&#039; MSI Parameter.  Also, a check-mark is available in the setup dialog.&lt;br /&gt;
&lt;br /&gt;
=== Call an external application for calls ===&lt;br /&gt;
&lt;br /&gt;
Phone Apps (such as the phoneapp or softphone) can initiate the start of an external application when a new call appears (either incoming or outgoing).  The actual spawning of the application is done by the myApps platform service.  Also, the application properties (such as e.g. the executable&#039;s path) is configured in the myApps platform services (see [[#UI elements|Advanced settings]] in the &#039;&#039;UI elements&#039;&#039; section below).&lt;br /&gt;
&lt;br /&gt;
A number of arguments can be passed to the application by substituting $-variables in the &#039;&#039;Parameter&#039;&#039; field:&lt;br /&gt;
&lt;br /&gt;
; $n : phone number as dialed (called party number for outgoing calls) or received (calling party number for incoming calls)&lt;br /&gt;
&lt;br /&gt;
; $N : called or calling party number in &#039;&#039;national&#039;&#039; format (e.g. 07031730090)&lt;br /&gt;
&lt;br /&gt;
; $I : called or calling party number in &#039;&#039;international&#039;&#039; format (e.g. +497031730090)&lt;br /&gt;
&lt;br /&gt;
: note that both $N and $I only work if $n includes both subscriber number and area code (e.g. 07031730090). Otherwise they are equal to $n&lt;br /&gt;
&lt;br /&gt;
; $d : display name of peer (if known)&lt;br /&gt;
&lt;br /&gt;
; $u : URI name of the peer (if available eg with a federation call)&lt;br /&gt;
&lt;br /&gt;
; $c : conference id&lt;br /&gt;
&lt;br /&gt;
: this is a globally unique ID for this call and may be used to relate the call to the &#039;&#039;guid&#039;&#039; found in the CallInfo structure in the [http://wiki.innovaphone.com/index.php?title=Reference10:SOAP_API#CallInfo SOAP-API] and [http://sdk.innovaphone.com/doc/appwebsocket/RCC.htm RCC-API ].  Also, corresponding [[Reference10:Call Detail Record CDR PBX|CDRs]] can be related using the &#039;&#039;event&#039;&#039; tag&#039;s &#039;&#039;conf&#039;&#039; attribute.&lt;br /&gt;
The start of an external application can be requested using the &#039;&#039;com.innovaphone.externalapps&#039;&#039; API.&lt;br /&gt;
&lt;br /&gt;
Some setup examples are [[Howto:Integrate External Apps in innovaphone UC clients|shown here]].&lt;br /&gt;
&lt;br /&gt;
=== Push ===&lt;br /&gt;
&lt;br /&gt;
Mobile operating systems usually inhibit network operation of apps which run in the background or are closed by the user.  This is done in order to reduce battery consumption.  Unfortunately, this also stops such apps to maintain a registration by regularly sending &#039;&#039;keep alive&#039;&#039; messages to a server (in our case to the PBX).  As a result, myApps will be disconnected from the PBX.   When the PBX determines that there is an event for the application which needs a response, it needs to wake up the app using a dedicated channel provided by the operating system.  This mechanism is know as &#039;&#039;push&#039;&#039;. When running on iOS or Android, myApps supports &#039;&#039;push&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
For &#039;&#039;push&#039;&#039; to work, a [[{{NAMESPACE}}:PBX/Objects/Push|&#039;&#039;push object&#039;&#039;]] needs to be configured in the PBX .  Also, it needs to be enabled on the mobile phone for the myApps app.&lt;br /&gt;
This mechanism is quite similar in v12 and v13, so you can refer to [[{{NAMESPACE}}:Concept_Push_Notifications_for_iOS_and_Android|Reference14r2:Concept_Push_Notifications_for_iOS_and_Android]] for more details. &lt;br /&gt;
&lt;br /&gt;
Also, helpful hints can be found in [[Howto:Troubleshoot v13 Push with myApps for Android and iOS]].&lt;br /&gt;
&lt;br /&gt;
=== App Proxy ===&lt;br /&gt;
&lt;br /&gt;
myApps runs further &#039;&#039;Apps&#039;&#039; (such as e.g. the &#039;&#039;phoneapp&#039;&#039;) as a web page in an IFRAME of the browser myApps is running in.  The App&#039;s page code is loaded either from the PBX or from an &#039;&#039;application platform&#039;&#039; (AP).   This however would mean that the App&#039;s IFRAME would remain empty (a dead white screen) when the PBX or AP is not available. To make sure the App can start-up anyway, the myApps platform services feature the so-called &#039;&#039;App Proxy&#039;&#039;.  This is a caching proxy that caches all the App code so it is available even in case of network failure. When myApps runs in the context of the platform services, Apps are therefore not loaded from the App source directly, but from the local App proxy. &lt;br /&gt;
&lt;br /&gt;
The cached files are stored in the PCs local file system in the &amp;lt;code&amp;gt;%LOCALAPPDATA%\innovaphone\myApps\appproxy&amp;lt;/path&amp;gt;&amp;lt;/code&amp;gt;.  There is no configuration required.  However, if myApps seems to run with outdated or corrupt cached copies of the App, you can safely delete the entire directory.&lt;br /&gt;
&lt;br /&gt;
=== Auto update ===&lt;br /&gt;
&lt;br /&gt;
On Windows and on macOS, the myApps platform services can auto-update themselves to a common version.  This is controlled by the [[{{NAMESPACE}}:PBX/Config/myApps#Launcher_Software_Update | &#039;&#039;Launcher Software Update&#039;&#039;]] settings under &#039;&#039;PBX/Config/myApps&#039;&#039; in the PBX. &lt;br /&gt;
&lt;br /&gt;
When myApps is started or the user logs in or myApps needs to re-connect to the PBX, the platform services will use the [http://sdk.innovaphone.com/web1/com.innovaphone.client/lib1_api_client.htm com.innovaphone.client API] to learn the desired version (&#039;&#039;launcherUpdateBuild&#039;&#039;, which is part of the API&#039;s &#039;&#039;model&#039;&#039;). If this differs from the current version, the platform services will try to download the respective new version. &lt;br /&gt;
&lt;br /&gt;
 {&lt;br /&gt;
    &amp;quot;mt&amp;quot;: &amp;quot;ApiUpdate&amp;quot;,&lt;br /&gt;
    &amp;quot;apis&amp;quot;: {&lt;br /&gt;
        &amp;quot;com.innovaphone.client&amp;quot;: {&lt;br /&gt;
            &amp;quot;@client&amp;quot;: {&lt;br /&gt;
                &amp;quot;title&amp;quot;: &amp;quot;innovaphone myApps&amp;quot;,&lt;br /&gt;
                &amp;quot;model&amp;quot;: {&lt;br /&gt;
                    &amp;quot;launcher&amp;quot;: true,&lt;br /&gt;
                    &amp;quot;launcherUpdateBuild&amp;quot;: &amp;quot;134906&amp;quot;,&lt;br /&gt;
                    &amp;quot;appStoreUrl&amp;quot;: &amp;quot;http://store.innovaphone.com/release/download/&amp;quot;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
The installation of the downloaded version is done by the &#039;&#039;innovaphonemyAppsUpdateService&#039;&#039;. This service is installed and enabled during the initial installation of the myApps platform services.  To disable auto-update, either leave the &#039;&#039;Launcher Software Update&#039;&#039; settings empty or set the service&#039;s start mode to &#039;&#039;disabled&#039;&#039; in the Windows &#039;&#039;services control panel&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Note that on Windows the update service does not work on terminal servers. Administrators must do myApps base services updates using standard windows mechanisms.&lt;br /&gt;
&lt;br /&gt;
Note that on macOS if myApps has been installed from the Apple Store it is assumed that auto update from the PBX is not desired and disabled therefore.&lt;br /&gt;
&lt;br /&gt;
On Android/iOS/macOS updates can be downloaded from the respective app store.&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;Devices&#039;&#039; app can not update software installed on Windows PCs directly. However, when the PBX is updated using an &#039;&#039;update job&#039;&#039; in the &#039;&#039;Devices&#039;&#039; App, the &#039;&#039;Launcher Software Update&#039;&#039; settings will be updated accordingly and hence the myApps base services will ultimately also be updated to the same version.&lt;br /&gt;
&lt;br /&gt;
==== Auto update flow on Windows ====&lt;br /&gt;
&lt;br /&gt;
* On start of myApps, myApps checks if an update is available and ready for installation&lt;br /&gt;
** if yes, the update is installed directly, without user interaction (a popup is shown during the installation)&lt;br /&gt;
** if not, myApps starts&lt;br /&gt;
* if an update is available while myApps is already running, an update notification will be shown which let&#039;s the user choose to install the update now or later (the notification will then popup again after one hour)&lt;br /&gt;
&lt;br /&gt;
==UI elements ==&lt;br /&gt;
There are a few user interfaces provided by the platform services:&lt;br /&gt;
===tray-icon (Windows only) ===&lt;br /&gt;
::[[Image:myapps-tray.png|myapps-tray.png/|myapps-tray.png/]]&lt;br /&gt;
:Allows to&lt;br /&gt;
:* terminate myApps&lt;br /&gt;
:* toggle the &#039;&#039;autostart&#039;&#039; state&lt;br /&gt;
:* toggle the &#039;&#039;show in task bar&#039;&#039; state&lt;br /&gt;
:* open the trace folder&lt;br /&gt;
:&lt;br /&gt;
=== PBX connect form===&lt;br /&gt;
:: [[Image:myapps-connect.png|myapps-connect.png/|myapps-connect.png/]]&lt;br /&gt;
: Allows the user to specify the connect data for the PBX (i.e. IP address or DNS name)&lt;br /&gt;
:&lt;br /&gt;
=== Advanced settings===&lt;br /&gt;
::[[Image:myapps-settings0.png|myapps-settings0.png/|myapps-settings0.png/]]&lt;br /&gt;
::[[Image:myapps-settings.png|myapps-settings.png/|myapps-settings.png/]] [[Image:myapps-settings2.png|myapps-settings2.png/|myapps-settings2.png/]] [[Image:myapps-settings3.png|myapps-settings3.png/|myapps-settings3.png/]]&lt;br /&gt;
&lt;br /&gt;
: Allows to modify various platform dependant settings (such as e.g. the hotkey selection on Windows)&lt;br /&gt;
&lt;br /&gt;
== Interfaces ==&lt;br /&gt;
=== Provided APIs ===&lt;br /&gt;
&lt;br /&gt;
; [http://sdk.innovaphone.com/web1/com.innovaphone.search/lib1_api_search.htm com.innovaphone.search] : access to local phone book entries by the [[#Local phonebook access|Local phonebook access]] component.&lt;br /&gt;
; [http://sdk.innovaphone.com/web1/com.innovaphone.launcher/com.innovaphone.launcher.htm com.innovaphone.launcher] : display of OS specific user notifications and receipt of related user actions&lt;br /&gt;
; com.innovaphone.notificationhandler : reports back click on a notification.&lt;br /&gt;
; com.innovaphone.externalapps : to start external applications, see [[#Call an external application for calls|Call an external application for calls]]  above&lt;br /&gt;
&lt;br /&gt;
=== Used APIs ===&lt;br /&gt;
&lt;br /&gt;
; [http://sdk.innovaphone.com/web1/com.innovaphone.phone/com.innovaphone.phone.htm com.innovaphone.phone] : used to initiate new or manipulate existing calls by the [[#Hot keys|Hot keys]] and [[#URL handler|URL handler]] components.&lt;br /&gt;
&lt;br /&gt;
; [http://sdk.innovaphone.com/web1/com.innovaphone.chat/com.innovaphone.chat.htm com.innovaphone.chat] : used to start a new chat by the [[#URL handler|URL handler]] component.&lt;br /&gt;
&lt;br /&gt;
; [http://sdk.innovaphone.com/web1/com.innovaphone.client/lib1_api_client.htm com.innovaphone.client] : the model is used to learn the update settings, see [[#Auto update|Auto update]] above&lt;br /&gt;
&lt;br /&gt;
=== Protocols ===&lt;br /&gt;
&lt;br /&gt;
; [https://sdk.innovaphone.com/doc/launcher/Media.htm Media Protocol] : used by apps to allocate RTP channels, see [[#RTP service for audio.2C video and data|RTP service for audio, video and data]] above&lt;br /&gt;
&lt;br /&gt;
== Related App Services ==&lt;br /&gt;
&lt;br /&gt;
none&lt;br /&gt;
&lt;br /&gt;
== Known limitations ==&lt;br /&gt;
; Incoming call as banner on myApps for iOS : Since iOS 14 the iOS CallKit presents incoming calls as a banner leaving the original green answer button of myApps visible. Use only the blue button of the banner to accept the call or change iPhone Settings, App &amp;quot;Phone&amp;quot;, &amp;quot;Incoming Calls&amp;quot; to &amp;quot;Full Screen&amp;quot; to hide the myApps user interface again during call answering.&lt;br /&gt;
&lt;br /&gt;
; Call answer in speakerphone mode even with active Bluetooth headset on myApps for iOS : This causes unwanted speakerphone operation if the smartphone is used with a Bluetooth car audio system. The behaviour can be changed by selecting &#039;&#039;Bluetooth Headset&#039;&#039; in this setting:&lt;br /&gt;
:&#039;&#039;iOS Settings-&amp;gt;Accessibility-&amp;gt;Touch-&amp;gt;Call Audio Routing: Automatic / Bluetooth Headset / Speaker&#039;&#039;&lt;br /&gt;
:&#039;&#039;iOS Einstellungen-&amp;gt;Bedienungshilfen-&amp;gt;Tippen-&amp;gt;Anrufaudioausgabe: Automatisch / Bluetooth-Headset / Lautsprecher&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
; Windows Server 2016 (Windows 10 Build 1607) : windows just shows the first notification. Further notifications aren&#039;t displayed until the previous ones are removed from the notification center. Current windows builds do not show this behaviour anymore.&lt;br /&gt;
&lt;br /&gt;
; Problems on Mac computers with Yealink USB headsets&lt;br /&gt;
: we have received reports that myApps quits unexpectedly on some Mac computers when a Yealink headset is plugged in.  Unfortunately, we could not find out the cause yet.  If you use Yealink USB headsets and have a similar issue, please open a support ticket and send myApps traces.&lt;br /&gt;
&lt;br /&gt;
; Poly / Plantronics headset buttons only functional if myApps is started with Rosetta&lt;br /&gt;
: myApps macOS supports Apple M1/M2 hardware natively. However, the Poly / Plantronics headset SDK is only available for Intel platform and thus myApps needs to be started via Apple&#039;s Intel emulator Rosetta if a Poly / Plantronics headset is used. This is done with right-click on the myApps executable, &#039;&#039;Information&#039;&#039;, &#039;&#039;Open with Rosetta&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
; Windows surface devices may not work correctly&lt;br /&gt;
: Chromium does not get touch keyboard events. USB Keyboards may not be recognized either.&lt;br /&gt;
&lt;br /&gt;
= Installation =&lt;br /&gt;
&lt;br /&gt;
== Windows ==&lt;br /&gt;
&lt;br /&gt;
myApps platform services are installed on Windows using the .msi file found in the &#039;&#039;myApps Windows&#039;&#039; package from [https://store.innovaphone.com/release/download.htm store.innovaphone.com].&lt;br /&gt;
&lt;br /&gt;
myApps can update itself automatically, see [[#Auto update|Auto update]] above.&lt;br /&gt;
&lt;br /&gt;
=== MSI Parameters and install options ===&lt;br /&gt;
&lt;br /&gt;
The MSI installer of myApps for Windows supports the following parameters and can be edited with [https://docs.microsoft.com/en-us/windows/win32/msi/orca-exe Microsoft Orca]. You can add your parameters in the table &#039;&#039;property&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
; SERVER (REG_SZ): the PBX&#039;s server address (without protocol like https://)&lt;br /&gt;
; OFFICEPRESENCE (REG_DWORD): &#039;&#039;&#039;false&#039;&#039;&#039; to disable presence integration in Microsoft Office&lt;br /&gt;
: this is also available as a check-mark when running the install manually&lt;br /&gt;
&lt;br /&gt;
; DISABLEHEADSETS (REG_DWORD): &#039;&#039;&#039;true&#039;&#039;&#039; to disable headsets support, see [[#Device handling|Device handling]] above&lt;br /&gt;
&lt;br /&gt;
; EXTERNALAPPS (REG_SZ): pre-define external applications, see [[#Call an external application for calls|Call an external application for calls]] above&lt;br /&gt;
: e.g. &amp;lt;code&amp;gt;&amp;quot;{&amp;quot;&amp;quot;externalApps&amp;quot;&amp;quot;:[{&amp;quot;&amp;quot;id&amp;quot;&amp;quot;:0,&amp;quot;&amp;quot;name&amp;quot;&amp;quot;:&amp;quot;&amp;quot;Wireshark&amp;quot;&amp;quot;,&amp;quot;&amp;quot;path&amp;quot;&amp;quot;:&amp;quot;&amp;quot;C:\\Program Files\\Wireshark\\Wireshark.exe&amp;quot;&amp;quot;,&amp;quot;&amp;quot;param&amp;quot;&amp;quot;:&amp;quot;&amp;quot;test $I&amp;quot;&amp;quot;}]}&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; FORCERESTART (REG_DWORD): &#039;&#039;&#039;true&#039;&#039;&#039; (or any string ...) kills myApps during the installation and restarts it for the currently logged in user, if it was running&lt;br /&gt;
&lt;br /&gt;
; DISABLELOCALHOST (REG_DWORD): &#039;&#039;&#039;true&#039;&#039;&#039; to disable use of &#039;&#039;&#039;localhost&#039;&#039;&#039; string to access the local webserver. Use &#039;&#039;&#039;127.0.0.1&#039;&#039;&#039; instead&lt;br /&gt;
&lt;br /&gt;
; EXCLUDEINTERFACES (REG_SZ): some VPN interfaces are not detected by Windows as IF_TYPE_PPP or IF_TYPE_TUNNEL and therefore the &#039;&#039;&#039;media outside VPN&#039;&#039;&#039; setting is not taking effect. With this option interfaces can be pre-defined that will not be used for media. Interfaces must be comma separated&lt;br /&gt;
: e.g. &amp;lt;code&amp;gt;EXCLUDEINTERFACES=&amp;quot;172,192.168,10.10&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; FASTERDOWNLOADS (REG_DWORD): &#039;&#039;&#039;true&#039;&#039;&#039; to have faster downloads without artificially slowing down the download of an update (which is done to avoid audio lags if clients have slow networks).&lt;br /&gt;
&lt;br /&gt;
Current settings are stored in the registry at &amp;lt;code&amp;gt;Computer\HKEY_CURRENT_USER\Software\innovaphone\myApps&amp;lt;/code&amp;gt; or at &amp;lt;code&amp;gt;Computer\HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\innovaphone\myApps&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Boolean values like OfficePresence are stored in registry entries with type REG_DWORD and values 1 or 0. 0 disables the setting and 1 enables it.&lt;br /&gt;
&lt;br /&gt;
== iOS ==&lt;br /&gt;
&lt;br /&gt;
myApps platform services are installed on iOS by loading &#039;&#039;innovaphone myApps&#039;&#039; from the &#039;&#039;App Store&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Configuration via MDM ===&lt;br /&gt;
&lt;br /&gt;
the PBX&#039;s server URL can be pre-configured by specifying this dictionary in the MDM&lt;br /&gt;
 &amp;lt;plist&amp;gt;&lt;br /&gt;
   &amp;lt;dict&amp;gt;&lt;br /&gt;
     &amp;lt;key&amp;gt;server&amp;lt;/key&amp;gt;&lt;br /&gt;
     &amp;lt;string&amp;gt;pbx.example.com&amp;lt;/string&amp;gt;&lt;br /&gt;
   &amp;lt;/dict&amp;gt;&lt;br /&gt;
 &amp;lt;/plist&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== macOS ==&lt;br /&gt;
&lt;br /&gt;
myApps platform services might be installed directly from the Apple store. An installer package &amp;lt;code&amp;gt;myapps.pkg&amp;lt;/code&amp;gt; and a disk image &amp;lt;code&amp;gt;myapps.dmg&amp;lt;/code&amp;gt; is also available from the innovaphone app store. Install &amp;lt;code&amp;gt;myapps.pkg&amp;lt;/code&amp;gt; by double-click on the file and follow the instructions of the installer. myApps becomes available in the Applications folder and can be opened by double-click. Or download and open &amp;lt;code&amp;gt;myapps.dmg&amp;lt;/code&amp;gt; and double klick myApps. If desired integrate it into the app dock by right click, &#039;&#039;Options, Keep in the dock&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
If installed from the innovaphone app store, myApps can update itself automatically, see [[#Auto update|Auto update]] above.&lt;br /&gt;
&lt;br /&gt;
If installed from the Apple store, macOS notifies about updates on the Apple store. myApps [[#Auto update|Auto update]] is disabled then.&lt;br /&gt;
&lt;br /&gt;
If a clean-install of the client is necessary, the folder &amp;quot;/Users/username/Library/Containers/myapps&amp;quot; needs to be deleted. To be on the safe side also delete it from the trash bin.&lt;br /&gt;
&lt;br /&gt;
=== Configuration via MDM ===&lt;br /&gt;
&lt;br /&gt;
the PBX&#039;s server URL can be pre-configured by specifying this dictionary in the MDM&lt;br /&gt;
 &amp;lt;plist&amp;gt;&lt;br /&gt;
   &amp;lt;dict&amp;gt;&lt;br /&gt;
     &amp;lt;key&amp;gt;server&amp;lt;/key&amp;gt;&lt;br /&gt;
     &amp;lt;string&amp;gt;pbx.example.com&amp;lt;/string&amp;gt;&lt;br /&gt;
   &amp;lt;/dict&amp;gt;&lt;br /&gt;
 &amp;lt;/plist&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Preferences ===&lt;br /&gt;
&lt;br /&gt;
macOS supports preference settings that can be set via a shell command or via Mac remote management&lt;br /&gt;
&lt;br /&gt;
 defaults write com.innovaphone.client-ios-14r1 server &amp;quot;PBX-server-URL&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The following parameters and can be set through this method:&lt;br /&gt;
&lt;br /&gt;
; server: the PBX&#039;s server URL&lt;br /&gt;
&lt;br /&gt;
=== Setting myApps as Default App for SIP-URLs ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|defaults write com.apple.LaunchServices/com.apple.launchservices.secure LSHandlers -array-add &#039;{&lt;br /&gt;
   LSHandlerURLScheme = sip;&lt;br /&gt;
   LSHandlerRoleAll = &amp;quot;&amp;lt;CFBundleIdentifier&amp;gt;&amp;quot;;&lt;br /&gt;
}&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
To find the “CFBundleIdentifier”, proceed as follows:&lt;br /&gt;
* In the Finder under “Applications”, search for the desired myApps client that you want to set as the default app.&lt;br /&gt;
* Right-click on “Show package contents” -&amp;gt; you will find the “CFBundleIdentifier” in the Info.plist file.&lt;br /&gt;
&lt;br /&gt;
A restart of the MAC is required.&lt;br /&gt;
&lt;br /&gt;
=== Using Sennheiser headsets ===&lt;br /&gt;
If you use Sennheiser headsets, you should also install the then-current &amp;lt;code&amp;gt;DSEA_SDK_v&amp;lt;/code&amp;gt;&#039;&#039;version&#039;&#039;&amp;lt;code&amp;gt;.pkg&amp;lt;/code&amp;gt; package, after you installed the myApps client.  Without that, audio will still work, but not the controls on the headset.  You will need to keep that up-to-date yourself, as it is not updated by myApps&#039;s auto-update function.&lt;br /&gt;
&lt;br /&gt;
== Android ==&lt;br /&gt;
&lt;br /&gt;
myApps platform services are installed on Android by loading &#039;&#039;innovaphone myApps&#039;&#039; from the &#039;&#039;Play Store&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Configuration via MDM ===&lt;br /&gt;
&lt;br /&gt;
the PBX&#039;s server URL can be pre-configured by specifying a property &amp;quot;server&amp;quot; with string value &amp;quot;pbx.example.com&amp;quot; in the MDM.&lt;br /&gt;
&lt;br /&gt;
= Configuration =&lt;br /&gt;
&lt;br /&gt;
== Server configuration ==&lt;br /&gt;
When opening myApps for the first time, the user is prompted for the Server. Usually only the hostname (DNS host name or IP address) needs to be configured.&lt;br /&gt;
&lt;br /&gt;
But there are more options for special PBX configurations.&lt;br /&gt;
&lt;br /&gt;
; Non-standard HTTPS port&lt;br /&gt;
: If the PBX uses a non-standard HTTPS port, it must be appended to the host name separated by a colon (&amp;lt;code&amp;gt;:&amp;lt;/code&amp;gt;).&lt;br /&gt;
: Example: &amp;lt;code&amp;gt;pbx.example.com:4444&amp;lt;/code&amp;gt; (expands to &amp;lt;code&amp;gt;https://pbx.example.com:4444/PBX0/APPCLIENT/appclient.htm&amp;lt;/code&amp;gt;)&lt;br /&gt;
; DynPBX module name&lt;br /&gt;
: If the PBX is a DynPBX, the module id must be appended to PBX0 separated - (&amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt;).&lt;br /&gt;
: Example: &amp;lt;code&amp;gt;pbx.example.com/PBX0-1&amp;lt;/code&amp;gt; (expands to &amp;lt;code&amp;gt;https://pbx.example.com/PBX0-1/APPCLIENT/appclient.htm&amp;lt;/code&amp;gt;)&lt;br /&gt;
; Softphone physical location&lt;br /&gt;
: If user defined physical location shall be used for softphone, you can append it using a parameter &amp;lt;code&amp;gt;#phys=&amp;lt;/code&amp;gt;.&lt;br /&gt;
: Example: &amp;lt;code&amp;gt;pbx.example.com#phys=slave&amp;lt;/code&amp;gt; (expands to &amp;lt;code&amp;gt;https://pbx.example.com/PBX0/APPCLIENT/appclient.htm#phys=slave&amp;lt;/code&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Example 1: PBX pbx.example.com with standard configuration&lt;br /&gt;
 pbx.example.com&lt;br /&gt;
&lt;br /&gt;
Example 2: PBX slave.example with DynPBX module ID 1, HTTPS port 4444 and physical location master&lt;br /&gt;
 slave.example.com:4444/PBX0-1#phys=master&lt;br /&gt;
&lt;br /&gt;
=== HTTP proxy support ===&lt;br /&gt;
&lt;br /&gt;
myApps platform services do support operation via HTTP proxy now. If one or more proxies have been configured in the network settings of the operating system for the active network connection, HTTP CONNECT tunnels are established.&lt;br /&gt;
&lt;br /&gt;
On Windows user name and password can be specified for the tunnel servers as generic credentials in the credentials manager (Anmeldeinformationsverwaltung). The name of the credentials must be the tunnel server hostname.&lt;br /&gt;
&lt;br /&gt;
On Android user name and password can be specified through Android &#039;&#039;Settings, Accounts&#039;&#039; by adding a myApps &#039;&#039;HTTP Proxy Credentials&#039;&#039; account. The name of the account must be the tunnel server hostname.&lt;br /&gt;
&lt;br /&gt;
== Platform specific settings ==&lt;br /&gt;
When myApps runs under the myApps platform services, it will show various platform specific settings as part of its &#039;&#039;burger menu&#039;&#039;, so the user can set them.  See &#039;&#039;Advanced settings&#039;&#039; in [[#UI elements|UI elements]] above.&lt;br /&gt;
&lt;br /&gt;
Some options can also be set globally for all myApps clients in the PBX&#039;s [[{{NAMESPACE}}:PBX/Config/myApps#Client_Settings|PBX/Config/myApps &#039;&#039;Client Settings&#039;&#039;]]&lt;br /&gt;
{|&lt;br /&gt;
! style=&amp;quot;text-align: left; font-weight: bold&amp;quot; | Option&lt;br /&gt;
&lt;br /&gt;
! style=&amp;quot;text-align: left; font-weight: bold&amp;quot; | Description&lt;br /&gt;
&lt;br /&gt;
! style=&amp;quot;text-align: left; font-weight: bold&amp;quot; | Where to set&lt;br /&gt;
&lt;br /&gt;
!&lt;br /&gt;
! style=&amp;quot;text-align: left; font-weight: bold&amp;quot;| Availability&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| || || User menu || PBX &#039;&#039;Client Settings&#039;&#039; || Windows || iOS || Android || macOS&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| Autostart || Launch myApps on login || &amp;amp;#10004; ||&amp;amp;#10004; ||&amp;amp;#10004; || &amp;amp;#10007; || &amp;amp;#10007; || &amp;amp;#10004;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| Appear offline after || controls after which idle time a user is considered &#039;&#039;inactive&#039;&#039;. See [[#User activity|User activity]] above || &amp;amp;#10004; ||&amp;amp;#10004; ||&amp;amp;#10004; || &amp;amp;#10007; || &amp;amp;#10007; || &amp;amp;#10004;&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| Hotkeys || Hotkeys for call dial, accept, reject. See [[#Hot keys|Hot keys]] above || &amp;amp;#10004; ||&amp;amp;#10004; ||&amp;amp;#10004; || &amp;amp;#10007; || &amp;amp;#10007; || &amp;amp;#10004;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| Docking || Docking mode (left, right, none). See [[#???|??]] above || &amp;amp;#10004; ||&amp;amp;#10004; ||&amp;amp;#10004; || &amp;amp;#10007; || &amp;amp;#10007; || &amp;amp;#10007;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| Desktop notifications|| Turn on/off platform notifications. See [[#Notifications|  Notifications]] above || &amp;amp;#10004; ||&amp;amp;#10004; ||&amp;amp;#10004; || &amp;amp;#10007; || &amp;amp;#10007; || &amp;amp;#10004;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| VPN || Disable VPN address for ICE candidate selection. See [[#RTP ports| RTP ports]] above || &amp;amp;#10004; ||&amp;amp;#10004; ||&amp;amp;#10004; || &amp;amp;#10007; || &amp;amp;#10004; || &amp;amp;#10004;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| Show in taskbar|| Show myApps in the taskbar in addition to it&#039;s tray icon.  || &amp;amp;#10004; ||&amp;amp;#10007; ||&amp;amp;#10004; || &amp;amp;#10007; || &amp;amp;#10007; || &amp;amp;#10007;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| Log flags || turn on/off certain trace levels. See [[#Troubleshooting|Troubleshooting]] below.  || &amp;amp;#10004; ||&amp;amp;#10004; ||&amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| External applications || define the applications available for Apps to be started. See [[#Call an external application for calls|Call an external application for calls]] above.  || &amp;amp;#10004; ||&amp;amp;#10007; ||&amp;amp;#10004; || &amp;amp;#10007; || &amp;amp;#10007; || &amp;amp;#10004;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| Ring in headset || send ring tone for incoming to headset instead of loudspeaker.  || &amp;amp;#10004; ||&amp;amp;#10007; ||&amp;amp;#10004; || &amp;amp;#10007; || &amp;amp;#10007; || &amp;amp;#10007;&lt;br /&gt;
|}&lt;br /&gt;
== Start parameters for Windows ==&lt;br /&gt;
&lt;br /&gt;
On Windows, it is not possible to pass start parameters from the [https://www.chromium.org/developers Chromium documentation] to the myApps process.&lt;br /&gt;
&lt;br /&gt;
== OS Settings for Windows ==&lt;br /&gt;
Windows settings can influence the display of &#039;&#039;Desktop notifications&#039;&#039;. See [https://support.microsoft.com/en-us/help/4028678/windows-10-change-notification-settings Change notification settings in Windows 10/11] for details.&lt;br /&gt;
&lt;br /&gt;
=== Windows 11 ===&lt;br /&gt;
&lt;br /&gt;
* Windows 11 has a feature &amp;quot;do not disturb&amp;quot;. This hides notifications if enabled.&lt;br /&gt;
* Windows 11 has a feature &amp;quot;focus&amp;quot;. This enables &amp;quot;do not disturb&amp;quot; and thus hides notifications too.&lt;br /&gt;
* Windows 11 has priority settings for notifications. Ensure that VoIP notifications for calls are allowed any maybe also include myApps as an App which is allowed to show notifications.&lt;br /&gt;
&lt;br /&gt;
== OS settings for Android ==&lt;br /&gt;
; Events : The appearance of notifications can be controlled here.&lt;br /&gt;
&lt;br /&gt;
; Call accounts : For proper incoming call signaling, the call account &#039;&#039;myApps&#039;&#039; needs to be enabled. Note that on Samsung smartphones the call account switch likely toggles back and a few tries may need to be done until it persists. Please double-check the state.&lt;br /&gt;
&lt;br /&gt;
; Preferred Calling Account : Choose which calling account (myApps/SIM/..) should be used for outgoing calls initiated from within the native phone app / phone book.&lt;br /&gt;
&lt;br /&gt;
; Background data, unlimited data usage : Grant background data use to enable &#039;&#039;myApps&#039;&#039; to connect to the PBX immediately on an incoming call.&lt;br /&gt;
&lt;br /&gt;
; Overlaying : This setting is not needed if call account &#039;&#039;myApps&#039;&#039; has been enabled. Should there be a reason for not enabling call account &#039;&#039;myApps&#039;&#039;, the permission for overlaying needs to be granted on Android 10 or higher for proper call signaling.&lt;br /&gt;
&lt;br /&gt;
Note: If no SIM card is installed some Android smartphones exhibit a problem dialing from the smartphone contacts. The contacts app shows a choice &#039;&#039;Select SIM card for this call&#039;&#039; but all possible dialers are greyed out. In this case make myApps the default phone app in Android settings &#039;&#039;Apps, Default apps, Telephony&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== OS settings for iOS ==&lt;br /&gt;
; Notifications : The appearance of notifications can be controlled in iOS &#039;&#039;Settings, myApps&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== OS settings for macOS ==&lt;br /&gt;
&lt;br /&gt;
; Notifications : The appearance of notifications can be controlled in macOS &#039;&#039;Preferences, Notifications, myApps&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=Troubleshooting=&lt;br /&gt;
&lt;br /&gt;
myApps platform services can write various traces for debugging.  Trace can be turned on and off selectively in the [[#Advanced settings|Advanced settings]].&lt;br /&gt;
&lt;br /&gt;
The following trace flags can be set:&lt;br /&gt;
&lt;br /&gt;
(&#039;&#039;Recommended trace options are: &#039;&#039;&#039;App, Browser, ICE, TURN, Signaling and Audio&#039;&#039;&#039;. Please do not activate other flags unless innovaphone support says otherwise&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
!style=&amp;quot;text-align: left; font-weight: bold&amp;quot; |  Abbreviation&lt;br /&gt;
&lt;br /&gt;
!style=&amp;quot;text-align: left; font-weight: bold&amp;quot; |code&lt;br /&gt;
&lt;br /&gt;
!style=&amp;quot;text-align: left; font-weight: bold&amp;quot; | description&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| App||0x000000001|| logs from the App Service itself&lt;br /&gt;
|-&lt;br /&gt;
| DNS||0x000000008|| logs DNS requests and results&lt;br /&gt;
|-&lt;br /&gt;
| HTTP client||0x000000080|| http client logs&lt;br /&gt;
|-&lt;br /&gt;
| TLS||0x000000400|| TLS logs&lt;br /&gt;
|-&lt;br /&gt;
| TCP||0x000000800|| TCP logs&lt;br /&gt;
|-&lt;br /&gt;
| LDS||0x000001000|| local domain sockets&lt;br /&gt;
|-&lt;br /&gt;
| WebSocket client||0x000004000|| logs outgoing websocket connections&lt;br /&gt;
|-&lt;br /&gt;
| App WebSocket||0x000008000|| logs app websocket connections (e.g. from PBX objects to an App Service or from the UI to the App Service)&lt;br /&gt;
|-&lt;br /&gt;
| UDP||0x000200000|| UDP logs&lt;br /&gt;
|-&lt;br /&gt;
| DTLS||0x000400000|| logs DTLS handshake and messages&lt;br /&gt;
|-&lt;br /&gt;
| Media||0x000800000|| logs media events&lt;br /&gt;
|-&lt;br /&gt;
| Media channel||0x001000000|| logs RTP/SCTP media connections&lt;br /&gt;
|-&lt;br /&gt;
| ICE||0x002000000|| logs ICE messages between peers&lt;br /&gt;
|-&lt;br /&gt;
| TURN||0x004000000|| logs TURN messages between peers&lt;br /&gt;
|-&lt;br /&gt;
| AppSharing||0x008000000|| logs AppSharing connection&lt;br /&gt;
|-&lt;br /&gt;
| Audio||0x010000000|| logs Audio connection and headset events&lt;br /&gt;
|-&lt;br /&gt;
| Video||0x020000000|| logs video connection and webcam events&lt;br /&gt;
|-&lt;br /&gt;
| Browser||0x040000000|| logs Chromium events&lt;br /&gt;
|-&lt;br /&gt;
| AppProxy||0x080000000|| logs requests which are proxied between the local webserver and the remote server&lt;br /&gt;
|-&lt;br /&gt;
| Webserver ||0x200000000|| enables webserver specific logs&lt;br /&gt;
|-&lt;br /&gt;
| Browser Console ||0x400000000|| logs browser console events&lt;br /&gt;
|-&lt;br /&gt;
| Signaling||0x800000000|| enables logs in the signaling module for debugging calls&lt;br /&gt;
|}&lt;br /&gt;
&#039;&#039;code&#039;&#039; can be or&#039;ed and used as value for the &#039;&#039;Log flags&#039;&#039; field in [[{{NAMESPACE}}:PBX/Config/myApps#Client_Settings|PBX/Config/myApps/Client Settings]].&lt;br /&gt;
&lt;br /&gt;
; Windows :On Windows, traces are written to the &amp;lt;code&amp;gt;%LOCALAPPDATA%\innovaphone\myApps&amp;lt;/code&amp;gt; directory. If you start myApps with --log-size as parameter, you can define the maximum size of a log file (e.g. --log-size=100000000 would be 100MB for each file)&lt;br /&gt;
&lt;br /&gt;
:* myApps-&#039;&#039;date-time&#039;&#039;.txt : main log file for the platform services&lt;br /&gt;
&lt;br /&gt;
:* myAppsOutlookSearch-&#039;&#039;date-time&#039;&#039;.txt : log file for the Outlook phone book access&lt;br /&gt;
&lt;br /&gt;
:* myAppsHookController-&#039;&#039;date-time&#039;&#039;.txt : log file for the hot-key interceptor (see [[#Hot keys|Hot keys]])&lt;br /&gt;
&lt;br /&gt;
; :myApps update installation traces are written to the &amp;lt;code&amp;gt;%windir%\temp\&amp;lt;/code&amp;gt; directory.&lt;br /&gt;
:* myAppsInstall.txt: MSI installation file&lt;br /&gt;
&lt;br /&gt;
; :myApps update service traces are written to the &amp;lt;code&amp;gt;%ProgramData%\innovaphone\myAppsUpdateService&amp;lt;/code&amp;gt; directory.&lt;br /&gt;
:* myAppsUpdateService-&#039;&#039;date-time&#039;&#039;.txt: myApps update service traces&lt;br /&gt;
&lt;br /&gt;
;Android : traces can be sent by e-mail.&lt;br /&gt;
&lt;br /&gt;
: also, an Android device might also be connected to a PC via an USB cable to get the traces. The files can be found in &amp;lt;code&amp;gt;Android/data/com.innovaphone.clientandroid/files&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; iOS : traces can be sent by e-mail.&lt;br /&gt;
&lt;br /&gt;
; macOS : traces can be sent by e-mail.&lt;br /&gt;
&lt;br /&gt;
: also, the files can be found in &amp;lt;code&amp;gt;~/Library/Containers/com.innovaphone.client-ios/Data/Documents/&amp;lt;/code&amp;gt;. Press &#039;&#039;Alt+N&#039;&#039; followed by space to get tilde &#039;&#039;~&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
= Known Problems =&lt;br /&gt;
[[:Category:Problem myApps platform services|Known Problems]]&lt;br /&gt;
&lt;br /&gt;
= Related Articles =&lt;br /&gt;
* [[{{NAMESPACE}}:Concept_myApps]]&lt;br /&gt;
* [[{{NAMESPACE}}:Concept_myApps_Redundancy|Reference14r2:Concept_myApps_Redundancy]]&lt;br /&gt;
* [[{{NAMESPACE}}:Concept_myApps_Office_Integration|Reference14r2:Concept_myApps_Office_Integration]]&lt;br /&gt;
* [[{{NAMESPACE}}:Concept_myAPPs_Search_in_local-Outlook_Contacts|Reference14r2:Concept_myAPPs_Search_in_local-Outlook_Contacts]]&lt;br /&gt;
* [[{{NAMESPACE}}:Call_Detail_Record_CDR_PBX|Reference14r2:Call_Detail_Record_CDR_PBX]]&lt;br /&gt;
* [[{{NAMESPACE}}:Concept Push Notifications for myPBX iOS and Android|Reference14r2:Concept Push Notifications for myPBX iOS and Android]]&lt;br /&gt;
* [[Howto:Troubleshoot v13 Push with myApps for Android and iOS]]&lt;br /&gt;
* [[{{NAMESPACE}}:PBX/Config/myApps]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Concept myApps platform services]]&lt;/div&gt;</summary>
		<author><name>Tfu</name></author>
	</entry>
	<entry>
		<id>https://wiki.innovaphone.com/index.php?title=Reference14r2:Concept_myApps_platform_services&amp;diff=79524</id>
		<title>Reference14r2:Concept myApps platform services</title>
		<link rel="alternate" type="text/html" href="https://wiki.innovaphone.com/index.php?title=Reference14r2:Concept_myApps_platform_services&amp;diff=79524"/>
		<updated>2026-04-21T09:01:47Z</updated>

		<summary type="html">&lt;p&gt;Tfu: /* Device handling */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Concept|myApps]]&lt;br /&gt;
&lt;br /&gt;
myApps platform services provide various operating system specific services which can be used by other &#039;&#039;Apps&#039;&#039; running in the [[{{NAMESPACE}}:Concept myApps|myApps client]]. Those services typically are not available in the browser&#039;s JavaScript environment and hence must be implemented in native platform code. Therefore, the platform services are installed as native executable on the respective platform.&lt;br /&gt;
&lt;br /&gt;
When myApps is started in a web browser (and hence has no access to the platform services), some Apps will use [https://en.wikipedia.org/wiki/WebRTC WebRTC] services implemented by the browser instead.  For ease of reference, features available in this scenario are also described here.&lt;br /&gt;
&lt;br /&gt;
On windows, the platform services also come with their own web browser in which the myApps web App will be started then.  This browser is based on google&#039;s [https://en.wikipedia.org/wiki/Chromium_(web_browser) Chromium] open source software.&lt;br /&gt;
= Applies To =&lt;br /&gt;
&lt;br /&gt;
* [[{{NAMESPACE}}:Concept myApps|myApps]]&lt;br /&gt;
* myApps for Windows&lt;br /&gt;
* myApps for macOS&lt;br /&gt;
* myApps for iOS&lt;br /&gt;
* myApps for Android&lt;br /&gt;
&lt;br /&gt;
* myApps Web App (WebRTC)&lt;br /&gt;
version 14r2&lt;br /&gt;
&lt;br /&gt;
=Features=&lt;br /&gt;
Not all features are available or required on all platforms.&lt;br /&gt;
 {|&lt;br /&gt;
! style=&amp;quot;text-align: left; font-weight: bold&amp;quot; | Feature&lt;br /&gt;
&lt;br /&gt;
! style=&amp;quot;text-align: left; font-weight: bold&amp;quot; | Description&lt;br /&gt;
&lt;br /&gt;
! style=&amp;quot;text-align: left; font-weight: bold&amp;quot;| Availability&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| || || Windows || iOS || Android || macOS || Browser&amp;lt;ref&amp;gt;This refers to the myApps web application running in a browser with no platform services available&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| audio || manage local audio devices to record and playback audio conversations || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; (audio available but devices managed by web browser)&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| video || manage local displays and cameras to capture and render video live stream || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; (video available but devices managed by web browser)&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| ringer || manage local ringing device || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004;&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| application sharing&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| &amp;amp;nbsp; presenter || share an application || &amp;amp;#10004; || &amp;amp;#10007; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004;&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| &amp;amp;nbsp; consumer  || view an application shared by the peer || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| hot keys || capture key presses for quick invocation of phone apps (e.g. dial selected number) || &amp;amp;#10004; || &amp;amp;#10007; || &amp;amp;#10007; || &amp;amp;#10004; || &amp;amp;#10007;&lt;br /&gt;
|-&lt;br /&gt;
| tel: and sip: URI handler || intercept clicks on tel: and sip: links in web sites to invoke phone apps || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10007;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| user activity || set presence state according to user activity ||  &amp;amp;#10004; || &amp;amp;#10007; || &amp;amp;#10007; || &amp;amp;#10004; || &amp;amp;#10004;&amp;lt;ref&amp;gt;limited, see [[#User activity|User activity]] below&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| docking || myApps can be docked persistently to the right or left edge of your screens ||  &amp;amp;#10004;  || &amp;amp;#10007; || &amp;amp;#10007; || &amp;amp;#10007; || &amp;amp;#10007;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| multi-windowing|| Apps can be launched in separate windows||  &amp;amp;#10004;  || &amp;amp;#10007; || &amp;amp;#10007; || &amp;amp;#10004; || &amp;amp;#10007;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| recording|| Calls can be recorded to recording app||  &amp;amp;#10004;  || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10007;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| notifications || ||&lt;br /&gt;
|-&lt;br /&gt;
| &amp;amp;nbsp; display notifications || display notifications with OS standard mechanism ||  &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;amp;nbsp; push notifications || receive push notifications while myApps is not running  ||  &amp;amp;#10007; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004;&amp;lt;ref&amp;gt;The browser needs to be running in order to receive push notifications.&amp;lt;/ref&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;amp;nbsp; chat and apps || display notifications for chat and other apps  ||  &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;amp;nbsp; calls || display notifications for incoming calls  ||  &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10007;&amp;lt;ref&amp;gt;Call notifications are only displayed locally while the phone or softphone app is started.&amp;lt;/ref&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| phone book access || access local phone book ||  &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10007;&lt;br /&gt;
|-&lt;br /&gt;
| office presence provider || maps PBX presence state to Microsoft office presence state ||  &amp;amp;#10004;  || &amp;amp;#10007; || &amp;amp;#10007; || &amp;amp;#10007; || &amp;amp;#10007;&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| external application start || start arbitrary external applications for calls || &amp;amp;#10004; || &amp;amp;#10007; || &amp;amp;#10007; || &amp;amp;#10004; || &amp;amp;#10007;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| app proxy|| a caching proxy that provides app persistence  || &amp;amp;#10004;  || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10007;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| auto update || automatically updates myApps platform services to the same version the PBX has || &amp;amp;#10004;  || &amp;amp;#10004; || &amp;amp;#10007; || &amp;amp;#10004; || &amp;amp;#10004;&amp;lt;ref&amp;gt;The then-current web app is always loaded from the PBX upon startup and hence up-to-date by definition&amp;lt;/ref&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| three party conference || initiate 3-pty-conference using Softphone-App || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10007;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| exclude VPN || disable use of VPN connections for audio/video/appsharing || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10007;&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Requirements=&lt;br /&gt;
* innovaphone PBX 14r2 and up&lt;br /&gt;
&lt;br /&gt;
== Hardware ==&lt;br /&gt;
Recommended hardware requirements&lt;br /&gt;
* Processor: Dual-core 2Ghz or higher&lt;br /&gt;
* RAM: 4 Gb&lt;br /&gt;
&lt;br /&gt;
== myApps for Windows ==&lt;br /&gt;
* Windows 10 and up&lt;br /&gt;
* Windows Server 2016 and later versions&lt;br /&gt;
&lt;br /&gt;
=== 32 &amp;amp; 64 bit Windows ===&lt;br /&gt;
* 32 bit Windows: install the myAppsSetup32.msi from the App Store&lt;br /&gt;
* 64 bit Windows: install the myAppsSetup.msi from the App Store&lt;br /&gt;
** the 64 bit variant still installs into Program Files (x86), as the main myApps.exe is still a 32bit application&lt;br /&gt;
** the 64 bit variant just contains an additional 64 bit binary for the outlook search&lt;br /&gt;
&lt;br /&gt;
=== Windows N editions ===&lt;br /&gt;
&lt;br /&gt;
Windows N editions are missing the &#039;&#039;Media Feature Pack&#039;&#039; which is pre installed on other Windows versions.&lt;br /&gt;
&lt;br /&gt;
Please install the pack from [https://www.microsoft.com/en-us/software-download/mediafeaturepack Microsoft (Windows 10 pack)] before you install myApps. The installer will check if the file &amp;lt;code&amp;gt;C:\Windows\SysWOW64\mfplat.dll&amp;lt;/code&amp;gt; exist on your system.&lt;br /&gt;
&lt;br /&gt;
Make sure to install the correct pack depending on your Windows version! There are different packs for Windows 10 1703, 1803, 1809 and 32bit or 64bit etc.&lt;br /&gt;
&lt;br /&gt;
NB: Sometimes the myApps installation will not work even though the media pack is already installed. This is because the installer has no read access to check if the package is already installed. If the above-mentioned file exists and the installer asks to install the Windows Media Feature Pack nevertheless, you have to start the myApps install with administrative rights.&lt;br /&gt;
&lt;br /&gt;
=== Terminal Server environments ===&lt;br /&gt;
&lt;br /&gt;
Audio driver was removed if myApps discovers that it is running in a terminal server environment like Citrix.&lt;br /&gt;
&lt;br /&gt;
The audio driver is needed for the Softphone App but the Softphone App should not use an audio driver at the server side because the audio devices are plugged locally and there would be a delay sending and receiving audio data with the server.&lt;br /&gt;
&lt;br /&gt;
If a customer wants to use the Softphone App at the server side he needs to make use of the myApps Plugin for virtual desktops solution:&lt;br /&gt;
&lt;br /&gt;
[[{{NAMESPACE}}:MyApps_Plugin_for_Virtual_Desktops]]&lt;br /&gt;
&lt;br /&gt;
== myApps for macOS ==&lt;br /&gt;
* macOS 10.13 or higher&lt;br /&gt;
&lt;br /&gt;
== myApps for iOS ==&lt;br /&gt;
* iOS 13 or higher&lt;br /&gt;
&lt;br /&gt;
== myApps for Android ==&lt;br /&gt;
* Android 6.0 or higher. Android 6.x may need an update of the Chrome browser.&lt;br /&gt;
&lt;br /&gt;
= Licenses =&lt;br /&gt;
* No license needed for myApps platform services&lt;br /&gt;
&lt;br /&gt;
= Overview =&lt;br /&gt;
myApps platform services is a native executable that is installed using the standard mechanisms on the respective operating system. It provides various advanced services which can be used by the myApps web client code as well as the Apps running in the myApps context. &lt;br /&gt;
&lt;br /&gt;
Also, on Windows, the platform services come with their own, dedicated browser to run myApps in.  This browser is based on [https://en.wikipedia.org/wiki/Chromium_(web_browser) Chromium].  On iOS, macOS and Android, it is based upon native embedded web view facilities (such as WKWebView) instead.&lt;br /&gt;
== Components ==&lt;br /&gt;
&lt;br /&gt;
=== RTP service for audio, video and data ===&lt;br /&gt;
The RTP service provides audio, video and data (app sharing) VoIP RTP endpoints (e.g. for softphones).  It supports STUN, TURN, ICE, SRTP, DTLS. Note however that unlike WebRTC, these endpoints do not &#039;&#039;require&#039;&#039; ICE and DTLS. In other words, they can communicate also with non-compliant (i.e. older) VoIP devices.&lt;br /&gt;
&lt;br /&gt;
Note that the available capabilities when not running the myApps platform services depend on the used browser&#039;s WebRTC implementation. See your browser documentation for details.&lt;br /&gt;
&lt;br /&gt;
Apps can request RTP channels using the [https://sdk.innovaphone.com/doc/launcher/Media.htm Media Protocol]&#039;s &#039;&#039;AllocChannel&#039;&#039; message.&lt;br /&gt;
&lt;br /&gt;
===== RTP ports=====&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|  audio || 50000 -&amp;gt; 50099&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| video || 50100 -&amp;gt; 50199&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| data || 50200 -&amp;gt; 50299&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The RTP service will enumerate all local interfaces and create local HOST candidates for ICE.  There is an option however to disregard VPN interfaces (more precisely such interfaces with type of &#039;&#039;IF_TYPE_PPP&#039;&#039; or &#039;&#039;IF_TYPE_TUNNEL&#039;&#039;).  This can eliminate quality issues when RTP data is transmitted through TCP based VPN tunnels.&lt;br /&gt;
&lt;br /&gt;
SRFLX and RELAY candidates are obtained using the STUN and TURN server configuration passed by the App (e.g the &#039;&#039;softphone&#039;&#039; App) as part of the &#039;&#039;AllocChannel&#039;&#039; request.&lt;br /&gt;
&amp;lt;code&amp;gt;{&amp;quot;mt&amp;quot;:&amp;quot;AllocChannel&amp;quot;,&amp;quot;channel&amp;quot;:&amp;quot;81429cba-396d-43de-8a76-ec020ba8796e&amp;quot;,&amp;quot;iceServers&amp;quot;:[{&amp;quot;urls&amp;quot;:&amp;quot;turn:myturn.domaincom:4077?transport=udp&amp;quot;,&amp;quot;username&amp;quot;:&amp;quot;turnuser&amp;quot;,&amp;quot;credential&amp;quot;:&amp;quot;pwd&amp;quot;,&amp;quot;credentialType&amp;quot;:&amp;quot;password&amp;quot;},{&amp;quot;urls&amp;quot;:&amp;quot;stun:mystun.domain.com:4077&amp;quot;}],&amp;quot;dn&amp;quot;:&amp;quot;Foo Bar&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;RemoteRtp&amp;quot;,&amp;quot;kind&amp;quot;:&amp;quot;video&amp;quot;}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Codecs =====&lt;br /&gt;
&lt;br /&gt;
The installed myApps launchers provide codecs that can be used by softphone apps for media streams. When running in a web browser the codecs depend on the browser version and operating system. See the documentation of your browser for details.&lt;br /&gt;
&lt;br /&gt;
The following codecs are supported:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
!style=&amp;quot;text-align:left;width:100px;&amp;quot;|Codec&lt;br /&gt;
!style=&amp;quot;width:100px&amp;quot;|Windows-Launcher&lt;br /&gt;
!style=&amp;quot;width:100px&amp;quot;|Android&lt;br /&gt;
!style=&amp;quot;width:100px&amp;quot;|iOS&lt;br /&gt;
!style=&amp;quot;width:100px&amp;quot;|macOS&lt;br /&gt;
!style=&amp;quot;width:100px&amp;quot;|Firefox (Browser)&lt;br /&gt;
!style=&amp;quot;width:100px&amp;quot;|Chrome (Browser)&lt;br /&gt;
!style=&amp;quot;width:100px&amp;quot;|Edge (Browser)&lt;br /&gt;
!style=&amp;quot;width:100px&amp;quot;|Safari (Browser)&lt;br /&gt;
!style=&amp;quot;width:100px&amp;quot;|Opera (Browser)&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:left; background-color:lightgray&amp;quot; colspan=&amp;quot;10&amp;quot;|Audio&lt;br /&gt;
|-&lt;br /&gt;
|G711A&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|-&lt;br /&gt;
|G711u&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|-&lt;br /&gt;
|G722&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|-&lt;br /&gt;
|G729&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|-&lt;br /&gt;
|G729A&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|-&lt;br /&gt;
|G729B&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|-&lt;br /&gt;
|G729AB&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|-&lt;br /&gt;
|[https://caniuse.com/#search=Opus OPUS-NB]&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|-&lt;br /&gt;
|[https://caniuse.com/#search=Opus OPUS-WB]&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:left; background-color:lightgray&amp;quot; colspan=&amp;quot;10&amp;quot;|Video&lt;br /&gt;
|-&lt;br /&gt;
|[https://caniuse.com/#search=VP8 VP8]&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
|[https://caniuse.com/#search=VP9 VP9]&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔**&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔**&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔**&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔**&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔**&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔**&lt;br /&gt;
|-&lt;br /&gt;
|[https://caniuse.com/#search=H264 H264]&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔**&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:left; background-color:lightgray&amp;quot; colspan=&amp;quot;10&amp;quot;|Application Sharing&lt;br /&gt;
|-&lt;br /&gt;
|Share&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|-&lt;br /&gt;
|Watch&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔*&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔*&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X&lt;br /&gt;
|style=&amp;quot;color:green;text-align:center&amp;quot;|✔&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;* small presentation only&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;** only for 1:1 calls, not for conferences&lt;br /&gt;
&lt;br /&gt;
===== Video capture =====&lt;br /&gt;
&lt;br /&gt;
The default resolution for video capture is 1280x720 if available.  Otherwise, 640x480, 352x288 or 320x240 will be used.  The frame rate is 30 fps if available, otherwise 15 fps. The resulting average bandwidth could reach 1 Mbps.&lt;br /&gt;
&lt;br /&gt;
===== Application sharing =====&lt;br /&gt;
&lt;br /&gt;
Screen content will be transmitted by the presenter.&lt;br /&gt;
&lt;br /&gt;
===== Device handling =====&lt;br /&gt;
&lt;br /&gt;
The RTP service enumerates microphones, loudspeaker, cameras and ringing devices and notifies apps when devices come and go. It is up to the apps using the devices to store preferences.&lt;br /&gt;
&lt;br /&gt;
The RTP service also enables some extended features (such as hook switch or volume control) for supported USB headsets or Bluetooth headsets connected to myApps.&lt;br /&gt;
The supported headset-SDKs determine which headset vendors are recommended to be used with the myApps softphone app. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For this to work, the following vendor specific development kits are integrated in our myApps client. Be aware that the SDK are updated within our Service release :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! SDK Vendor !! Supported OS !! SDK Version !! innovaphone Service Release&lt;br /&gt;
|-&lt;br /&gt;
| Jabra|| MacOS || 1.16.4.0 || 14r2sr11&lt;br /&gt;
|-&lt;br /&gt;
||| Windows || 1.16.4.0 || 15r1sr3&lt;br /&gt;
|-&lt;br /&gt;
| Epos &#039;&#039;(formerly Sennheiser)&#039;&#039; || MacOS || 12.4.0.5478 || 14r1sr3&lt;br /&gt;
|-&lt;br /&gt;
||| Windows || n.a. - [[Support:13r3 sr10 MyApps Windows Client - Epos/Sennheiser-Headsets require installed Epos-Connect Software|to be installed separately]]|| 13r3sr10&lt;br /&gt;
|-&lt;br /&gt;
| Poly &#039;&#039;(formerly Plantronics)&#039;&#039; || MacOS || 3.25.53799.37131 || 13r3sr9&lt;br /&gt;
|-&lt;br /&gt;
||| Windows || 3.25.53800.37131 || 13r3sr10&lt;br /&gt;
|-&lt;br /&gt;
| Yealink || MacOS || 3.1.1.23 || 14r2sr1&lt;br /&gt;
|-&lt;br /&gt;
||| Windows || 3.1.1.23 || 14r2sr2&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
* It is possible to inhibit the start of the Sennheiser SDK (SenncomSDK.exe) using the &amp;lt;code&amp;gt;DISABLEHEADSETS&amp;lt;/code&amp;gt; directive of the installer (see [[#MSI Parameters and install options|  MSI parameters]]  below).&lt;br /&gt;
&lt;br /&gt;
* Starting with V13r3sr10, the Epos-SDK needs to be installed separately using the Epos Connect software to ensure full compatibility between current Epos headset models and native myApps-Windows client. For details [[Support:13r3 sr10 MyApps Windows Client - Epos/Sennheiser-Headsets require installed Epos-Connect Software|refer to this article]].&lt;br /&gt;
&amp;lt;!--Keywords: myapps softphone supported headsets sdk--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Ring tones =====&lt;br /&gt;
&lt;br /&gt;
Ring tones can be played. Apps can choose the tone from a pre-defined list of ring tones.&lt;br /&gt;
&lt;br /&gt;
On Windows, custom ring tones can be uploaded as .mp3 files to the &amp;lt;code&amp;gt;ringtones&amp;lt;/code&amp;gt; sub-directory of myApps&#039; roaming directory (which usually is in &amp;lt;code&amp;gt;C:\Users\...\AppData\Roaming\innovaphone\myApps\ringtones&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
On Android, custom ring tones can be added to the system via Android settings.&lt;br /&gt;
&lt;br /&gt;
On iOS, custom ring tones can be uploaded as .mp3 files to the &amp;lt;code&amp;gt;Ringtones&amp;lt;/code&amp;gt; subdirectory of the myApps file share that is available in iTunes if the iPhone has been connected via USB.&lt;br /&gt;
&lt;br /&gt;
On macOS, custom ring tones can be uploaded as .mp3 files to &amp;lt;code&amp;gt;~/Library/Containers/com.innovaphone.client-macos/Data/Documents/Ringtones&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===== Debugging =====&lt;br /&gt;
For extended debugging, turn on the &#039;&#039;Audio&#039;&#039;, &#039;&#039;Media&#039;&#039; and &#039;&#039;AppSharing&#039;&#039; traces in myApps.&lt;br /&gt;
&lt;br /&gt;
=== Hot keys ===&lt;br /&gt;
On Windows and macOS systems, myApps platform services can listen for hot keys and invoke certain functions. Invocation is done by sending API messages to myApps which passes it to an appropriate API provider (in the cases described here, this will be a &#039;&#039;phone&#039;&#039; or &#039;&#039;softphone&#039;&#039; or &#039;&#039;rcc&#039;&#039; App typically.  See [[{{NAMESPACE}}:Concept_myApps#Client_APIs_and_default_apps | Client APIs and default apps]] for more details about this mechanism.&lt;br /&gt;
&lt;br /&gt;
The hot keys can be specified using the &#039;&#039;advanced settings&#039;&#039; user interface (see [[#UI elements| UI elements]] below. Any of the function keys F1 to F11 (optionally combined with up to two modifier keys &#039;&#039;alt&#039;&#039;, &#039;&#039;ctrl&#039;&#039;, &#039;&#039;shift&#039;&#039; or &#039;&#039;win&#039;&#039;) can be chosen for each function. If you do not want to start the call with &amp;quot;Hotkey+Enter&amp;quot; because you would have to wait for the focus, the hotkey can also be pressed twice and the number is dialled directly.&lt;br /&gt;
&lt;br /&gt;
; dial selected number : Initiates a call using the currently selected text as target.&lt;br /&gt;
&lt;br /&gt;
: A &#039;&#039;PrepareCall&#039;&#039; message with the &#039;&#039;text&#039;&#039; argument set to the selected text and the &#039;&#039;adjust&#039;&#039; argument set to &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; will be sent to the [http://sdk.innovaphone.com/web1/com.innovaphone.phone/com.innovaphone.phone.htm &#039;&#039;com.innovaphone.phone&#039;&#039; API].&lt;br /&gt;
&lt;br /&gt;
:: &amp;lt;code&amp;gt;{&amp;quot;mt&amp;quot;:&amp;quot;ApiRequest&amp;quot;,&amp;quot;apiId&amp;quot;:&amp;quot;com.innovaphone.phone&amp;quot;,&amp;quot;consumer&amp;quot;:&amp;quot;@local-ae2fc2ab74-3f1e-4ab9-b215-d42f213520317&amp;quot;,&amp;quot;msg&amp;quot;:&amp;quot;mt&amp;quot;:&amp;quot;PrepareCall&amp;quot;,&amp;quot;text&amp;quot;:&amp;quot;13&amp;quot;,&amp;quot;adjust&amp;quot;:true}}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; accept call : Accepts a currently alerting call.&lt;br /&gt;
&lt;br /&gt;
: A &#039;&#039;ConnectCall&#039;&#039; message will be sent to the [http://sdk.innovaphone.com/web1/com.innovaphone.phone/com.innovaphone.phone.htm &#039;&#039;com.innovaphone.phone&#039;&#039; API].&lt;br /&gt;
&lt;br /&gt;
:: &amp;lt;code&amp;gt;{&amp;quot;mt&amp;quot;:&amp;quot;ApiRequest&amp;quot;,&amp;quot;apiId&amp;quot;:&amp;quot;com.innovaphone.phone&amp;quot;,&amp;quot;consumer&amp;quot;:&amp;quot;@local-ae2fc2ab74-3f1e-4ab9-b215-d42f213520317&amp;quot;,&amp;quot;msg&amp;quot;:{&amp;quot;mt&amp;quot;:&amp;quot;ConnectCall&amp;quot;}}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; reject/disconnect call : Rejects a currently alerting call or disconnects an active call.&lt;br /&gt;
&lt;br /&gt;
: A &#039;&#039;DisconnectCall&#039;&#039; message will be sent to the [http://sdk.innovaphone.com/web1/com.innovaphone.phone/com.innovaphone.phone.htm &#039;&#039;com.innovaphone.phone&#039;&#039; API].&lt;br /&gt;
&lt;br /&gt;
:: &amp;lt;code&amp;gt;{&amp;quot;mt&amp;quot;:&amp;quot;ApiRequest&amp;quot;,&amp;quot;apiId&amp;quot;:&amp;quot;com.innovaphone.phone&amp;quot;,&amp;quot;consumer&amp;quot;:&amp;quot;@local-ae2fc2ab74-3f1e-4ab9-b215-d42f213520317&amp;quot;,&amp;quot;msg&amp;quot;:{&amp;quot;mt&amp;quot;:&amp;quot;DisconnectCall&amp;quot;}}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== URL Handler ===&lt;br /&gt;
&lt;br /&gt;
On Windows systems, two URI-handler are installed with the myApps platform services.  Windows will call up this URI handler when a user clicks on an appropriate link, for example in a web site.&lt;br /&gt;
&lt;br /&gt;
The handler will the send an API message to myApps which passes it to an appropriate API provider (in the cases described here, this will be a &#039;&#039;phone&#039;&#039; or &#039;&#039;softphone&#039;&#039; or &#039;&#039;rcc&#039;&#039; App typically.  See [[{{NAMESPACE}}:Concept_myApps#Client_APIs_and_default_apps | Client APIs and default apps]] for more details about this mechanism.&lt;br /&gt;
&lt;br /&gt;
; tel URI : call a number, e.g. &amp;lt;code&amp;gt;tel:4711&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: A &#039;&#039;PrepareCall&#039;&#039; message with the &#039;&#039;num&#039;&#039; argument set to the selected text and the &#039;&#039;adjust&#039;&#039; argument set to &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; will be sent to the [http://sdk.innovaphone.com/web1/com.innovaphone.phone/com.innovaphone.phone.htm &#039;&#039;com.innovaphone.phone&#039;&#039; API].&lt;br /&gt;
:: &amp;lt;code&amp;gt;{&amp;quot;mt&amp;quot;:&amp;quot;ApiRequest&amp;quot;,&amp;quot;apiId&amp;quot;:&amp;quot;com.innovaphone.phone&amp;quot;,&amp;quot;consumer&amp;quot;:&amp;quot;@local-ae2fc2ab74-3f1e-4ab9-b215-d42f213520317&amp;quot;,&amp;quot;msg&amp;quot;:{&amp;quot;mt&amp;quot;:&amp;quot;StartCall&amp;quot;,&amp;quot;num&amp;quot;:&amp;quot;4711&amp;quot;,&amp;quot;adjust&amp;quot;:true}}&amp;lt;/code&amp;gt;&lt;br /&gt;
; sip URI : call a SIP name, e.g. &amp;lt;code&amp;gt;sip:zkl@innovaphone.com&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: A &#039;&#039;PrepareCall&#039;&#039; message with the &#039;&#039;sip&#039;&#039; argument set to the selected text and the &#039;&#039;adjust&#039;&#039; argument set to &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; will be sent to the [http://sdk.innovaphone.com/web1/com.innovaphone.phone/com.innovaphone.phone.htm &#039;&#039;com.innovaphone.phone&#039;&#039; API].&lt;br /&gt;
:: &amp;lt;code&amp;gt;{&amp;quot;mt&amp;quot;:&amp;quot;ApiRequest&amp;quot;,&amp;quot;apiId&amp;quot;:&amp;quot;com.innovaphone.phone&amp;quot;,&amp;quot;consumer&amp;quot;:&amp;quot;@local-ae2fc2ab74-3f1e-4ab9-b215-d42f213520317&amp;quot;,&amp;quot;msg&amp;quot;:{&amp;quot;mt&amp;quot;:&amp;quot;StartCall&amp;quot;,&amp;quot;sip&amp;quot;:&amp;quot;zkl@innovaphone.com&amp;quot;,&amp;quot;adjust&amp;quot;:true}}&amp;lt;/code&amp;gt;&lt;br /&gt;
; im URI : start chat with SIP name, e.g. &amp;lt;code&amp;gt;im:zkl@innovaphone.com&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: A &#039;&#039;StartChat&#039;&#039; message with the &#039;&#039;sip&#039;&#039; argument set to the selected text will be sent to the [http://sdk.innovaphone.com/web1/com.innovaphone.chat/com.innovaphone.chat.htm &#039;&#039;com.innovaphone.chat&#039;&#039; API].&lt;br /&gt;
:: &amp;lt;code&amp;gt;{&amp;quot;mt&amp;quot;:&amp;quot;ApiRequest&amp;quot;,&amp;quot;apiId&amp;quot;:&amp;quot;com.innovaphone.chat&amp;quot;,&amp;quot;consumer&amp;quot;:&amp;quot;@local-ae2fc2ab74-3f1e-4ab9-b215-d42f213520317&amp;quot;,&amp;quot;msg&amp;quot;:{&amp;quot;mt&amp;quot;:&amp;quot;StartChat&amp;quot;,&amp;quot;sip&amp;quot;:&amp;quot;zkl@innovaphone.com&amp;quot;}}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On macOS systems myApps might be made the default application to handle tel URI e.g. &amp;lt;code&amp;gt;tel:4711&amp;lt;/code&amp;gt; via Apple FaceTime. Open the &amp;quot;FaceTime&amp;quot; menu &amp;quot;Settings...&amp;quot; and select myApps as &amp;quot;Default for phone calls&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
On iOS &#039;&#039;tel&#039;&#039; URIs are always dialed via GSM. Therefore myApps iOS also reacts to URI schemes &#039;&#039;com.innovaphone.tel&#039;&#039;, &#039;&#039;com.innovaphone.sip&#039;&#039; and &#039;&#039;com.innovaphone.im&#039;&#039;, e.g. &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;com.innovaphone.tel:4711&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;com.innovaphone.sip:zkl@innovaphone.com&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;com.innovaphone.im:zkl@innovaphone.com&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== User activity ===&lt;br /&gt;
On Windows and macOS systems, the myApps platform services can monitor user keyboard/mouse activity and change the user&#039;s presence state after a certain amount of inactivity.  The timeout can be specified using the &#039;&#039;advanced settings&#039;&#039; user interface (see [[#UI elements| UI elements]] below.&lt;br /&gt;
&lt;br /&gt;
myApps will then send a [https://sdk.innovaphone.com/doc/appwebsocket/myApps.htm#SetUserActivity&#039;&#039;SetUserActivity&#039;&#039;] message to the PBX using the &#039;&#039;myApps&#039;&#039; protocol.&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;code&amp;gt;{&amp;quot;mt&amp;quot;:&amp;quot;SetUserActivity&amp;quot;,&amp;quot;inactive&amp;quot;:true}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will change the &#039;&#039;status&#039;&#039; property of the &#039;&#039;im:&#039;&#039; contact for the user&#039;s own presence and hence result in a presence update from the PBX to myApps&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;code&amp;gt;{&amp;quot;mt&amp;quot;:&amp;quot;UpdateOwnPresence&amp;quot;,&amp;quot;presence&amp;quot;:[{...},{&amp;quot;contact&amp;quot;:&amp;quot;im:&amp;quot;,&amp;quot;activity&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;status&amp;quot;:&amp;quot;closed&amp;quot;}]}&amp;lt;/code&amp;gt;&lt;br /&gt;
The &#039;&#039;closed&#039;&#039; status is reflected in the grey status color when displaying a contact [[Image:myapps-inactive.png|myapps-inactive.png/|myapps-inactive.png/]].&lt;br /&gt;
&lt;br /&gt;
On iOS and Android, the state is set to &#039;&#039;inactive&#039;&#039; as soon as the App is brought to background.&lt;br /&gt;
When myApps platform services are not available (i.e. when running the web application in a browser solely) a limited user activity monitoring is available: the state is set to active when the web page is not used for more than 5 minutes.&lt;br /&gt;
&lt;br /&gt;
=== Recording ===&lt;br /&gt;
&lt;br /&gt;
The new launcher offers the possibility to record the audio of incoming and outgoing calls. In order to activate that functionality the URL of the recording instance must be configured in either the PBX (PBX-&amp;gt;myApps-&amp;gt;Config: Recording URL) or the softphone App (Settings-&amp;gt;Audio Recording (URL)) &lt;br /&gt;
&lt;br /&gt;
[[Image:PBX-Recording-Settings.png|pbx-recording-settings.png/|pbx-recording-settings.png/]] [[Image:Recording-Softphone-Settings.png|recording-softphone-settings.png/|recording-softphone-settings.png/]]. &lt;br /&gt;
&lt;br /&gt;
As long as that URL is configured the audio data of all calls are stored as pcap-files under that URL.&lt;br /&gt;
If the URL points to a CF device in the PBX, write access must be granted for that URL (PBX-&amp;gt;Services-&amp;gt;HTTP-&amp;gt;Server:Public compact flash access) and if the URL points to the recording app, the files can be accessed via the recording app [[{{NAMESPACE}}:Concept_App_Service_Recordings|recording]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Under PBX-&amp;gt;myApps the administrator can set a certain default behaviour of the audio recording like whether or not the recording should start automatically at the beginning of the call (Recording by Default ON/OFF), only calls with external numbers should be recorded (Record external calls only) or whether or not the user should be able to start/stop the recording himself (Allow user incall recording control). Except for the last parameter these parameters can also be modified by the user in its softphone settings if the administrator doesn&#039;t set the FORCE flag.&lt;br /&gt;
&lt;br /&gt;
If the user was allowed by the admin to control the recording a recording switch is active during the call when the &amp;quot;Media&amp;quot; Panel is opened. There the audio recording may be stopped and continued at will. A red recording notice is shown in the top right corner when the recording actually takes place.&lt;br /&gt;
 &lt;br /&gt;
[[Image:Recording-incall-switch.png|recording-incall-switch.png/|recording-incall-switch.png/]]&lt;br /&gt;
&lt;br /&gt;
=== Notifications ===&lt;br /&gt;
&lt;br /&gt;
The myApps platform services can use the OS specific notification mechanism (e.g. &#039;&#039;desktop notifications&#039;&#039; on Windows) to display messages (e.g. &#039;&#039;incoming new chat message&#039;&#039;) to the user.&lt;br /&gt;
&lt;br /&gt;
Note that the actual rendering of the notification is under control of the OS.  Therefore, myApps must be allowed to show notifications and its appearance can be restricted by OS native settings.&lt;br /&gt;
&lt;br /&gt;
==== Microsoft Windows Notifications ====&lt;br /&gt;
&lt;br /&gt;
Microsoft Windows Server editions (2016, 2019, 2022) are just capable of showing a single &#039;&#039;IncomingCall&#039;&#039; notification at the same time (we couldn&#039;t find a workaround for this limitation).&amp;lt;br/&amp;gt;&lt;br /&gt;
An &#039;&#039;IncomingCall&#039;&#039; notification is visible the whole time instead of being moved to the action center after a certain time.&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
A notification about a missed call uses the &#039;&#039;IncomingCall&#039;&#039; type so that this notification is visible until the user returns.&amp;lt;br/&amp;gt;&lt;br /&gt;
Due to the above limitation, on a new arriving call such a missed call notification is transformed to a default notification which will be moved to the action center automatically.&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
On non server editions, you can have multiple IncomingCall notifications at the same time (so two parallel incoming calls will be indeed notified at the same time), but the missed call notification handling is the same on both platforms!&lt;br /&gt;
&lt;br /&gt;
 Thus there will be always just &#039;&#039;&#039;one&#039;&#039;&#039; missed call notification visible and previous missed calls can be found inside your action center!&lt;br /&gt;
&lt;br /&gt;
To see myApps notifications, ensure:&lt;br /&gt;
* System -&amp;gt; Notifications &lt;br /&gt;
** enable notifications&lt;br /&gt;
** disable &amp;quot;Do not disturb&amp;quot; or allow myApps as priority application while &amp;quot;Do not disturb&amp;quot; is active&lt;br /&gt;
** enable notifications for myApps in the list of applications&lt;br /&gt;
* System -&amp;gt; Focus &lt;br /&gt;
** if a focus session is active and the &amp;quot;Do not disturb&amp;quot; is activated during a focus session, make sure that myApps is a priority application (see above)&lt;br /&gt;
&lt;br /&gt;
==== macOS Notifications ====&lt;br /&gt;
Notifications are the same as on Windows.&lt;br /&gt;
The difference is, that for macOS, notifications need to be allowed in the system settings.&lt;br /&gt;
Go to Notifications - myApps, select Banner and enable all check marks.&lt;br /&gt;
&lt;br /&gt;
=== Local phonebook access ===&lt;br /&gt;
&#039;&#039;&#039;Contact Search:&#039;&#039;&#039; The myApps platform services implement an &#039;&#039;API provider&#039;&#039; for the [http://sdk.innovaphone.com/web1/com.innovaphone.search/lib1_api_search.htm &#039;&#039;com.innovaphone.search&#039;&#039; API]]. They perform search capabilities on the OS&#039; local phone books which can be used by Apps like the &#039;&#039;phoneapp&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Apps would send a &#039;&#039;Search&#039;&#039; request to the API:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;code&amp;gt;{&amp;quot;mt&amp;quot;:&amp;quot;ApiRequest&amp;quot;,&amp;quot;consumer&amp;quot;:&amp;quot;dev:SwPh_zkl_5e42e884&amp;quot;,&amp;quot;provider&amp;quot;:&amp;quot;*&amp;quot;,&amp;quot;src&amp;quot;:&amp;quot;4&amp;quot;,&amp;quot;msg&amp;quot;:{&amp;quot;mt&amp;quot;:&amp;quot;Search&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;contact&amp;quot;,&amp;quot;search&amp;quot;:&amp;quot;john doe&amp;quot;},&amp;quot;apiId&amp;quot;:&amp;quot;com.innovaphone.search&amp;quot;}&amp;lt;/code&amp;gt;&lt;br /&gt;
Search results are delivered as &#039;&#039;SearchInfo&#039;&#039; messages:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;code&amp;gt;{&amp;quot;mt&amp;quot;:&amp;quot;ApiResult&amp;quot;,&amp;quot;src&amp;quot;:&amp;quot;3&amp;quot;,&amp;quot;provider&amp;quot;:&amp;quot;@local-8125d22e37-519d-4056-bfe5-c52ef2ae8fabb0&amp;quot;,&amp;quot;consumer&amp;quot;:&amp;quot;dev:SwPh_zkl_5e42e884&amp;quot;,&amp;quot;client&amp;quot;:&amp;quot;@client-f62702dd86-be3f-47fc-b4bc-7a21627b75b2ea&amp;quot;,&amp;quot;msg&amp;quot;:{&amp;quot;mt&amp;quot;:&amp;quot;SearchInfo&amp;quot;,&amp;quot;relevance&amp;quot;:2000,&amp;quot;adjust&amp;quot;:true,&amp;quot;type&amp;quot;:&amp;quot;contact&amp;quot;,&amp;quot;contact&amp;quot;:{&amp;quot;givenname&amp;quot;:&amp;quot;John&amp;quot;,&amp;quot;sn&amp;quot;:&amp;quot;Doe&amp;quot;,&amp;quot;company&amp;quot;:&amp;quot;ACME&amp;quot;,&amp;quot;position&amp;quot;:&amp;quot;Head of everything&amp;quot;,&amp;quot;telephonenumber&amp;quot;:[&amp;quot;11111&amp;quot;,&amp;quot;22222&amp;quot;],&amp;quot;homephone&amp;quot;:[&amp;quot;+4944444&amp;quot;,&amp;quot;33333&amp;quot;],&amp;quot;mobile&amp;quot;:[&amp;quot;+49 (123) 55555&amp;quot;]}},&amp;quot;api&amp;quot;:&amp;quot;com.innovaphone.search&amp;quot;}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Reverse Lookup:&#039;&#039;&#039; The myApps platform services implement an &#039;&#039;API provider&#039;&#039; for the [http://sdk.innovaphone.com/web1/com.innovaphone.phonelookup/lib1_api_phonelookup.htm &#039;&#039;com.innovaphone.phonelookup&#039;&#039; API]. They perform search capabilities on the OS&#039; local phone books which can be used by Apps like the &#039;&#039;phoneapp&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Apps would send a &#039;&#039;Lookup&#039;&#039; request to the API: &lt;br /&gt;
&lt;br /&gt;
: &amp;lt;code&amp;gt;{&amp;quot;mt&amp;quot;:&amp;quot;ApiRequest&amp;quot;,&amp;quot;consumer&amp;quot;:&amp;quot;dev:SwPh_zkl_5e42e884&amp;quot;,&amp;quot;provider&amp;quot;:&amp;quot;*&amp;quot;,&amp;quot;src&amp;quot;:&amp;quot;4&amp;quot;,&amp;quot;msg&amp;quot;:{ mt: &amp;quot;Lookup&amp;quot;, prefixIntl: &amp;quot;000&amp;quot;, prefixNtl: &amp;quot;00&amp;quot;, prefixExt:&amp;quot;0&amp;quot;, area: &amp;quot;7031&amp;quot;, country: &amp;quot;49&amp;quot;, lookup: &amp;quot;0004970311234567&amp;quot; },&amp;quot;apiId&amp;quot;:&amp;quot;com.innovaphone.lookup&amp;quot;}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Search results are delivered as &#039;&#039;LookupInfo&#039;&#039; messages:&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;code&amp;gt;{&amp;quot;mt&amp;quot;:&amp;quot;ApiResult&amp;quot;,&amp;quot;src&amp;quot;:&amp;quot;3&amp;quot;,&amp;quot;provider&amp;quot;:&amp;quot;@local-8125d22e37-519d-4056-bfe5-c52ef2ae8fabb0&amp;quot;,&amp;quot;consumer&amp;quot;:&amp;quot;dev:SwPh_zkl_5e42e884&amp;quot;,&amp;quot;client&amp;quot;:&amp;quot;@client-f62702dd86-be3f-47fc-b4bc-7a21627b75b2ea&amp;quot;,&amp;quot;msg&amp;quot;:{mt: &amp;quot;LookupInfo&amp;quot;, dn: &amp;quot;Jake Blues&amp;quot;, contact: { telephonenumber: [&amp;quot;0004970311234567&amp;quot;], givenname: &amp;quot;Jake&amp;quot;, sn: &amp;quot;Blues&amp;quot;, company: &amp;quot;Blues Brothers&amp;quot; &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Windows ====&lt;br /&gt;
On Windows, the search and lookup are performed in all of the user&#039;s Outlook contact folders.  As opposed to the search implemented in the &#039;&#039;Contacts&#039;&#039; and &#039;&#039;Users&#039;&#039; App, all items are returned which match any of the search words (i.e. searching for &#039;&#039;a b&#039;&#039; will return items matching either &#039;&#039;a&#039;&#039; or &#039;&#039;b&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
; searched properties : firstname, lastname&lt;br /&gt;
; returned properties : Following Outlook contact phone number properties are returned  (if available):&lt;br /&gt;
&lt;br /&gt;
:* OFFICE_TELEPHONE_NUMBER as &#039;&#039;telephonenumber&#039;&#039;&lt;br /&gt;
:* OFFICE2_TELEPHONE_NUMBER as &#039;&#039;telephonenumber&#039;&#039;&lt;br /&gt;
:* HOME_TELEPHONE_NUMBER as &#039;&#039;homephone&#039;&#039;&lt;br /&gt;
:* HOME2_TELEPHONE_NUMBER as &#039;&#039;homephone&#039;&#039;&lt;br /&gt;
:* MOBILE_TELEPHONE_NUMBER as &#039;&#039;mobile&#039;&#039;&lt;br /&gt;
:* BUSINESS_FAX_NUMBER as &#039;&#039;facsimiletelephonenumber&#039;&#039;&lt;br /&gt;
Note that contact information is cached in the search provider.  Updated contacts may therefore become effective after a while only.&lt;br /&gt;
Outlook search will create its own trace file &amp;lt;code&amp;gt;myAppsOutlookSearch-&amp;lt;/code&amp;gt;&#039;&#039;date-time&#039;&#039;&amp;lt;code&amp;gt;.txt&amp;lt;/code&amp;gt; in the standard trace directory.&lt;br /&gt;
&lt;br /&gt;
This search provider is always installed and can be disabled.  There is no need (nor possibility) to enable it in the &#039;&#039;Apps&#039;&#039; tab of the PBX&#039;s user object.  Also, no &#039;&#039;App&#039;&#039; object needs to be created for it.&lt;br /&gt;
&lt;br /&gt;
==== Android/iOS ====&lt;br /&gt;
The search and lookup are performed in the contacts.&lt;br /&gt;
&lt;br /&gt;
==== macOS ====&lt;br /&gt;
The search and lookup are performed in the contacts. If you wish to disable local contact lookup, go to system settings - Security &amp;amp; Privacy and disable the access to contacts for myapps.&lt;br /&gt;
&lt;br /&gt;
=== Microsoft Office integration ===&lt;br /&gt;
&lt;br /&gt;
The myApps platform services has a &#039;&#039;office presence provider&#039;&#039; that can provide the user&#039;s presence state to Office applications.  See [[{{NAMESPACE}}:Concept_myApps_Office_Integration|myApps Office Integration]] for details.&lt;br /&gt;
&lt;br /&gt;
This feature is installed by default.  However, it can be disabled using the &#039;&#039;OFFICEPRESENCE&#039;&#039; MSI Parameter.  Also, a check-mark is available in the setup dialog.&lt;br /&gt;
&lt;br /&gt;
=== Call an external application for calls ===&lt;br /&gt;
&lt;br /&gt;
Phone Apps (such as the phoneapp or softphone) can initiate the start of an external application when a new call appears (either incoming or outgoing).  The actual spawning of the application is done by the myApps platform service.  Also, the application properties (such as e.g. the executable&#039;s path) is configured in the myApps platform services (see [[#UI elements|Advanced settings]] in the &#039;&#039;UI elements&#039;&#039; section below).&lt;br /&gt;
&lt;br /&gt;
A number of arguments can be passed to the application by substituting $-variables in the &#039;&#039;Parameter&#039;&#039; field:&lt;br /&gt;
&lt;br /&gt;
; $n : phone number as dialed (called party number for outgoing calls) or received (calling party number for incoming calls)&lt;br /&gt;
&lt;br /&gt;
; $N : called or calling party number in &#039;&#039;national&#039;&#039; format (e.g. 07031730090)&lt;br /&gt;
&lt;br /&gt;
; $I : called or calling party number in &#039;&#039;international&#039;&#039; format (e.g. +497031730090)&lt;br /&gt;
&lt;br /&gt;
: note that both $N and $I only work if $n includes both subscriber number and area code (e.g. 07031730090). Otherwise they are equal to $n&lt;br /&gt;
&lt;br /&gt;
; $d : display name of peer (if known)&lt;br /&gt;
&lt;br /&gt;
; $u : URI name of the peer (if available eg with a federation call)&lt;br /&gt;
&lt;br /&gt;
; $c : conference id&lt;br /&gt;
&lt;br /&gt;
: this is a globally unique ID for this call and may be used to relate the call to the &#039;&#039;guid&#039;&#039; found in the CallInfo structure in the [http://wiki.innovaphone.com/index.php?title=Reference10:SOAP_API#CallInfo SOAP-API] and [http://sdk.innovaphone.com/doc/appwebsocket/RCC.htm RCC-API ].  Also, corresponding [[Reference10:Call Detail Record CDR PBX|CDRs]] can be related using the &#039;&#039;event&#039;&#039; tag&#039;s &#039;&#039;conf&#039;&#039; attribute.&lt;br /&gt;
The start of an external application can be requested using the &#039;&#039;com.innovaphone.externalapps&#039;&#039; API.&lt;br /&gt;
&lt;br /&gt;
Some setup examples are [[Howto:Integrate External Apps in innovaphone UC clients|shown here]].&lt;br /&gt;
&lt;br /&gt;
=== Push ===&lt;br /&gt;
&lt;br /&gt;
Mobile operating systems usually inhibit network operation of apps which run in the background or are closed by the user.  This is done in order to reduce battery consumption.  Unfortunately, this also stops such apps to maintain a registration by regularly sending &#039;&#039;keep alive&#039;&#039; messages to a server (in our case to the PBX).  As a result, myApps will be disconnected from the PBX.   When the PBX determines that there is an event for the application which needs a response, it needs to wake up the app using a dedicated channel provided by the operating system.  This mechanism is know as &#039;&#039;push&#039;&#039;. When running on iOS or Android, myApps supports &#039;&#039;push&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
For &#039;&#039;push&#039;&#039; to work, a [[{{NAMESPACE}}:PBX/Objects/Push|&#039;&#039;push object&#039;&#039;]] needs to be configured in the PBX .  Also, it needs to be enabled on the mobile phone for the myApps app.&lt;br /&gt;
This mechanism is quite similar in v12 and v13, so you can refer to [[{{NAMESPACE}}:Concept_Push_Notifications_for_iOS_and_Android|Reference14r2:Concept_Push_Notifications_for_iOS_and_Android]] for more details. &lt;br /&gt;
&lt;br /&gt;
Also, helpful hints can be found in [[Howto:Troubleshoot v13 Push with myApps for Android and iOS]].&lt;br /&gt;
&lt;br /&gt;
=== App Proxy ===&lt;br /&gt;
&lt;br /&gt;
myApps runs further &#039;&#039;Apps&#039;&#039; (such as e.g. the &#039;&#039;phoneapp&#039;&#039;) as a web page in an IFRAME of the browser myApps is running in.  The App&#039;s page code is loaded either from the PBX or from an &#039;&#039;application platform&#039;&#039; (AP).   This however would mean that the App&#039;s IFRAME would remain empty (a dead white screen) when the PBX or AP is not available. To make sure the App can start-up anyway, the myApps platform services feature the so-called &#039;&#039;App Proxy&#039;&#039;.  This is a caching proxy that caches all the App code so it is available even in case of network failure. When myApps runs in the context of the platform services, Apps are therefore not loaded from the App source directly, but from the local App proxy. &lt;br /&gt;
&lt;br /&gt;
The cached files are stored in the PCs local file system in the &amp;lt;code&amp;gt;C:\Users\...\AppData\Local\innovaphone\myApps\appproxy&amp;lt;/path&amp;gt;&amp;lt;/code&amp;gt;.  There is no configuration required.  However, if myApps seems to run with outdated or corrupt cached copies of the App, you can safely delete the entire directory.&lt;br /&gt;
&lt;br /&gt;
=== Auto update ===&lt;br /&gt;
&lt;br /&gt;
On Windows and on macOS, the myApps platform services can auto-update themselves to a common version.  This is controlled by the [[{{NAMESPACE}}:PBX/Config/myApps#Launcher_Software_Update | &#039;&#039;Launcher Software Update&#039;&#039;]] settings under &#039;&#039;PBX/Config/myApps&#039;&#039; in the PBX. &lt;br /&gt;
&lt;br /&gt;
When myApps is started or the user logs in or myApps needs to re-connect to the PBX, the platform services will use the [http://sdk.innovaphone.com/web1/com.innovaphone.client/lib1_api_client.htm com.innovaphone.client API] to learn the desired version (&#039;&#039;launcherUpdateBuild&#039;&#039;, which is part of the API&#039;s &#039;&#039;model&#039;&#039;). If this differs from the current version, the platform services will try to download the respective new version. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 {&lt;br /&gt;
    &amp;quot;mt&amp;quot;: &amp;quot;ApiUpdate&amp;quot;,&lt;br /&gt;
    &amp;quot;apis&amp;quot;: {&lt;br /&gt;
        &amp;quot;com.innovaphone.client&amp;quot;: {&lt;br /&gt;
            &amp;quot;@client&amp;quot;: {&lt;br /&gt;
                &amp;quot;title&amp;quot;: &amp;quot;innovaphone myApps&amp;quot;,&lt;br /&gt;
                &amp;quot;model&amp;quot;: {&lt;br /&gt;
                    &amp;quot;launcher&amp;quot;: true,&lt;br /&gt;
                    &amp;quot;launcherUpdateBuild&amp;quot;: &amp;quot;134906&amp;quot;,&lt;br /&gt;
                    &amp;quot;appStoreUrl&amp;quot;: &amp;quot;http://store.innovaphone.com/release/download/&amp;quot;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
 }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The installation of the downloaded version is done by the &#039;&#039;innovaphonemyAppsUpdateService&#039;&#039;. This service is installed and enabled during the initial installation of the myApps platform services.  To disable auto-update, either leave the &#039;&#039;Launcher Software Update&#039;&#039; settings empty or set the service&#039;s start mode to &#039;&#039;disabled&#039;&#039; in the Windows &#039;&#039;services control panel&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Note that on Windows the update service does not work on terminal servers. Administrators must do myApps base services updates using standard windows mechanisms.&lt;br /&gt;
&lt;br /&gt;
Note that on macOS if myApps has been installed from the Apple Store it is assumed that auto update from the PBX is not desired and disabled therefore.&lt;br /&gt;
&lt;br /&gt;
On Android/iOS/macOS updates can be downloaded from the respective app store.&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;Devices&#039;&#039; app can not update software installed on Windows PCs directly. However, when the PBX is updated using an &#039;&#039;update job&#039;&#039; in the &#039;&#039;Devices&#039;&#039; App, the &#039;&#039;Launcher Software Update&#039;&#039; settings will be updated accordingly and hence the myApps base services will ultimately also be updated to the same version.&lt;br /&gt;
&lt;br /&gt;
==== Auto update flow on Windows ====&lt;br /&gt;
&lt;br /&gt;
* On start of myApps, myApps checks if an update is available and ready for installation&lt;br /&gt;
** if yes, the update is installed directly, without user interaction (a popup is shown during the installation)&lt;br /&gt;
** if not, myApps starts&lt;br /&gt;
* if an update is available while myApps is already running, an update notification will be shown which let&#039;s the user choose to install the update now or later (the notification will then popup again after one hour)&lt;br /&gt;
&lt;br /&gt;
==UI elements ==&lt;br /&gt;
There are a few user interfaces provided by the platform services:&lt;br /&gt;
===tray-icon (Windows only) ===&lt;br /&gt;
::[[Image:myapps-tray.png|myapps-tray.png/|myapps-tray.png/]]&lt;br /&gt;
:Allows to&lt;br /&gt;
:* terminate myApps&lt;br /&gt;
:* toggle the &#039;&#039;autostart&#039;&#039; state&lt;br /&gt;
:* toggle the &#039;&#039;show in task bar&#039;&#039; state&lt;br /&gt;
:* open the trace folder&lt;br /&gt;
:&lt;br /&gt;
=== PBX connect form===&lt;br /&gt;
:: [[Image:myapps-connect.png|myapps-connect.png/|myapps-connect.png/]]&lt;br /&gt;
: Allows the user to specify the connect data for the PBX (i.e. IP address or DNS name)&lt;br /&gt;
:&lt;br /&gt;
=== Advanced settings===&lt;br /&gt;
::[[Image:myapps-settings0.png|myapps-settings0.png/|myapps-settings0.png/]]&lt;br /&gt;
::[[Image:myapps-settings.png|myapps-settings.png/|myapps-settings.png/]] [[Image:myapps-settings2.png|myapps-settings2.png/|myapps-settings2.png/]] [[Image:myapps-settings3.png|myapps-settings3.png/|myapps-settings3.png/]]&lt;br /&gt;
&lt;br /&gt;
: Allows to modify various platform dependant settings (such as e.g. the hotkey selection on Windows)&lt;br /&gt;
&lt;br /&gt;
== Interfaces ==&lt;br /&gt;
=== Provided APIs ===&lt;br /&gt;
&lt;br /&gt;
; [http://sdk.innovaphone.com/web1/com.innovaphone.search/lib1_api_search.htm com.innovaphone.search] : access to local phone book entries by the [[#Local phonebook access|Local phonebook access]] component.&lt;br /&gt;
; [http://sdk.innovaphone.com/web1/com.innovaphone.launcher/com.innovaphone.launcher.htm com.innovaphone.launcher] : display of OS specific user notifications and receipt of related user actions&lt;br /&gt;
; com.innovaphone.notificationhandler : reports back click on a notification.&lt;br /&gt;
; com.innovaphone.externalapps : to start external applications, see [[#Call an external application for calls|Call an external application for calls]]  above&lt;br /&gt;
&lt;br /&gt;
=== Used APIs ===&lt;br /&gt;
&lt;br /&gt;
; [http://sdk.innovaphone.com/web1/com.innovaphone.phone/com.innovaphone.phone.htm com.innovaphone.phone] : used to initiate new or manipulate existing calls by the [[#Hot keys|Hot keys]] and [[#URL handler|URL handler]] components.&lt;br /&gt;
&lt;br /&gt;
; [http://sdk.innovaphone.com/web1/com.innovaphone.chat/com.innovaphone.chat.htm com.innovaphone.chat] : used to start a new chat by the [[#URL handler|URL handler]] component.&lt;br /&gt;
&lt;br /&gt;
; [http://sdk.innovaphone.com/web1/com.innovaphone.client/lib1_api_client.htm com.innovaphone.client] : the model is used to learn the update settings, see [[#Auto update|Auto update]] above&lt;br /&gt;
&lt;br /&gt;
=== Protocols ===&lt;br /&gt;
&lt;br /&gt;
; [https://sdk.innovaphone.com/doc/launcher/Media.htm Media Protocol] : used by apps to allocate RTP channels, see [[#RTP service for audio.2C video and data|RTP service for audio, video and data]] above&lt;br /&gt;
&lt;br /&gt;
== Related App Services ==&lt;br /&gt;
&lt;br /&gt;
none&lt;br /&gt;
&lt;br /&gt;
== Known limitations ==&lt;br /&gt;
; Incoming call as banner on myApps for iOS : Since iOS 14 the iOS CallKit presents incoming calls as a banner leaving the original green answer button of myApps visible. Use only the blue button of the banner to accept the call or change iPhone Settings, App &amp;quot;Phone&amp;quot;, &amp;quot;Incoming Calls&amp;quot; to &amp;quot;Full Screen&amp;quot; to hide the myApps user interface again during call answering.&lt;br /&gt;
&lt;br /&gt;
; Call answer in speakerphone mode even with active Bluetooth headset on myApps for iOS : This causes unwanted speakerphone operation if the smartphone is used with a Bluetooth car audio system. The behaviour can be changed by selecting &#039;&#039;Bluetooth Headset&#039;&#039; in this setting:&lt;br /&gt;
:&#039;&#039;iOS Settings-&amp;gt;Accessibility-&amp;gt;Touch-&amp;gt;Call Audio Routing: Automatic / Bluetooth Headset / Speaker&#039;&#039;&lt;br /&gt;
:&#039;&#039;iOS Einstellungen-&amp;gt;Bedienungshilfen-&amp;gt;Tippen-&amp;gt;Anrufaudioausgabe: Automatisch / Bluetooth-Headset / Lautsprecher&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
; Windows Server 2016 (Windows 10 Build 1607) : windows just shows the first notification. Further notifications aren&#039;t displayed until the previous ones are removed from the notification center. Current windows builds do not show this behaviour anymore.&lt;br /&gt;
&lt;br /&gt;
; Problems on Mac computers with Yealink USB headsets&lt;br /&gt;
: we have received reports that myApps quits unexpectedly on some Mac computers when a Yealink headset is plugged in.  Unfortunately, we could not find out the cause yet.  If you use Yealink USB headsets and have a similar issue, please open a support ticket and send myApps traces.&lt;br /&gt;
&lt;br /&gt;
; Poly / Plantronics headset buttons only functional if myApps is started with Rosetta&lt;br /&gt;
: myApps macOS supports Apple M1/M2 hardware natively. However, the Poly / Plantronics headset SDK is only available for Intel platform and thus myApps needs to be started via Apple&#039;s Intel emulator Rosetta if a Poly / Plantronics headset is used. This is done with right-click on the myApps executable, &#039;&#039;Information&#039;&#039;, &#039;&#039;Open with Rosetta&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
; Windows surface devices may not work correctly&lt;br /&gt;
: Chromium does not get touch keyboard events. USB Keyboards may not be recognized either.&lt;br /&gt;
&lt;br /&gt;
= Installation =&lt;br /&gt;
&lt;br /&gt;
== Windows ==&lt;br /&gt;
&lt;br /&gt;
myApps platform services are installed on Windows using the .msi file found in the &#039;&#039;myApps Windows&#039;&#039; package from [https://store.innovaphone.com/release/download.htm store.innovaphone.com].&lt;br /&gt;
&lt;br /&gt;
myApps can update itself automatically, see [[#Auto update|Auto update]] above.&lt;br /&gt;
&lt;br /&gt;
=== MSI Parameters and install options ===&lt;br /&gt;
&lt;br /&gt;
The MSI installer of myApps for Windows supports the following parameters and can be edited with [https://docs.microsoft.com/en-us/windows/win32/msi/orca-exe Microsoft Orca]. You can add your parameters in the table &#039;&#039;property&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
; SERVER (REG_SZ): the PBX&#039;s server URL&lt;br /&gt;
; OFFICEPRESENCE (REG_DWORD): &#039;&#039;&#039;false&#039;&#039;&#039; to disable presence integration in Microsoft Office&lt;br /&gt;
: this is also available as a check-mark when running the install manually&lt;br /&gt;
&lt;br /&gt;
; DISABLEHEADSETS (REG_DWORD): &#039;&#039;&#039;true&#039;&#039;&#039; to disable headsets support, see [[#Device handling|Device handling]] above&lt;br /&gt;
&lt;br /&gt;
; EXTERNALAPPS (REG_SZ): pre-define external applications, see [[#Call an external application for calls|Call an external application for calls]] above&lt;br /&gt;
: e.g. &amp;lt;code&amp;gt;&amp;quot;{&amp;quot;&amp;quot;externalApps&amp;quot;&amp;quot;:[{&amp;quot;&amp;quot;id&amp;quot;&amp;quot;:0,&amp;quot;&amp;quot;name&amp;quot;&amp;quot;:&amp;quot;&amp;quot;Wireshark&amp;quot;&amp;quot;,&amp;quot;&amp;quot;path&amp;quot;&amp;quot;:&amp;quot;&amp;quot;C:\\Program Files\\Wireshark\\Wireshark.exe&amp;quot;&amp;quot;,&amp;quot;&amp;quot;param&amp;quot;&amp;quot;:&amp;quot;&amp;quot;test $I&amp;quot;&amp;quot;}]}&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; FORCERESTART (REG_DWORD): &#039;&#039;&#039;true&#039;&#039;&#039; (or any string ...) kills myApps during the installation and restarts it for the currently logged in user, if it was running&lt;br /&gt;
&lt;br /&gt;
; DISABLELOCALHOST (REG_DWORD): &#039;&#039;&#039;true&#039;&#039;&#039; to disable use of &#039;&#039;&#039;localhost&#039;&#039;&#039; string to access the local webserver. Use &#039;&#039;&#039;127.0.0.1&#039;&#039;&#039; instead&lt;br /&gt;
&lt;br /&gt;
; EXCLUDEINTERFACES (REG_SZ): some VPN interfaces are not detected by Windows as IF_TYPE_PPP or IF_TYPE_TUNNEL and therefore the &#039;&#039;&#039;media outside VPN&#039;&#039;&#039; setting is not taking effect. With this option interfaces can be pre-defined that will not be used for media. Interfaces must be comma separated&lt;br /&gt;
: e.g. &amp;lt;code&amp;gt;EXCLUDEINTERFACES=&amp;quot;172,192.168,10.10&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Current settings are stored in the registry at &amp;lt;code&amp;gt;Computer\HKEY_CURRENT_USER\Software\innovaphone\myApps&amp;lt;/code&amp;gt; or at &amp;lt;code&amp;gt;Computer\HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\innovaphone\myApps&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Boolean values like OfficePresence are stored in registry entries with type REG_DWORD and values 1 or 0. 0 disables the setting and 1 enables it.&lt;br /&gt;
&lt;br /&gt;
== iOS ==&lt;br /&gt;
&lt;br /&gt;
myApps platform services are installed on iOS by loading &#039;&#039;innovaphone myApps&#039;&#039; from the &#039;&#039;App Store&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Configuration via MDM ===&lt;br /&gt;
&lt;br /&gt;
the PBX&#039;s server URL can be pre-configured by specifying this dictionary in the MDM&lt;br /&gt;
    &amp;lt;code&amp;gt;&amp;lt;plist&amp;gt;&lt;br /&gt;
        &amp;lt;dict&amp;gt;&lt;br /&gt;
            &amp;lt;key&amp;gt;server&amp;lt;/key&amp;gt;&lt;br /&gt;
            &amp;lt;string&amp;gt;pbx.example.com&amp;lt;/string&amp;gt;&lt;br /&gt;
        &amp;lt;/dict&amp;gt;&lt;br /&gt;
    &amp;lt;/plist&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== macOS ==&lt;br /&gt;
&lt;br /&gt;
myApps platform services might be installed directly from the Apple store. An installer package &amp;lt;code&amp;gt;myapps.pkg&amp;lt;/code&amp;gt; and a disk image &amp;lt;code&amp;gt;myapps.dmg&amp;lt;/code&amp;gt; is also available from the innovaphone app store. Install &amp;lt;code&amp;gt;myapps.pkg&amp;lt;/code&amp;gt; by double-click on the file and follow the instructions of the installer. myApps becomes available in the Applications folder and can be opened by double-click. Or download and open &amp;lt;code&amp;gt;myapps.dmg&amp;lt;/code&amp;gt; and double klick myApps. If desired integrate it into the app dock by right click, &#039;&#039;Options, Keep in the dock&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
If installed from the innovaphone app store, myApps can update itself automatically, see [[#Auto update|Auto update]] above.&lt;br /&gt;
&lt;br /&gt;
If installed from the Apple store, macOS notifies about updates on the Apple store. myApps [[#Auto update|Auto update]] is disabled then.&lt;br /&gt;
&lt;br /&gt;
If a clean-install of the client is necessary, the folder &amp;quot;/Users/username/Library/Containers/myapps&amp;quot; needs to be deleted. To be on the safe side also delete it from the trash bin.&lt;br /&gt;
&lt;br /&gt;
=== Configuration via MDM ===&lt;br /&gt;
&lt;br /&gt;
the PBX&#039;s server URL can be pre-configured by specifying this dictionary in the MDM&lt;br /&gt;
    &amp;lt;code&amp;gt;&amp;lt;plist&amp;gt;&lt;br /&gt;
        &amp;lt;dict&amp;gt;&lt;br /&gt;
            &amp;lt;key&amp;gt;server&amp;lt;/key&amp;gt;&lt;br /&gt;
            &amp;lt;string&amp;gt;pbx.example.com&amp;lt;/string&amp;gt;&lt;br /&gt;
        &amp;lt;/dict&amp;gt;&lt;br /&gt;
    &amp;lt;/plist&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Preferences ===&lt;br /&gt;
&lt;br /&gt;
macOS supports preference settings that can be set via a shell command or via Mac remote management&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;gt; defaults write com.innovaphone.client-ios-14r1 server &amp;quot;PBX-server-URL&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following parameters and can be set through this method:&lt;br /&gt;
&lt;br /&gt;
; server: the PBX&#039;s server URL&lt;br /&gt;
&lt;br /&gt;
=== Setting myApps as Default App for SIP-URLs ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|defaults write com.apple.LaunchServices/com.apple.launchservices.secure LSHandlers -array-add &#039;{&lt;br /&gt;
   LSHandlerURLScheme = sip;&lt;br /&gt;
   LSHandlerRoleAll = &amp;quot;&amp;lt;CFBundleIdentifier&amp;gt;&amp;quot;;&lt;br /&gt;
}&#039;&lt;br /&gt;
|}&lt;br /&gt;
To find the “CFBundleIdentifier”, proceed as follows:&lt;br /&gt;
&lt;br /&gt;
* In the Finder under “Applications”, search for the desired myApps client that you want to set as the default app.&lt;br /&gt;
&lt;br /&gt;
* Right-click on “Show package contents” -&amp;gt; you will find the “CFBundleIdentifier” in the Info.plist file.&lt;br /&gt;
&lt;br /&gt;
A restart of the MAC is required.&lt;br /&gt;
&lt;br /&gt;
=== Using Sennheiser headsets ===&lt;br /&gt;
If you use Sennheiser headsets, you should also install the then-current &amp;lt;code&amp;gt;DSEA_SDK_v&amp;lt;/code&amp;gt;&#039;&#039;version&#039;&#039;&amp;lt;code&amp;gt;.pkg&amp;lt;/code&amp;gt; package, after you installed the myApps client.  Without that, audio will still work, but not the controls on the headset.  You will need to keep that up-to-date yourself, as it is not updated by myApps&#039;s auto-update function.&lt;br /&gt;
&lt;br /&gt;
== Android ==&lt;br /&gt;
&lt;br /&gt;
myApps platform services are installed on Android by loading &#039;&#039;innovaphone myApps&#039;&#039; from the &#039;&#039;Play Store&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Configuration via MDM ===&lt;br /&gt;
&lt;br /&gt;
the PBX&#039;s server URL can be pre-configured by specifying a property &amp;quot;server&amp;quot; with string value &amp;quot;pbx.example.com&amp;quot; in the MDM.&lt;br /&gt;
&lt;br /&gt;
= Configuration =&lt;br /&gt;
&lt;br /&gt;
== Server configuration ==&lt;br /&gt;
When opening myApps for the first time, the user is prompted for the Server. Usually only the hostname (DNS host name or IP address) needs to be configured.&lt;br /&gt;
&lt;br /&gt;
But there are more options for special PBX configurations.&lt;br /&gt;
&lt;br /&gt;
; Non-standard HTTPS port&lt;br /&gt;
: If the PBX uses a non-standard HTTPS port, it must be appended to the host name separated by a colon (&amp;lt;code&amp;gt;:&amp;lt;/code&amp;gt;).&lt;br /&gt;
: Example: &amp;lt;code&amp;gt;pbx.example.com:4444&amp;lt;/code&amp;gt; (expands to &amp;lt;code&amp;gt;https://pbx.example.com:4444/PBX0/APPCLIENT/appclient.htm&amp;lt;/code&amp;gt;)&lt;br /&gt;
; DynPBX module name&lt;br /&gt;
: If the PBX is a DynPBX, the module id must be appended to PBX0 separated - (&amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt;).&lt;br /&gt;
: Example: &amp;lt;code&amp;gt;pbx.example.com/PBX0-1&amp;lt;/code&amp;gt; (expands to &amp;lt;code&amp;gt;https://pbx.example.com/PBX0-1/APPCLIENT/appclient.htm&amp;lt;/code&amp;gt;)&lt;br /&gt;
; Softphone physical location&lt;br /&gt;
: If user defined physical location shall be used for softphone, you can append it using a parameter &amp;lt;code&amp;gt;#phys=&amp;lt;/code&amp;gt;.&lt;br /&gt;
: Example: &amp;lt;code&amp;gt;pbx.example.com#phys=slave&amp;lt;/code&amp;gt; (expands to &amp;lt;code&amp;gt;https://pbx.example.com/PBX0/APPCLIENT/appclient.htm#phys=slave&amp;lt;/code&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Example 1: PBX pbx.example.com with standard configuration&lt;br /&gt;
 pbx.example.com&lt;br /&gt;
&lt;br /&gt;
Example 2: PBX slave.example with DynPBX module ID 1, HTTPS port 4444 and physical location master&lt;br /&gt;
 slave.example.com:4444/PBX0-1#phys=master&lt;br /&gt;
&lt;br /&gt;
=== HTTP proxy support ===&lt;br /&gt;
&lt;br /&gt;
myApps platform services do support operation via HTTP proxy now. If one or more proxies have been configured in the network settings of the operating system for the active network connection, HTTP CONNECT tunnels are established.&lt;br /&gt;
&lt;br /&gt;
On Windows user name and password can be specified for the tunnel servers as generic credentials in the credentials manager (Anmeldeinformationsverwaltung). The name of the credentials must be the tunnel server hostname.&lt;br /&gt;
&lt;br /&gt;
On Android user name and password can be specified through Android &#039;&#039;Settings, Accounts&#039;&#039; by adding a myApps &#039;&#039;HTTP Proxy Credentials&#039;&#039; account. The name of the account must be the tunnel server hostname.&lt;br /&gt;
&lt;br /&gt;
== Platform specific settings ==&lt;br /&gt;
When myApps runs under the myApps platform services, it will show various platform specific settings as part of its &#039;&#039;burger menu&#039;&#039;, so the user can set them.  See &#039;&#039;Advanced settings&#039;&#039; in [[#UI elements|UI elements]] above.&lt;br /&gt;
&lt;br /&gt;
Some options can also be set globally for all myApps clients in the PBX&#039;s [[{{NAMESPACE}}:PBX/Config/myApps#Client_Settings|PBX/Config/myApps &#039;&#039;Client Settings&#039;&#039;]]&lt;br /&gt;
{|&lt;br /&gt;
! style=&amp;quot;text-align: left; font-weight: bold&amp;quot; | Option&lt;br /&gt;
&lt;br /&gt;
! style=&amp;quot;text-align: left; font-weight: bold&amp;quot; | Description&lt;br /&gt;
&lt;br /&gt;
! style=&amp;quot;text-align: left; font-weight: bold&amp;quot; | Where to set&lt;br /&gt;
&lt;br /&gt;
!&lt;br /&gt;
! style=&amp;quot;text-align: left; font-weight: bold&amp;quot;| Availability&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| || || User menu || PBX &#039;&#039;Client Settings&#039;&#039; || Windows || iOS || Android || macOS&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| Autostart || Launch myApps on login || &amp;amp;#10004; ||&amp;amp;#10004; ||&amp;amp;#10004; || &amp;amp;#10007; || &amp;amp;#10007; || &amp;amp;#10004;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| Appear offline after || controls after which idle time a user is considered &#039;&#039;inactive&#039;&#039;. See [[#User activity|User activity]] above || &amp;amp;#10004; ||&amp;amp;#10004; ||&amp;amp;#10004; || &amp;amp;#10007; || &amp;amp;#10007; || &amp;amp;#10004;&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| Hotkeys || Hotkeys for call dial, accept, reject. See [[#Hot keys|Hot keys]] above || &amp;amp;#10004; ||&amp;amp;#10004; ||&amp;amp;#10004; || &amp;amp;#10007; || &amp;amp;#10007; || &amp;amp;#10004;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| Docking || Docking mode (left, right, none). See [[#???|??]] above || &amp;amp;#10004; ||&amp;amp;#10004; ||&amp;amp;#10004; || &amp;amp;#10007; || &amp;amp;#10007; || &amp;amp;#10007;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| Desktop notifications|| Turn on/off platform notifications. See [[#Notifications|  Notifications]] above || &amp;amp;#10004; ||&amp;amp;#10004; ||&amp;amp;#10004; || &amp;amp;#10007; || &amp;amp;#10007; || &amp;amp;#10004;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| VPN || Disable VPN address for ICE candidate selection. See [[#RTP ports| RTP ports]] above || &amp;amp;#10004; ||&amp;amp;#10004; ||&amp;amp;#10004; || &amp;amp;#10007; || &amp;amp;#10004; || &amp;amp;#10004;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| Show in taskbar|| Show myApps in the taskbar in addition to it&#039;s tray icon.  || &amp;amp;#10004; ||&amp;amp;#10007; ||&amp;amp;#10004; || &amp;amp;#10007; || &amp;amp;#10007; || &amp;amp;#10007;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| Log flags || turn on/off certain trace levels. See [[#Troubleshooting|Troubleshooting]] below.  || &amp;amp;#10004; ||&amp;amp;#10004; ||&amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004; || &amp;amp;#10004;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| External applications || define the applications available for Apps to be started. See [[#Call an external application for calls|Call an external application for calls]] above.  || &amp;amp;#10004; ||&amp;amp;#10007; ||&amp;amp;#10004; || &amp;amp;#10007; || &amp;amp;#10007; || &amp;amp;#10004;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| Ring in headset || send ring tone for incoming to headset instead of loudspeaker.  || &amp;amp;#10004; ||&amp;amp;#10007; ||&amp;amp;#10004; || &amp;amp;#10007; || &amp;amp;#10007; || &amp;amp;#10007;&lt;br /&gt;
|}&lt;br /&gt;
== Start parameters for Windows ==&lt;br /&gt;
&lt;br /&gt;
On Windows, it is not possible to pass start parameters from the [https://www.chromium.org/developers Chromium documentation] to the myApps process.&lt;br /&gt;
&lt;br /&gt;
== OS Settings for Windows ==&lt;br /&gt;
Windows settings can influence the display of &#039;&#039;Desktop notifications&#039;&#039;. See [https://support.microsoft.com/en-us/help/4028678/windows-10-change-notification-settings Change notification settings in Windows 10/11] for details.&lt;br /&gt;
&lt;br /&gt;
=== Windows 11 ===&lt;br /&gt;
&lt;br /&gt;
* Windows 11 has a feature &amp;quot;do not disturb&amp;quot;. This hides notifications if enabled.&lt;br /&gt;
* Windows 11 has a feature &amp;quot;focus&amp;quot;. This enables &amp;quot;do not disturb&amp;quot; and thus hides notifications too.&lt;br /&gt;
* Windows 11 has priority settings for notifications. Ensure that VoIP notifications for calls are allowed any maybe also include myApps as an App which is allowed to show notifications.&lt;br /&gt;
&lt;br /&gt;
== OS settings for Android ==&lt;br /&gt;
; Events : The appearance of notifications can be controlled here.&lt;br /&gt;
&lt;br /&gt;
; Call accounts : For proper incoming call signaling, the call account &#039;&#039;myApps&#039;&#039; needs to be enabled. Note that on Samsung smartphones the call account switch likely toggles back and a few tries may need to be done until it persists. Please double-check the state.&lt;br /&gt;
&lt;br /&gt;
; Preferred Calling Account : Choose which calling account (myApps/SIM/..) should be used for outgoing calls initiated from within the native phone app / phone book.&lt;br /&gt;
&lt;br /&gt;
; Background data, unlimited data usage : Grant background data use to enable &#039;&#039;myApps&#039;&#039; to connect to the PBX immediately on an incoming call.&lt;br /&gt;
&lt;br /&gt;
; Overlaying : This setting is not needed if call account &#039;&#039;myApps&#039;&#039; has been enabled. Should there be a reason for not enabling call account &#039;&#039;myApps&#039;&#039;, the permission for overlaying needs to be granted on Android 10 or higher for proper call signaling.&lt;br /&gt;
&lt;br /&gt;
Note: If no SIM card is installed some Android smartphones exhibit a problem dialing from the smartphone contacts. The contacts app shows a choice &#039;&#039;Select SIM card for this call&#039;&#039; but all possible dialers are greyed out. In this case make myApps the default phone app in Android settings &#039;&#039;Apps, Default apps, Telephony&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== OS settings for iOS ==&lt;br /&gt;
; Notifications : The appearance of notifications can be controlled in iOS &#039;&#039;Settings, myApps&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== OS settings for macOS ==&lt;br /&gt;
&lt;br /&gt;
; Notifications : The appearance of notifications can be controlled in macOS &#039;&#039;Preferences, Notifications, myApps&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=Troubleshooting=&lt;br /&gt;
&lt;br /&gt;
myApps platform services can write various traces for debugging.  Trace can be turned on and off selectively in the [[#Advanced settings|Advanced settings]].&lt;br /&gt;
&lt;br /&gt;
The following trace flags can be set:&lt;br /&gt;
&lt;br /&gt;
(&#039;&#039;Recommended trace options are: &#039;&#039;&#039;App, Browser, ICE, TURN, Signaling and Audio&#039;&#039;&#039;. Please do not activate other flags unless innovaphone support says otherwise&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
!style=&amp;quot;text-align: left; font-weight: bold&amp;quot; |  Abbreviation&lt;br /&gt;
&lt;br /&gt;
!style=&amp;quot;text-align: left; font-weight: bold&amp;quot; |code&lt;br /&gt;
&lt;br /&gt;
!style=&amp;quot;text-align: left; font-weight: bold&amp;quot; | description&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| App||0x000000001|| logs from the App Service itself&lt;br /&gt;
|-&lt;br /&gt;
| DNS||0x000000008|| logs DNS requests and results&lt;br /&gt;
|-&lt;br /&gt;
| HTTP client||0x000000080|| http client logs&lt;br /&gt;
|-&lt;br /&gt;
| TLS||0x000000400|| TLS logs&lt;br /&gt;
|-&lt;br /&gt;
| TCP||0x000000800|| TCP logs&lt;br /&gt;
|-&lt;br /&gt;
| LDS||0x000001000|| local domain sockets&lt;br /&gt;
|-&lt;br /&gt;
| WebSocket client||0x000004000|| logs outgoing websocket connections&lt;br /&gt;
|-&lt;br /&gt;
| App WebSocket||0x000008000|| logs app websocket connections (e.g. from PBX objects to an App Service or from the UI to the App Service)&lt;br /&gt;
|-&lt;br /&gt;
| UDP||0x000200000|| UDP logs&lt;br /&gt;
|-&lt;br /&gt;
| DTLS||0x000400000|| logs DTLS handshake and messages&lt;br /&gt;
|-&lt;br /&gt;
| Media||0x000800000|| logs media events&lt;br /&gt;
|-&lt;br /&gt;
| Media channel||0x001000000|| logs RTP/SCTP media connections&lt;br /&gt;
|-&lt;br /&gt;
| ICE||0x002000000|| logs ICE messages between peers&lt;br /&gt;
|-&lt;br /&gt;
| TURN||0x004000000|| logs TURN messages between peers&lt;br /&gt;
|-&lt;br /&gt;
| AppSharing||0x008000000|| logs AppSharing connection&lt;br /&gt;
|-&lt;br /&gt;
| Audio||0x010000000|| logs Audio connection and headset events&lt;br /&gt;
|-&lt;br /&gt;
| Video||0x020000000|| logs video connection and webcam events&lt;br /&gt;
|-&lt;br /&gt;
| Browser||0x040000000|| logs Chromium events&lt;br /&gt;
|-&lt;br /&gt;
| AppProxy||0x080000000|| logs requests which are proxied between the local webserver and the remote server&lt;br /&gt;
|-&lt;br /&gt;
| Webserver ||0x200000000|| enables webserver specific logs&lt;br /&gt;
|-&lt;br /&gt;
| Browser Console ||0x400000000|| logs browser console events&lt;br /&gt;
|-&lt;br /&gt;
| Signaling||0x800000000|| enables logs in the signaling module for debugging calls&lt;br /&gt;
|}&lt;br /&gt;
&#039;&#039;code&#039;&#039; can be or&#039;ed and used as value for the &#039;&#039;Log flags&#039;&#039; field in [[{{NAMESPACE}}:PBX/Config/myApps#Client_Settings|PBX/Config/myApps/Client Settings]].&lt;br /&gt;
&lt;br /&gt;
; Windows :On Windows, traces are written to the &amp;lt;code&amp;gt;C:\Users\[UserName]\AppData\Local\innovaphone\myApps&amp;lt;/code&amp;gt; directory. If you start myApps with --log-size as parameter, you can define the maximum size of a log file (e.g. --log-size=100000000 would be 100MB for each file)&lt;br /&gt;
&lt;br /&gt;
:* myApps-&#039;&#039;date-time&#039;&#039;.txt : main log file for the platform services&lt;br /&gt;
&lt;br /&gt;
:* myAppsOutlookSearch-&#039;&#039;date-time&#039;&#039;.txt : log file for the Outlook phone book access&lt;br /&gt;
&lt;br /&gt;
:* myAppsHookController-&#039;&#039;date-time&#039;&#039;.txt : log file for the hot-key interceptor (see [[#Hot keys|Hot keys]])&lt;br /&gt;
&lt;br /&gt;
; :myApps update installation traces are written to the &amp;lt;code&amp;gt;%windir%\temp\&amp;lt;/code&amp;gt; directory.&lt;br /&gt;
:* myAppsInstall.txt: MSI installation file&lt;br /&gt;
&lt;br /&gt;
; :myApps update service traces are written to the &amp;lt;code&amp;gt;%ALLUSERSPROFILE%\innovaphone\myAppsUpdateService&amp;lt;/code&amp;gt; directory.&lt;br /&gt;
:* myAppsUpdateService-&#039;&#039;date-time&#039;&#039;.txt: myApps update service traces&lt;br /&gt;
&lt;br /&gt;
;Android : traces can be sent by e-mail.&lt;br /&gt;
&lt;br /&gt;
: also, an Android device might also be connected to a PC via an USB cable to get the traces. The files can be found in &amp;lt;code&amp;gt;Android/data/com.innovaphone.clientandroid/files&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; iOS : traces can be sent by e-mail.&lt;br /&gt;
&lt;br /&gt;
; macOS : traces can be sent by e-mail.&lt;br /&gt;
&lt;br /&gt;
: also, the files can be found in &amp;lt;code&amp;gt;~/Library/Containers/com.innovaphone.client-ios/Data/Documents/&amp;lt;/code&amp;gt;. Press &#039;&#039;Alt+N&#039;&#039; followed by space to get tilde &#039;&#039;~&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
= Known Problems =&lt;br /&gt;
[[:Category:Problem myApps platform services|Known Problems]]&lt;br /&gt;
&lt;br /&gt;
= Related Articles =&lt;br /&gt;
* [[{{NAMESPACE}}:Concept_myApps]]&lt;br /&gt;
* [[{{NAMESPACE}}:Concept_myApps_Redundancy|Reference14r2:Concept_myApps_Redundancy]]&lt;br /&gt;
* [[{{NAMESPACE}}:Concept_myApps_Office_Integration|Reference14r2:Concept_myApps_Office_Integration]]&lt;br /&gt;
* [[{{NAMESPACE}}:Concept_myAPPs_Search_in_local-Outlook_Contacts|Reference14r2:Concept_myAPPs_Search_in_local-Outlook_Contacts]]&lt;br /&gt;
* [[{{NAMESPACE}}:Call_Detail_Record_CDR_PBX|Reference14r2:Call_Detail_Record_CDR_PBX]]&lt;br /&gt;
* [[{{NAMESPACE}}:Concept Push Notifications for myPBX iOS and Android|Reference14r2:Concept Push Notifications for myPBX iOS and Android]]&lt;br /&gt;
* [[Howto:Troubleshoot v13 Push with myApps for Android and iOS]]&lt;br /&gt;
* [[{{NAMESPACE}}:PBX/Config/myApps]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Concept myApps platform services]]&lt;/div&gt;</summary>
		<author><name>Tfu</name></author>
	</entry>
	<entry>
		<id>https://wiki.innovaphone.com/index.php?title=Main_Page&amp;diff=78946</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://wiki.innovaphone.com/index.php?title=Main_Page&amp;diff=78946"/>
		<updated>2026-02-24T09:53:01Z</updated>

		<summary type="html">&lt;p&gt;Tfu: /* Latest News */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&amp;lt;!-- Message of the day --&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;margin:0px; margin-right:10px; border:1px solid #58C4C3; background-color:#F4F4F4; padding:0em 1em 0em 1em;&amp;quot;&amp;gt;&lt;br /&gt;
== Remote Support ==&lt;br /&gt;
[[Image:RemoteControl-click.png|left|60px|RemoteControl.png/|Download Remote Control|link=https://store.innovaphone.com/alpha/download/software/remotecontrolwindowsportable/16r1/remoteControl.exe]]&lt;br /&gt;
innovaphone only carries out scheduled remote maintenance via our ticket system by prior consultation.&amp;lt;br/&amp;gt;&lt;br /&gt;
As Remote Support Tool, we use our own product Remote Control ([https://www.innovaphone.com/en/all-apps/apps-to-work-with/remote-control-app.html more info]).&lt;br /&gt;
&lt;br /&gt;
You can &#039;&#039;&#039;[https://store.innovaphone.com/alpha/download/software/remotecontrolwindowsportable/16r1/remoteControl.exe download]&#039;&#039;&#039; the Remote Control client already or use the support link received from our support team.&amp;lt;br/&amp;gt;&lt;br /&gt;
After installing and opening the client you can &#039;&#039;&#039;pass the shown ID&#039;&#039;&#039; or &#039;&#039;&#039;use the received link&#039;&#039;&#039; to request the support session.&lt;br /&gt;
&lt;br /&gt;
== Searching ==&lt;br /&gt;
Searching in wiki works, but is sometimes cumbersome.  However, you can have Google do the job for you.  Try [https://www.google.de/search?q=site%3Ainnovaphone.com+xml+documentation &amp;lt;code&amp;gt;site:innovaphone.com your search terms&amp;lt;/code&amp;gt;] to search the innovaphone sites for matches!&lt;br /&gt;
&lt;br /&gt;
If you still don&#039;t find what you are looking for, [mailto:presales@innovaphone.com drop us a message]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- latest news commented out, may be reactivated once there are new really --&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;margin:0px; margin-right:10px; margin-top:15px; border:1px solid #58C4C3; background-color:#F4F4F4; padding:0em 1em 0.5em 1em;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!-- please insert new message ON TOP and remove extraneous (more than 5) old messages --&amp;gt;&lt;br /&gt;
&amp;lt;!-- &amp;lt;nowiki&amp;gt; ~~~~ is replaced by your name and date automatically &amp;lt;/nowiki&amp;gt; --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Latest News ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p align=&amp;quot;right&amp;quot;&amp;gt;[[User:Tfu|Tfu]] 10:48, 24 February 2026 (CET)&amp;lt;/p&amp;gt;&lt;br /&gt;
[[Support:WinPDM Software 3130114 (4.2.1) released| WinPDM Software 3130113 (4.2.1)]] is now available from the [https://store.innovaphone.com/release/download.htm App store].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p align=&amp;quot;right&amp;quot;&amp;gt;[[User:Msc|Msc]] ([[User talk:Msc|talk]]) 15:05, 2 February 2026 (CET)&amp;lt;/p&amp;gt; [[Support:Firmware_V16r1_product/16r1/firmware_1610613_(beta5)_available | Version 16r1 Beta 5]] is now available from the [http://store.innovaphone.com/beta/download.htm Beta Store]. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;p align=&amp;quot;right&amp;quot;&amp;gt;[[User:Ndiehl|Ndiehl]] ([[User talk:Ndiehl|talk]]) 13:47, 10 February 2026 (CET)&amp;lt;/p&amp;gt; [[Support:Firmware V15r1 product/15r1/firmware 1510665 (sr 10) available | Version 15r1 Service Release 10]] is now available from the [http://store.innovaphone.com/release/download.htm download page].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p align=&amp;quot;right&amp;quot;&amp;gt;[[User:Ndiehl|Ndiehl]] ([[User talk:Ndiehl|talk]]) 13:47, 10 February 2026 (CET)&amp;lt;/p&amp;gt; [[Support:Firmware V14r2 product/14r2/firmware 1420581 (sr 18) available | Version 14r2 Service Release 18]] is now available from the [http://store.innovaphone.com/release/download.htm download page].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p align=&amp;quot;right&amp;quot;&amp;gt;[[User:Ndiehl|Ndiehl]] ([[User talk:Ndiehl|talk]]) 13:47, 10 February 2026 (CET)&amp;lt;/p&amp;gt; [[Support:Firmware V13r3 product/13r3/firmware 138045 (sr 35) available | Version 13r3 Service Release 35]] is now available from the [http://store.innovaphone.com/release/download.htm download page].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p align=&amp;quot;right&amp;quot;&amp;gt;[[User:Tfu|Tfu]] ([[User talk:Tfu&amp;amp;action=edit&amp;amp;redlink=1|talk]]) 15:28, 13 March 2025 (CEST)&amp;lt;/p&amp;gt;&lt;br /&gt;
[[Support:Wireless Handset Firmware IP73 1012 (6.1.13) released| Wireless Handset Firmware IP73 1012 (6.1.13) released]] is now available from the [https://store.innovaphone.com/release/download.htm App store].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p align=&amp;quot;right&amp;quot;&amp;gt;[[User:Msu|Msu]] ([[User talk:Msu&amp;amp;action=edit&amp;amp;redlink=1|talk]]) 15:54, 18 February 2025 (CEST)&amp;lt;/p&amp;gt;&lt;br /&gt;
[[Support:Wireless Handset Firmware IP64 10317 (4.3.2)/IP65 10122 (4.3.2) released| Wireless Handset Firmware IP64 10317 (4.3.2)/IP65 10122 (4.3.2)]] is now available from the [https://store.innovaphone.com/release/download.htm App store].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p align=&amp;quot;right&amp;quot;&amp;gt;[[User:Msu|Msu]] ([[User talk:Msu&amp;amp;action=edit&amp;amp;redlink=1|talk]]) 15:54, 18 February 2025 (CEST)&amp;lt;/p&amp;gt;&lt;br /&gt;
[[Support:Wireless Handset Firmware D83 10002 (2.0.5) released| Wireless Handset Firmware D83 10002 (2.0.5)]] is now available from the [https://store.innovaphone.com/release/download.htm App store].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p align=&amp;quot;right&amp;quot;&amp;gt;[[User:Afi|Afi]] 15:38, 6 February 2023 (CET)&amp;lt;/p&amp;gt;&lt;br /&gt;
[[Support:Wireless Handset Firmware IP62 3040621 (6.2.7) released| Wireless Handset Firmware IP62 3040621 (6.2.7)]] is now available from the [https://store.innovaphone.com/release/download.htm App store].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p align=&amp;quot;right&amp;quot;&amp;gt;[[User:Afi|Afi]] 12:46, 16 June 2021 (CEST))&amp;lt;/p&amp;gt;&lt;br /&gt;
[[Support:TAPI Service Provider 8188 (hotfix21) available|TAPI Service Provider 8188 (hotfix21)]] is now available from [https://store.innovaphone.com/release/download.htm the Software download area].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p align=&amp;quot;right&amp;quot;&amp;gt;[[User:Afi|Afi]] 18:21, 12 October 2020 (CEST)&amp;lt;/p&amp;gt;&lt;br /&gt;
[[Support:Wireless Handset Firmware IP61 3022811 (4.7.8)/IP63 3022912 (4.7.8) released| Wireless Handset Firmware IP61 3022811 (4.7.8)/IP63 3022912 (4.7.8)]] is now available from the [https://store.innovaphone.com/release/download.htm App store].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p align=&amp;quot;right&amp;quot;&amp;gt;[[User:Afi|Afi]] 21:30, 27 March 2020 (CET)&amp;lt;/p&amp;gt;&lt;br /&gt;
[[Support:Wireless Handset Firmware and Management Software product/9.00/wireless 100037 (hotfix19) available| Wireless Package hotfix 19]] is now available from the [http://download.innovaphone.com/ice/9.00#wireless V9 download area].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;margin:0px; margin-right:10px; margin-top:15px; border:1px solid #58C4C3; background-color:#F4F4F4; padding:0em 1em 0.5em 1em;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== New Articles ==&lt;br /&gt;
&amp;lt;!-- https://www.mediawiki.org/wiki/Extension:Newest_Pages --&amp;gt;&lt;br /&gt;
{{Special:Newestpages/all/20}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;margin:0px; margin-right:10px; margin-top:15px; border:1px solid #58C4C3; background-color:#F4F4F4; padding:0em 1em 0.5em 1em; font-size:1&amp;quot;&amp;gt;&lt;br /&gt;
== More innovaphone Ressources ==&lt;br /&gt;
* [http://www.innovaphone.com Home Page]&lt;br /&gt;
* [http://download.innovaphone.com Download Site ]&lt;br /&gt;
* [http://my.innovaphone.com my.innovaphone ]&lt;br /&gt;
* [http://mantis.innovaphone.com/ Ticketing System ]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>Tfu</name></author>
	</entry>
	<entry>
		<id>https://wiki.innovaphone.com/index.php?title=User:Tfu&amp;diff=78945</id>
		<title>User:Tfu</title>
		<link rel="alternate" type="text/html" href="https://wiki.innovaphone.com/index.php?title=User:Tfu&amp;diff=78945"/>
		<updated>2026-02-24T09:52:19Z</updated>

		<summary type="html">&lt;p&gt;Tfu: Blanked the page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Tfu</name></author>
	</entry>
	<entry>
		<id>https://wiki.innovaphone.com/index.php?title=Main_Page&amp;diff=78944</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://wiki.innovaphone.com/index.php?title=Main_Page&amp;diff=78944"/>
		<updated>2026-02-24T09:52:01Z</updated>

		<summary type="html">&lt;p&gt;Tfu: /* Latest News */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&amp;lt;!-- Message of the day --&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;margin:0px; margin-right:10px; border:1px solid #58C4C3; background-color:#F4F4F4; padding:0em 1em 0em 1em;&amp;quot;&amp;gt;&lt;br /&gt;
== Remote Support ==&lt;br /&gt;
[[Image:RemoteControl-click.png|left|60px|RemoteControl.png/|Download Remote Control|link=https://store.innovaphone.com/alpha/download/software/remotecontrolwindowsportable/16r1/remoteControl.exe]]&lt;br /&gt;
innovaphone only carries out scheduled remote maintenance via our ticket system by prior consultation.&amp;lt;br/&amp;gt;&lt;br /&gt;
As Remote Support Tool, we use our own product Remote Control ([https://www.innovaphone.com/en/all-apps/apps-to-work-with/remote-control-app.html more info]).&lt;br /&gt;
&lt;br /&gt;
You can &#039;&#039;&#039;[https://store.innovaphone.com/alpha/download/software/remotecontrolwindowsportable/16r1/remoteControl.exe download]&#039;&#039;&#039; the Remote Control client already or use the support link received from our support team.&amp;lt;br/&amp;gt;&lt;br /&gt;
After installing and opening the client you can &#039;&#039;&#039;pass the shown ID&#039;&#039;&#039; or &#039;&#039;&#039;use the received link&#039;&#039;&#039; to request the support session.&lt;br /&gt;
&lt;br /&gt;
== Searching ==&lt;br /&gt;
Searching in wiki works, but is sometimes cumbersome.  However, you can have Google do the job for you.  Try [https://www.google.de/search?q=site%3Ainnovaphone.com+xml+documentation &amp;lt;code&amp;gt;site:innovaphone.com your search terms&amp;lt;/code&amp;gt;] to search the innovaphone sites for matches!&lt;br /&gt;
&lt;br /&gt;
If you still don&#039;t find what you are looking for, [mailto:presales@innovaphone.com drop us a message]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- latest news commented out, may be reactivated once there are new really --&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;margin:0px; margin-right:10px; margin-top:15px; border:1px solid #58C4C3; background-color:#F4F4F4; padding:0em 1em 0.5em 1em;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!-- please insert new message ON TOP and remove extraneous (more than 5) old messages --&amp;gt;&lt;br /&gt;
&amp;lt;!-- &amp;lt;nowiki&amp;gt; ~~~~ is replaced by your name and date automatically &amp;lt;/nowiki&amp;gt; --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Latest News ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p align=&amp;quot;right&amp;quot;&amp;gt;[[User:Tfu|Tfu]] 10:48, 24 February 2026 (CET)&amp;lt;/p&amp;gt;&lt;br /&gt;
[[Support:WinPDM Software 3130114 (4.2.1) released| WinPDM Software 3130113 (4.1.8)]] is now available from the [https://store.innovaphone.com/release/download.htm App store].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p align=&amp;quot;right&amp;quot;&amp;gt;[[User:Msc|Msc]] ([[User talk:Msc|talk]]) 15:05, 2 February 2026 (CET)&amp;lt;/p&amp;gt; [[Support:Firmware_V16r1_product/16r1/firmware_1610613_(beta5)_available | Version 16r1 Beta 5]] is now available from the [http://store.innovaphone.com/beta/download.htm Beta Store]. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;p align=&amp;quot;right&amp;quot;&amp;gt;[[User:Ndiehl|Ndiehl]] ([[User talk:Ndiehl|talk]]) 13:47, 10 February 2026 (CET)&amp;lt;/p&amp;gt; [[Support:Firmware V15r1 product/15r1/firmware 1510665 (sr 10) available | Version 15r1 Service Release 10]] is now available from the [http://store.innovaphone.com/release/download.htm download page].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p align=&amp;quot;right&amp;quot;&amp;gt;[[User:Ndiehl|Ndiehl]] ([[User talk:Ndiehl|talk]]) 13:47, 10 February 2026 (CET)&amp;lt;/p&amp;gt; [[Support:Firmware V14r2 product/14r2/firmware 1420581 (sr 18) available | Version 14r2 Service Release 18]] is now available from the [http://store.innovaphone.com/release/download.htm download page].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p align=&amp;quot;right&amp;quot;&amp;gt;[[User:Ndiehl|Ndiehl]] ([[User talk:Ndiehl|talk]]) 13:47, 10 February 2026 (CET)&amp;lt;/p&amp;gt; [[Support:Firmware V13r3 product/13r3/firmware 138045 (sr 35) available | Version 13r3 Service Release 35]] is now available from the [http://store.innovaphone.com/release/download.htm download page].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p align=&amp;quot;right&amp;quot;&amp;gt;[[User:Tfu|Tfu]] ([[User talk:Tfu&amp;amp;action=edit&amp;amp;redlink=1|talk]]) 15:28, 13 March 2025 (CEST)&amp;lt;/p&amp;gt;&lt;br /&gt;
[[Support:Wireless Handset Firmware IP73 1012 (6.1.13) released| Wireless Handset Firmware IP73 1012 (6.1.13) released]] is now available from the [https://store.innovaphone.com/release/download.htm App store].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p align=&amp;quot;right&amp;quot;&amp;gt;[[User:Msu|Msu]] ([[User talk:Msu&amp;amp;action=edit&amp;amp;redlink=1|talk]]) 15:54, 18 February 2025 (CEST)&amp;lt;/p&amp;gt;&lt;br /&gt;
[[Support:Wireless Handset Firmware IP64 10317 (4.3.2)/IP65 10122 (4.3.2) released| Wireless Handset Firmware IP64 10317 (4.3.2)/IP65 10122 (4.3.2)]] is now available from the [https://store.innovaphone.com/release/download.htm App store].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p align=&amp;quot;right&amp;quot;&amp;gt;[[User:Msu|Msu]] ([[User talk:Msu&amp;amp;action=edit&amp;amp;redlink=1|talk]]) 15:54, 18 February 2025 (CEST)&amp;lt;/p&amp;gt;&lt;br /&gt;
[[Support:Wireless Handset Firmware D83 10002 (2.0.5) released| Wireless Handset Firmware D83 10002 (2.0.5)]] is now available from the [https://store.innovaphone.com/release/download.htm App store].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p align=&amp;quot;right&amp;quot;&amp;gt;[[User:Afi|Afi]] 15:38, 6 February 2023 (CET)&amp;lt;/p&amp;gt;&lt;br /&gt;
[[Support:Wireless Handset Firmware IP62 3040621 (6.2.7) released| Wireless Handset Firmware IP62 3040621 (6.2.7)]] is now available from the [https://store.innovaphone.com/release/download.htm App store].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p align=&amp;quot;right&amp;quot;&amp;gt;[[User:Afi|Afi]] 12:46, 16 June 2021 (CEST))&amp;lt;/p&amp;gt;&lt;br /&gt;
[[Support:TAPI Service Provider 8188 (hotfix21) available|TAPI Service Provider 8188 (hotfix21)]] is now available from [https://store.innovaphone.com/release/download.htm the Software download area].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p align=&amp;quot;right&amp;quot;&amp;gt;[[User:Afi|Afi]] 18:21, 12 October 2020 (CEST)&amp;lt;/p&amp;gt;&lt;br /&gt;
[[Support:Wireless Handset Firmware IP61 3022811 (4.7.8)/IP63 3022912 (4.7.8) released| Wireless Handset Firmware IP61 3022811 (4.7.8)/IP63 3022912 (4.7.8)]] is now available from the [https://store.innovaphone.com/release/download.htm App store].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p align=&amp;quot;right&amp;quot;&amp;gt;[[User:Afi|Afi]] 21:30, 27 March 2020 (CET)&amp;lt;/p&amp;gt;&lt;br /&gt;
[[Support:Wireless Handset Firmware and Management Software product/9.00/wireless 100037 (hotfix19) available| Wireless Package hotfix 19]] is now available from the [http://download.innovaphone.com/ice/9.00#wireless V9 download area].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;margin:0px; margin-right:10px; margin-top:15px; border:1px solid #58C4C3; background-color:#F4F4F4; padding:0em 1em 0.5em 1em;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== New Articles ==&lt;br /&gt;
&amp;lt;!-- https://www.mediawiki.org/wiki/Extension:Newest_Pages --&amp;gt;&lt;br /&gt;
{{Special:Newestpages/all/20}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;margin:0px; margin-right:10px; margin-top:15px; border:1px solid #58C4C3; background-color:#F4F4F4; padding:0em 1em 0.5em 1em; font-size:1&amp;quot;&amp;gt;&lt;br /&gt;
== More innovaphone Ressources ==&lt;br /&gt;
* [http://www.innovaphone.com Home Page]&lt;br /&gt;
* [http://download.innovaphone.com Download Site ]&lt;br /&gt;
* [http://my.innovaphone.com my.innovaphone ]&lt;br /&gt;
* [http://mantis.innovaphone.com/ Ticketing System ]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>Tfu</name></author>
	</entry>
	<entry>
		<id>https://wiki.innovaphone.com/index.php?title=Reference16r1:Concept_App_Service_Connector_for_Microsoft_365&amp;diff=78908</id>
		<title>Reference16r1:Concept App Service Connector for Microsoft 365</title>
		<link rel="alternate" type="text/html" href="https://wiki.innovaphone.com/index.php?title=Reference16r1:Concept_App_Service_Connector_for_Microsoft_365&amp;diff=78908"/>
		<updated>2026-02-13T11:22:31Z</updated>

		<summary type="html">&lt;p&gt;Tfu: /* Correctness of notification URL */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
{{FIXME|reason=This article is still work in progress}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Concept|Apps]]&lt;br /&gt;
== Applies To == &lt;br /&gt;
&lt;br /&gt;
* Connector for Microsoft 365 from Version 16r1&lt;br /&gt;
&lt;br /&gt;
= Overview =&lt;br /&gt;
&lt;br /&gt;
Connector for Microsoft 365 synchronizes Microsoft Teams presences with the innovaphone PBX and back, and optionally additionally Calendar presence from Exchange Online (part of the Microsoft 365 Cloud Services).&lt;br /&gt;
It is also possible to search for your own contacts. &lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
* innovaphone PBX&lt;br /&gt;
* innovaphone Application Platform (minimum version 120004)&lt;br /&gt;
* V16r1&lt;br /&gt;
* App(Connector for Microsoft 365)&lt;br /&gt;
* PBX-App(innovaphone-microsoft365) license per user - order no. 02-00050-009&lt;br /&gt;
&lt;br /&gt;
== Concept ==&lt;br /&gt;
&lt;br /&gt;
=== User Presence ===&lt;br /&gt;
&lt;br /&gt;
==== Configuration ====&lt;br /&gt;
Please have a look into our [[Howto15r1:Configure User Presence Sync by Connector for Microsoft365|Howto guide for basic configuration aid]].&lt;br /&gt;
&lt;br /&gt;
==== Technical Overview ====&lt;br /&gt;
If the Connector for Microsoft 365 app is fully configured, the app connects to Microsoft to obtain a token. With the token, the app gets the teams users (with a Teams license) through the Microsoft Graph API.&lt;br /&gt;
A presence subscription to Microsoft is started with the licensed users of the PBX to get presence changes in Microsoft Teams for these users. A user subscription is also started to get changes of the users (adding, deleting or update). If a user has changed, the Teams users are retrieved again. If the presence has changed, it is forwarded to the PBX. The presences of Teams are mapped to the presences of the PBX.&lt;br /&gt;
&lt;br /&gt;
* User subscriptions are renewed every 60 minutes.&lt;br /&gt;
* Presence subscriptions are renewed every 10 minutes.&lt;br /&gt;
* License Check is made periodically.&lt;br /&gt;
&lt;br /&gt;
The app synchronises the PBX presence with Teams through the Graph Api. The on-the-phone presence will be renewed every 5 minutes. The other presences have a lifetime of 1 day but the away has a lifetime of 7 days.&lt;br /&gt;
The lifetimes are described [https://learn.microsoft.com/en-us/graph/api/presence-setuserpreferredpresence?view=graph-rest-1.0&amp;amp;tabs=http here]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Please be aware:&#039;&#039;&#039; The actual change of presence or line state will be live, the above-mentioned subscriptions are needed to register against the Microsoft API for changes. &lt;br /&gt;
After successful subscription Microsoft will trigger the Connector for Microsoft 365 App every time a presence or line state for a user has changed.&lt;br /&gt;
The subscription will then be renewed in the above-mentioned time interval to receive further live updates.&lt;br /&gt;
&lt;br /&gt;
===== User Matching =====&lt;br /&gt;
You now can choose the fields used for user matching on either side from the following options:&lt;br /&gt;
* PBX&lt;br /&gt;
** CN (Long Name property from the PBX user object)&lt;br /&gt;
** h323 (Name property from the PBX user object)&lt;br /&gt;
* Azure Portal&lt;br /&gt;
** displayName&lt;br /&gt;
** mail&lt;br /&gt;
** mailNickname&lt;br /&gt;
** onPremisesDistinguishedName&lt;br /&gt;
** onPremisesSamAccountName&lt;br /&gt;
** onPremisesUserPrincipalName&lt;br /&gt;
** userPrincipalName&lt;br /&gt;
&lt;br /&gt;
Additionally, you have the possibility to remove a possibly contained domain from the Azure fields content. &amp;lt;br&amp;gt;&lt;br /&gt;
Example: &#039;user@domain.tld&#039; is transformed to &#039;user&#039;, if this option is checked.&lt;br /&gt;
&lt;br /&gt;
===== Mapping Table =====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Teams Presence&lt;br /&gt;
! PBX Presence&lt;br /&gt;
|-&lt;br /&gt;
| Away&lt;br /&gt;
| away&lt;br /&gt;
|-&lt;br /&gt;
| BeRightBack&lt;br /&gt;
| away&lt;br /&gt;
|-&lt;br /&gt;
| Busy&lt;br /&gt;
| busy&lt;br /&gt;
|-&lt;br /&gt;
| DoNotDisturb&lt;br /&gt;
| dnd&lt;br /&gt;
|-&lt;br /&gt;
| InACall&lt;br /&gt;
| on-the-phone&lt;br /&gt;
|-&lt;br /&gt;
| InAMeeting&lt;br /&gt;
| meeting&lt;br /&gt;
|-&lt;br /&gt;
| Inactive&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| PresenceUnknown&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| Available&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| Offline&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| Offwork&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| OutOfOffice&lt;br /&gt;
| away&lt;br /&gt;
|-&lt;br /&gt;
| UrgentInterruptionsOnly&lt;br /&gt;
| dnd&lt;br /&gt;
|-&lt;br /&gt;
| Presenting&lt;br /&gt;
| on-the-phone&lt;br /&gt;
|-&lt;br /&gt;
| InAConferenceCall&lt;br /&gt;
| on-the-phone&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The value &amp;quot;online&amp;quot; unsets the Teams presence in the PBX.&lt;br /&gt;
&lt;br /&gt;
===== Master/Slave =====&lt;br /&gt;
&lt;br /&gt;
For Master/Slave combination the &amp;quot;Connector for Microsoft 365&amp;quot; App has to be added to the slave (if no full replication is on). The slave websocket connection is needed to display &amp;quot;on-the-phone&amp;quot; presence.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Calendar Presence ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Configuration ====&lt;br /&gt;
Please have a look into our [[Howto15r1:Configure_Calendar_Presence_Sync_by_Connector_for_Microsoft365|Howto guide for basic configuration aid]].&lt;br /&gt;
&lt;br /&gt;
==== Technical Overview ====&lt;br /&gt;
Introduced in 15r1 the Connector for Microsoft 365 will offer a possibility to sync Azure Portal calendar events (Teams, Exchange online) via the Graph API with the PXB presence.&amp;lt;br&amp;gt;&lt;br /&gt;
For now the [https://wiki.innovaphone.com/index.php?title=Reference13r3:Concept_App_Service_Calendar Calendar App] is (along with other functions) also capable of syncing calendar events, but using the old EWS mechanism, which Microsoft announced as end of life starting from 2026.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Warning:&#039;&#039;&#039; Please make sure to not use both apps for syncing calendar events in parallel, this is not supported and will most likely lead to conflicts and unexpected behaviours.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
When the configuration of the connector for Microsoft 365 Calendar Presence Sync is complete, the app connects to Microsoft to receive a token with the calendar app registered in the Azure portal.&amp;lt;br&amp;gt;&lt;br /&gt;
With the token, the app can pick up the users from the Azure portal.&amp;lt;br&amp;gt;&lt;br /&gt;
These are matched against the users in the PBX, based on the configured &amp;quot;User Assignment&amp;quot; settings.&amp;lt;br&amp;gt;&lt;br /&gt;
For each matched user with a valid Connector for Microsoft 365 licence applied, a subscription for calendar events is created at Microsoft to receive event changes in Microsoft Calendar for these users.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
A user subscription is also started to receive user changes (add, delete or update).&amp;lt;br&amp;gt;&lt;br /&gt;
If a user has changed, the users are retrieved again. &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
If a calendar event has been started or ended, it is forwarded to the PBX.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* User subscriptions are renewed every 60 minutes.&lt;br /&gt;
* Event subscriptions are renewed every day.&lt;br /&gt;
* License Check is made every hour.&lt;br /&gt;
&lt;br /&gt;
=== Contact Search ===&lt;br /&gt;
&lt;br /&gt;
==== Configuration ====&lt;br /&gt;
Please have a look into our [[Howto16r1:Configure Calendar Presence Sync by Connector for Microsoft365|Howto guide for basic configuration aid]].&lt;br /&gt;
&lt;br /&gt;
==== Technical Overview ====&lt;br /&gt;
Introduced in 16r1 the Connector for Microsoft 365 will offer a possibility to search for your own contacts (Teams, Exchange online) via the Graph API.&lt;br /&gt;
&lt;br /&gt;
When the configuration of the connector for Microsoft 365 Contact Search is complete, the app connects to Microsoft to receive a token with the contact search app registered in the Azure portal.&amp;lt;br&amp;gt;&lt;br /&gt;
With the token, the app can pick up the users from the Azure portal.&amp;lt;br&amp;gt;&lt;br /&gt;
These are matched against the users in the PBX, based on the configured &amp;quot;User Assignment&amp;quot; settings.&amp;lt;br&amp;gt;&lt;br /&gt;
For each matched user with a valid Connector for Microsoft 365 licence applied, the user can search with the Phone App, for example (a myApps search provider will be provided for all apps looking using search providers looking up contacts). The search string is made available to the Connector for Microsoft 365 via the microsoft365-api. The results are sent to the consumer, e.g. the Phone App and presented there.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
A user subscription is started to receive user changes (add, delete or update).&amp;lt;br&amp;gt;&lt;br /&gt;
If a user has changed, the users are retrieved again. &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* User subscriptions are renewed every 60 minutes.&lt;br /&gt;
* License Check is made every hour.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Be aware:&#039;&#039;&#039; Since the Connector for Microsoft 365 is an app in the Scope of myApps App Platform, IP Phones and other services not using Apps cannot benefit from this search service.&lt;br /&gt;
&lt;br /&gt;
== Related Articles ==&lt;br /&gt;
&lt;br /&gt;
=Known Limitation=&lt;br /&gt;
&lt;br /&gt;
== General ==&lt;br /&gt;
&#039;&#039;Applies to the User Presence and the Calendar Presence&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Synchronization Delay ===&lt;br /&gt;
In the official Graph-API documentation, Microsoft is providing an overview about expected latencies for change notifications.&amp;lt;br&amp;gt;&lt;br /&gt;
You can find a whole overview table here:&amp;lt;br&amp;gt;&lt;br /&gt;
https://learn.microsoft.com/en-us/graph/change-notifications-overview#latency&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
For the user presences the resource &amp;quot;presence&amp;quot; is used and an average latency of 10 seconds but a maximum up to 1 minute is provided.&amp;lt;br&amp;gt;&lt;br /&gt;
Such a delay in syncing changed presences from Teams down to the PBX are considered normal and are caused by the Microsoft Graph-API.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
In case of calendar events the average is provided as &amp;quot;less than 1 minute&amp;quot; and the maximum to 3 minutes.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== User Presence ==&lt;br /&gt;
=== Line states set by the PBX does not block calls in Teams ===&lt;br /&gt;
Line states set by a 3rd party application (like the Connector for Microsoft 365) through the graph API are currently &#039;&#039;&#039;only for display purpose and do not block new calls&#039;&#039;&#039; in Teams.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
https://techcommunity.microsoft.com/t5/teams-developer/ms-graph-setpresence-problems/m-p/2798805/highlight/true#M3957&amp;lt;br&amp;gt;&lt;br /&gt;
As you can see in the above linked discussion, there once existed a feature request on Microsoft Voice, which is no longer available since it was not voted.&lt;br /&gt;
=== Maximum number of supported users ===&lt;br /&gt;
The connector now supports multiple Microsoft Teams communication users, which is the prerequisite to subscribe for more than 650 users. There is a new ribbon (Manage Teams Accounts) that allows you to configure as many communication users as you need. Every configured communication user can be used to subscribe 650 users, for example:&lt;br /&gt;
&lt;br /&gt;
*3 configured communication users x 650 licensed users = 1950 users can be subscribed&lt;br /&gt;
&#039;&#039;&#039;Please be aware&#039;&#039;&#039;: Each communication user must have a Teams license applied.&lt;br /&gt;
&lt;br /&gt;
This limitation is caused by Microsoft.&amp;lt;br&amp;gt;&lt;br /&gt;
In the documentation of the Graph-API you will find a hint to this limitation:&amp;lt;br&amp;gt;&lt;br /&gt;
https://learn.microsoft.com/en-us/graph/changenotifications-for-presence#subscribe-to-multiple-users-presence&amp;lt;br&amp;gt;&lt;br /&gt;
Trying to subscribe more than 650 users (with one communication user) by using the presence subscription API will be declined by the graph API with an error message, that too many users are requested.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Communication User (UserSynctoPbx) ===&lt;br /&gt;
Users with MFA (multi-factor-authentication) are not supported as technical communication user for the Connector.&lt;br /&gt;
&lt;br /&gt;
=== Multiple sites / instances require multiple communication users ===&lt;br /&gt;
Each instance or each site must have separate communication users, as Microsoft only allows one concurrent subscription per communication user. (otherwise an HTTP 409 conflict will occur)&lt;br /&gt;
&lt;br /&gt;
This means that if you want to subscribe to the same Azure Portal backend from two different sites (or instances), you will need to have multiple communication users (each with an applied Teams licence) in order to be able to subscribe from all endpoints.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Subscription Timeout ===&lt;br /&gt;
&lt;br /&gt;
==== Situation ====&lt;br /&gt;
Due to a current limitation in the Graph API it is not possible to cancel or delete an active presence subscription.&amp;lt;br&amp;gt;&lt;br /&gt;
As you can see in the [https://learn.microsoft.com/en-us/graph/api/subscription-delete?view=graph-rest-1.0&amp;amp;tabs=http|documentation of the current Graph API (1.0)] the “Delete subscription” chapter does not include presence subscriptions.&amp;lt;br&amp;gt;&lt;br /&gt;
It is also not possible to have multiple subscription in parallel. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To make sure to only request a new presence subscription when the old one is not valid anymore, the app will store the state of the presence subscription and the time until it is valid in the database.&amp;lt;br&amp;gt;&lt;br /&gt;
As mentioned in the chapter “Technical Overview” we are creating presence subscriptions with a validity of 10 minutes.&amp;lt;br&amp;gt;&lt;br /&gt;
The presence subscription will be renewed as soon as it is no longer valid which will be 10 minutes after initial subscription.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Impact ====&lt;br /&gt;
If settings are changed or the app instance is restarted it will check the corresponding database entry on startup.&amp;lt;br&amp;gt;&lt;br /&gt;
In case the last presence subscription was completed less than 10 minutes ago, there is still an active presence subscription and the app has to wait for it to become invalid. &amp;lt;br&amp;gt;&lt;br /&gt;
Some Changes (e.g., to the “Notification-URL”) will only take effect after a new created subscription. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The current Beta Version of the Graph API is already providing a function to delete presence subscriptions, so we hope we can improve this behavior in the future.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Troubleshooting=&lt;br /&gt;
== General ==&lt;br /&gt;
&lt;br /&gt;
===Creating an app trace===&lt;br /&gt;
For further analysis and creating a support ticket it will be useful to have a suitable app trace. &amp;lt;br&amp;gt;&lt;br /&gt;
Before creating the trace please make sure the following trace flags are activated for the app instance:&lt;br /&gt;
* App&lt;br /&gt;
* Database&lt;br /&gt;
* HTTP client&lt;br /&gt;
* TLS&lt;br /&gt;
* TCP&lt;br /&gt;
* App WebSocket&lt;br /&gt;
* Config&lt;br /&gt;
* Webserver&lt;br /&gt;
&lt;br /&gt;
After setting the config flags, please make sure to&lt;br /&gt;
* stop the instance&lt;br /&gt;
* deleting the current instance log&lt;br /&gt;
* start the instance&lt;br /&gt;
&#039;&#039;&#039;Now please wait at least 5 Minutes before you save the log&#039;&#039;&#039;, otherwise we could not have the whole picture in the trace.&lt;br /&gt;
&lt;br /&gt;
The restart and deletion of the the old log is useful the see the complete initialization process right away.&lt;br /&gt;
&lt;br /&gt;
===SSL Certificate for notification URL===&lt;br /&gt;
It also is useful to make sure the notification URL has a valid and public signed certificate.&amp;lt;br&amp;gt;&lt;br /&gt;
You can do that, using an SSL-Checker, for example: https://www.sslshopper.com/ssl-checker.html &amp;lt;br&amp;gt;&lt;br /&gt;
Without a valid, public signed certificate, Microsoft will decline the connection since it will not be possible to establish a trust relationship for the SSL/TLS secure channel.&lt;br /&gt;
&lt;br /&gt;
===Correctness of notification URL===&lt;br /&gt;
You can try to open the notification URL in your Browser&amp;lt;br&amp;gt;&lt;br /&gt;
Most likely you will see a HTTP 404 (Not Found) error message, which is the expected behavior since we are not providing an HTML website, the HTTP GET request from the browser will not be answered with content.&amp;lt;br&amp;gt;&lt;br /&gt;
This is perfectly fine since Microsoft will send presence updates with HTTP POST and will not try to request content from our app.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
What you can find out by trying to open the URL in your browser are the two following things: &amp;lt;br&amp;gt;&lt;br /&gt;
* If you receive a HTTP 404 error message you are most likely connected to an App Platform, if not you need to check your DNS (and maybe also reverse proxy) settings.&lt;br /&gt;
* If the URL is modified and the used build number is added, an app has answered your request&lt;br /&gt;
** Example: &amp;lt;code&amp;gt;https://public.dns/your.domain/microsoft365/subscriptions&amp;lt;/code&amp;gt; is modified to &amp;lt;code&amp;gt;https://public.dns/your.domain/microsoft365/&amp;lt;b&amp;gt;1510411&amp;lt;/b&amp;gt;/subscriptions&amp;lt;/code&amp;gt;&lt;br /&gt;
** If this is not the case, your URL is wrong. (Be aware: The URL depends on the settings of the web server path of your app instance)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Be aware:&#039;&#039;&#039; The URL-Recognition in the Application Platform is &#039;&#039;&#039;case sensitive&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Activation of &amp;quot;Public client flow&amp;quot; for the registered app in Azure Portal===&lt;br /&gt;
If the subscription is not working at all, please make sure &amp;quot;Public client flow&amp;quot; is activated for the registered app in the Azure portal (as described in our [[Howto16r1:Configure User Presence Sync by Connector for Microsoft365#Create_an_App_for_syncing_Teams_to_PBX|HowTo article]]).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
The App Service trace will contain the following message if this is not the case:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;AADSTS7000218: The request body must contain the following parameter: &#039;client_assertion&#039; or &#039;client_secret&#039;.&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== User Presence == &lt;br /&gt;
===GUI Feedback===&lt;br /&gt;
The app itself shows required states with green and red as connections to the Master PBX, Authentication and Presence Subscription to identify if there are problems. &amp;lt;br&amp;gt;&lt;br /&gt;
Sometimes it needs a little bit time until the states are changed. &amp;lt;br&amp;gt;&lt;br /&gt;
If the states remain, it is mandatory to enable logs on the app platform and check for more information. &amp;lt;br&amp;gt;&lt;br /&gt;
([[Howto13r3:Configure Connector for Microsoft365#Creating an app trace|Concept App Service Connector for Microsoft 365: Creating an app trace]])&lt;br /&gt;
&lt;br /&gt;
====No connection to Master PBX====&lt;br /&gt;
Check the MasterPBX name.&amp;lt;br&amp;gt;&lt;br /&gt;
The field must only contain the name [&amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;pbx&amp;lt;/span&amp;gt;], &#039;&#039;&#039;not the full domain&#039;&#039;&#039; [&amp;lt;span style=&amp;quot;color:red;text-decoration: line-through;&amp;quot;&amp;gt;pbx.domain.tld&amp;lt;/span&amp;gt;]. ([[Howto13r3:Configure Connector for Microsoft365#Synchronization from Teams to the PBX|Synchronization from Teams to the PBX - Master PBX field]])&lt;br /&gt;
&lt;br /&gt;
====Presence subscription failed====&lt;br /&gt;
There are many reasons why the &amp;quot;Presence subscription failed&amp;quot; message could be displayed.&amp;lt;br&amp;gt;&lt;br /&gt;
We try to list the most common reasons:&lt;br /&gt;
* The permission for the registered app in the Azure portal are not correctly set ([[Howto13r3:Configure Connector for Microsoft365#Create an App for syncing Teams to PBX|Howto: Create an App for syncing Teams to PBX]])&lt;br /&gt;
* The Notification URL is wrong ([[Reference13r3:Concept App Service Connector for Microsoft 365#Correctness of notification URL|Concept App Service Connector for Microsoft 365: Correctness of notification URL]] )&lt;br /&gt;
* The App service is not reachable from the internet ([[Reference13r3:Concept App Service Connector for Microsoft 365#Correctness of notification URL|Concept App Service Connector for Microsoft 365: Correctness of notification URL]] )&lt;br /&gt;
* The certificate for the public endpoint (e.g. reverse proxy) is not valid, or not publicly signed ([[Reference13r3:Concept App Service Connector for Microsoft 365#SSL Certificate for notification URL|Concept App Service Connector for Microsoft 365: SSL Certificate for notification URL]])&lt;br /&gt;
* The user from PBX and the Azure Portal cannot be matched ([[Reference13r3:Concept App Service Connector for Microsoft 365#User Matching|Concept App Service Connector for Microsoft 365: User Matching]])&lt;br /&gt;
* The App Platforms clock time is wrong ([[Reference13r3:Concept App Service Connector for Microsoft 365#App Platform clock time is wrong|Concept App Service Connector for Microsoft 365: App Platform clock time is wrong]])&lt;br /&gt;
* No user has a valid Connector for Microsoft 365 App license ([[Reference13r3:Concept App Service Connector for Microsoft 365#Requirements|Concept App Service Connector for Microsoft 365: Requirements]])&lt;br /&gt;
&lt;br /&gt;
===Teams License for communication user===&lt;br /&gt;
If presence subscription does not work, please check if all of the configured communication users have a Microsoft Teams license applied and no multifactor authentication is in use for this particular user. &amp;lt;br&amp;gt;&lt;br /&gt;
Also please make sure you can login with the configured credentials. (If you have set a password as an Administration, the user needs to change the password during the first login, therefore the given password will be invalid for API access).&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Sometimes, after changing setting or after the instance has restarted it can take up to 12 minutes until the presence subscription is working correctly. (Due to the subscription timeout)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
= Known Issues =&lt;br /&gt;
== Special Characters In Password ==&lt;br /&gt;
If you are using special characters (*, &amp;amp;, (, ), etc.) in your password you could run into a problem with the authentication of the communication user.&amp;lt;br&amp;gt;&lt;br /&gt;
The authentication failed status is being displayed. &amp;lt;br&amp;gt;&lt;br /&gt;
For the moment the only workaround is to eliminate special characters from your password.&lt;br /&gt;
&lt;br /&gt;
==App Platform clock time is wrong==&lt;br /&gt;
If the clock time at the App Platform is not correct, this will lead to an unstable behaviour of the Connector for Microsoft 365.&amp;lt;br&amp;gt;&lt;br /&gt;
Since the Connector for Microsoft 365 is using the Microsoft Graph APIs presence subscription function, it needs to provide in its request a precise time until the subscription validity will be expired.&amp;lt;br&amp;gt;&lt;br /&gt;
The app service is handling subscription and will automatically recreate a new subscription each time the previous one has expired.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A wrong clock time will lead to false expiration times and thus&lt;br /&gt;
*  the subscription will be expired earlier than expected (synchronisation is not working because there is no valid subscription)&lt;br /&gt;
*  the subscription will be valid longer than expected (the app service is trying to create a new subscription because it is expecting the previous one to be expired - will lead to a 409 conflict error, because only one subscription can be valid at a time)&lt;br /&gt;
&lt;br /&gt;
If you are not sure about the current time of the App Platform, you can login via SSH into the App Platform and execute the &amp;lt;code&amp;gt;date&amp;lt;/code&amp;gt; command to check the current time.&amp;lt;br&amp;gt;&lt;br /&gt;
You will receive an output like: &lt;br /&gt;
 Tue Mar 12 13:38:57 UTC 2024&lt;br /&gt;
Please be aware: The time is displayed in UTC, so please make sure to convert to your local time zone.&lt;br /&gt;
&lt;br /&gt;
==Geoblocking==&lt;br /&gt;
Since there might be no reliable country assignment for Microsoft addresses, all Microsoft addresses must be enabled on the upstream firewall in the event of geoblocking in order to ensure functionality of the Office365 Connector.&amp;lt;br&amp;gt;&lt;br /&gt;
As an alternative you might be able to configure your firewall to bypass the geoblocking for the configured notification URL.&lt;br /&gt;
&lt;br /&gt;
= Related Articles =&lt;br /&gt;
[[Howto16r1:Configure User Presence Sync by Connector for Microsoft365]] &amp;lt;br/&amp;gt;&lt;br /&gt;
[[Howto16r1:Configure Calendar Presence Sync by Connector for Microsoft365]] &amp;lt;br/&amp;gt;&lt;br /&gt;
[[Howto16r1:Configure Contact Search by Connector for Microsoft365]] &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Howto|{{PAGENAME}}]]&lt;/div&gt;</summary>
		<author><name>Tfu</name></author>
	</entry>
	<entry>
		<id>https://wiki.innovaphone.com/index.php?title=Reference15r1:Concept_App_Service_Connector_for_Microsoft_365&amp;diff=78907</id>
		<title>Reference15r1:Concept App Service Connector for Microsoft 365</title>
		<link rel="alternate" type="text/html" href="https://wiki.innovaphone.com/index.php?title=Reference15r1:Concept_App_Service_Connector_for_Microsoft_365&amp;diff=78907"/>
		<updated>2026-02-13T11:21:42Z</updated>

		<summary type="html">&lt;p&gt;Tfu: /* Activation of &amp;quot;Public client flow&amp;quot; for the registered app in Azure Portal */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Concept|Apps]]&lt;br /&gt;
== Applies To == &lt;br /&gt;
&lt;br /&gt;
* Connector for Microsoft 365 from Version 15r1&lt;br /&gt;
&lt;br /&gt;
= Overview =&lt;br /&gt;
&lt;br /&gt;
Connector for Microsoft 365 synchronizes Microsoft Teams presences with the innovaphone PBX and back, and optionally additionally Calendar presence from Exchange Online (part of the Microsoft 365 Cloud Services).&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
* innovaphone PBX&lt;br /&gt;
* innovaphone Application Platform (minimum version 120004)&lt;br /&gt;
* V15r1&lt;br /&gt;
* App(Connector for Microsoft 365)&lt;br /&gt;
* PBX-App(innovaphone-microsoft365) license per user - order no. 02-00050-009&lt;br /&gt;
&lt;br /&gt;
== Concept ==&lt;br /&gt;
&lt;br /&gt;
=== User Presence ===&lt;br /&gt;
&lt;br /&gt;
==== Configuration ====&lt;br /&gt;
Please have a look into our [[Howto15r1:Configure User Presence Sync by Connector for Microsoft365|Howto guide for basic configuration aid]].&lt;br /&gt;
&lt;br /&gt;
==== Technical Overview ====&lt;br /&gt;
If the Connector for Microsoft 365 app is fully configured, the app connects to Microsoft to obtain a token. With the token, the app gets the teams users (with a Teams license) through the Microsoft Graph API.&lt;br /&gt;
A presence subscription to Microsoft is started with the licensed users of the PBX to get presence changes in Microsoft Teams for these users. A user subscription is also started to get changes of the users (adding, deleting or update). If a user has changed, the Teams users are retrieved again. If the presence has changed, it is forwarded to the PBX. The presences of Teams are mapped to the presences of the PBX.&lt;br /&gt;
&lt;br /&gt;
* User subscriptions are renewed every 60 minutes.&lt;br /&gt;
* Presence subscriptions are renewed every 10 minutes.&lt;br /&gt;
* License Check is made periodically.&lt;br /&gt;
&lt;br /&gt;
The app synchronises the PBX presence with Teams through the Graph Api. The on-the-phone presence will be renewed every 5 minutes. The other presences have a lifetime of 1 day but the away has a lifetime of 7 days.&lt;br /&gt;
The lifetimes are described [https://learn.microsoft.com/en-us/graph/api/presence-setuserpreferredpresence?view=graph-rest-1.0&amp;amp;tabs=http here]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Please be aware:&#039;&#039;&#039; The actual change of presence or line state will be live, the above-mentioned subscriptions are needed to register against the Microsoft API for changes. &lt;br /&gt;
After successful subscription Microsoft will trigger the Connector for Microsoft 365 App every time a presence or line state for a user has changed.&lt;br /&gt;
The subscription will then be renewed in the above-mentioned time interval to receive further live updates.&lt;br /&gt;
&lt;br /&gt;
===== User Matching =====&lt;br /&gt;
You now can choose the fields used for user matching on either side from the following options:&lt;br /&gt;
* PBX&lt;br /&gt;
** CN (Long Name property from the PBX user object)&lt;br /&gt;
** h323 (Name property from the PBX user object)&lt;br /&gt;
* Azure Portal&lt;br /&gt;
** displayName&lt;br /&gt;
** mail&lt;br /&gt;
** mailNickname&lt;br /&gt;
** onPremisesDistinguishedName&lt;br /&gt;
** onPremisesSamAccountName&lt;br /&gt;
** onPremisesUserPrincipalName&lt;br /&gt;
** userPrincipalName&lt;br /&gt;
&lt;br /&gt;
Additionally, you have the possibility to remove a possibly contained domain from the Azure fields content. &amp;lt;br&amp;gt;&lt;br /&gt;
Example: &#039;user@domain.tld&#039; is transformed to &#039;user&#039;, if this option is checked.&lt;br /&gt;
&lt;br /&gt;
===== Mapping Table =====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Teams Presence&lt;br /&gt;
! PBX Presence&lt;br /&gt;
|-&lt;br /&gt;
| Away&lt;br /&gt;
| away&lt;br /&gt;
|-&lt;br /&gt;
| BeRightBack&lt;br /&gt;
| away&lt;br /&gt;
|-&lt;br /&gt;
| Busy&lt;br /&gt;
| busy&lt;br /&gt;
|-&lt;br /&gt;
| DoNotDisturb&lt;br /&gt;
| dnd&lt;br /&gt;
|-&lt;br /&gt;
| InACall&lt;br /&gt;
| on-the-phone&lt;br /&gt;
|-&lt;br /&gt;
| InAMeeting&lt;br /&gt;
| meeting&lt;br /&gt;
|-&lt;br /&gt;
| Inactive&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| PresenceUnknown&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| Available&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| Offline&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| Offwork&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| OutOfOffice&lt;br /&gt;
| away&lt;br /&gt;
|-&lt;br /&gt;
| UrgentInterruptionsOnly&lt;br /&gt;
| dnd&lt;br /&gt;
|-&lt;br /&gt;
| Presenting&lt;br /&gt;
| on-the-phone&lt;br /&gt;
|-&lt;br /&gt;
| InAConferenceCall&lt;br /&gt;
| on-the-phone&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The value &amp;quot;online&amp;quot; unsets the Teams presence in the PBX.&lt;br /&gt;
&lt;br /&gt;
===== Master/Slave =====&lt;br /&gt;
&lt;br /&gt;
For Master/Slave combination the &amp;quot;Connector for Microsoft 365&amp;quot; App has to be added to the slave (if no full replication is on). The slave websocket connection is needed to display &amp;quot;on-the-phone&amp;quot; presence.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Calendar Presence ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Configuration ====&lt;br /&gt;
Please have a look into our [[Howto15r1:Configure_Calendar_Presence_Sync_by_Connector_for_Microsoft365|Howto guide for basic configuration aid]].&lt;br /&gt;
&lt;br /&gt;
==== Technical Overview ====&lt;br /&gt;
Introduced in 15r1 the Connector for Microsoft 365 will offer a possibility to sync Azure Portal calendar events (Teams, Exchange online) via the Graph API with the PBX presence.&amp;lt;br&amp;gt;&lt;br /&gt;
For now the [https://wiki.innovaphone.com/index.php?title=Reference13r3:Concept_App_Service_Calendar Calendar App] is (along with other functions) also capable of syncing calendar events, but using the old EWS mechanism, which Microsoft announced as end of life starting from 2026.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Warning:&#039;&#039;&#039; Please make sure to not use both apps for syncing calendar events in parallel, this is not supported and will most likely lead to conflicts and unexpected behaviours.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
When the configuration of the connector for Microsoft 365 Calendar Presence Sync is complete, the app connects to Microsoft to receive a token with the calendar app registered in the Azure portal.&amp;lt;br&amp;gt;&lt;br /&gt;
With the token, the app can pick up the users from the Azure portal.&amp;lt;br&amp;gt;&lt;br /&gt;
These are matched against the users in the PBX, based on the configured &amp;quot;User Assignment&amp;quot; settings.&amp;lt;br&amp;gt;&lt;br /&gt;
For each matched user with a valid Connector for Microsoft 365 licence applied, a subscription for calendar events is created at Microsoft to receive event changes in Microsoft Calendar for these users.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
A user subscription is also started to receive user changes (add, delete or update).&amp;lt;br&amp;gt;&lt;br /&gt;
If a user has changed, the users are retrieved again. &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
If a calendar event has been started or ended, it is forwarded to the PBX.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* User subscriptions are renewed every 60 minutes.&lt;br /&gt;
* Event subscriptions are renewed every day.&lt;br /&gt;
* License Check is made every hour.&lt;br /&gt;
&lt;br /&gt;
== Related Articles ==&lt;br /&gt;
&lt;br /&gt;
=Known Limitation=&lt;br /&gt;
&lt;br /&gt;
== General ==&lt;br /&gt;
&#039;&#039;Applies to the User Presence and the Calendar Presence&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Synchronization Delay ===&lt;br /&gt;
In the official Graph-API documentation, Microsoft is providing an overview about expected latencies for change notifications.&amp;lt;br&amp;gt;&lt;br /&gt;
You can find a whole overview table here:&amp;lt;br&amp;gt;&lt;br /&gt;
https://learn.microsoft.com/en-us/graph/change-notifications-overview#latency&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
For the user presences the resource &amp;quot;presence&amp;quot; is used and an average latency of 10 seconds but a maximum up to 1 minute is provided.&amp;lt;br&amp;gt;&lt;br /&gt;
Such a delay in syncing changed presences from Teams down to the PBX are considered normal and are caused by the Microsoft Graph-API.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
In case of calendar events the average is provided as &amp;quot;less than 1 minute&amp;quot; and the maximum to 3 minutes.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== User Presence ==&lt;br /&gt;
=== Line states set by the PBX does not block calls in Teams ===&lt;br /&gt;
Line states set by a 3rd party application (like the Connector for Microsoft 365) through the graph API are currently &#039;&#039;&#039;only for display purpose and do not block new calls&#039;&#039;&#039; in Teams.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
https://techcommunity.microsoft.com/t5/teams-developer/ms-graph-setpresence-problems/m-p/2798805/highlight/true#M3957&amp;lt;br&amp;gt;&lt;br /&gt;
As you can see in the above linked discussion, there once existed a feature request on Microsoft Voice, which is no longer available since it was not voted.&lt;br /&gt;
=== Maximum number of supported users ===&lt;br /&gt;
The connector now supports multiple Microsoft Teams communication users, which is the prerequisite to subscribe for more than 650 users. There is a new ribbon (Manage Teams Accounts) that allows you to configure as many communication users as you need. Every configured communication user can be used to subscribe 650 users, for example:&lt;br /&gt;
&lt;br /&gt;
*3 configured communication users x 650 licensed users = 1950 users can be subscribed&lt;br /&gt;
&#039;&#039;&#039;Please be aware&#039;&#039;&#039;: Each communication user must have a Teams license applied.&lt;br /&gt;
&lt;br /&gt;
This limitation is caused by Microsoft.&amp;lt;br&amp;gt;&lt;br /&gt;
In the documentation of the Graph-API you will find a hint to this limitation:&amp;lt;br&amp;gt;&lt;br /&gt;
https://learn.microsoft.com/en-us/graph/changenotifications-for-presence#subscribe-to-multiple-users-presence&amp;lt;br&amp;gt;&lt;br /&gt;
Trying to subscribe more than 650 users (with one communication user) by using the presence subscription API will be declined by the graph API with an error message, that too many users are requested.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Communication User (UserSynctoPbx) ===&lt;br /&gt;
Users with MFA (multi-factor-authentication) are not supported as technical communication user for the Connector.&lt;br /&gt;
&lt;br /&gt;
=== Multiple sites / instances require multiple communication users ===&lt;br /&gt;
Each instance or each site must have separate communication users, as Microsoft only allows one concurrent subscription per communication user. (otherwise an HTTP 409 conflict will occur)&lt;br /&gt;
&lt;br /&gt;
This means that if you want to subscribe to the same Azure Portal backend from two different sites (or instances), you will need to have multiple communication users (each with an applied Teams licence) in order to be able to subscribe from all endpoints.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Subscription Timeout ===&lt;br /&gt;
&lt;br /&gt;
==== Situation ====&lt;br /&gt;
Due to a current limitation in the Graph API it is not possible to cancel or delete an active presence subscription.&amp;lt;br&amp;gt;&lt;br /&gt;
As you can see in the [https://learn.microsoft.com/en-us/graph/api/subscription-delete?view=graph-rest-1.0&amp;amp;tabs=http|documentation of the current Graph API (1.0)] the “Delete subscription” chapter does not include presence subscriptions.&amp;lt;br&amp;gt;&lt;br /&gt;
It is also not possible to have multiple subscription in parallel. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To make sure to only request a new presence subscription when the old one is not valid anymore, the app will store the state of the presence subscription and the time until it is valid in the database.&amp;lt;br&amp;gt;&lt;br /&gt;
As mentioned in the chapter “Technical Overview” we are creating presence subscriptions with a validity of 10 minutes.&amp;lt;br&amp;gt;&lt;br /&gt;
The presence subscription will be renewed as soon as it is no longer valid which will be 10 minutes after initial subscription.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Impact ====&lt;br /&gt;
If settings are changed or the app instance is restarted it will check the corresponding database entry on startup.&amp;lt;br&amp;gt;&lt;br /&gt;
In case the last presence subscription was completed less than 10 minutes ago, there is still an active presence subscription and the app has to wait for it to become invalid. &amp;lt;br&amp;gt;&lt;br /&gt;
Some Changes (e.g., to the “Notification-URL”) will only take effect after a new created subscription. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The current Beta Version of the Graph API is already providing a function to delete presence subscriptions, so we hope we can improve this behavior in the future.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Troubleshooting=&lt;br /&gt;
== General ==&lt;br /&gt;
&lt;br /&gt;
===Creating an app trace===&lt;br /&gt;
For further analysis and creating a support ticket it will be useful to have a suitable app trace. &amp;lt;br&amp;gt;&lt;br /&gt;
Before creating the trace please make sure the following trace flags are activated for the app instance:&lt;br /&gt;
* App&lt;br /&gt;
* Database&lt;br /&gt;
* HTTP client&lt;br /&gt;
* TLS&lt;br /&gt;
* TCP&lt;br /&gt;
* App WebSocket&lt;br /&gt;
* Config&lt;br /&gt;
* Webserver&lt;br /&gt;
&lt;br /&gt;
After setting the config flags, please make sure to&lt;br /&gt;
* stop the instance&lt;br /&gt;
* deleting the current instance log&lt;br /&gt;
* start the instance&lt;br /&gt;
&#039;&#039;&#039;Now please wait at least 5 Minutes before you save the log&#039;&#039;&#039;, otherwise we could not have the whole picture in the trace.&lt;br /&gt;
&lt;br /&gt;
The restart and deletion of the the old log is useful the see the complete initialization process right away.&lt;br /&gt;
&lt;br /&gt;
===SSL Certificate for notification URL===&lt;br /&gt;
It also is useful to make sure the notification URL has a valid and public signed certificate.&amp;lt;br&amp;gt;&lt;br /&gt;
You can do that, using an SSL-Checker, for example: https://www.sslshopper.com/ssl-checker.html &amp;lt;br&amp;gt;&lt;br /&gt;
Without a valid, public signed certificate, Microsoft will decline the connection since it will not be possible to establish a trust relationship for the SSL/TLS secure channel.&lt;br /&gt;
&lt;br /&gt;
===Correctness of notification URL===&lt;br /&gt;
You can try to open the notification URL in your Browser&amp;lt;br&amp;gt;&lt;br /&gt;
Most likely you will see a HTTP 404 (Not Found) error message, which is the expected behavior since we are not providing an HTML website, the HTTP GET request from the browser will not be answered with content.&amp;lt;br&amp;gt;&lt;br /&gt;
This is perfectly fine since Microsoft will send presence updates with HTTP POST and will not try to request content from our app.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
What you can find out by trying to open the URL in your browser are the two following things: &amp;lt;br&amp;gt;&lt;br /&gt;
* If you receive a HTTP 404 error message you are most likely connected to an App Platform, if not you need to check your DNS (and maybe also reverse proxy) settings.&lt;br /&gt;
* If the URL is modified and the used build number is added, an app has answered your request&lt;br /&gt;
** Example: &amp;lt;code&amp;gt;https://public.dns/your.domain/microsoft365/subscriptions&amp;lt;/code&amp;gt; is modified to &amp;lt;code&amp;gt;https://public.dns/your.domain/microsoft365/&amp;lt;b&amp;gt;1510411&amp;lt;/b&amp;gt;/subscriptions&amp;lt;/code&amp;gt;&lt;br /&gt;
** If this is not the case, your URL is wrong. (Be aware: The URL depends on the settings of the web server path of your app instance)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Be aware:&#039;&#039;&#039; The URL-Recognition in the Application Platform is &#039;&#039;&#039;case sensitive&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Activation of &amp;quot;Public client flow&amp;quot; for the registered app in Azure Portal===&lt;br /&gt;
If the subscription is not working at all, please make sure &amp;quot;Public client flow&amp;quot; is activated for the registered app in the Azure portal (as described in our [[Howto15r1:Configure User Presence Sync by Connector for Microsoft365#Create_an_App_for_syncing_Teams_to_PBX|HowTo article]]).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
The App Service trace will contain the following message if this is not the case:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;AADSTS7000218: The request body must contain the following parameter: &#039;client_assertion&#039; or &#039;client_secret&#039;.&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== User Presence == &lt;br /&gt;
===GUI Feedback===&lt;br /&gt;
The app itself shows required states with green and red as connections to the Master PBX, Authentication and Presence Subscription to identify if there are problems. &amp;lt;br&amp;gt;&lt;br /&gt;
Sometimes it needs a little bit time until the states are changed. &amp;lt;br&amp;gt;&lt;br /&gt;
If the states remain, it is mandatory to enable logs on the app platform and check for more information. &amp;lt;br&amp;gt;&lt;br /&gt;
([[Howto13r3:Configure Connector for Microsoft365#Creating an app trace|Concept App Service Connector for Microsoft 365: Creating an app trace]])&lt;br /&gt;
&lt;br /&gt;
====No connection to Master PBX====&lt;br /&gt;
Check the MasterPBX name.&amp;lt;br&amp;gt;&lt;br /&gt;
The field must only contain the name [&amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;pbx&amp;lt;/span&amp;gt;], &#039;&#039;&#039;not the full domain&#039;&#039;&#039; [&amp;lt;span style=&amp;quot;color:red;text-decoration: line-through;&amp;quot;&amp;gt;pbx.domain.tld&amp;lt;/span&amp;gt;]. ([[Howto13r3:Configure Connector for Microsoft365#Synchronization from Teams to the PBX|Synchronization from Teams to the PBX - Master PBX field]])&lt;br /&gt;
&lt;br /&gt;
====Presence subscription failed====&lt;br /&gt;
There are many reasons why the &amp;quot;Presence subscription failed&amp;quot; message could be displayed.&amp;lt;br&amp;gt;&lt;br /&gt;
We try to list the most common reasons:&lt;br /&gt;
* The permission for the registered app in the Azure portal are not correctly set ([[Howto13r3:Configure Connector for Microsoft365#Create an App for syncing Teams to PBX|Howto: Create an App for syncing Teams to PBX]])&lt;br /&gt;
* The Notification URL is wrong ([[Reference13r3:Concept App Service Connector for Microsoft 365#Correctness of notification URL|Concept App Service Connector for Microsoft 365: Correctness of notification URL]] )&lt;br /&gt;
* The App service is not reachable from the internet ([[Reference13r3:Concept App Service Connector for Microsoft 365#Correctness of notification URL|Concept App Service Connector for Microsoft 365: Correctness of notification URL]] )&lt;br /&gt;
* The certificate for the public endpoint (e.g. reverse proxy) is not valid, or not publicly signed ([[Reference13r3:Concept App Service Connector for Microsoft 365#SSL Certificate for notification URL|Concept App Service Connector for Microsoft 365: SSL Certificate for notification URL]])&lt;br /&gt;
* The user from PBX and the Azure Portal cannot be matched ([[Reference13r3:Concept App Service Connector for Microsoft 365#User Matching|Concept App Service Connector for Microsoft 365: User Matching]])&lt;br /&gt;
* The App Platforms clock time is wrong ([[Reference13r3:Concept App Service Connector for Microsoft 365#App Platform clock time is wrong|Concept App Service Connector for Microsoft 365: App Platform clock time is wrong]])&lt;br /&gt;
* No user has a valid Connector for Microsoft 365 App license ([[Reference13r3:Concept App Service Connector for Microsoft 365#Requirements|Concept App Service Connector for Microsoft 365: Requirements]])&lt;br /&gt;
&lt;br /&gt;
===Teams License for communication user===&lt;br /&gt;
If presence subscription does not work, please check if all of the configured communication users have a Microsoft Teams license applied and no multifactor authentication is in use for this particular user. &amp;lt;br&amp;gt;&lt;br /&gt;
Also please make sure you can login with the configured credentials. (If you have set a password as an Administration, the user needs to change the password during the first login, therefore the given password will be invalid for API access).&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Sometimes, after changing setting or after the instance has restarted it can take up to 12 minutes until the presence subscription is working correctly. (Due to the subscription timeout)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
= Known Issues =&lt;br /&gt;
== Special Characters In Password ==&lt;br /&gt;
If you are using special characters (*, &amp;amp;, (, ), etc.) in your password you could run into a problem with the authentication of the communication user.&amp;lt;br&amp;gt;&lt;br /&gt;
The authentication failed status is being displayed. &amp;lt;br&amp;gt;&lt;br /&gt;
For the moment the only workaround is to eliminate special characters from your password.&lt;br /&gt;
&lt;br /&gt;
==App Platform clock time is wrong==&lt;br /&gt;
If the clock time at the App Platform is not correct, this will lead to an unstable behaviour of the Connector for Microsoft 365.&amp;lt;br&amp;gt;&lt;br /&gt;
Since the Connector for Microsoft 365 is using the Microsoft Graph APIs presence subscription function, it needs to provide in its request a precise time until the subscription validity will be expired.&amp;lt;br&amp;gt;&lt;br /&gt;
The app service is handling subscription and will automatically recreate a new subscription each time the previous one has expired.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A wrong clock time will lead to false expiration times and thus&lt;br /&gt;
*  the subscription will be expired earlier than expected (synchronisation is not working because there is no valid subscription)&lt;br /&gt;
*  the subscription will be valid longer than expected (the app service is trying to create a new subscription because it is expecting the previous one to be expired - will lead to a 409 conflict error, because only one subscription can be valid at a time)&lt;br /&gt;
&lt;br /&gt;
If you are not sure about the current time of the App Platform, you can login via SSH into the App Platform and execute the &amp;lt;code&amp;gt;date&amp;lt;/code&amp;gt; command to check the current time.&amp;lt;br&amp;gt;&lt;br /&gt;
You will receive an output like: &lt;br /&gt;
 Tue Mar 12 13:38:57 UTC 2024&lt;br /&gt;
Please be aware: The time is displayed in UTC, so please make sure to convert to your local time zone.&lt;br /&gt;
&lt;br /&gt;
==Geoblocking==&lt;br /&gt;
Since there might be no reliable country assignment for Microsoft addresses, all Microsoft addresses must be enabled on the upstream firewall in the event of geoblocking in order to ensure functionality of the Office365 Connector.&amp;lt;br&amp;gt;&lt;br /&gt;
As an alternative you might be able to configure your firewall to bypass the geoblocking for the configured notification URL.&lt;br /&gt;
&lt;br /&gt;
= Related Articles =&lt;br /&gt;
[[Howto15r1:Configure User Presence Sync by Connector for Microsoft365]] &amp;lt;br/&amp;gt;&lt;br /&gt;
[[Howto15r1:Configure Calendar Presence Sync by Connector for Microsoft365]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Howto|{{PAGENAME}}]]&lt;/div&gt;</summary>
		<author><name>Tfu</name></author>
	</entry>
	<entry>
		<id>https://wiki.innovaphone.com/index.php?title=Reference15r1:Concept_App_Service_Connector_for_Microsoft_365&amp;diff=78906</id>
		<title>Reference15r1:Concept App Service Connector for Microsoft 365</title>
		<link rel="alternate" type="text/html" href="https://wiki.innovaphone.com/index.php?title=Reference15r1:Concept_App_Service_Connector_for_Microsoft_365&amp;diff=78906"/>
		<updated>2026-02-13T11:20:32Z</updated>

		<summary type="html">&lt;p&gt;Tfu: /* Correctness of notification URL */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Concept|Apps]]&lt;br /&gt;
== Applies To == &lt;br /&gt;
&lt;br /&gt;
* Connector for Microsoft 365 from Version 15r1&lt;br /&gt;
&lt;br /&gt;
= Overview =&lt;br /&gt;
&lt;br /&gt;
Connector for Microsoft 365 synchronizes Microsoft Teams presences with the innovaphone PBX and back, and optionally additionally Calendar presence from Exchange Online (part of the Microsoft 365 Cloud Services).&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
* innovaphone PBX&lt;br /&gt;
* innovaphone Application Platform (minimum version 120004)&lt;br /&gt;
* V15r1&lt;br /&gt;
* App(Connector for Microsoft 365)&lt;br /&gt;
* PBX-App(innovaphone-microsoft365) license per user - order no. 02-00050-009&lt;br /&gt;
&lt;br /&gt;
== Concept ==&lt;br /&gt;
&lt;br /&gt;
=== User Presence ===&lt;br /&gt;
&lt;br /&gt;
==== Configuration ====&lt;br /&gt;
Please have a look into our [[Howto15r1:Configure User Presence Sync by Connector for Microsoft365|Howto guide for basic configuration aid]].&lt;br /&gt;
&lt;br /&gt;
==== Technical Overview ====&lt;br /&gt;
If the Connector for Microsoft 365 app is fully configured, the app connects to Microsoft to obtain a token. With the token, the app gets the teams users (with a Teams license) through the Microsoft Graph API.&lt;br /&gt;
A presence subscription to Microsoft is started with the licensed users of the PBX to get presence changes in Microsoft Teams for these users. A user subscription is also started to get changes of the users (adding, deleting or update). If a user has changed, the Teams users are retrieved again. If the presence has changed, it is forwarded to the PBX. The presences of Teams are mapped to the presences of the PBX.&lt;br /&gt;
&lt;br /&gt;
* User subscriptions are renewed every 60 minutes.&lt;br /&gt;
* Presence subscriptions are renewed every 10 minutes.&lt;br /&gt;
* License Check is made periodically.&lt;br /&gt;
&lt;br /&gt;
The app synchronises the PBX presence with Teams through the Graph Api. The on-the-phone presence will be renewed every 5 minutes. The other presences have a lifetime of 1 day but the away has a lifetime of 7 days.&lt;br /&gt;
The lifetimes are described [https://learn.microsoft.com/en-us/graph/api/presence-setuserpreferredpresence?view=graph-rest-1.0&amp;amp;tabs=http here]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Please be aware:&#039;&#039;&#039; The actual change of presence or line state will be live, the above-mentioned subscriptions are needed to register against the Microsoft API for changes. &lt;br /&gt;
After successful subscription Microsoft will trigger the Connector for Microsoft 365 App every time a presence or line state for a user has changed.&lt;br /&gt;
The subscription will then be renewed in the above-mentioned time interval to receive further live updates.&lt;br /&gt;
&lt;br /&gt;
===== User Matching =====&lt;br /&gt;
You now can choose the fields used for user matching on either side from the following options:&lt;br /&gt;
* PBX&lt;br /&gt;
** CN (Long Name property from the PBX user object)&lt;br /&gt;
** h323 (Name property from the PBX user object)&lt;br /&gt;
* Azure Portal&lt;br /&gt;
** displayName&lt;br /&gt;
** mail&lt;br /&gt;
** mailNickname&lt;br /&gt;
** onPremisesDistinguishedName&lt;br /&gt;
** onPremisesSamAccountName&lt;br /&gt;
** onPremisesUserPrincipalName&lt;br /&gt;
** userPrincipalName&lt;br /&gt;
&lt;br /&gt;
Additionally, you have the possibility to remove a possibly contained domain from the Azure fields content. &amp;lt;br&amp;gt;&lt;br /&gt;
Example: &#039;user@domain.tld&#039; is transformed to &#039;user&#039;, if this option is checked.&lt;br /&gt;
&lt;br /&gt;
===== Mapping Table =====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Teams Presence&lt;br /&gt;
! PBX Presence&lt;br /&gt;
|-&lt;br /&gt;
| Away&lt;br /&gt;
| away&lt;br /&gt;
|-&lt;br /&gt;
| BeRightBack&lt;br /&gt;
| away&lt;br /&gt;
|-&lt;br /&gt;
| Busy&lt;br /&gt;
| busy&lt;br /&gt;
|-&lt;br /&gt;
| DoNotDisturb&lt;br /&gt;
| dnd&lt;br /&gt;
|-&lt;br /&gt;
| InACall&lt;br /&gt;
| on-the-phone&lt;br /&gt;
|-&lt;br /&gt;
| InAMeeting&lt;br /&gt;
| meeting&lt;br /&gt;
|-&lt;br /&gt;
| Inactive&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| PresenceUnknown&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| Available&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| Offline&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| Offwork&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| OutOfOffice&lt;br /&gt;
| away&lt;br /&gt;
|-&lt;br /&gt;
| UrgentInterruptionsOnly&lt;br /&gt;
| dnd&lt;br /&gt;
|-&lt;br /&gt;
| Presenting&lt;br /&gt;
| on-the-phone&lt;br /&gt;
|-&lt;br /&gt;
| InAConferenceCall&lt;br /&gt;
| on-the-phone&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The value &amp;quot;online&amp;quot; unsets the Teams presence in the PBX.&lt;br /&gt;
&lt;br /&gt;
===== Master/Slave =====&lt;br /&gt;
&lt;br /&gt;
For Master/Slave combination the &amp;quot;Connector for Microsoft 365&amp;quot; App has to be added to the slave (if no full replication is on). The slave websocket connection is needed to display &amp;quot;on-the-phone&amp;quot; presence.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Calendar Presence ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Configuration ====&lt;br /&gt;
Please have a look into our [[Howto15r1:Configure_Calendar_Presence_Sync_by_Connector_for_Microsoft365|Howto guide for basic configuration aid]].&lt;br /&gt;
&lt;br /&gt;
==== Technical Overview ====&lt;br /&gt;
Introduced in 15r1 the Connector for Microsoft 365 will offer a possibility to sync Azure Portal calendar events (Teams, Exchange online) via the Graph API with the PBX presence.&amp;lt;br&amp;gt;&lt;br /&gt;
For now the [https://wiki.innovaphone.com/index.php?title=Reference13r3:Concept_App_Service_Calendar Calendar App] is (along with other functions) also capable of syncing calendar events, but using the old EWS mechanism, which Microsoft announced as end of life starting from 2026.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Warning:&#039;&#039;&#039; Please make sure to not use both apps for syncing calendar events in parallel, this is not supported and will most likely lead to conflicts and unexpected behaviours.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
When the configuration of the connector for Microsoft 365 Calendar Presence Sync is complete, the app connects to Microsoft to receive a token with the calendar app registered in the Azure portal.&amp;lt;br&amp;gt;&lt;br /&gt;
With the token, the app can pick up the users from the Azure portal.&amp;lt;br&amp;gt;&lt;br /&gt;
These are matched against the users in the PBX, based on the configured &amp;quot;User Assignment&amp;quot; settings.&amp;lt;br&amp;gt;&lt;br /&gt;
For each matched user with a valid Connector for Microsoft 365 licence applied, a subscription for calendar events is created at Microsoft to receive event changes in Microsoft Calendar for these users.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
A user subscription is also started to receive user changes (add, delete or update).&amp;lt;br&amp;gt;&lt;br /&gt;
If a user has changed, the users are retrieved again. &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
If a calendar event has been started or ended, it is forwarded to the PBX.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* User subscriptions are renewed every 60 minutes.&lt;br /&gt;
* Event subscriptions are renewed every day.&lt;br /&gt;
* License Check is made every hour.&lt;br /&gt;
&lt;br /&gt;
== Related Articles ==&lt;br /&gt;
&lt;br /&gt;
=Known Limitation=&lt;br /&gt;
&lt;br /&gt;
== General ==&lt;br /&gt;
&#039;&#039;Applies to the User Presence and the Calendar Presence&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Synchronization Delay ===&lt;br /&gt;
In the official Graph-API documentation, Microsoft is providing an overview about expected latencies for change notifications.&amp;lt;br&amp;gt;&lt;br /&gt;
You can find a whole overview table here:&amp;lt;br&amp;gt;&lt;br /&gt;
https://learn.microsoft.com/en-us/graph/change-notifications-overview#latency&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
For the user presences the resource &amp;quot;presence&amp;quot; is used and an average latency of 10 seconds but a maximum up to 1 minute is provided.&amp;lt;br&amp;gt;&lt;br /&gt;
Such a delay in syncing changed presences from Teams down to the PBX are considered normal and are caused by the Microsoft Graph-API.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
In case of calendar events the average is provided as &amp;quot;less than 1 minute&amp;quot; and the maximum to 3 minutes.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== User Presence ==&lt;br /&gt;
=== Line states set by the PBX does not block calls in Teams ===&lt;br /&gt;
Line states set by a 3rd party application (like the Connector for Microsoft 365) through the graph API are currently &#039;&#039;&#039;only for display purpose and do not block new calls&#039;&#039;&#039; in Teams.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
https://techcommunity.microsoft.com/t5/teams-developer/ms-graph-setpresence-problems/m-p/2798805/highlight/true#M3957&amp;lt;br&amp;gt;&lt;br /&gt;
As you can see in the above linked discussion, there once existed a feature request on Microsoft Voice, which is no longer available since it was not voted.&lt;br /&gt;
=== Maximum number of supported users ===&lt;br /&gt;
The connector now supports multiple Microsoft Teams communication users, which is the prerequisite to subscribe for more than 650 users. There is a new ribbon (Manage Teams Accounts) that allows you to configure as many communication users as you need. Every configured communication user can be used to subscribe 650 users, for example:&lt;br /&gt;
&lt;br /&gt;
*3 configured communication users x 650 licensed users = 1950 users can be subscribed&lt;br /&gt;
&#039;&#039;&#039;Please be aware&#039;&#039;&#039;: Each communication user must have a Teams license applied.&lt;br /&gt;
&lt;br /&gt;
This limitation is caused by Microsoft.&amp;lt;br&amp;gt;&lt;br /&gt;
In the documentation of the Graph-API you will find a hint to this limitation:&amp;lt;br&amp;gt;&lt;br /&gt;
https://learn.microsoft.com/en-us/graph/changenotifications-for-presence#subscribe-to-multiple-users-presence&amp;lt;br&amp;gt;&lt;br /&gt;
Trying to subscribe more than 650 users (with one communication user) by using the presence subscription API will be declined by the graph API with an error message, that too many users are requested.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Communication User (UserSynctoPbx) ===&lt;br /&gt;
Users with MFA (multi-factor-authentication) are not supported as technical communication user for the Connector.&lt;br /&gt;
&lt;br /&gt;
=== Multiple sites / instances require multiple communication users ===&lt;br /&gt;
Each instance or each site must have separate communication users, as Microsoft only allows one concurrent subscription per communication user. (otherwise an HTTP 409 conflict will occur)&lt;br /&gt;
&lt;br /&gt;
This means that if you want to subscribe to the same Azure Portal backend from two different sites (or instances), you will need to have multiple communication users (each with an applied Teams licence) in order to be able to subscribe from all endpoints.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Subscription Timeout ===&lt;br /&gt;
&lt;br /&gt;
==== Situation ====&lt;br /&gt;
Due to a current limitation in the Graph API it is not possible to cancel or delete an active presence subscription.&amp;lt;br&amp;gt;&lt;br /&gt;
As you can see in the [https://learn.microsoft.com/en-us/graph/api/subscription-delete?view=graph-rest-1.0&amp;amp;tabs=http|documentation of the current Graph API (1.0)] the “Delete subscription” chapter does not include presence subscriptions.&amp;lt;br&amp;gt;&lt;br /&gt;
It is also not possible to have multiple subscription in parallel. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To make sure to only request a new presence subscription when the old one is not valid anymore, the app will store the state of the presence subscription and the time until it is valid in the database.&amp;lt;br&amp;gt;&lt;br /&gt;
As mentioned in the chapter “Technical Overview” we are creating presence subscriptions with a validity of 10 minutes.&amp;lt;br&amp;gt;&lt;br /&gt;
The presence subscription will be renewed as soon as it is no longer valid which will be 10 minutes after initial subscription.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Impact ====&lt;br /&gt;
If settings are changed or the app instance is restarted it will check the corresponding database entry on startup.&amp;lt;br&amp;gt;&lt;br /&gt;
In case the last presence subscription was completed less than 10 minutes ago, there is still an active presence subscription and the app has to wait for it to become invalid. &amp;lt;br&amp;gt;&lt;br /&gt;
Some Changes (e.g., to the “Notification-URL”) will only take effect after a new created subscription. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The current Beta Version of the Graph API is already providing a function to delete presence subscriptions, so we hope we can improve this behavior in the future.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Troubleshooting=&lt;br /&gt;
== General ==&lt;br /&gt;
&lt;br /&gt;
===Creating an app trace===&lt;br /&gt;
For further analysis and creating a support ticket it will be useful to have a suitable app trace. &amp;lt;br&amp;gt;&lt;br /&gt;
Before creating the trace please make sure the following trace flags are activated for the app instance:&lt;br /&gt;
* App&lt;br /&gt;
* Database&lt;br /&gt;
* HTTP client&lt;br /&gt;
* TLS&lt;br /&gt;
* TCP&lt;br /&gt;
* App WebSocket&lt;br /&gt;
* Config&lt;br /&gt;
* Webserver&lt;br /&gt;
&lt;br /&gt;
After setting the config flags, please make sure to&lt;br /&gt;
* stop the instance&lt;br /&gt;
* deleting the current instance log&lt;br /&gt;
* start the instance&lt;br /&gt;
&#039;&#039;&#039;Now please wait at least 5 Minutes before you save the log&#039;&#039;&#039;, otherwise we could not have the whole picture in the trace.&lt;br /&gt;
&lt;br /&gt;
The restart and deletion of the the old log is useful the see the complete initialization process right away.&lt;br /&gt;
&lt;br /&gt;
===SSL Certificate for notification URL===&lt;br /&gt;
It also is useful to make sure the notification URL has a valid and public signed certificate.&amp;lt;br&amp;gt;&lt;br /&gt;
You can do that, using an SSL-Checker, for example: https://www.sslshopper.com/ssl-checker.html &amp;lt;br&amp;gt;&lt;br /&gt;
Without a valid, public signed certificate, Microsoft will decline the connection since it will not be possible to establish a trust relationship for the SSL/TLS secure channel.&lt;br /&gt;
&lt;br /&gt;
===Correctness of notification URL===&lt;br /&gt;
You can try to open the notification URL in your Browser&amp;lt;br&amp;gt;&lt;br /&gt;
Most likely you will see a HTTP 404 (Not Found) error message, which is the expected behavior since we are not providing an HTML website, the HTTP GET request from the browser will not be answered with content.&amp;lt;br&amp;gt;&lt;br /&gt;
This is perfectly fine since Microsoft will send presence updates with HTTP POST and will not try to request content from our app.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
What you can find out by trying to open the URL in your browser are the two following things: &amp;lt;br&amp;gt;&lt;br /&gt;
* If you receive a HTTP 404 error message you are most likely connected to an App Platform, if not you need to check your DNS (and maybe also reverse proxy) settings.&lt;br /&gt;
* If the URL is modified and the used build number is added, an app has answered your request&lt;br /&gt;
** Example: &amp;lt;code&amp;gt;https://public.dns/your.domain/microsoft365/subscriptions&amp;lt;/code&amp;gt; is modified to &amp;lt;code&amp;gt;https://public.dns/your.domain/microsoft365/&amp;lt;b&amp;gt;1510411&amp;lt;/b&amp;gt;/subscriptions&amp;lt;/code&amp;gt;&lt;br /&gt;
** If this is not the case, your URL is wrong. (Be aware: The URL depends on the settings of the web server path of your app instance)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Be aware:&#039;&#039;&#039; The URL-Recognition in the Application Platform is &#039;&#039;&#039;case sensitive&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Activation of &amp;quot;Public client flow&amp;quot; for the registered app in Azure Portal===&lt;br /&gt;
If the subscription is not working at all, please make sure &amp;quot;Public client flow&amp;quot; is activated for the registered app in the Azure portal (as described in our [[Howto15r1:Configure User Presence Sync by Connector for Microsoft365|HowTo article]]).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
The App Service trace will contain the following message if this is not the case:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;AADSTS7000218: The request body must contain the following parameter: &#039;client_assertion&#039; or &#039;client_secret&#039;.&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== User Presence == &lt;br /&gt;
===GUI Feedback===&lt;br /&gt;
The app itself shows required states with green and red as connections to the Master PBX, Authentication and Presence Subscription to identify if there are problems. &amp;lt;br&amp;gt;&lt;br /&gt;
Sometimes it needs a little bit time until the states are changed. &amp;lt;br&amp;gt;&lt;br /&gt;
If the states remain, it is mandatory to enable logs on the app platform and check for more information. &amp;lt;br&amp;gt;&lt;br /&gt;
([[Howto13r3:Configure Connector for Microsoft365#Creating an app trace|Concept App Service Connector for Microsoft 365: Creating an app trace]])&lt;br /&gt;
&lt;br /&gt;
====No connection to Master PBX====&lt;br /&gt;
Check the MasterPBX name.&amp;lt;br&amp;gt;&lt;br /&gt;
The field must only contain the name [&amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;pbx&amp;lt;/span&amp;gt;], &#039;&#039;&#039;not the full domain&#039;&#039;&#039; [&amp;lt;span style=&amp;quot;color:red;text-decoration: line-through;&amp;quot;&amp;gt;pbx.domain.tld&amp;lt;/span&amp;gt;]. ([[Howto13r3:Configure Connector for Microsoft365#Synchronization from Teams to the PBX|Synchronization from Teams to the PBX - Master PBX field]])&lt;br /&gt;
&lt;br /&gt;
====Presence subscription failed====&lt;br /&gt;
There are many reasons why the &amp;quot;Presence subscription failed&amp;quot; message could be displayed.&amp;lt;br&amp;gt;&lt;br /&gt;
We try to list the most common reasons:&lt;br /&gt;
* The permission for the registered app in the Azure portal are not correctly set ([[Howto13r3:Configure Connector for Microsoft365#Create an App for syncing Teams to PBX|Howto: Create an App for syncing Teams to PBX]])&lt;br /&gt;
* The Notification URL is wrong ([[Reference13r3:Concept App Service Connector for Microsoft 365#Correctness of notification URL|Concept App Service Connector for Microsoft 365: Correctness of notification URL]] )&lt;br /&gt;
* The App service is not reachable from the internet ([[Reference13r3:Concept App Service Connector for Microsoft 365#Correctness of notification URL|Concept App Service Connector for Microsoft 365: Correctness of notification URL]] )&lt;br /&gt;
* The certificate for the public endpoint (e.g. reverse proxy) is not valid, or not publicly signed ([[Reference13r3:Concept App Service Connector for Microsoft 365#SSL Certificate for notification URL|Concept App Service Connector for Microsoft 365: SSL Certificate for notification URL]])&lt;br /&gt;
* The user from PBX and the Azure Portal cannot be matched ([[Reference13r3:Concept App Service Connector for Microsoft 365#User Matching|Concept App Service Connector for Microsoft 365: User Matching]])&lt;br /&gt;
* The App Platforms clock time is wrong ([[Reference13r3:Concept App Service Connector for Microsoft 365#App Platform clock time is wrong|Concept App Service Connector for Microsoft 365: App Platform clock time is wrong]])&lt;br /&gt;
* No user has a valid Connector for Microsoft 365 App license ([[Reference13r3:Concept App Service Connector for Microsoft 365#Requirements|Concept App Service Connector for Microsoft 365: Requirements]])&lt;br /&gt;
&lt;br /&gt;
===Teams License for communication user===&lt;br /&gt;
If presence subscription does not work, please check if all of the configured communication users have a Microsoft Teams license applied and no multifactor authentication is in use for this particular user. &amp;lt;br&amp;gt;&lt;br /&gt;
Also please make sure you can login with the configured credentials. (If you have set a password as an Administration, the user needs to change the password during the first login, therefore the given password will be invalid for API access).&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Sometimes, after changing setting or after the instance has restarted it can take up to 12 minutes until the presence subscription is working correctly. (Due to the subscription timeout)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
= Known Issues =&lt;br /&gt;
== Special Characters In Password ==&lt;br /&gt;
If you are using special characters (*, &amp;amp;, (, ), etc.) in your password you could run into a problem with the authentication of the communication user.&amp;lt;br&amp;gt;&lt;br /&gt;
The authentication failed status is being displayed. &amp;lt;br&amp;gt;&lt;br /&gt;
For the moment the only workaround is to eliminate special characters from your password.&lt;br /&gt;
&lt;br /&gt;
==App Platform clock time is wrong==&lt;br /&gt;
If the clock time at the App Platform is not correct, this will lead to an unstable behaviour of the Connector for Microsoft 365.&amp;lt;br&amp;gt;&lt;br /&gt;
Since the Connector for Microsoft 365 is using the Microsoft Graph APIs presence subscription function, it needs to provide in its request a precise time until the subscription validity will be expired.&amp;lt;br&amp;gt;&lt;br /&gt;
The app service is handling subscription and will automatically recreate a new subscription each time the previous one has expired.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A wrong clock time will lead to false expiration times and thus&lt;br /&gt;
*  the subscription will be expired earlier than expected (synchronisation is not working because there is no valid subscription)&lt;br /&gt;
*  the subscription will be valid longer than expected (the app service is trying to create a new subscription because it is expecting the previous one to be expired - will lead to a 409 conflict error, because only one subscription can be valid at a time)&lt;br /&gt;
&lt;br /&gt;
If you are not sure about the current time of the App Platform, you can login via SSH into the App Platform and execute the &amp;lt;code&amp;gt;date&amp;lt;/code&amp;gt; command to check the current time.&amp;lt;br&amp;gt;&lt;br /&gt;
You will receive an output like: &lt;br /&gt;
 Tue Mar 12 13:38:57 UTC 2024&lt;br /&gt;
Please be aware: The time is displayed in UTC, so please make sure to convert to your local time zone.&lt;br /&gt;
&lt;br /&gt;
==Geoblocking==&lt;br /&gt;
Since there might be no reliable country assignment for Microsoft addresses, all Microsoft addresses must be enabled on the upstream firewall in the event of geoblocking in order to ensure functionality of the Office365 Connector.&amp;lt;br&amp;gt;&lt;br /&gt;
As an alternative you might be able to configure your firewall to bypass the geoblocking for the configured notification URL.&lt;br /&gt;
&lt;br /&gt;
= Related Articles =&lt;br /&gt;
[[Howto15r1:Configure User Presence Sync by Connector for Microsoft365]] &amp;lt;br/&amp;gt;&lt;br /&gt;
[[Howto15r1:Configure Calendar Presence Sync by Connector for Microsoft365]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Howto|{{PAGENAME}}]]&lt;/div&gt;</summary>
		<author><name>Tfu</name></author>
	</entry>
	<entry>
		<id>https://wiki.innovaphone.com/index.php?title=Reference16r1:Concept_App_Service_Conference_Transcriptions&amp;diff=78841</id>
		<title>Reference16r1:Concept App Service Conference Transcriptions</title>
		<link rel="alternate" type="text/html" href="https://wiki.innovaphone.com/index.php?title=Reference16r1:Concept_App_Service_Conference_Transcriptions&amp;diff=78841"/>
		<updated>2026-01-30T11:40:11Z</updated>

		<summary type="html">&lt;p&gt;Tfu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{FIXME|reason=This article is still work in progress}}&lt;br /&gt;
[[Category:Concept|Apps]]&lt;br /&gt;
[[Category:Concept App Service Conference Transcriptions]]&lt;br /&gt;
== Applies To == &lt;br /&gt;
&lt;br /&gt;
* innovaphone Conference Transciptions from version 16r1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
[[File:Reference16r1 Concept App Service Conference Transcriptions Softphone App.png|thumb|309x309px|After the meeting ended, find the created summary|reference16r1_concept_app_service_conference_transcriptions_softphone_app.png/]]&lt;br /&gt;
The main goal of the Conference Transcriptions Service is to create video‑conference meeting summaries, which can be accessed in the Phone Apps.&lt;br /&gt;
&lt;br /&gt;
To achieve this:&lt;br /&gt;
# Users can start a transcription of the conference audio by clicking the &#039;&#039;&#039;“Transcribe Conference”&#039;&#039;&#039; button in the Phone Apps.&lt;br /&gt;
#* This action makes the Conference Transcriptions service connect to the conference room.&lt;br /&gt;
#* It records the audio and creates audio files of approximately one minute in length.&lt;br /&gt;
#* It forwards these small audio files via the com.innovaphone.transcriptions API, offered by the Transcriptions Service ([[Reference16r1:Concept_App_Service_Transcriptions]])&lt;br /&gt;
#* It receives the transcripts of these small files and stores them in the service database.&lt;br /&gt;
# If the user stops the transcription by clicking on the &amp;quot;&#039;&#039;&#039;Transcribe Conference&#039;&#039;&#039;&amp;quot; Button again&lt;br /&gt;
#* The Conference Transcriptions Service gathers the transcribed text from the database&lt;br /&gt;
#* It retrieves the prompt configured in the settings plugin [[Reference16r1:Apps/PbxManager/App myApps ConferenceTranscriptions]]&lt;br /&gt;
#* It sends the transcript together with the prompt to the Assistant App Service via the com.innovaphone.assistant API&lt;br /&gt;
#* It receives the meeting summary and stores that summary in the database of the service&lt;br /&gt;
# Users may start and stop transcriptions multiple times during a meeting. As long as users remain in the room, the service recognizes that the meeting is still the same for that room.&lt;br /&gt;
# After the meeting, users can find the AI‑generated meeting summary in the call list of their Phone Apps by clicking on the &#039;&#039;&#039;“i”&#039;&#039;&#039; button.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Licensing ==&lt;br /&gt;
&lt;br /&gt;
In order to use the service you will need the newly introduced &#039;&#039;&#039;UCC license&#039;&#039;&#039;&lt;br /&gt;
== Installation ==&lt;br /&gt;
Go to the &#039;&#039;&#039;Settings App&#039;&#039;&#039; (fomerly known as PBX manager) and open the &#039;&#039;&#039;&amp;quot;AP app installer&amp;quot;&#039;&#039;&#039; plugin. On the right panel, the App Store will be shown. &#039;&#039;Hint : if you access it for the first time, you will need to accept the &amp;quot;Terms of Use of the innovaphone App Store&amp;quot;&#039;&#039;&lt;br /&gt;
* In the search field located on the top right corner of the store, search for &#039;&#039;&#039;&amp;quot;Conference Transcriptions&amp;quot;&#039;&#039;&#039; and click on it.&lt;br /&gt;
* Select the proper firmware version, for example &#039;&#039;&#039;&amp;quot;Version 16r1&amp;quot;&#039;&#039;&#039; and click on install.&lt;br /&gt;
* Tick &amp;quot;I accept the terms of use&amp;quot; and continue by clicking on the install yellow button.&lt;br /&gt;
* Wait until the install has been finished.&lt;br /&gt;
* Close and reopen the &#039;&#039;&#039;Settings App&#039;&#039;&#039; (PBX manager) in order to refresh the list of the available colored AP plugin icons.&lt;br /&gt;
* Open the &#039;&#039;&#039;&amp;quot;AP Conference Transcriptions&amp;quot;&#039;&#039;&#039; Plugin by clicking on it and click on &#039;&#039;&#039;&amp;quot; + Add an App&amp;quot;&#039;&#039;&#039; and then on the &#039;&#039;&#039;&amp;quot;Conference Transcriptions API&amp;quot;&#039;&#039;&#039; button.&lt;br /&gt;
* Enter a &#039;&#039;&#039;&amp;quot;Name&amp;quot;&#039;&#039;&#039; &#039;&#039;(used as display name / all character allowed)&#039;&#039; and the &#039;&#039;&#039;&amp;quot;SIP&amp;quot;&#039;&#039;&#039; &#039;&#039;(no space, no capital letters)&#039;&#039;. &#039;&#039;e.g : Name: Conference Transcriptions API, SIP: conference-transcriptions-api&#039;&#039;&lt;br /&gt;
* Choose a LLM (model) from the dropdown&lt;br /&gt;
* Tick the appropriate template to distribute the App (the app is needed at every user object from any user who wants to use the assistant API)&lt;br /&gt;
* Click OK to save the settings. A green check mark will be shown to confirm that the configuration is good.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In order to make the service work properly, two supplemental services must be installed:&lt;br /&gt;
&lt;br /&gt;
* the myApps Assistant which will summarize the transcript [[Reference16r1:Concept App Service myApps Assistant]]&lt;br /&gt;
* the Transcriptions Service which establishes a connection to a remote transcription server [[Reference16r1:Concept_App_Service_Transcriptions]]&lt;br /&gt;
&lt;br /&gt;
== Conference Transcriptions - App Service ==&lt;br /&gt;
The App Service performs tasks in the following areas:&lt;br /&gt;
* Transcribes the audio of a conference room&lt;br /&gt;
* Stores the transcript in the database&lt;br /&gt;
* Creates and stores the summary of the transcript in the database&lt;br /&gt;
&lt;br /&gt;
It can be configured in the &#039;&#039;&#039;Settings App&#039;&#039;&#039; (formerly known as PBXManager App) [[Reference16r1:Apps/PbxManager/App_myApps_ConferenceTranscriptions]]&lt;br /&gt;
&lt;br /&gt;
== Summary prompts ==&lt;br /&gt;
You may configure the prompt freely. Here are some propositions you may copy/paste into the corresponding field of the settings plugin:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
You will receive a meeting transcript. Your task is to turn it into a structured meeting summary.&lt;br /&gt;
&lt;br /&gt;
The entire summary — including section headers, bullet points, and all text — must be written in the same language as the transcript. Detect the language automatically. If the transcript is in german write the summary in german. If the transcript is in english, write the summary in english...&lt;br /&gt;
&lt;br /&gt;
Follow these instructions exactly:&lt;br /&gt;
&lt;br /&gt;
1. Read the transcript carefully.&lt;br /&gt;
2. Extract only the information that is clearly stated. Do not guess or invent anything.&lt;br /&gt;
3.  Create the final summary using the exact structure below, but translate the section headers into the language of the transcript.&lt;br /&gt;
&lt;br /&gt;
OUTPUT FORMAT (translate the headers into the transcript language, but keep the structure):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;A short title describing the meeting.&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Summary: &amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
(2–4 sentences describing the purpose of the meeting and the main outcomes.)&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Decisions:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Decision 1&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Decision 2&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;!-- Write “None mentioned” if no decisions were made. --&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Key Points:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Bullet point 1&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Bullet point 2&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Bullet point 3&amp;lt;/li&amp;gt;&lt;br /&gt;
 &amp;lt;!-- Add more if needed --&amp;gt;&lt;br /&gt;
 &amp;lt;!-- 2-3 sentences for each point --&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Tasks:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
 &amp;lt;li&amp;gt;Person — Task — Deadline (or “No deadline mentioned”)&amp;lt;/li&amp;gt;&lt;br /&gt;
 &amp;lt;!-- Add as many as needed.  Or none of none mentionned--&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Open Questions:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Question 1&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Question 2&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;!-- Write “None mentioned” if none. --&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
RULES:&lt;br /&gt;
&lt;br /&gt;
Use HTML lists (&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;) only for bullet points.&lt;br /&gt;
Do not add information that is not in the transcript.&lt;br /&gt;
Keep the writing clear and concise.&lt;br /&gt;
Keep the structure exactly as shown, but translate the headers.&lt;br /&gt;
Do not wrap the whole answer in a single HTML tag.&lt;br /&gt;
&lt;br /&gt;
TRANSCRIPT:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
For troubleshooting the Conference Transcirptions App Service, you need activate the traceflags &#039;&#039;App&#039;&#039;, &#039;&#039;Database and&#039;&#039; &#039;&#039;HTTP-Client&#039;&#039; in your App instance.&lt;br /&gt;
&lt;br /&gt;
== Related Articles ==&lt;br /&gt;
* [https://sdk.innovaphone.com/16r1/web1/com.innovaphone.conference-transcriptions/com.innovaphone.conference-transcriptions.htm SDK Documentation - Conference Transcriptions API]&lt;br /&gt;
* [[Reference16r1:Concept App Service myApps Assistant]]&lt;br /&gt;
* [[Reference16r1:Apps/PbxManager/App myApps ConferenceTranscriptions]]&lt;/div&gt;</summary>
		<author><name>Tfu</name></author>
	</entry>
	<entry>
		<id>https://wiki.innovaphone.com/index.php?title=Reference16r1:Concept_App_Service_Transcriptions&amp;diff=78840</id>
		<title>Reference16r1:Concept App Service Transcriptions</title>
		<link rel="alternate" type="text/html" href="https://wiki.innovaphone.com/index.php?title=Reference16r1:Concept_App_Service_Transcriptions&amp;diff=78840"/>
		<updated>2026-01-30T11:28:24Z</updated>

		<summary type="html">&lt;p&gt;Tfu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{FIXME|reason=This article is still work in progress}}&lt;br /&gt;
[[Category:Concept|Apps]]&lt;br /&gt;
[[Category:Concept App Service Transcriptions]]&lt;br /&gt;
== Applies To == &lt;br /&gt;
&lt;br /&gt;
* innovaphone Transcription Service from version 16r1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
The Transcription Service converts audio input into text using automatic speech recognition (ASR) models. In terms of its concept, it is located between the client services that generate or capture audio data and the transcription backend that performs the actual speech-to-text processing.&lt;br /&gt;
These transcription backends can run either as a locally hosted AI service within the same environment or as an external service accessed through a compatible API.&lt;br /&gt;
&lt;br /&gt;
The Transcription Service itself is responsible for managing sessions, handling parallel requests, and coordinating the data flow between clients and the selected backend. The external ASR model performs the actual transcription.&lt;br /&gt;
&lt;br /&gt;
The service is designed to work with OpenAI-compatible APIs, enabling clients to freely choose their preferred backend provider.&lt;br /&gt;
&lt;br /&gt;
== Licensing ==&lt;br /&gt;
&lt;br /&gt;
In order to use the Transcriptions Service including the Transcriptions App the newly introduced UCC license is necessary.&lt;br /&gt;
== Installation ==&lt;br /&gt;
Go to the &#039;&#039;&#039;Settings App&#039;&#039;&#039; (formerly known as PBX manager) and open the &#039;&#039;&#039;&amp;quot;AP app installer&amp;quot;&#039;&#039;&#039; plugin. On the right panel, the App Store will be shown. &#039;&#039;Hint : if you access it for the first time, you will need to accept the &amp;quot;Terms of Use of the innovaphone App Store&amp;quot;&#039;&#039;&lt;br /&gt;
* In the search field located on the top right corner of the store, search for &#039;&#039;&#039;&amp;quot;Transcriptions&amp;quot;&#039;&#039;&#039; and click on it&lt;br /&gt;
* Select the proper firmware version, for example &#039;&#039;&#039;&amp;quot;Version 16r1&amp;quot;&#039;&#039;&#039; and click on install&lt;br /&gt;
* Tick &amp;quot;I accept the terms of use&amp;quot; and continue by clicking on the install yellow button&lt;br /&gt;
* Wait until the install has been finished&lt;br /&gt;
* Close and reopen the &#039;&#039;&#039;Settings App&#039;&#039;&#039; (PBX manager) in order to refresh the list of the available colored AP plugin icons.&lt;br /&gt;
* Open the &#039;&#039;&#039;&amp;quot;AP transcriptions&amp;quot;&#039;&#039;&#039; plugin by clicking on it and select &#039;&#039;&#039;&amp;quot; + Add an App&amp;quot;&#039;&#039;&#039; afterwards. Then click on the &#039;&#039;&#039;&amp;quot;Transcriptions API&amp;quot;&#039;&#039;&#039; button.&lt;br /&gt;
* Enter a &#039;&#039;&#039;&amp;quot;Name&amp;quot;&#039;&#039;&#039; &#039;&#039;(used as display name / all character allowed)&#039;&#039; and the &#039;&#039;&#039;&amp;quot;SIP&amp;quot;&#039;&#039;&#039; &#039;&#039;(no space, no capital letters)&#039;&#039;. &#039;&#039;e.g : Name: Transcriptions API, SIP: transcriptions-api&#039;&#039;&lt;br /&gt;
* Enter the &#039;&#039;&#039;Remote service Url&#039;&#039;&#039; (Destination URL of the service provider)&lt;br /&gt;
* Enter the &#039;&#039;&#039;API Key&#039;&#039;&#039; (provided by the service provider)&lt;br /&gt;
* Enter the &#039;&#039;&#039;model name&#039;&#039;&#039; (must be supported by the configured provider) &lt;br /&gt;
* Tick the appropriate template to distribute the App (the app is needed at every user object from any user who wants to use the assistant API)&lt;br /&gt;
* Click OK to save the settings. A green check mark will be shown to confirm that the configuration is good.&lt;br /&gt;
&lt;br /&gt;
== How it works ==&lt;br /&gt;
&lt;br /&gt;
*A client service that requires transcription initiates the process by sending a transcription request via a WebSocket connection.&lt;br /&gt;
* The transcription service creates a session, assigns a transcription ID, and returns a dedicated HTTP endpoint to the client.&lt;br /&gt;
* The client uploads the audio data to the transcription service using HTTP connections, targeting the provided endpoint.&lt;br /&gt;
* The transcription service forwards the received audio data to the configured ASR backend (for example, a Whisper-compatible API) over HTTP.&lt;br /&gt;
* The ASR backend performs the transcription and returns the result to the transcription service, which then forwards the outcome back to the client.&lt;br /&gt;
&lt;br /&gt;
== Transcriptions Flow Overview ==&lt;br /&gt;
[[File:Screenshot 2026-01-29 161703.png|center|thumb|964x964px|screenshot_2026-01-29_161703.png/|screenshot_2026-01-29_161703.png/]]&lt;br /&gt;
&lt;br /&gt;
== Transcriptions - App Service ==&lt;br /&gt;
The App Service implements an API to use a remote transcription provider (e.g. whisper).&lt;br /&gt;
&lt;br /&gt;
It can be configured in the &#039;&#039;&#039;Settings App&#039;&#039;&#039; (PBX Manager App) [[Reference16r1:Apps/PbxManager/App_myApps_Transcriptions]]&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;Remote Service URL&#039;&#039;&#039; defines the target URL of the remote transcription provider. &lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;API Key&#039;&#039;&#039; is required to access the selected backend and to authenticate with the remote provider.&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;Model&#039;&#039;&#039; defines which model the backend should use for transcription.&lt;br /&gt;
&lt;br /&gt;
These parameters are stored as a configuration and are forwarded to the backend. At present, these values must be entered manually in the Settings plugin.&lt;br /&gt;
&lt;br /&gt;
The service does not validate or confirm these values. It assumes that all the given values are correct and only uses them for communication with the backend. Since the users are able to chose their own providers, they are also responsible for selecting a fitting model and understanding the limitations of the models  (such as supported Audio formats, size limits, etc.).&lt;br /&gt;
&lt;br /&gt;
Furthermore, applications that require transcription functionality must explicitly consume the Transcription Service API and demonstrate this functionality in their own user interface, such as applied in the Conference Transcriptions app.&lt;br /&gt;
&lt;br /&gt;
== Transcriptions App ==&lt;br /&gt;
The service also provides a user interface where audio files can be uploaded and transcribed directly.&lt;br /&gt;
&lt;br /&gt;
Once the transcription is complete, a simple summary can be generated and exported as a PDF (basic version).&lt;br /&gt;
&lt;br /&gt;
Audio files can be selected using the Choose audio file button. The transcription process and its results are displayed on the same screen. &lt;br /&gt;
&lt;br /&gt;
Neither the uploaded audio data nor the generated transcription text is stored by the service.[[File:ReferenceConceptTranscriptionsAppServiceTranscriptionsApp.png|thumb|referenceconcepttranscriptionsappservicetranscriptionsapp.png/|referenceconcepttranscriptionsappservicetranscriptionsapp.png/]]&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
For troubleshooting the Transcriptions App Service, you need to activate the traceflags &#039;&#039;App&#039;&#039;, &#039;&#039;Database and&#039;&#039; &#039;&#039;HTTP-Client&#039;&#039; in your Transcription App instance.&lt;br /&gt;
&lt;br /&gt;
== Limitations ==&lt;br /&gt;
&lt;br /&gt;
* Limitations such as maximum audio size, supported languages, or handling multilingual audio mainly depend on the selected model and provider and may vary based on the user’s provider choice.&lt;br /&gt;
* Differences in response structure can also occur. These responses are forwarded unchanged, since they may contain important metadata for the client, such as timestamps.&lt;br /&gt;
* The service does not validate the selected model. Choosing a suitable model is therefore the user’s responsibility.&lt;br /&gt;
* Transcriptions may contain misheard words or spelling inaccuracies, especially in cases of background noise or strong accents.&lt;br /&gt;
&lt;br /&gt;
== Related Articles ==&lt;br /&gt;
* [https://sdk.innovaphone.com/16r1/web1/com.innovaphone.transcriptions/com.innovaphone.transcriptions.htm SDK Documentation - Transcriptions API]&lt;br /&gt;
* [[Reference16r1:Apps/PbxManager/App_myApps_Transcriptions]]&lt;/div&gt;</summary>
		<author><name>Tfu</name></author>
	</entry>
	<entry>
		<id>https://wiki.innovaphone.com/index.php?title=Reference16r1:Concept_App_Service_Transcriptions&amp;diff=78839</id>
		<title>Reference16r1:Concept App Service Transcriptions</title>
		<link rel="alternate" type="text/html" href="https://wiki.innovaphone.com/index.php?title=Reference16r1:Concept_App_Service_Transcriptions&amp;diff=78839"/>
		<updated>2026-01-30T11:26:35Z</updated>

		<summary type="html">&lt;p&gt;Tfu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{FIXME|reason=This article is still work in progress}}&lt;br /&gt;
[[Category:Concept|Apps]]&lt;br /&gt;
[[Category:Concept App Service Transcriptions]]&lt;br /&gt;
== Applies To == &lt;br /&gt;
&lt;br /&gt;
* innovaphone from version 16r1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
The Transcription Service converts audio input into text using automatic speech recognition (ASR) models. In terms of its concept, it is located between the client services that generate or capture audio data and the transcription backend that performs the actual speech-to-text processing.&lt;br /&gt;
These transcription backends can run either as a locally hosted AI service within the same environment or as an external service accessed through a compatible API.&lt;br /&gt;
&lt;br /&gt;
The Transcription Service itself is responsible for managing sessions, handling parallel requests, and coordinating the data flow between clients and the selected backend. The external ASR model performs the actual transcription.&lt;br /&gt;
&lt;br /&gt;
The service is designed to work with OpenAI-compatible APIs, enabling clients to freely choose their preferred backend provider.&lt;br /&gt;
&lt;br /&gt;
== Licensing ==&lt;br /&gt;
&lt;br /&gt;
In order to use the Transcriptions Service including the Transcriptions App the newly introduced UCC license is necessary.&lt;br /&gt;
== Installation ==&lt;br /&gt;
Go to the &#039;&#039;&#039;Settings App&#039;&#039;&#039; (formerly known as PBX manager) and open the &#039;&#039;&#039;&amp;quot;AP app installer&amp;quot;&#039;&#039;&#039; plugin. On the right panel, the App Store will be shown. &#039;&#039;Hint : if you access it for the first time, you will need to accept the &amp;quot;Terms of Use of the innovaphone App Store&amp;quot;&#039;&#039;&lt;br /&gt;
* In the search field located on the top right corner of the store, search for &#039;&#039;&#039;&amp;quot;Transcriptions&amp;quot;&#039;&#039;&#039; and click on it&lt;br /&gt;
* Select the proper firmware version, for example &#039;&#039;&#039;&amp;quot;Version 16r1&amp;quot;&#039;&#039;&#039; and click on install&lt;br /&gt;
* Tick &amp;quot;I accept the terms of use&amp;quot; and continue by clicking on the install yellow button&lt;br /&gt;
* Wait until the install has been finished&lt;br /&gt;
* Close and reopen the &#039;&#039;&#039;Settings App&#039;&#039;&#039; (PBX manager) in order to refresh the list of the available colored AP plugin icons.&lt;br /&gt;
* Open the &#039;&#039;&#039;&amp;quot;AP transcriptions&amp;quot;&#039;&#039;&#039; plugin by clicking on it and select &#039;&#039;&#039;&amp;quot; + Add an App&amp;quot;&#039;&#039;&#039; afterwards. Then click on the &#039;&#039;&#039;&amp;quot;Transcriptions API&amp;quot;&#039;&#039;&#039; button.&lt;br /&gt;
* Enter a &#039;&#039;&#039;&amp;quot;Name&amp;quot;&#039;&#039;&#039; &#039;&#039;(used as display name / all character allowed)&#039;&#039; and the &#039;&#039;&#039;&amp;quot;SIP&amp;quot;&#039;&#039;&#039; &#039;&#039;(no space, no capital letters)&#039;&#039;. &#039;&#039;e.g : Name: Transcriptions API, SIP: transcriptions-api&#039;&#039;&lt;br /&gt;
* Enter the &#039;&#039;&#039;Remote service Url&#039;&#039;&#039; (Destination URL of the service provider)&lt;br /&gt;
* Enter the &#039;&#039;&#039;API Key&#039;&#039;&#039; (provided by the service provider)&lt;br /&gt;
* Enter the &#039;&#039;&#039;model name&#039;&#039;&#039; (must be supported by the configured provider) &lt;br /&gt;
* Tick the appropriate template to distribute the App (the app is needed at every user object from any user who wants to use the assistant API)&lt;br /&gt;
* Click OK to save the settings. A green check mark will be shown to confirm that the configuration is good.&lt;br /&gt;
&lt;br /&gt;
== How it works ==&lt;br /&gt;
&lt;br /&gt;
*A client service that requires transcription initiates the process by sending a transcription request via a WebSocket connection.&lt;br /&gt;
* The transcription service creates a session, assigns a transcription ID, and returns a dedicated HTTP endpoint to the client.&lt;br /&gt;
* The client uploads the audio data to the transcription service using HTTP connections, targeting the provided endpoint.&lt;br /&gt;
* The transcription service forwards the received audio data to the configured ASR backend (for example, a Whisper-compatible API) over HTTP.&lt;br /&gt;
* The ASR backend performs the transcription and returns the result to the transcription service, which then forwards the outcome back to the client.&lt;br /&gt;
&lt;br /&gt;
== Transcriptions Flow Overview ==&lt;br /&gt;
[[File:Screenshot 2026-01-29 161703.png|center|thumb|964x964px|/Screenshot_2026-01-29_161703.png|screenshot_2026-01-29_161703.png/]]&lt;br /&gt;
&lt;br /&gt;
== Transcriptions - App Service ==&lt;br /&gt;
The App Service implements an API to use a remote transcription provider (e.g. whisper).&lt;br /&gt;
&lt;br /&gt;
It can be configured in the &#039;&#039;&#039;Settings App&#039;&#039;&#039; (PBX Manager App) [[Reference16r1:Apps/PbxManager/App_myApps_Transcriptions]]&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;Remote Service URL&#039;&#039;&#039; defines the target URL of the remote transcription provider. &lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;API Key&#039;&#039;&#039; is required to access the selected backend and to authenticate with the remote provider.&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;Model&#039;&#039;&#039; defines which model the backend should use for transcription.&lt;br /&gt;
&lt;br /&gt;
These parameters are stored as a configuration and are forwarded to the backend. At present, these values must be entered manually in the Settings plugin.&lt;br /&gt;
&lt;br /&gt;
The service does not validate or confirm these values. It assumes that all the given values are correct and only uses them for communication with the backend. Since the users are able to chose their own providers, they are also responsible for selecting a fitting model and understanding the limitations of the models  (such as supported Audio formats, size limits, etc.).&lt;br /&gt;
&lt;br /&gt;
Furthermore, applications that require transcription functionality must explicitly consume the Transcription Service API and demonstrate this functionality in their own user interface, such as applied in the Conference Transcriptions app.&lt;br /&gt;
&lt;br /&gt;
== Transcriptions App ==&lt;br /&gt;
The service also provides a user interface where audio files can be uploaded and transcribed directly.&lt;br /&gt;
&lt;br /&gt;
Once the transcription is complete, a simple summary can be generated and exported as a PDF (basic version).&lt;br /&gt;
&lt;br /&gt;
Audio files can be selected using the Choose audio file button. The transcription process and its results are displayed on the same screen. &lt;br /&gt;
&lt;br /&gt;
Neither the uploaded audio data nor the generated transcription text is stored by the service.[[File:ReferenceConceptTranscriptionsAppServiceTranscriptionsApp.png|thumb|/ReferenceConceptTranscriptionsAppServiceTranscriptionsApp.png|referenceconcepttranscriptionsappservicetranscriptionsapp.png/]]&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
For troubleshooting the Transcriptions App Service, you need to activate the traceflags &#039;&#039;App&#039;&#039;, &#039;&#039;Database and&#039;&#039; &#039;&#039;HTTP-Client&#039;&#039; in your Transcription App instance.&lt;br /&gt;
&lt;br /&gt;
== Limitations ==&lt;br /&gt;
&lt;br /&gt;
* Limitations such as maximum audio size, supported languages, or handling multilingual audio mainly depend on the selected model and provider and may vary based on the user’s provider choice.&lt;br /&gt;
* Differences in response structure can also occur. These responses are forwarded unchanged, since they may contain important metadata for the client, such as timestamps.&lt;br /&gt;
* The service does not validate the selected model. Choosing a suitable model is therefore the user’s responsibility.&lt;br /&gt;
* Transcriptions may contain misheard words or spelling inaccuracies, especially in cases of background noise or strong accents.&lt;br /&gt;
&lt;br /&gt;
== Related Articles ==&lt;br /&gt;
* [https://sdk.innovaphone.com/16r1/web1/com.innovaphone.transcriptions/com.innovaphone.transcriptions.htm SDK Documentation - Transcriptions API]&lt;br /&gt;
* [[Reference16r1:Apps/PbxManager/App_myApps_Transcriptions]]&lt;/div&gt;</summary>
		<author><name>Tfu</name></author>
	</entry>
	<entry>
		<id>https://wiki.innovaphone.com/index.php?title=Reference16r1:Concept_App_Service_Transcriptions&amp;diff=78836</id>
		<title>Reference16r1:Concept App Service Transcriptions</title>
		<link rel="alternate" type="text/html" href="https://wiki.innovaphone.com/index.php?title=Reference16r1:Concept_App_Service_Transcriptions&amp;diff=78836"/>
		<updated>2026-01-30T10:38:47Z</updated>

		<summary type="html">&lt;p&gt;Tfu: /* Overview */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{FIXME|reason=This article is still work in progress}}&lt;br /&gt;
[[Category:Concept|Apps]]&lt;br /&gt;
[[Category:Concept App Service Transcriptions]]&lt;br /&gt;
== Applies To == &lt;br /&gt;
&lt;br /&gt;
* innovaphone from version 16r1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
The Transcription Service converts audio input into text using automatic speech recognition (ASR) models. In terms of its concept, it is located between the client services that generate or capture audio data and the transcription backends that perform the actual speech-to-text processing.&lt;br /&gt;
These transcription backends can run either as a locally hosted AI service within the same environment or as an external service accessed through a compatible API.&lt;br /&gt;
&lt;br /&gt;
The Transcription Service itself is responsible for managing sessions, handling parallel requests, and coordinating the data flow between clients and the selected backend. The external ASR model performs the actual transcription.&lt;br /&gt;
&lt;br /&gt;
The service is designed to work with OpenAI-compatible APIs, enabling clients to freely choose their preferred backend provider.&lt;br /&gt;
&lt;br /&gt;
== Licensing ==&lt;br /&gt;
&lt;br /&gt;
In order to use the Transcriptions Service including the Transcriptions App the newly introduced UCC license is necessary.&lt;br /&gt;
== Installation ==&lt;br /&gt;
Go to the &#039;&#039;&#039;Settings App&#039;&#039;&#039; (PBX manager) and open the &#039;&#039;&#039;&amp;quot;AP app installer&amp;quot;&#039;&#039;&#039; plugin. On the right panel, the App Store will be shown. &#039;&#039;Hint : if you access it for the first time, you will need to accept the &amp;quot;Terms of Use of the innovaphone App Store&amp;quot;&#039;&#039;&lt;br /&gt;
* In the search field located on the top right corner of the store, search for &#039;&#039;&#039;&amp;quot;Transcriptions&amp;quot;&#039;&#039;&#039; and click on it&lt;br /&gt;
* Select the proper firmware version, for example &#039;&#039;&#039;&amp;quot;Version 16r1&amp;quot;&#039;&#039;&#039; and click on install&lt;br /&gt;
* Tick &amp;quot;I accept the terms of use&amp;quot; and continue by clicking on the install yellow button&lt;br /&gt;
* Wait until the install has been finished&lt;br /&gt;
* Close and reopen the &#039;&#039;&#039;Settings App&#039;&#039;&#039; (PBX manager) again in order to refresh the list of the available colored AP plugin&lt;br /&gt;
* Click on the &#039;&#039;&#039;&amp;quot;AP transcriptions&amp;quot;&#039;&#039;&#039; and click on &#039;&#039;&#039;&amp;quot; + Add an App&amp;quot;&#039;&#039;&#039; and then on the &#039;&#039;&#039;&amp;quot;Transcriptions API&amp;quot;&#039;&#039;&#039; button.&lt;br /&gt;
* Enter a &#039;&#039;&#039;&amp;quot;Name&amp;quot;&#039;&#039;&#039; that is used as display name &#039;&#039;(all character allowed)&#039;&#039; for it and the &#039;&#039;&#039;&amp;quot;SIP&amp;quot;&#039;&#039;&#039; name that is the administrative field &#039;&#039;(no space, no capital letters)&#039;&#039;. &#039;&#039;e.g : Name: Transcriptions API, SIP: transcriptions-api&#039;&#039;&lt;br /&gt;
* Choose a LLM (model) from the dropdown&lt;br /&gt;
* Tick the appropriate template to distribute the App (the app is needed at every user object from any user who wants to use the assistant API)&lt;br /&gt;
* Click OK to save the settings and a green check mark will be shown to inform you that the configuration is good&lt;br /&gt;
&lt;br /&gt;
== How it works ==&lt;br /&gt;
&lt;br /&gt;
*A client service that requires transcription initiates the process by sending a transcription request via a WebSocket connection.&lt;br /&gt;
* The transcription service creates a session, assigns a transcription Id, and returns a dedicated HTTP endpoint to the client.&lt;br /&gt;
* The client uploads the audio data to the transcription service using HTTP connections, targeting the provided endpoint.&lt;br /&gt;
* The transcription service forwards the received audio data to the configured ASR backend (for example, a Whisper-compatible API) over HTTP.&lt;br /&gt;
* The ASR backend performs the transcription and returns the result to the transcription service, which then forwards the outcome back to the client.&lt;br /&gt;
&lt;br /&gt;
== Transcriptions Flow Overview ==&lt;br /&gt;
[[File:Screenshot 2026-01-29 161703.png|center|thumb|964x964px|/Screenshot_2026-01-29_161703.png|/Screenshot_2026-01-29_161703.png]]&lt;br /&gt;
&lt;br /&gt;
== Transcriptions - App Service ==&lt;br /&gt;
The App Service implements the API to a remote transcription server (e.g. whisper)&lt;br /&gt;
&lt;br /&gt;
It can be configured in the &#039;&#039;&#039;Settings App&#039;&#039;&#039; (PBX Manager App) [[Reference16r1:Apps/PbxManager/App_myApps_Transcriptions]]&lt;br /&gt;
&lt;br /&gt;
* The Remote service Url defines where requests are sent. &lt;br /&gt;
&lt;br /&gt;
* API key required to access the selected backend and to authenticates with the remote provider.&lt;br /&gt;
&lt;br /&gt;
* Model value defines which model the backend should use for transcription.&lt;br /&gt;
&lt;br /&gt;
These parameters are stored as a configuration and are forwarded to the backend. At present, these values must be entered manually in the Settings plugin.&lt;br /&gt;
&lt;br /&gt;
The service does not validate or confirm these values. It assumes that all the given values are correct and only uses them for communication with the backend. Since the users are able to chose their own providers, they are also responsible for selecting a fitting model and understanding the limitations of the models  (such as supported Audio formats, size limits etc.)&lt;br /&gt;
&lt;br /&gt;
Furthermore, Applications that require transcription functionality must explicitly consume the Transcription Service API and demonstrate this functionality in their own user interface, such as in Conference Transcriptions.&lt;br /&gt;
&lt;br /&gt;
== Transcriptions App ==&lt;br /&gt;
The service also provides a user interface where audio files can be uploaded and transcribed directly.&lt;br /&gt;
&lt;br /&gt;
Once the transcription is complete, a simple summary can be generated and exported as a PDF (basic version).&lt;br /&gt;
&lt;br /&gt;
Audio files can be selected using the Choose audio file button. The transcription process and its results are displayed on the same screen. &lt;br /&gt;
&lt;br /&gt;
Neither the uploaded audio data nor the generated transcription text is stored by the service.[[File:ReferenceConceptTranscriptionsAppServiceTranscriptionsApp.png|thumb|/ReferenceConceptTranscriptionsAppServiceTranscriptionsApp.png|/ReferenceConceptTranscriptionsAppServiceTranscriptionsApp.png]]&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
To troubleshoot this App Service, you need the traceflags &#039;&#039;App&#039;&#039;, &#039;&#039;Database&#039;&#039;, &#039;&#039;HTTP-Client&#039;&#039; in your App instance.&lt;br /&gt;
&lt;br /&gt;
== Limitations ==&lt;br /&gt;
&lt;br /&gt;
* Limitations such as maximum audio size, supported languages, or handling multilingual audio mainly depend on the selected model and provider, and may vary based on the user’s provider choice.&lt;br /&gt;
* Differences in response structure can also occur. These responses are forwarded unchanged, since they may contain important metadata for the client, such as timestamps.&lt;br /&gt;
* The service does not validate the selected model. Choosing a suitable model is therefore the user’s responsibility.&lt;br /&gt;
* Transcriptions may contain misheard words or spelling inaccuracies, especially in cases of background noise or strong accents.&lt;br /&gt;
&lt;br /&gt;
== Related Articles ==&lt;br /&gt;
* [https://sdk.innovaphone.com/16r1/web1/com.innovaphone.transcriptions/com.innovaphone.transcriptions.htm SDK Documentation - Transcriptions API]&lt;br /&gt;
* [[Reference16r1:Apps/PbxManager/App_myApps_Transcriptions]]&lt;/div&gt;</summary>
		<author><name>Tfu</name></author>
	</entry>
	<entry>
		<id>https://wiki.innovaphone.com/index.php?title=Howto13r1:Installation_Scenarios&amp;diff=78804</id>
		<title>Howto13r1:Installation Scenarios</title>
		<link rel="alternate" type="text/html" href="https://wiki.innovaphone.com/index.php?title=Howto13r1:Installation_Scenarios&amp;diff=78804"/>
		<updated>2026-01-28T10:33:19Z</updated>

		<summary type="html">&lt;p&gt;Tfu: /* Scenario - proxy-secured internet access */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__toc__&lt;br /&gt;
&amp;lt;!-- Keywords: v13 install, v13 dns, installer, setup scenarios --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Before starting your Version 13 Installation you have to check the customer network and his requirements first. &lt;br /&gt;
&lt;br /&gt;
You can install a Version 13 setup in different ways, so we will give you an overview and a best practice for your specific case.&lt;br /&gt;
&lt;br /&gt;
==Applies To==&lt;br /&gt;
This information applies to&lt;br /&gt;
&lt;br /&gt;
* Firmware Version 13 onwards&lt;br /&gt;
&lt;br /&gt;
== IP/DNS-Installation scenarios ==&lt;br /&gt;
&lt;br /&gt;
=== Decision Matrix ===&lt;br /&gt;
&lt;br /&gt;
On the left side you can choose the needs and conditions of your customer. Then you will see which solutions are possible or recommended.&lt;br /&gt;
&lt;br /&gt;
Some information to understand the conditions in the table:&lt;br /&gt;
;Reverse Proxy&lt;br /&gt;
:Needed if you want connect with external phones (e.g. Smartphones or HomeOffices) to your internal PBX or Application Platform. The requirements are an official domain and access to the router configuration to configure port forwardings. If you do not have a domain, you have to rent one. If you do not have access to the router, your customer must use a Cloud Solution.&lt;br /&gt;
;Local DNS server&lt;br /&gt;
:All applications can work with DNS Names. You have to configure some internal subdomains with the private IP addresses of your gateways&lt;br /&gt;
:Example PBX: &amp;lt;code&amp;gt;pbx.domanin.tld =&amp;gt; 192.168.2.10&amp;lt;/code&amp;gt;&lt;br /&gt;
:Example Ap Platform: &amp;lt;code&amp;gt;ap.domanin.tld =&amp;gt; 192.168.2.11&amp;lt;/code&amp;gt;&lt;br /&gt;
;External DNS server&lt;br /&gt;
:In combination with the reverse proxy you can offer some subdomains from your external domain name with the external IP or the NAT-IP of your Reverse Proxy&lt;br /&gt;
:Example PBX: &amp;lt;code&amp;gt;pbx.domanin.tld =&amp;gt; 1.2.3.4&amp;lt;/code&amp;gt; &lt;br /&gt;
:Example Ap Platform: &amp;lt;code&amp;gt;ap.domanin.tld =&amp;gt; 1.2.3.4&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Reverse Proxy is needed ===&lt;br /&gt;
&lt;br /&gt;
Please check on the vertical lines the starting conditions on your customer site. After that you can check on the right columns possible scenarios for your customer.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| &amp;amp;nbsp; || style=&amp;quot;background-color: #EAECF0;text-align:center&amp;quot;|Cloud || style=&amp;quot;background-color:#B3B7FF&amp;quot;|&amp;amp;nbsp; ||  colspan=&amp;quot;4&amp;quot; style=&amp;quot;background-color: #EAECF0;text-align:center&amp;quot;| On Premise&lt;br /&gt;
|-&lt;br /&gt;
|- style=&amp;quot;background-color: #FAEBA3&amp;quot;&lt;br /&gt;
! / !! &amp;amp;nbsp;innovaphone Cloud&amp;amp;nbsp; !! style=&amp;quot;background-color:#B3B7FF&amp;quot;| !! &amp;amp;nbsp;internal DNS Server&amp;amp;nbsp; !! &amp;amp;nbsp;external NAT Hairpinning&amp;amp;nbsp; !! &amp;amp;nbsp;new DNS Server with a innovaphone Box&amp;amp;nbsp; !! &amp;amp;nbsp;use only IP addresses&amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;font-weight:bold;background-color: #FAEBA3&amp;quot;|&amp;amp;nbsp;&amp;amp;bull; local DNS server exists || style=&amp;quot;color:green;text-align:center;&amp;quot;|✔✔✔ || style=&amp;quot;background-color:#B3B7FF&amp;quot;| ||  style=&amp;quot;color:green;text-align:center&amp;quot;|✔✔✔ ||  style=&amp;quot;color:green;text-align:center&amp;quot;|✔ || style=&amp;quot;color:green;text-align:center&amp;quot;|✔ || style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;font-weight:bold;background-color: #FAEBA3&amp;quot;|&amp;amp;nbsp;&amp;amp;bull; no local DNS server exists || style=&amp;quot;color:green;text-align:center&amp;quot;|✔✔✔ || style=&amp;quot;background-color:#B3B7FF&amp;quot;| || style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X || style=&amp;quot;color:green;text-align:center&amp;quot;|✔ || style=&amp;quot;color:green;text-align:center&amp;quot;|✔ || style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Reverse Proxy is not needed ===&lt;br /&gt;
&lt;br /&gt;
Please check on the vertical lines the starting conditions on your customer site. After that you can check on the right columns possible scenarios for your customer.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| &amp;amp;nbsp; || style=&amp;quot;background-color: #EAECF0;text-align:center&amp;quot;|Cloud || style=&amp;quot;background-color:#B3B7FF&amp;quot;|&amp;amp;nbsp; ||  colspan=&amp;quot;4&amp;quot; style=&amp;quot;background-color: #EAECF0;text-align:center&amp;quot;| On Premise&lt;br /&gt;
|-&lt;br /&gt;
|- style=&amp;quot;background-color: #FAEBA3&amp;quot;&lt;br /&gt;
! / !! &amp;amp;nbsp;innovaphone Cloud&amp;amp;nbsp; !! style=&amp;quot;background-color:#B3B7FF&amp;quot;| !! &amp;amp;nbsp;internal DNS Server&amp;amp;nbsp; !! &amp;amp;nbsp;external NAT Hairpinning&amp;amp;nbsp; !! &amp;amp;nbsp;new DNS Server with a innovaphone Box&amp;amp;nbsp; !! &amp;amp;nbsp;use only IP addresses&amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;font-weight:bold;background-color: #FAEBA3&amp;quot;|&amp;amp;nbsp;&amp;amp;bull; local DNS server exists || style=&amp;quot;color:green;text-align:center;&amp;quot;|✔✔✔ || style=&amp;quot;background-color:#B3B7FF&amp;quot;| ||  style=&amp;quot;color:green;text-align:center&amp;quot;|✔✔✔ ||  style=&amp;quot;color:green;text-align:center&amp;quot;|✔ || style=&amp;quot;color:green;text-align:center&amp;quot;|✔ || style=&amp;quot;color:green;text-align:center&amp;quot;|✔✔ &lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;font-weight:bold;background-color: #FAEBA3&amp;quot;|&amp;amp;nbsp;&amp;amp;bull; no local DNS server exists || style=&amp;quot;color:green;text-align:center&amp;quot;|✔✔✔ || style=&amp;quot;background-color:#B3B7FF&amp;quot;| || style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;|X || style=&amp;quot;color:green;text-align:center&amp;quot;|✔ || style=&amp;quot;color:green;text-align:center&amp;quot;|✔ || style=&amp;quot;color:green;text-align:center&amp;quot;|✔✔ &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;span style=&amp;quot;color:green;text-align:center&amp;quot;&amp;gt;✔✔✔&amp;lt;/span&amp;gt; means that we recommend it&lt;br /&gt;
*&amp;lt;span style=&amp;quot;color:green;text-align:center&amp;quot;&amp;gt;✔✔&amp;lt;/span&amp;gt; means that you can do it, and it works fine&lt;br /&gt;
*&amp;lt;span style=&amp;quot;color:green;text-align:center&amp;quot;&amp;gt;✔&amp;lt;/span&amp;gt; means that you can do it, it works fine but you should do some local network adjustment&lt;br /&gt;
*&amp;lt;span style=&amp;quot;color:orange;text-align:center;font-weight:bold;&amp;quot;&amp;gt;O&amp;lt;/span&amp;gt; means that you can do it, but we don&#039;t recommended it&lt;br /&gt;
*&amp;lt;span style=&amp;quot;color:red;text-align:center;font-weight:bold;&amp;quot;&amp;gt;X&amp;lt;/span&amp;gt; means that you should not do it, otherwise you may run into problems&lt;br /&gt;
&lt;br /&gt;
We recommend to take a look [[Courseware:IT Advanced - 06 Public Access to PBX Resources (theory) - optional|into our training books]] to decide how to setup the whole network.&lt;br /&gt;
&lt;br /&gt;
=== Scenario - innovaphone Cloud ===&lt;br /&gt;
Refer to [[Howto:MyApps Cloud - Installation|respective article]].&lt;br /&gt;
&lt;br /&gt;
=== Scenario - internal DNS Server ===&lt;br /&gt;
You can use your existing DNS Server to setup your DNS names to resolv it to the correct internal IP addresses.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
* pbx.example.com =&amp;gt; 192.168.2.10&lt;br /&gt;
* apps.example.com =&amp;gt; 192.168.2.11&lt;br /&gt;
&lt;br /&gt;
=== Scenario - external NAT Hairpinning ===&lt;br /&gt;
If you have no internal DNS Server and your NAT router support &#039;&#039;[https://en.wikipedia.org/wiki/Hairpinning Hairpinning]&#039;&#039; you can use external DNS entries with a record to your external IP-Address.&lt;br /&gt;
&lt;br /&gt;
Your internal client should resolve &#039;&#039;pbx.example.com&#039;&#039; to your public IP address of your own router. If you configure needed NAT rules to your internal IP, your router will accept the package from inside and forward it back to the internal IP from your NAT rule. &lt;br /&gt;
&lt;br /&gt;
In this scenario no separate internal dns server are required and your internal client (eg. 192.168.3.5) can talk with your PBX (eg. pbx.example.com -&amp;gt; 1.2.3.4) with a mapping to the internal IP (eg. 192.168.3.10)&lt;br /&gt;
&lt;br /&gt;
The most used NAT Rules are:&lt;br /&gt;
 // H.323/TLS &lt;br /&gt;
 [from outside] tcp/1300     =&amp;gt; [internal IP of your Reverse Proxy] &lt;br /&gt;
 &lt;br /&gt;
 // LDAPS&lt;br /&gt;
 [from outside] tcp/636      =&amp;gt; [internal IP of your Reverse Proxy] &lt;br /&gt;
 &lt;br /&gt;
 // HTTPS&lt;br /&gt;
 [from outside] tcp/443      =&amp;gt; [internal IP of your Reverse Proxy] &lt;br /&gt;
 &lt;br /&gt;
 // TURN&lt;br /&gt;
 [from outside] tcp/udp/3478 =&amp;gt; [internal IP of your Reverse Proxy]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
During the install process you have to set up a temporary internal DNS first and to configure your PC and the innovaphone Gateway to use them, which provides the local addresses. Only during the install you have to distribute the internal DNS by DHCP in your router to the Clients. If everything is finished, you can turn off the local DNS.&lt;br /&gt;
If you have no Hardware/Software for a temporary DNS Server you can use a innovaphone Box which is described [[Howto:V13 Installation Scenarios#Scenario - new DNS Server with a innovaphone Box|here]].&lt;br /&gt;
&lt;br /&gt;
If you cannot setup temporary DNS records the installer will automatic activate the [[Reference13r1:PBX/Config/General|Operation without DNS]] mode, to communicate via IP address. You have to deactivate the mode after setup the correct DNS entries.&lt;br /&gt;
&lt;br /&gt;
=== Scenario - new DNS Server with a innovaphone Box ===&lt;br /&gt;
If you decided to setup an internal DNS than you can do that as described here:&lt;br /&gt;
&lt;br /&gt;
First choose Manual Installation&lt;br /&gt;
&lt;br /&gt;
[[Image:SetupInternerDNS-Part1.png|setupinternerdns-part1.png/]]&lt;br /&gt;
&lt;br /&gt;
Than enable the DNS Server and create A Records&lt;br /&gt;
&lt;br /&gt;
[[Image:SetupInternerDNS-Part2.png|setupinternerdns-part2.png/]]&lt;br /&gt;
&lt;br /&gt;
Afterwards it looks like that:&lt;br /&gt;
&lt;br /&gt;
[[Image:SetupInternerDNS-Part3.png|setupinternerdns-part3.png/]]&lt;br /&gt;
&lt;br /&gt;
In the next step you should provide the IP of this box as DNS server to all of you phones. &lt;br /&gt;
Therefore you could use your own DHCP Server. &lt;br /&gt;
&lt;br /&gt;
Now you can go back to the normal installation process of the box. &lt;br /&gt;
Therefore just ....&lt;br /&gt;
&lt;br /&gt;
=== Scenario - use only IP addresses ===&lt;br /&gt;
You can use static IP addresses in the installations process. So no DNS is needed.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
*PBX DNS Name =&amp;gt; 192.168.2.10&lt;br /&gt;
*AP DNS Name =&amp;gt; 192.168.2.11&lt;br /&gt;
&lt;br /&gt;
=== Scenario - proxy-secured internet access ===&lt;br /&gt;
If Internet access is only possible via a proxy server, a local store can be used for installation.&lt;br /&gt;
For details refer to the [[Special:Search/intitle:offline incategory:&amp;quot;Step-by-Step&amp;quot;|offline installation articles]].&lt;br /&gt;
&lt;br /&gt;
== Possible scenarios if port 443 is already in use ==&lt;br /&gt;
Sometimes the HTTPS (tcp/443) or HTTP (tcp/80) is already in use by other systems like Webmail or Webserver on the customers side. To use your myApps Clients externally the myApps Client need to connect also via Port 443 to the customer network. &lt;br /&gt;
&lt;br /&gt;
There are some possible solutions to resolve that conflict.&lt;br /&gt;
&lt;br /&gt;
=== Use an innovaphone Cloud Setup ===&lt;br /&gt;
If you don&#039;t want to or can&#039;t change the network on customers side you can use an [https://www.innovaphone.com/en/cloud/rent-buy-or-move-to-the-cloud.html innovaphone Cloud Setup].&lt;br /&gt;
&lt;br /&gt;
=== Separate IP Address for Reverse Proxy ===&lt;br /&gt;
The best way is to have more than one public IP-Addresses. In this scenario you use a separate IP-Address for a specific server/service. In this way you can use different IP-Addresses on your Firewall and route the traffic to the different servers/services.&lt;br /&gt;
&lt;br /&gt;
=== Distribute traffic based on hostname ===&lt;br /&gt;
If you only have a single IP-Address you have to decide which is the target system for an incoming tcp/443 packet. For this, you can use a system that forwards the request based on the hostname in the GET Request and forward the packet to the correct service.&lt;br /&gt;
&lt;br /&gt;
==== Use existing firewall ====&lt;br /&gt;
Most of the Next-Gen firewalls support features like &#039;&#039;Load-Balancer&#039;&#039;, &#039;&#039;Reverse Proxy&#039;&#039; or something similar that can do the forwarding.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note: Please consult your firewall vendor or system admin if you need help to configure this.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==== Use innovaphone&#039;s Reverse Proxy ====&lt;br /&gt;
The Reverse Proxy can do the forwarding to [[Courseware:IT Advanced - 06 Public Access to PBX Resources (theory) - optional#Service Name Definition|configured destination IP-addresses]] too.&lt;br /&gt;
With this setup you route or NAT (depending from your Firewall) all incoming Traffic based on tcp/443 to the Reverse Proxy.&lt;br /&gt;
The Reverse Proxy distributes it to the appropriate system (eg. for &amp;quot;&#039;&#039;webmail.domain.tld&#039;&#039;&amp;quot; to the local Exchange IP and traffic for &amp;quot;&#039;&#039;apps.domain.tld&#039;&#039;&amp;quot; to the innovaphone AP-Platform).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note: the reverse proxy can [[Courseware:IT Advanced - 06 Public Access to PBX Resources (theory) - optional#Reverse Proxy and Certificates|handle a single SSL-Certificate]] only. You have to use a wildcard (*.domain.tld) certificate therefore.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Separate WAN Uplink ===&lt;br /&gt;
You can book a separate internet connection to get a second public IP-Address and forward the Traffic to your Reverse Proxy.&lt;br /&gt;
&lt;br /&gt;
== Related Articles ==&lt;br /&gt;
* [[Reference13r1:Install]]&lt;br /&gt;
* [[Howto:Firmware_Upgrade]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Howto|{{PAGENAME}}]]&lt;/div&gt;</summary>
		<author><name>Tfu</name></author>
	</entry>
	<entry>
		<id>https://wiki.innovaphone.com/index.php?title=Reference16r1:Concept_App_Service_Connector_for_Microsoft_365&amp;diff=78428</id>
		<title>Reference16r1:Concept App Service Connector for Microsoft 365</title>
		<link rel="alternate" type="text/html" href="https://wiki.innovaphone.com/index.php?title=Reference16r1:Concept_App_Service_Connector_for_Microsoft_365&amp;diff=78428"/>
		<updated>2025-11-05T09:54:23Z</updated>

		<summary type="html">&lt;p&gt;Tfu: /* Technical Overview */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
{{FIXME|reason=This article is still work in progress}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Concept|Apps]]&lt;br /&gt;
== Applies To == &lt;br /&gt;
&lt;br /&gt;
* Connector for Microsoft 365 from Version 16r1&lt;br /&gt;
&lt;br /&gt;
= Overview =&lt;br /&gt;
&lt;br /&gt;
Connector for Microsoft 365 synchronizes Microsoft Teams presences with the innovaphone PBX and back, and optionally additionally Calendar presence from Exchange Online (part of the Microsoft 365 Cloud Services).&lt;br /&gt;
It is also possible to search for your own contacts. &lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
* innovaphone PBX&lt;br /&gt;
* innovaphone Application Platform (minimum version 120004)&lt;br /&gt;
* V16r1&lt;br /&gt;
* App(Connector for Microsoft 365)&lt;br /&gt;
* PBX-App(innovaphone-microsoft365) license per user - order no. 02-00050-009&lt;br /&gt;
&lt;br /&gt;
== Concept ==&lt;br /&gt;
&lt;br /&gt;
=== User Presence ===&lt;br /&gt;
&lt;br /&gt;
==== Configuration ====&lt;br /&gt;
Please have a look into our [[Howto15r1:Configure User Presence Sync by Connector for Microsoft365|Howto guide for basic configuration aid]].&lt;br /&gt;
&lt;br /&gt;
==== Technical Overview ====&lt;br /&gt;
If the Connector for Microsoft 365 app is fully configured, the app connects to Microsoft to obtain a token. With the token, the app gets the teams users (with a Teams license) through the Microsoft Graph API.&lt;br /&gt;
A presence subscription to Microsoft is started with the licensed users of the PBX to get presence changes in Microsoft Teams for these users. A user subscription is also started to get changes of the users (adding, deleting or update). If a user has changed, the Teams users are retrieved again. If the presence has changed, it is forwarded to the PBX. The presences of Teams are mapped to the presences of the PBX.&lt;br /&gt;
&lt;br /&gt;
* User subscriptions are renewed every 60 minutes.&lt;br /&gt;
* Presence subscriptions are renewed every 10 minutes.&lt;br /&gt;
* License Check is made periodically.&lt;br /&gt;
&lt;br /&gt;
The app synchronises the PBX presence with Teams through the Graph Api. The on-the-phone presence will be renewed every 5 minutes. The other presences have a lifetime of 1 day but the away has a lifetime of 7 days.&lt;br /&gt;
The lifetimes are described [https://learn.microsoft.com/en-us/graph/api/presence-setuserpreferredpresence?view=graph-rest-1.0&amp;amp;tabs=http here]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Please be aware:&#039;&#039;&#039; The actual change of presence or line state will be live, the above-mentioned subscriptions are needed to register against the Microsoft API for changes. &lt;br /&gt;
After successful subscription Microsoft will trigger the Connector for Microsoft 365 App every time a presence or line state for a user has changed.&lt;br /&gt;
The subscription will then be renewed in the above-mentioned time interval to receive further live updates.&lt;br /&gt;
&lt;br /&gt;
===== User Matching =====&lt;br /&gt;
You now can choose the fields used for user matching on either side from the following options:&lt;br /&gt;
* PBX&lt;br /&gt;
** CN (Long Name property from the PBX user object)&lt;br /&gt;
** h323 (Name property from the PBX user object)&lt;br /&gt;
* Azure Portal&lt;br /&gt;
** displayName&lt;br /&gt;
** mail&lt;br /&gt;
** mailNickname&lt;br /&gt;
** onPremisesDistinguishedName&lt;br /&gt;
** onPremisesSamAccountName&lt;br /&gt;
** onPremisesUserPrincipalName&lt;br /&gt;
** userPrincipalName&lt;br /&gt;
&lt;br /&gt;
Additionally, you have the possibility to remove a possibly contained domain from the Azure fields content. &amp;lt;br&amp;gt;&lt;br /&gt;
Example: &#039;user@domain.tld&#039; is transformed to &#039;user&#039;, if this option is checked.&lt;br /&gt;
&lt;br /&gt;
===== Mapping Table =====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Teams Presence&lt;br /&gt;
! PBX Presence&lt;br /&gt;
|-&lt;br /&gt;
| Away&lt;br /&gt;
| away&lt;br /&gt;
|-&lt;br /&gt;
| BeRightBack&lt;br /&gt;
| away&lt;br /&gt;
|-&lt;br /&gt;
| Busy&lt;br /&gt;
| busy&lt;br /&gt;
|-&lt;br /&gt;
| DoNotDisturb&lt;br /&gt;
| dnd&lt;br /&gt;
|-&lt;br /&gt;
| InACall&lt;br /&gt;
| on-the-phone&lt;br /&gt;
|-&lt;br /&gt;
| InAMeeting&lt;br /&gt;
| meeting&lt;br /&gt;
|-&lt;br /&gt;
| Inactive&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| PresenceUnknown&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| Available&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| Offline&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| Offwork&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| OutOfOffice&lt;br /&gt;
| away&lt;br /&gt;
|-&lt;br /&gt;
| UrgentInterruptionsOnly&lt;br /&gt;
| dnd&lt;br /&gt;
|-&lt;br /&gt;
| Presenting&lt;br /&gt;
| on-the-phone&lt;br /&gt;
|-&lt;br /&gt;
| InAConferenceCall&lt;br /&gt;
| on-the-phone&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The value &amp;quot;online&amp;quot; unsets the Teams presence in the PBX.&lt;br /&gt;
&lt;br /&gt;
===== Master/Slave =====&lt;br /&gt;
&lt;br /&gt;
For Master/Slave combination the &amp;quot;Connector for Microsoft 365&amp;quot; App has to be added to the slave (if no full replication is on). The slave websocket connection is needed to display &amp;quot;on-the-phone&amp;quot; presence.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Calendar Presence ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Configuration ====&lt;br /&gt;
Please have a look into our [[Howto15r1:Configure_Calendar_Presence_Sync_by_Connector_for_Microsoft365|Howto guide for basic configuration aid]].&lt;br /&gt;
&lt;br /&gt;
==== Technical Overview ====&lt;br /&gt;
Introduced in 15r1 the Connector for Microsoft 365 will offer a possibility to sync Azure Portal calendar events (Teams, Exchange online) via the Graph API with the PXB presence.&amp;lt;br&amp;gt;&lt;br /&gt;
For now the [https://wiki.innovaphone.com/index.php?title=Reference13r3:Concept_App_Service_Calendar Calendar App] is (along with other functions) also capable of syncing calendar events, but using the old EWS mechanism, which Microsoft announced as end of life starting from 2026.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Warning:&#039;&#039;&#039; Please make sure to not use both apps for syncing calendar events in parallel, this is not supported and will most likely lead to conflicts and unexpected behaviours.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
When the configuration of the connector for Microsoft 365 Calendar Presence Sync is complete, the app connects to Microsoft to receive a token with the calendar app registered in the Azure portal.&amp;lt;br&amp;gt;&lt;br /&gt;
With the token, the app can pick up the users from the Azure portal.&amp;lt;br&amp;gt;&lt;br /&gt;
These are matched against the users in the PBX, based on the configured &amp;quot;User Assignment&amp;quot; settings.&amp;lt;br&amp;gt;&lt;br /&gt;
For each matched user with a valid Connector for Microsoft 365 licence applied, a subscription for calendar events is created at Microsoft to receive event changes in Microsoft Calendar for these users.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
A user subscription is also started to receive user changes (add, delete or update).&amp;lt;br&amp;gt;&lt;br /&gt;
If a user has changed, the users are retrieved again. &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
If a calendar event has been started or ended, it is forwarded to the PBX.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* User subscriptions are renewed every 60 minutes.&lt;br /&gt;
* Event subscriptions are renewed every day.&lt;br /&gt;
* License Check is made every hour.&lt;br /&gt;
&lt;br /&gt;
=== Contact Search ===&lt;br /&gt;
&lt;br /&gt;
==== Configuration ====&lt;br /&gt;
Please have a look into our [[Howto16r1:Configure Calendar Presence Sync by Connector for Microsoft365|Howto guide for basic configuration aid]].&lt;br /&gt;
&lt;br /&gt;
==== Technical Overview ====&lt;br /&gt;
Introduced in 16r1 the Connector for Microsoft 365 will offer a possibility to search for your own contacts (Teams, Exchange online) via the Graph API.&lt;br /&gt;
&lt;br /&gt;
When the configuration of the connector for Microsoft 365 Contact Search is complete, the app connects to Microsoft to receive a token with the contact search app registered in the Azure portal.&amp;lt;br&amp;gt;&lt;br /&gt;
With the token, the app can pick up the users from the Azure portal.&amp;lt;br&amp;gt;&lt;br /&gt;
These are matched against the users in the PBX, based on the configured &amp;quot;User Assignment&amp;quot; settings.&amp;lt;br&amp;gt;&lt;br /&gt;
For each matched user with a valid Connector for Microsoft 365 licence applied, the user can search with the Phone App, for example (a myApps search provider will be provided for all apps looking using search providers looking up contacts). The search string is made available to the Connector for Microsoft 365 via the microsoft365-api. The results are sent to the consumer, e.g. the Phone App and presented there.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
A user subscription is started to receive user changes (add, delete or update).&amp;lt;br&amp;gt;&lt;br /&gt;
If a user has changed, the users are retrieved again. &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* User subscriptions are renewed every 60 minutes.&lt;br /&gt;
* License Check is made every hour.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Be aware:&#039;&#039;&#039; Since the Connector for Microsoft 365 is an app in the Scope of myApps App Platform, IP Phones and other services not using Apps cannot benefit from this search service.&lt;br /&gt;
&lt;br /&gt;
== Related Articles ==&lt;br /&gt;
&lt;br /&gt;
=Known Limitation=&lt;br /&gt;
&lt;br /&gt;
== General ==&lt;br /&gt;
&#039;&#039;Applies to the User Presence and the Calendar Presence&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Synchronization Delay ===&lt;br /&gt;
In the official Graph-API documentation, Microsoft is providing an overview about expected latencies for change notifications.&amp;lt;br&amp;gt;&lt;br /&gt;
You can find a whole overview table here:&amp;lt;br&amp;gt;&lt;br /&gt;
https://learn.microsoft.com/en-us/graph/change-notifications-overview#latency&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
For the user presences the resource &amp;quot;presence&amp;quot; is used and an average latency of 10 seconds but a maximum up to 1 minute is provided.&amp;lt;br&amp;gt;&lt;br /&gt;
Such a delay in syncing changed presences from Teams down to the PBX are considered normal and are caused by the Microsoft Graph-API.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
In case of calendar events the average is provided as &amp;quot;less than 1 minute&amp;quot; and the maximum to 3 minutes.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== User Presence ==&lt;br /&gt;
=== Line states set by the PBX does not block calls in Teams ===&lt;br /&gt;
Line states set by a 3rd party application (like the Connector for Microsoft 365) through the graph API are currently &#039;&#039;&#039;only for display purpose and do not block new calls&#039;&#039;&#039; in Teams.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
https://techcommunity.microsoft.com/t5/teams-developer/ms-graph-setpresence-problems/m-p/2798805/highlight/true#M3957&amp;lt;br&amp;gt;&lt;br /&gt;
As you can see in the above linked discussion, there once existed a feature request on Microsoft Voice, which is no longer available since it was not voted.&lt;br /&gt;
=== Maximum number of supported users ===&lt;br /&gt;
The connector now supports multiple Microsoft Teams communication users, which is the prerequisite to subscribe for more than 650 users. There is a new ribbon (Manage Teams Accounts) that allows you to configure as many communication users as you need. Every configured communication user can be used to subscribe 650 users, for example:&lt;br /&gt;
&lt;br /&gt;
*3 configured communication users x 650 licensed users = 1950 users can be subscribed&lt;br /&gt;
&#039;&#039;&#039;Please be aware&#039;&#039;&#039;: Each communication user must have a Teams license applied.&lt;br /&gt;
&lt;br /&gt;
This limitation is caused by Microsoft.&amp;lt;br&amp;gt;&lt;br /&gt;
In the documentation of the Graph-API you will find a hint to this limitation:&amp;lt;br&amp;gt;&lt;br /&gt;
https://learn.microsoft.com/en-us/graph/changenotifications-for-presence#subscribe-to-multiple-users-presence&amp;lt;br&amp;gt;&lt;br /&gt;
Trying to subscribe more than 650 users (with one communication user) by using the presence subscription API will be declined by the graph API with an error message, that too many users are requested.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Communication User (UserSynctoPbx) ===&lt;br /&gt;
Users with MFA (multi-factor-authentication) are not supported as technical communication user for the Connector.&lt;br /&gt;
&lt;br /&gt;
=== Multiple sites / instances require multiple communication users ===&lt;br /&gt;
Each instance or each site must have separate communication users, as Microsoft only allows one concurrent subscription per communication user. (otherwise an HTTP 409 conflict will occur)&lt;br /&gt;
&lt;br /&gt;
This means that if you want to subscribe to the same Azure Portal backend from two different sites (or instances), you will need to have multiple communication users (each with an applied Teams licence) in order to be able to subscribe from all endpoints.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Subscription Timeout ===&lt;br /&gt;
&lt;br /&gt;
==== Situation ====&lt;br /&gt;
Due to a current limitation in the Graph API it is not possible to cancel or delete an active presence subscription.&amp;lt;br&amp;gt;&lt;br /&gt;
As you can see in the [https://learn.microsoft.com/en-us/graph/api/subscription-delete?view=graph-rest-1.0&amp;amp;tabs=http|documentation of the current Graph API (1.0)] the “Delete subscription” chapter does not include presence subscriptions.&amp;lt;br&amp;gt;&lt;br /&gt;
It is also not possible to have multiple subscription in parallel. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To make sure to only request a new presence subscription when the old one is not valid anymore, the app will store the state of the presence subscription and the time until it is valid in the database.&amp;lt;br&amp;gt;&lt;br /&gt;
As mentioned in the chapter “Technical Overview” we are creating presence subscriptions with a validity of 10 minutes.&amp;lt;br&amp;gt;&lt;br /&gt;
The presence subscription will be renewed as soon as it is no longer valid which will be 10 minutes after initial subscription.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Impact ====&lt;br /&gt;
If settings are changed or the app instance is restarted it will check the corresponding database entry on startup.&amp;lt;br&amp;gt;&lt;br /&gt;
In case the last presence subscription was completed less than 10 minutes ago, there is still an active presence subscription and the app has to wait for it to become invalid. &amp;lt;br&amp;gt;&lt;br /&gt;
Some Changes (e.g., to the “Notification-URL”) will only take effect after a new created subscription. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The current Beta Version of the Graph API is already providing a function to delete presence subscriptions, so we hope we can improve this behavior in the future.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Troubleshooting=&lt;br /&gt;
== General ==&lt;br /&gt;
&lt;br /&gt;
===Creating an app trace===&lt;br /&gt;
For further analysis and creating a support ticket it will be useful to have a suitable app trace. &amp;lt;br&amp;gt;&lt;br /&gt;
Before creating the trace please make sure the following trace flags are activated for the app instance:&lt;br /&gt;
* App&lt;br /&gt;
* Database&lt;br /&gt;
* HTTP client&lt;br /&gt;
* TLS&lt;br /&gt;
* TCP&lt;br /&gt;
* App WebSocket&lt;br /&gt;
* Config&lt;br /&gt;
* Webserver&lt;br /&gt;
&lt;br /&gt;
After setting the config flags, please make sure to&lt;br /&gt;
* stop the instance&lt;br /&gt;
* deleting the current instance log&lt;br /&gt;
* start the instance&lt;br /&gt;
&#039;&#039;&#039;Now please wait at least 5 Minutes before you save the log&#039;&#039;&#039;, otherwise we could not have the whole picture in the trace.&lt;br /&gt;
&lt;br /&gt;
The restart and deletion of the the old log is useful the see the complete initialization process right away.&lt;br /&gt;
&lt;br /&gt;
===SSL Certificate for notification URL===&lt;br /&gt;
It also is useful to make sure the notification URL has a valid and public signed certificate.&amp;lt;br&amp;gt;&lt;br /&gt;
You can do that, using an SSL-Checker, for example: https://www.sslshopper.com/ssl-checker.html &amp;lt;br&amp;gt;&lt;br /&gt;
Without a valid, public signed certificate, Microsoft will decline the connection since it will not be possible to establish a trust relationship for the SSL/TLS secure channel.&lt;br /&gt;
&lt;br /&gt;
===Correctness of notification URL===&lt;br /&gt;
You can try to open the notification URL in your Browser&amp;lt;br&amp;gt;&lt;br /&gt;
Most likely you will see a HTTP 404 (Not Found) error message, which is the expected behavior since we are not providing an HTML website, the HTTP GET request from the browser will not be answered with content.&amp;lt;br&amp;gt;&lt;br /&gt;
This is perfectly fine since Microsoft will send presence updates with HTTP POST and will not try to request content from our app.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
What you can find out by trying to open the URL in your browser are the two following things: &amp;lt;br&amp;gt;&lt;br /&gt;
* If you receive a HTTP 404 error message you are most likely connected to an App Platform, if not you need to check your DNS (and maybe also reverse proxy) settings.&lt;br /&gt;
* If the URL is modified and the used build number is added, an app has answered your request&lt;br /&gt;
** Example: &amp;lt;code&amp;gt;https://public.dns/your.domain/microsoft365/subscriptions&amp;lt;/code&amp;gt; is modified to &amp;lt;code&amp;gt;https://public.dns/your.domain/microsoft365/&amp;lt;b&amp;gt;1510411&amp;lt;/b&amp;gt;/subscriptions&amp;lt;/code&amp;gt;&lt;br /&gt;
** If this is not the case, your URL is wrong. (Be aware: The URL depends on the settings of the web server path of your app instance)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Be aware:&#039;&#039;&#039; The URL-Recognition in the Application Platform is &#039;&#039;&#039;case sensitive&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== User Presence == &lt;br /&gt;
===GUI Feedback===&lt;br /&gt;
The app itself shows required states with green and red as connections to the Master PBX, Authentication and Presence Subscription to identify if there are problems. &amp;lt;br&amp;gt;&lt;br /&gt;
Sometimes it needs a little bit time until the states are changed. &amp;lt;br&amp;gt;&lt;br /&gt;
If the states remain, it is mandatory to enable logs on the app platform and check for more information. &amp;lt;br&amp;gt;&lt;br /&gt;
([[Howto13r3:Configure Connector for Microsoft365#Creating an app trace|Concept App Service Connector for Microsoft 365: Creating an app trace]])&lt;br /&gt;
&lt;br /&gt;
====No connection to Master PBX====&lt;br /&gt;
Check the MasterPBX name.&amp;lt;br&amp;gt;&lt;br /&gt;
The field must only contain the name [&amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;pbx&amp;lt;/span&amp;gt;], &#039;&#039;&#039;not the full domain&#039;&#039;&#039; [&amp;lt;span style=&amp;quot;color:red;text-decoration: line-through;&amp;quot;&amp;gt;pbx.domain.tld&amp;lt;/span&amp;gt;]. ([[Howto13r3:Configure Connector for Microsoft365#Synchronization from Teams to the PBX|Synchronization from Teams to the PBX - Master PBX field]])&lt;br /&gt;
&lt;br /&gt;
====Presence subscription failed====&lt;br /&gt;
There are many reasons why the &amp;quot;Presence subscription failed&amp;quot; message could be displayed.&amp;lt;br&amp;gt;&lt;br /&gt;
We try to list the most common reasons:&lt;br /&gt;
* The permission for the registered app in the Azure portal are not correctly set ([[Howto13r3:Configure Connector for Microsoft365#Create an App for syncing Teams to PBX|Howto: Create an App for syncing Teams to PBX]])&lt;br /&gt;
* The Notification URL is wrong ([[Reference13r3:Concept App Service Connector for Microsoft 365#Correctness of notification URL|Concept App Service Connector for Microsoft 365: Correctness of notification URL]] )&lt;br /&gt;
* The App service is not reachable from the internet ([[Reference13r3:Concept App Service Connector for Microsoft 365#Correctness of notification URL|Concept App Service Connector for Microsoft 365: Correctness of notification URL]] )&lt;br /&gt;
* The certificate for the public endpoint (e.g. reverse proxy) is not valid, or not publicly signed ([[Reference13r3:Concept App Service Connector for Microsoft 365#SSL Certificate for notification URL|Concept App Service Connector for Microsoft 365: SSL Certificate for notification URL]])&lt;br /&gt;
* The user from PBX and the Azure Portal cannot be matched ([[Reference13r3:Concept App Service Connector for Microsoft 365#User Matching|Concept App Service Connector for Microsoft 365: User Matching]])&lt;br /&gt;
* The App Platforms clock time is wrong ([[Reference13r3:Concept App Service Connector for Microsoft 365#App Platform clock time is wrong|Concept App Service Connector for Microsoft 365: App Platform clock time is wrong]])&lt;br /&gt;
* No user has a valid Connector for Microsoft 365 App license ([[Reference13r3:Concept App Service Connector for Microsoft 365#Requirements|Concept App Service Connector for Microsoft 365: Requirements]])&lt;br /&gt;
&lt;br /&gt;
===Teams License for communication user===&lt;br /&gt;
If presence subscription does not work, please check if all of the configured communication users have a Microsoft Teams license applied and no multifactor authentication is in use for this particular user. &amp;lt;br&amp;gt;&lt;br /&gt;
Also please make sure you can login with the configured credentials. (If you have set a password as an Administration, the user needs to change the password during the first login, therefore the given password will be invalid for API access).&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Sometimes, after changing setting or after the instance has restarted it can take up to 12 minutes until the presence subscription is working correctly. (Due to the subscription timeout)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
= Known Issues =&lt;br /&gt;
== Special Characters In Password ==&lt;br /&gt;
If you are using special characters (*, &amp;amp;, (, ), etc.) in your password you could run into a problem with the authentication of the communication user.&amp;lt;br&amp;gt;&lt;br /&gt;
The authentication failed status is being displayed. &amp;lt;br&amp;gt;&lt;br /&gt;
For the moment the only workaround is to eliminate special characters from your password.&lt;br /&gt;
&lt;br /&gt;
==App Platform clock time is wrong==&lt;br /&gt;
If the clock time at the App Platform is not correct, this will lead to an unstable behaviour of the Connector for Microsoft 365.&amp;lt;br&amp;gt;&lt;br /&gt;
Since the Connector for Microsoft 365 is using the Microsoft Graph APIs presence subscription function, it needs to provide in its request a precise time until the subscription validity will be expired.&amp;lt;br&amp;gt;&lt;br /&gt;
The app service is handling subscription and will automatically recreate a new subscription each time the previous one has expired.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A wrong clock time will lead to false expiration times and thus&lt;br /&gt;
*  the subscription will be expired earlier than expected (synchronisation is not working because there is no valid subscription)&lt;br /&gt;
*  the subscription will be valid longer than expected (the app service is trying to create a new subscription because it is expecting the previous one to be expired - will lead to a 409 conflict error, because only one subscription can be valid at a time)&lt;br /&gt;
&lt;br /&gt;
If you are not sure about the current time of the App Platform, you can login via SSH into the App Platform and execute the &amp;lt;code&amp;gt;date&amp;lt;/code&amp;gt; command to check the current time.&amp;lt;br&amp;gt;&lt;br /&gt;
You will receive an output like: &lt;br /&gt;
 Tue Mar 12 13:38:57 UTC 2024&lt;br /&gt;
Please be aware: The time is displayed in UTC, so please make sure to convert to your local time zone.&lt;br /&gt;
&lt;br /&gt;
==Geoblocking==&lt;br /&gt;
Since there might be no reliable country assignment for Microsoft addresses, all Microsoft addresses must be enabled on the upstream firewall in the event of geoblocking in order to ensure functionality of the Office365 Connector.&amp;lt;br&amp;gt;&lt;br /&gt;
As an alternative you might be able to configure your firewall to bypass the geoblocking for the configured notification URL.&lt;br /&gt;
&lt;br /&gt;
= Related Articles =&lt;br /&gt;
[[Howto16r1:Configure User Presence Sync by Connector for Microsoft365]] &amp;lt;br/&amp;gt;&lt;br /&gt;
[[Howto16r1:Configure Calendar Presence Sync by Connector for Microsoft365]] &amp;lt;br/&amp;gt;&lt;br /&gt;
[[Howto16r1:Configure Contact Search by Connector for Microsoft365]] &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Howto|{{PAGENAME}}]]&lt;/div&gt;</summary>
		<author><name>Tfu</name></author>
	</entry>
	<entry>
		<id>https://wiki.innovaphone.com/index.php?title=Reference16r1:Concept_App_Service_Connector_for_Microsoft_365&amp;diff=78427</id>
		<title>Reference16r1:Concept App Service Connector for Microsoft 365</title>
		<link rel="alternate" type="text/html" href="https://wiki.innovaphone.com/index.php?title=Reference16r1:Concept_App_Service_Connector_for_Microsoft_365&amp;diff=78427"/>
		<updated>2025-11-05T09:53:06Z</updated>

		<summary type="html">&lt;p&gt;Tfu: /* Technical Overview */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
{{FIXME|reason=This article is still work in progress}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Concept|Apps]]&lt;br /&gt;
== Applies To == &lt;br /&gt;
&lt;br /&gt;
* Connector for Microsoft 365 from Version 16r1&lt;br /&gt;
&lt;br /&gt;
= Overview =&lt;br /&gt;
&lt;br /&gt;
Connector for Microsoft 365 synchronizes Microsoft Teams presences with the innovaphone PBX and back, and optionally additionally Calendar presence from Exchange Online (part of the Microsoft 365 Cloud Services).&lt;br /&gt;
It is also possible to search for your own contacts. &lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
* innovaphone PBX&lt;br /&gt;
* innovaphone Application Platform (minimum version 120004)&lt;br /&gt;
* V16r1&lt;br /&gt;
* App(Connector for Microsoft 365)&lt;br /&gt;
* PBX-App(innovaphone-microsoft365) license per user - order no. 02-00050-009&lt;br /&gt;
&lt;br /&gt;
== Concept ==&lt;br /&gt;
&lt;br /&gt;
=== User Presence ===&lt;br /&gt;
&lt;br /&gt;
==== Configuration ====&lt;br /&gt;
Please have a look into our [[Howto15r1:Configure User Presence Sync by Connector for Microsoft365|Howto guide for basic configuration aid]].&lt;br /&gt;
&lt;br /&gt;
==== Technical Overview ====&lt;br /&gt;
If the Connector for Microsoft 365 app is fully configured, the app connects to Microsoft to obtain a token. With the token, the app gets the teams users (with a Teams license) through the Microsoft Graph API.&lt;br /&gt;
A presence subscription to Microsoft is started with the licensed users of the PBX to get presence changes in Microsoft Teams for these users. A user subscription is also started to get changes of the users (adding, deleting or update). If a user has changed, the Teams users are retrieved again. If the presence has changed, it is forwarded to the PBX. The presences of Teams are mapped to the presences of the PBX.&lt;br /&gt;
&lt;br /&gt;
* User subscriptions are renewed every 60 minutes.&lt;br /&gt;
* Presence subscriptions are renewed every 10 minutes.&lt;br /&gt;
* License Check is made periodically.&lt;br /&gt;
&lt;br /&gt;
The app synchronises the PBX presence with Teams through the Graph Api. The on-the-phone presence will be renewed every 5 minutes. The other presences have a lifetime of 1 day but the away has a lifetime of 7 days.&lt;br /&gt;
The lifetimes are described [https://learn.microsoft.com/en-us/graph/api/presence-setuserpreferredpresence?view=graph-rest-1.0&amp;amp;tabs=http here]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Please be aware:&#039;&#039;&#039; The actual change of presence or line state will be live, the above-mentioned subscriptions are needed to register against the Microsoft API for changes. &lt;br /&gt;
After successful subscription Microsoft will trigger the Connector for Microsoft 365 App every time a presence or line state for a user has changed.&lt;br /&gt;
The subscription will then be renewed in the above-mentioned time interval to receive further live updates.&lt;br /&gt;
&lt;br /&gt;
===== User Matching =====&lt;br /&gt;
You now can choose the fields used for user matching on either side from the following options:&lt;br /&gt;
* PBX&lt;br /&gt;
** CN (Long Name property from the PBX user object)&lt;br /&gt;
** h323 (Name property from the PBX user object)&lt;br /&gt;
* Azure Portal&lt;br /&gt;
** displayName&lt;br /&gt;
** mail&lt;br /&gt;
** mailNickname&lt;br /&gt;
** onPremisesDistinguishedName&lt;br /&gt;
** onPremisesSamAccountName&lt;br /&gt;
** onPremisesUserPrincipalName&lt;br /&gt;
** userPrincipalName&lt;br /&gt;
&lt;br /&gt;
Additionally, you have the possibility to remove a possibly contained domain from the Azure fields content. &amp;lt;br&amp;gt;&lt;br /&gt;
Example: &#039;user@domain.tld&#039; is transformed to &#039;user&#039;, if this option is checked.&lt;br /&gt;
&lt;br /&gt;
===== Mapping Table =====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Teams Presence&lt;br /&gt;
! PBX Presence&lt;br /&gt;
|-&lt;br /&gt;
| Away&lt;br /&gt;
| away&lt;br /&gt;
|-&lt;br /&gt;
| BeRightBack&lt;br /&gt;
| away&lt;br /&gt;
|-&lt;br /&gt;
| Busy&lt;br /&gt;
| busy&lt;br /&gt;
|-&lt;br /&gt;
| DoNotDisturb&lt;br /&gt;
| dnd&lt;br /&gt;
|-&lt;br /&gt;
| InACall&lt;br /&gt;
| on-the-phone&lt;br /&gt;
|-&lt;br /&gt;
| InAMeeting&lt;br /&gt;
| meeting&lt;br /&gt;
|-&lt;br /&gt;
| Inactive&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| PresenceUnknown&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| Available&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| Offline&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| Offwork&lt;br /&gt;
| online&lt;br /&gt;
|-&lt;br /&gt;
| OutOfOffice&lt;br /&gt;
| away&lt;br /&gt;
|-&lt;br /&gt;
| UrgentInterruptionsOnly&lt;br /&gt;
| dnd&lt;br /&gt;
|-&lt;br /&gt;
| Presenting&lt;br /&gt;
| on-the-phone&lt;br /&gt;
|-&lt;br /&gt;
| InAConferenceCall&lt;br /&gt;
| on-the-phone&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The value &amp;quot;online&amp;quot; unsets the Teams presence in the PBX.&lt;br /&gt;
&lt;br /&gt;
===== Master/Slave =====&lt;br /&gt;
&lt;br /&gt;
For Master/Slave combination the &amp;quot;Connector for Microsoft 365&amp;quot; App has to be added to the slave (if no full replication is on). The slave websocket connection is needed to display &amp;quot;on-the-phone&amp;quot; presence.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Calendar Presence ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Configuration ====&lt;br /&gt;
Please have a look into our [[Howto15r1:Configure_Calendar_Presence_Sync_by_Connector_for_Microsoft365|Howto guide for basic configuration aid]].&lt;br /&gt;
&lt;br /&gt;
==== Technical Overview ====&lt;br /&gt;
Introduced in 15r1 the Connector for Microsoft 365 will offer a possibility to sync Azure Portal calendar events (Teams, Exchange online) via the Graph API with the PXB presence.&amp;lt;br&amp;gt;&lt;br /&gt;
For now the [https://wiki.innovaphone.com/index.php?title=Reference13r3:Concept_App_Service_Calendar Calendar App] is (along with other functions) also capable of syncing calendar events, but using the old EWS mechanism, which Microsoft announced as end of life starting from 2026.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Warning:&#039;&#039;&#039; Please make sure to not use both apps for syncing calendar events in parallel, this is not supported and will most likely lead to conflicts and unexpected behaviours.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
When the configuration of the connector for Microsoft 365 Calendar Presence Sync is complete, the app connects to Microsoft to receive a token with the calendar app registered in the Azure portal.&amp;lt;br&amp;gt;&lt;br /&gt;
With the token, the app can pick up the users from the Azure portal.&amp;lt;br&amp;gt;&lt;br /&gt;
These are matched against the users in the PBX, based on the configured &amp;quot;User Assignment&amp;quot; settings.&amp;lt;br&amp;gt;&lt;br /&gt;
For each matched user with a valid Connector for Microsoft 365 licence applied, a subscription for calendar events is created at Microsoft to receive event changes in Microsoft Calendar for these users.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
A user subscription is also started to receive user changes (add, delete or update).&amp;lt;br&amp;gt;&lt;br /&gt;
If a user has changed, the users are retrieved again. &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
If a calendar event has been started or ended, it is forwarded to the PBX.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* User subscriptions are renewed every 60 minutes.&lt;br /&gt;
* Event subscriptions are renewed every day.&lt;br /&gt;
* License Check is made every hour.&lt;br /&gt;
&lt;br /&gt;
=== Contact Search ===&lt;br /&gt;
&lt;br /&gt;
==== Configuration ====&lt;br /&gt;
Please have a look into our [[Howto16r1:Configure Calendar Presence Sync by Connector for Microsoft365|Howto guide for basic configuration aid]].&lt;br /&gt;
&lt;br /&gt;
==== Technical Overview ====&lt;br /&gt;
Introduced in 16r1 the Connector for Microsoft 365 will offer a possibility to search for your own contacts (Teams, Exchange online) via the Graph API.&lt;br /&gt;
&lt;br /&gt;
When the configuration of the connector for Microsoft 365 Contact Search is complete, the app connects to Microsoft to receive a token with the contact search app registered in the Azure portal.&amp;lt;br&amp;gt;&lt;br /&gt;
With the token, the app can pick up the users from the Azure portal.&amp;lt;br&amp;gt;&lt;br /&gt;
These are matched against the users in the PBX, based on the configured &amp;quot;User Assignment&amp;quot; settings.&amp;lt;br&amp;gt;&lt;br /&gt;
For each matched user with a valid Connector for Microsoft 365 licence applied, the user can search with the Phone App, for example (a myApps search provider will be provided for all apps looking using search providers looking up contacts). The search string is made available to the Connector for Microsoft 365 via the microsoft365-api. The results are sent to the consumer, e.g. the Phone App and presented there.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
A user subscription is started to receive user changes (add, delete or update).&amp;lt;br&amp;gt;&lt;br /&gt;
If a user has changed, the users are retrieved again. &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* User subscriptions are renewed every 60 minutes.&lt;br /&gt;
* License Check is made every hour.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Be aware:&#039;&#039;&#039; Since the Connector for Microsoft 365 is an app in the Scope of myApps App Platform, IP Phones and other services not using Apps cannot benefit from this search service.&lt;br /&gt;
&lt;br /&gt;
== Related Articles ==&lt;br /&gt;
&lt;br /&gt;
=Known Limitation=&lt;br /&gt;
&lt;br /&gt;
== General ==&lt;br /&gt;
&#039;&#039;Applies to the User Presence and the Calendar Presence&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Synchronization Delay ===&lt;br /&gt;
In the official Graph-API documentation, Microsoft is providing an overview about expected latencies for change notifications.&amp;lt;br&amp;gt;&lt;br /&gt;
You can find a whole overview table here:&amp;lt;br&amp;gt;&lt;br /&gt;
https://learn.microsoft.com/en-us/graph/change-notifications-overview#latency&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
For the user presences the resource &amp;quot;presence&amp;quot; is used and an average latency of 10 seconds but a maximum up to 1 minute is provided.&amp;lt;br&amp;gt;&lt;br /&gt;
Such a delay in syncing changed presences from Teams down to the PBX are considered normal and are caused by the Microsoft Graph-API.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
In case of calendar events the average is provided as &amp;quot;less than 1 minute&amp;quot; and the maximum to 3 minutes.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== User Presence ==&lt;br /&gt;
=== Line states set by the PBX does not block calls in Teams ===&lt;br /&gt;
Line states set by a 3rd party application (like the Connector for Microsoft 365) through the graph API are currently &#039;&#039;&#039;only for display purpose and do not block new calls&#039;&#039;&#039; in Teams.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
https://techcommunity.microsoft.com/t5/teams-developer/ms-graph-setpresence-problems/m-p/2798805/highlight/true#M3957&amp;lt;br&amp;gt;&lt;br /&gt;
As you can see in the above linked discussion, there once existed a feature request on Microsoft Voice, which is no longer available since it was not voted.&lt;br /&gt;
=== Maximum number of supported users ===&lt;br /&gt;
The connector now supports multiple Microsoft Teams communication users, which is the prerequisite to subscribe for more than 650 users. There is a new ribbon (Manage Teams Accounts) that allows you to configure as many communication users as you need. Every configured communication user can be used to subscribe 650 users, for example:&lt;br /&gt;
&lt;br /&gt;
*3 configured communication users x 650 licensed users = 1950 users can be subscribed&lt;br /&gt;
&#039;&#039;&#039;Please be aware&#039;&#039;&#039;: Each communication user must have a Teams license applied.&lt;br /&gt;
&lt;br /&gt;
This limitation is caused by Microsoft.&amp;lt;br&amp;gt;&lt;br /&gt;
In the documentation of the Graph-API you will find a hint to this limitation:&amp;lt;br&amp;gt;&lt;br /&gt;
https://learn.microsoft.com/en-us/graph/changenotifications-for-presence#subscribe-to-multiple-users-presence&amp;lt;br&amp;gt;&lt;br /&gt;
Trying to subscribe more than 650 users (with one communication user) by using the presence subscription API will be declined by the graph API with an error message, that too many users are requested.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Communication User (UserSynctoPbx) ===&lt;br /&gt;
Users with MFA (multi-factor-authentication) are not supported as technical communication user for the Connector.&lt;br /&gt;
&lt;br /&gt;
=== Multiple sites / instances require multiple communication users ===&lt;br /&gt;
Each instance or each site must have separate communication users, as Microsoft only allows one concurrent subscription per communication user. (otherwise an HTTP 409 conflict will occur)&lt;br /&gt;
&lt;br /&gt;
This means that if you want to subscribe to the same Azure Portal backend from two different sites (or instances), you will need to have multiple communication users (each with an applied Teams licence) in order to be able to subscribe from all endpoints.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Subscription Timeout ===&lt;br /&gt;
&lt;br /&gt;
==== Situation ====&lt;br /&gt;
Due to a current limitation in the Graph API it is not possible to cancel or delete an active presence subscription.&amp;lt;br&amp;gt;&lt;br /&gt;
As you can see in the [https://learn.microsoft.com/en-us/graph/api/subscription-delete?view=graph-rest-1.0&amp;amp;tabs=http|documentation of the current Graph API (1.0)] the “Delete subscription” chapter does not include presence subscriptions.&amp;lt;br&amp;gt;&lt;br /&gt;
It is also not possible to have multiple subscription in parallel. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To make sure to only request a new presence subscription when the old one is not valid anymore, the app will store the state of the presence subscription and the time until it is valid in the database.&amp;lt;br&amp;gt;&lt;br /&gt;
As mentioned in the chapter “Technical Overview” we are creating presence subscriptions with a validity of 10 minutes.&amp;lt;br&amp;gt;&lt;br /&gt;
The presence subscription will be renewed as soon as it is no longer valid which will be 10 minutes after initial subscription.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Impact ====&lt;br /&gt;
If settings are changed or the app instance is restarted it will check the corresponding database entry on startup.&amp;lt;br&amp;gt;&lt;br /&gt;
In case the last presence subscription was completed less than 10 minutes ago, there is still an active presence subscription and the app has to wait for it to become invalid. &amp;lt;br&amp;gt;&lt;br /&gt;
Some Changes (e.g., to the “Notification-URL”) will only take effect after a new created subscription. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The current Beta Version of the Graph API is already providing a function to delete presence subscriptions, so we hope we can improve this behavior in the future.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Troubleshooting=&lt;br /&gt;
== General ==&lt;br /&gt;
&lt;br /&gt;
===Creating an app trace===&lt;br /&gt;
For further analysis and creating a support ticket it will be useful to have a suitable app trace. &amp;lt;br&amp;gt;&lt;br /&gt;
Before creating the trace please make sure the following trace flags are activated for the app instance:&lt;br /&gt;
* App&lt;br /&gt;
* Database&lt;br /&gt;
* HTTP client&lt;br /&gt;
* TLS&lt;br /&gt;
* TCP&lt;br /&gt;
* App WebSocket&lt;br /&gt;
* Config&lt;br /&gt;
* Webserver&lt;br /&gt;
&lt;br /&gt;
After setting the config flags, please make sure to&lt;br /&gt;
* stop the instance&lt;br /&gt;
* deleting the current instance log&lt;br /&gt;
* start the instance&lt;br /&gt;
&#039;&#039;&#039;Now please wait at least 5 Minutes before you save the log&#039;&#039;&#039;, otherwise we could not have the whole picture in the trace.&lt;br /&gt;
&lt;br /&gt;
The restart and deletion of the the old log is useful the see the complete initialization process right away.&lt;br /&gt;
&lt;br /&gt;
===SSL Certificate for notification URL===&lt;br /&gt;
It also is useful to make sure the notification URL has a valid and public signed certificate.&amp;lt;br&amp;gt;&lt;br /&gt;
You can do that, using an SSL-Checker, for example: https://www.sslshopper.com/ssl-checker.html &amp;lt;br&amp;gt;&lt;br /&gt;
Without a valid, public signed certificate, Microsoft will decline the connection since it will not be possible to establish a trust relationship for the SSL/TLS secure channel.&lt;br /&gt;
&lt;br /&gt;
===Correctness of notification URL===&lt;br /&gt;
You can try to open the notification URL in your Browser&amp;lt;br&amp;gt;&lt;br /&gt;
Most likely you will see a HTTP 404 (Not Found) error message, which is the expected behavior since we are not providing an HTML website, the HTTP GET request from the browser will not be answered with content.&amp;lt;br&amp;gt;&lt;br /&gt;
This is perfectly fine since Microsoft will send presence updates with HTTP POST and will not try to request content from our app.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
What you can find out by trying to open the URL in your browser are the two following things: &amp;lt;br&amp;gt;&lt;br /&gt;
* If you receive a HTTP 404 error message you are most likely connected to an App Platform, if not you need to check your DNS (and maybe also reverse proxy) settings.&lt;br /&gt;
* If the URL is modified and the used build number is added, an app has answered your request&lt;br /&gt;
** Example: &amp;lt;code&amp;gt;https://public.dns/your.domain/microsoft365/subscriptions&amp;lt;/code&amp;gt; is modified to &amp;lt;code&amp;gt;https://public.dns/your.domain/microsoft365/&amp;lt;b&amp;gt;1510411&amp;lt;/b&amp;gt;/subscriptions&amp;lt;/code&amp;gt;&lt;br /&gt;
** If this is not the case, your URL is wrong. (Be aware: The URL depends on the settings of the web server path of your app instance)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Be aware:&#039;&#039;&#039; The URL-Recognition in the Application Platform is &#039;&#039;&#039;case sensitive&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== User Presence == &lt;br /&gt;
===GUI Feedback===&lt;br /&gt;
The app itself shows required states with green and red as connections to the Master PBX, Authentication and Presence Subscription to identify if there are problems. &amp;lt;br&amp;gt;&lt;br /&gt;
Sometimes it needs a little bit time until the states are changed. &amp;lt;br&amp;gt;&lt;br /&gt;
If the states remain, it is mandatory to enable logs on the app platform and check for more information. &amp;lt;br&amp;gt;&lt;br /&gt;
([[Howto13r3:Configure Connector for Microsoft365#Creating an app trace|Concept App Service Connector for Microsoft 365: Creating an app trace]])&lt;br /&gt;
&lt;br /&gt;
====No connection to Master PBX====&lt;br /&gt;
Check the MasterPBX name.&amp;lt;br&amp;gt;&lt;br /&gt;
The field must only contain the name [&amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;pbx&amp;lt;/span&amp;gt;], &#039;&#039;&#039;not the full domain&#039;&#039;&#039; [&amp;lt;span style=&amp;quot;color:red;text-decoration: line-through;&amp;quot;&amp;gt;pbx.domain.tld&amp;lt;/span&amp;gt;]. ([[Howto13r3:Configure Connector for Microsoft365#Synchronization from Teams to the PBX|Synchronization from Teams to the PBX - Master PBX field]])&lt;br /&gt;
&lt;br /&gt;
====Presence subscription failed====&lt;br /&gt;
There are many reasons why the &amp;quot;Presence subscription failed&amp;quot; message could be displayed.&amp;lt;br&amp;gt;&lt;br /&gt;
We try to list the most common reasons:&lt;br /&gt;
* The permission for the registered app in the Azure portal are not correctly set ([[Howto13r3:Configure Connector for Microsoft365#Create an App for syncing Teams to PBX|Howto: Create an App for syncing Teams to PBX]])&lt;br /&gt;
* The Notification URL is wrong ([[Reference13r3:Concept App Service Connector for Microsoft 365#Correctness of notification URL|Concept App Service Connector for Microsoft 365: Correctness of notification URL]] )&lt;br /&gt;
* The App service is not reachable from the internet ([[Reference13r3:Concept App Service Connector for Microsoft 365#Correctness of notification URL|Concept App Service Connector for Microsoft 365: Correctness of notification URL]] )&lt;br /&gt;
* The certificate for the public endpoint (e.g. reverse proxy) is not valid, or not publicly signed ([[Reference13r3:Concept App Service Connector for Microsoft 365#SSL Certificate for notification URL|Concept App Service Connector for Microsoft 365: SSL Certificate for notification URL]])&lt;br /&gt;
* The user from PBX and the Azure Portal cannot be matched ([[Reference13r3:Concept App Service Connector for Microsoft 365#User Matching|Concept App Service Connector for Microsoft 365: User Matching]])&lt;br /&gt;
* The App Platforms clock time is wrong ([[Reference13r3:Concept App Service Connector for Microsoft 365#App Platform clock time is wrong|Concept App Service Connector for Microsoft 365: App Platform clock time is wrong]])&lt;br /&gt;
* No user has a valid Connector for Microsoft 365 App license ([[Reference13r3:Concept App Service Connector for Microsoft 365#Requirements|Concept App Service Connector for Microsoft 365: Requirements]])&lt;br /&gt;
&lt;br /&gt;
===Teams License for communication user===&lt;br /&gt;
If presence subscription does not work, please check if all of the configured communication users have a Microsoft Teams license applied and no multifactor authentication is in use for this particular user. &amp;lt;br&amp;gt;&lt;br /&gt;
Also please make sure you can login with the configured credentials. (If you have set a password as an Administration, the user needs to change the password during the first login, therefore the given password will be invalid for API access).&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Sometimes, after changing setting or after the instance has restarted it can take up to 12 minutes until the presence subscription is working correctly. (Due to the subscription timeout)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
= Known Issues =&lt;br /&gt;
== Special Characters In Password ==&lt;br /&gt;
If you are using special characters (*, &amp;amp;, (, ), etc.) in your password you could run into a problem with the authentication of the communication user.&amp;lt;br&amp;gt;&lt;br /&gt;
The authentication failed status is being displayed. &amp;lt;br&amp;gt;&lt;br /&gt;
For the moment the only workaround is to eliminate special characters from your password.&lt;br /&gt;
&lt;br /&gt;
==App Platform clock time is wrong==&lt;br /&gt;
If the clock time at the App Platform is not correct, this will lead to an unstable behaviour of the Connector for Microsoft 365.&amp;lt;br&amp;gt;&lt;br /&gt;
Since the Connector for Microsoft 365 is using the Microsoft Graph APIs presence subscription function, it needs to provide in its request a precise time until the subscription validity will be expired.&amp;lt;br&amp;gt;&lt;br /&gt;
The app service is handling subscription and will automatically recreate a new subscription each time the previous one has expired.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A wrong clock time will lead to false expiration times and thus&lt;br /&gt;
*  the subscription will be expired earlier than expected (synchronisation is not working because there is no valid subscription)&lt;br /&gt;
*  the subscription will be valid longer than expected (the app service is trying to create a new subscription because it is expecting the previous one to be expired - will lead to a 409 conflict error, because only one subscription can be valid at a time)&lt;br /&gt;
&lt;br /&gt;
If you are not sure about the current time of the App Platform, you can login via SSH into the App Platform and execute the &amp;lt;code&amp;gt;date&amp;lt;/code&amp;gt; command to check the current time.&amp;lt;br&amp;gt;&lt;br /&gt;
You will receive an output like: &lt;br /&gt;
 Tue Mar 12 13:38:57 UTC 2024&lt;br /&gt;
Please be aware: The time is displayed in UTC, so please make sure to convert to your local time zone.&lt;br /&gt;
&lt;br /&gt;
==Geoblocking==&lt;br /&gt;
Since there might be no reliable country assignment for Microsoft addresses, all Microsoft addresses must be enabled on the upstream firewall in the event of geoblocking in order to ensure functionality of the Office365 Connector.&amp;lt;br&amp;gt;&lt;br /&gt;
As an alternative you might be able to configure your firewall to bypass the geoblocking for the configured notification URL.&lt;br /&gt;
&lt;br /&gt;
= Related Articles =&lt;br /&gt;
[[Howto16r1:Configure User Presence Sync by Connector for Microsoft365]] &amp;lt;br/&amp;gt;&lt;br /&gt;
[[Howto16r1:Configure Calendar Presence Sync by Connector for Microsoft365]] &amp;lt;br/&amp;gt;&lt;br /&gt;
[[Howto16r1:Configure Contact Search by Connector for Microsoft365]] &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Howto|{{PAGENAME}}]]&lt;/div&gt;</summary>
		<author><name>Tfu</name></author>
	</entry>
	<entry>
		<id>https://wiki.innovaphone.com/index.php?title=Howto16r1:Firmware_Upgrade_V15r1_V16r1&amp;diff=78233</id>
		<title>Howto16r1:Firmware Upgrade V15r1 V16r1</title>
		<link rel="alternate" type="text/html" href="https://wiki.innovaphone.com/index.php?title=Howto16r1:Firmware_Upgrade_V15r1_V16r1&amp;diff=78233"/>
		<updated>2025-10-10T16:18:43Z</updated>

		<summary type="html">&lt;p&gt;Tfu: /* Connector for Microsoft 365 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Applies To ==&lt;br /&gt;
This information applies to:&lt;br /&gt;
&lt;br /&gt;
* All 16r1 capable innovaphone devices&lt;br /&gt;
: For a general overview of the upgrade process and a list of supported devices with 16r1, see [[Howto:Firmware Upgrade]]&lt;br /&gt;
== Licenses ==&lt;br /&gt;
In case of cloud or rental model, don&#039;t worry about licenses.&lt;br /&gt;
&lt;br /&gt;
If the system is licensed on premise, you&#039;ll need to regenerate the license file for v16 in https://portal.innovaphone.com/ and load into the system before upgrade (The system needs to have the SSC up to date).&lt;br /&gt;
&lt;br /&gt;
== Migration Policy ==&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red; font-weight: bold&amp;quot;&amp;gt;Before you begin, be sure that your whole installation is running the latest 15r1 service release.&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== TechAssist Upgrade Helper ===&lt;br /&gt;
* Before you start, make sure that all TechAssist tests (you will receive the required tests in the last update in the previous major version) labelled &amp;lt;code&amp;gt;Pre Upgrade: xy&amp;lt;/code&amp;gt; are positive, if available&lt;br /&gt;
* When you are finished, make sure that all TechAssist tests (you will receive new tests with the upgrade) are positive&lt;br /&gt;
&lt;br /&gt;
=== New TLS Profile ===&lt;br /&gt;
Please note that we have changed our TLS profiles ([[Reference16r1:IP4/General/TLS]]). The new &#039;&#039;Normal&#039;&#039; setting, which is the default value, now only allows TLS 1.3 and TLS 1.2.&lt;br /&gt;
&lt;br /&gt;
== Changes visible to the end customers ==&lt;br /&gt;
Listed here are changes that should be communicated by resellers to end users prior to a upgrade, as the change will be visible/audible in the behaviour of the application/device.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;Nothing&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Manual steps needed after upgrade ==&lt;br /&gt;
If the installer is not used for a new installation, some new default settings are not set. Please evaluate per app whether you want to configure the new default settings manually.&lt;br /&gt;
&lt;br /&gt;
=== Connector for Microsoft 365 ===&lt;br /&gt;
If you plan to use the new &#039;&#039;&#039;Contact Search&#039;&#039;&#039; feature of the Connector for Microsoft 365, you need to perform two manual Steps:&lt;br /&gt;
# Create the &#039;&#039;&#039;microsoft365-api&#039;&#039;&#039; app object by using the Settings template&lt;br /&gt;
# Assign the &#039;&#039;&#039;microsoft365-api&#039;&#039;&#039; app object to every user who should be able to use the new Contact Search feature. (Of cause, you can use a template for that)&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
For a more detailed guide, please refer to the how-to article: [[Howto16r1:Configure Contact Search by Connector for Microsoft365#Creating the PBX app object using the PBX Manager Plugin]]&lt;br /&gt;
&lt;br /&gt;
== New Apps ==&lt;br /&gt;
New Apps will not be installed automatically by the upgrade. The installation description of new apps is usually in the concept article. Please rate per app whether you want to install/use the new app and configure it manually.&lt;br /&gt;
&lt;br /&gt;
* App Polls: [[Reference16r1:Concept App Polls]]&lt;br /&gt;
* App Service Conference Transcriptions [[Reference16r1:Concept_App_Service_myApps_Assistant]]&lt;br /&gt;
&lt;br /&gt;
== Removed ==&lt;br /&gt;
The following software is no longer included.&lt;br /&gt;
&lt;br /&gt;
* IP110A (can still be used with 15r1 firmware on current PBX versions)&lt;br /&gt;
* IP240A (can still be used with 15r1 firmware on current PBX versions)&lt;br /&gt;
* CA on CF card feature&lt;br /&gt;
&lt;br /&gt;
== Deprecated ==&lt;br /&gt;
The following software is based on legacy technology, with no further development and limited maintenance and support.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;Nothing&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Previously deprecated and now no longer supported == &lt;br /&gt;
The following software is based on legacy technology, with no further development and no more maintenance and support.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;Nothing&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Known Problems==&lt;br /&gt;
===Long Update-duration===&lt;br /&gt;
When you update, it can be up to 10 minutes before you have access to your app platform again.&lt;br /&gt;
&lt;br /&gt;
== Related Articles ==&lt;br /&gt;
*[[Howto:Firmware_Upgrade]]&lt;br /&gt;
* [[Howto15r1:Firmware_Upgrade_V14r2_V15r1]]&lt;br /&gt;
[[Category:Howto|{{PAGENAME}}]]&lt;/div&gt;</summary>
		<author><name>Tfu</name></author>
	</entry>
	<entry>
		<id>https://wiki.innovaphone.com/index.php?title=Howto16r1:Firmware_Upgrade_V15r1_V16r1&amp;diff=78232</id>
		<title>Howto16r1:Firmware Upgrade V15r1 V16r1</title>
		<link rel="alternate" type="text/html" href="https://wiki.innovaphone.com/index.php?title=Howto16r1:Firmware_Upgrade_V15r1_V16r1&amp;diff=78232"/>
		<updated>2025-10-10T14:05:49Z</updated>

		<summary type="html">&lt;p&gt;Tfu: /* Connector for Microsoft 365 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Applies To ==&lt;br /&gt;
This information applies to:&lt;br /&gt;
&lt;br /&gt;
* All 16r1 capable innovaphone devices&lt;br /&gt;
: For a general overview of the upgrade process and a list of supported devices with 16r1, see [[Howto:Firmware Upgrade]]&lt;br /&gt;
== Licenses ==&lt;br /&gt;
In case of cloud or rental model, don&#039;t worry about licenses.&lt;br /&gt;
&lt;br /&gt;
If the system is licensed on premise, you&#039;ll need to regenerate the license file for v16 in https://portal.innovaphone.com/ and load into the system before upgrade (The system needs to have the SSC up to date).&lt;br /&gt;
&lt;br /&gt;
== Migration Policy ==&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red; font-weight: bold&amp;quot;&amp;gt;Before you begin, be sure that your whole installation is running the latest 15r1 service release.&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== TechAssist Upgrade Helper ===&lt;br /&gt;
* Before you start, make sure that all TechAssist tests (you will receive the required tests in the last update in the previous major version) labelled &amp;lt;code&amp;gt;Pre Upgrade: xy&amp;lt;/code&amp;gt; are positive, if available&lt;br /&gt;
* When you are finished, make sure that all TechAssist tests (you will receive new tests with the upgrade) are positive&lt;br /&gt;
&lt;br /&gt;
=== New TLS Profile ===&lt;br /&gt;
Please note that we have changed our TLS profiles ([[Reference16r1:IP4/General/TLS]]). The new &#039;&#039;Normal&#039;&#039; setting, which is the default value, now only allows TLS 1.3 and TLS 1.2.&lt;br /&gt;
&lt;br /&gt;
== Changes visible to the end customers ==&lt;br /&gt;
Listed here are changes that should be communicated by resellers to end users prior to a upgrade, as the change will be visible/audible in the behaviour of the application/device.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;Nothing&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Manual steps needed after upgrade ==&lt;br /&gt;
If the installer is not used for a new installation, some new default settings are not set. Please evaluate per app whether you want to configure the new default settings manually.&lt;br /&gt;
&lt;br /&gt;
=== Connector for Microsoft 365 ===&lt;br /&gt;
If you plan to use the new &#039;&#039;&#039;Contact Search&#039;&#039;&#039; feature of the Connector for Microsoft 365, you need to perform two manual Steps:&lt;br /&gt;
# Create the &#039;&#039;&#039;microsoft365-api&#039;&#039;&#039; app object by using the settings template&lt;br /&gt;
# Assign the &#039;&#039;&#039;microsoft365-api&#039;&#039;&#039; app object to every user who should be able to use the new Contact Search feature. (Of cause, you can use a template for that)&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
For a more detailed guide, please refer to the how-to article: [[Howto16r1:Configure Contact Search by Connector for Microsoft365#Creating the PBX app object using the PBX Manager Plugin]]&lt;br /&gt;
&lt;br /&gt;
== New Apps ==&lt;br /&gt;
New Apps will not be installed automatically by the upgrade. The installation description of new apps is usually in the concept article. Please rate per app whether you want to install/use the new app and configure it manually.&lt;br /&gt;
&lt;br /&gt;
* App Polls: [[Reference16r1:Concept App Polls]]&lt;br /&gt;
* App Service Conference Transcriptions [[Reference16r1:Concept_App_Service_myApps_Assistant]]&lt;br /&gt;
&lt;br /&gt;
== Removed ==&lt;br /&gt;
The following software is no longer included.&lt;br /&gt;
&lt;br /&gt;
* IP110A (can still be used with 15r1 firmware on current PBX versions)&lt;br /&gt;
* IP240A (can still be used with 15r1 firmware on current PBX versions)&lt;br /&gt;
* CA on CF card feature&lt;br /&gt;
&lt;br /&gt;
== Deprecated ==&lt;br /&gt;
The following software is based on legacy technology, with no further development and limited maintenance and support.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;Nothing&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Previously deprecated and now no longer supported == &lt;br /&gt;
The following software is based on legacy technology, with no further development and no more maintenance and support.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;Nothing&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Known Problems==&lt;br /&gt;
===Long Update-duration===&lt;br /&gt;
When you update, it can be up to 10 minutes before you have access to your app platform again.&lt;br /&gt;
&lt;br /&gt;
== Related Articles ==&lt;br /&gt;
*[[Howto:Firmware_Upgrade]]&lt;br /&gt;
* [[Howto15r1:Firmware_Upgrade_V14r2_V15r1]]&lt;br /&gt;
[[Category:Howto|{{PAGENAME}}]]&lt;/div&gt;</summary>
		<author><name>Tfu</name></author>
	</entry>
	<entry>
		<id>https://wiki.innovaphone.com/index.php?title=Howto16r1:Firmware_Upgrade_V15r1_V16r1&amp;diff=78231</id>
		<title>Howto16r1:Firmware Upgrade V15r1 V16r1</title>
		<link rel="alternate" type="text/html" href="https://wiki.innovaphone.com/index.php?title=Howto16r1:Firmware_Upgrade_V15r1_V16r1&amp;diff=78231"/>
		<updated>2025-10-10T13:55:25Z</updated>

		<summary type="html">&lt;p&gt;Tfu: /* Manual steps needed after upgrade */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Applies To ==&lt;br /&gt;
This information applies to:&lt;br /&gt;
&lt;br /&gt;
* All 16r1 capable innovaphone devices&lt;br /&gt;
: For a general overview of the upgrade process and a list of supported devices with 16r1, see [[Howto:Firmware Upgrade]]&lt;br /&gt;
== Licenses ==&lt;br /&gt;
In case of cloud or rental model, don&#039;t worry about licenses.&lt;br /&gt;
&lt;br /&gt;
If the system is licensed on premise, you&#039;ll need to regenerate the license file for v16 in https://portal.innovaphone.com/ and load into the system before upgrade (The system needs to have the SSC up to date).&lt;br /&gt;
&lt;br /&gt;
== Migration Policy ==&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red; font-weight: bold&amp;quot;&amp;gt;Before you begin, be sure that your whole installation is running the latest 15r1 service release.&amp;lt;/span&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== TechAssist Upgrade Helper ===&lt;br /&gt;
* Before you start, make sure that all TechAssist tests (you will receive the required tests in the last update in the previous major version) labelled &amp;lt;code&amp;gt;Pre Upgrade: xy&amp;lt;/code&amp;gt; are positive, if available&lt;br /&gt;
* When you are finished, make sure that all TechAssist tests (you will receive new tests with the upgrade) are positive&lt;br /&gt;
&lt;br /&gt;
=== New TLS Profile ===&lt;br /&gt;
Please note that we have changed our TLS profiles ([[Reference16r1:IP4/General/TLS]]). The new &#039;&#039;Normal&#039;&#039; setting, which is the default value, now only allows TLS 1.3 and TLS 1.2.&lt;br /&gt;
&lt;br /&gt;
== Changes visible to the end customers ==&lt;br /&gt;
Listed here are changes that should be communicated by resellers to end users prior to a upgrade, as the change will be visible/audible in the behaviour of the application/device.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;Nothing&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Manual steps needed after upgrade ==&lt;br /&gt;
If the installer is not used for a new installation, some new default settings are not set. Please evaluate per app whether you want to configure the new default settings manually.&lt;br /&gt;
&lt;br /&gt;
=== Connector for Microsoft 365 ===&lt;br /&gt;
If you plan to use the new &#039;&#039;&#039;Contact Search&#039;&#039;&#039; feature of the Connector for Microsoft 365, you need to perform two manual Steps:&lt;br /&gt;
# Create the &#039;&#039;&#039;micrsofot365-api&#039;&#039;&#039; app object by using the settings template&lt;br /&gt;
# Assign the &#039;&#039;&#039;microsoft365-api&#039;&#039;&#039; app object to every user who should be able to use the new Contact Search feature. (Of cause, you can use a template for that)&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
For a more detailed guide, please refer to the how-to article: [[Howto16r1:Configure Contact Search by Connector for Microsoft365#Creating the PBX app object using the PBX Manager Plugin]]&lt;br /&gt;
&lt;br /&gt;
== New Apps ==&lt;br /&gt;
New Apps will not be installed automatically by the upgrade. The installation description of new apps is usually in the concept article. Please rate per app whether you want to install/use the new app and configure it manually.&lt;br /&gt;
&lt;br /&gt;
* App Polls: [[Reference16r1:Concept App Polls]]&lt;br /&gt;
* App Service Conference Transcriptions [[Reference16r1:Concept_App_Service_myApps_Assistant]]&lt;br /&gt;
&lt;br /&gt;
== Removed ==&lt;br /&gt;
The following software is no longer included.&lt;br /&gt;
&lt;br /&gt;
* IP110A (can still be used with 15r1 firmware on current PBX versions)&lt;br /&gt;
* IP240A (can still be used with 15r1 firmware on current PBX versions)&lt;br /&gt;
* CA on CF card feature&lt;br /&gt;
&lt;br /&gt;
== Deprecated ==&lt;br /&gt;
The following software is based on legacy technology, with no further development and limited maintenance and support.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;Nothing&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Previously deprecated and now no longer supported == &lt;br /&gt;
The following software is based on legacy technology, with no further development and no more maintenance and support.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;Nothing&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Known Problems==&lt;br /&gt;
===Long Update-duration===&lt;br /&gt;
When you update, it can be up to 10 minutes before you have access to your app platform again.&lt;br /&gt;
&lt;br /&gt;
== Related Articles ==&lt;br /&gt;
*[[Howto:Firmware_Upgrade]]&lt;br /&gt;
* [[Howto15r1:Firmware_Upgrade_V14r2_V15r1]]&lt;br /&gt;
[[Category:Howto|{{PAGENAME}}]]&lt;/div&gt;</summary>
		<author><name>Tfu</name></author>
	</entry>
	<entry>
		<id>https://wiki.innovaphone.com/index.php?title=Howto16r1:Configure_Contact_Search_by_Connector_for_Microsoft365&amp;diff=78230</id>
		<title>Howto16r1:Configure Contact Search by Connector for Microsoft365</title>
		<link rel="alternate" type="text/html" href="https://wiki.innovaphone.com/index.php?title=Howto16r1:Configure_Contact_Search_by_Connector_for_Microsoft365&amp;diff=78230"/>
		<updated>2025-10-10T13:41:12Z</updated>

		<summary type="html">&lt;p&gt;Tfu: /* Creating the PBX app object using the PBX Manager Plugin */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{FIXME|reason=This article is still work in progress}}&lt;br /&gt;
&lt;br /&gt;
==Applies To==&lt;br /&gt;
This information applies to&lt;br /&gt;
Connector for Microsoft 365 from version 16r1&lt;br /&gt;
&lt;br /&gt;
==More Information==&lt;br /&gt;
&lt;br /&gt;
This article outlines a configuration scheme for Connector for Microsoft365 functionality.&amp;lt;br&amp;gt;&lt;br /&gt;
In preparation, you first will need to configure one Application in your Azure Portal. &amp;lt;br&amp;gt;&lt;br /&gt;
After that, you will install the App in your Application Platform, and configure everything.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===System Requirements===&lt;br /&gt;
&lt;br /&gt;
* Licenses &#039;&#039;&#039;innovaphone Connector for Microsoft 365&#039;&#039;&#039; per user who wants to use the innovaphone myApps Connector for Microsoft 365.&lt;br /&gt;
* &#039;&#039;&#039;account in Azure Portal of Microsoft&#039;&#039;&#039; (for each of the technical communication users, no permission role needed)&amp;lt;br&amp;gt;&lt;br /&gt;
* Must have access from the internet to your App Platform&lt;br /&gt;
** This can be done by using a reverse proxy or other firewall&lt;br /&gt;
* The public endpoint &#039;&#039;&#039;must have &#039;&#039;&#039; a &#039;&#039;&#039;valid, public signed certificate&#039;&#039;&#039; (in order to make a trusted SSL connection from the Azure cloud to the Application Platform possible)&lt;br /&gt;
** A valid certificate is required in all involved network entities - at least in the App Platform and if used in the Reverse Proxy; to ensure transmission of MS365 HTTPS POST requests to the app service in order to send notifications.&lt;br /&gt;
* Admin account for Azure Portal (only necessary for granting needed permission for registered app during setup)&lt;br /&gt;
&lt;br /&gt;
==Installation==&lt;br /&gt;
&lt;br /&gt;
===Configuration in Azure Portal===&lt;br /&gt;
&lt;br /&gt;
====Create an App to search for contacts====&lt;br /&gt;
* &#039;&#039;&#039;In the Azure Portal of Microsoft you have to add an app registration&#039;&#039;&#039; &lt;br /&gt;
* &#039;&#039;&#039;You only have to give a name for the app&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[Image:App_Registration_Connector_for_Microsoft365.png|thumb|none|600px|App Registration|app_registration_connector_for_microsoft365.png/]]&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Switch to Certificates &amp;amp; Secrets on the left&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;You only have to configure a client secret and save the value for the configuration of the app&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[Image:Authentication_Connector_for_Microsoft365_Calendar.png|thumb|none|600px|authentication_connector_for_microsoft365_calendar.png/]]&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Switch to api permissions on the left&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;You have to configure application permission (Contacts.Read) and (User.Read.All) as shown in the picture&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;Grant access to the api permissions, if not possible you have to ask an admin&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[Image:Azure_Select_Api-Permission.png|thumb|none|600px|azure_select_api-permission.png/]]&lt;br /&gt;
[[Image:Azure_Select_Api-Permission_Application.png|thumb|none|600px|azure_select_api-permission_application.png/]]&lt;br /&gt;
[[Image:APIPermission Connector for Microsoft365 ContactSearch.png|thumb|none|600px|APIPermission Connector for Microsoft365 ContactSearch/]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Installing and configuring App Platform and PBX===&lt;br /&gt;
====Installing the connector app====&lt;br /&gt;
* First you need to install the connector app from the App Store:&lt;br /&gt;
[[Image:Microsoft365_install_app_1.png|thumb|none|600px|microsoft365_install_app_1.png/]]&lt;br /&gt;
* Install the app by selecting&lt;br /&gt;
# All apps&lt;br /&gt;
# innovaphone AG&lt;br /&gt;
# innovaphone myApps Connector for Microsoft 365&lt;br /&gt;
# select the current Version &lt;br /&gt;
# Click install&lt;br /&gt;
[[Image:Microsoft365_install_app_2.png|thumb|none|600px|microsoft365_install_app_2.png/]]&lt;br /&gt;
====Creating an instance for the connector app====&lt;br /&gt;
* For creating an Instance, in the AP Manager you need to &lt;br /&gt;
# select &#039;&#039;&#039;innovaphone myApps Connector for Microsoft 365&#039;&#039;&#039;&lt;br /&gt;
# click &#039;&#039;&#039;add&#039;&#039;&#039;&lt;br /&gt;
[[Image:Microsoft365_create_instance_1.png|thumb|none|600px|microsoft365_create_instance_1.png/]]&lt;br /&gt;
* Insert the following information and save&lt;br /&gt;
# The technical Instance Name (we suggest microsoft365)&lt;br /&gt;
# Your Domain (This should be the domain you have already configured in your PBX and your Application Platform)&lt;br /&gt;
# define a password for the communication between the PBX and the app instance&lt;br /&gt;
# define a password for the communication between the app instance and the database&lt;br /&gt;
&#039;&#039;All other fields should be filled automatically&#039;&#039;&lt;br /&gt;
[[Image:Microsoft365_create_instance_2.png|thumb|none|600px|microsoft365_create_instance_2.png/]]&lt;br /&gt;
&lt;br /&gt;
====Creating the PBX app object using the PBX Manager Plugin====&lt;br /&gt;
* Open the PBX Manager and &lt;br /&gt;
# select the &#039;&#039;&#039;AP &amp;lt;code&amp;gt;InstanceName&amp;lt;/code&amp;gt;&#039;&#039;&#039; Tile&lt;br /&gt;
# Click &#039;&#039;&#039;Add an app&#039;&#039;&#039;&lt;br /&gt;
# Click &#039;&#039;&#039;Microsoft365 App&#039;&#039;&#039;&lt;br /&gt;
[[Image:Microsoft365_pbx_manager_1.png|thumb|none|600px|microsoft365_pbx_manager_1.png/]]&lt;br /&gt;
* Specify the &#039;&#039;&#039;Name&#039;&#039;&#039; and the &#039;&#039;&#039;SIP&#039;&#039;&#039; (We suggest using &#039;&#039;&#039;&amp;lt;code&amp;gt;microsoft365&amp;lt;/code&amp;gt;&#039;&#039;&#039; for this technical names)&lt;br /&gt;
[[Image:Microsoft365_pbx_manager_2.png|thumb|none|600px|microsoft365_pbx_manager_2.png/]]&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;Important:&#039;&#039;&#039; Please also add the &#039;&#039;&#039;microsoft365-api&#039;&#039;&#039; to a suitable Config-Template: Every user who should be able to search via the Connector for Microsoft 365 has to have access to the &#039;&#039;&#039;microsoft365-api&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
====Creating the API object using the PBX Manager Plugin====&lt;br /&gt;
* Open the PBX Manager and &lt;br /&gt;
# select the &#039;&#039;&#039;AP &amp;lt;code&amp;gt;InstanceName&amp;lt;/code&amp;gt;&#039;&#039;&#039; Tile&lt;br /&gt;
# Click &#039;&#039;&#039;Add an app&#039;&#039;&#039;&lt;br /&gt;
# Click &#039;&#039;&#039;Microsoft365 API&#039;&#039;&#039;&lt;br /&gt;
[[Image:Microsoft365_pbx_manager_1.png|thumb|none|600px|microsoft365_pbx_manager_1.png/]]&lt;br /&gt;
* The &#039;&#039;&#039;Name&#039;&#039;&#039; and &#039;&#039;&#039;SIP&#039;&#039;&#039; has to be &#039;&#039;&#039;&amp;lt;code&amp;gt;microsoft365-api&amp;lt;/code&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
[[Image:Microsoft_365_Settings_API.png|thumb|none|600px|microsoft_365_Settings_API.png/]]&lt;br /&gt;
&lt;br /&gt;
====Add the admin app to a user or a template====&lt;br /&gt;
To be able to configure the connector app, you need users to have access to the admin app.&amp;lt;br&amp;gt;&lt;br /&gt;
You can achieve this by adding the app to a user, or to a template. &amp;lt;br&amp;gt;&lt;br /&gt;
In this Howto - as an example - we will add the app to the &amp;lt;code&amp;gt;Config Admin&amp;lt;/code&amp;gt; template. &amp;lt;br&amp;gt;&lt;br /&gt;
* In the PBX Manager &lt;br /&gt;
# select the &amp;lt;code&amp;gt;Templates&amp;lt;/code&amp;gt; tile &lt;br /&gt;
# click on the &amp;lt;code&amp;gt;Config Admin&amp;lt;/code&amp;gt; template&lt;br /&gt;
[[Image:Microsoft365_template_1.png|thumb|none|600px|microsoft365_template_1.png/]]&lt;br /&gt;
* In the &amp;lt;code&amp;gt;Config Admin&amp;lt;/code&amp;gt; template&lt;br /&gt;
# open Apps&lt;br /&gt;
# Check the &amp;lt;code&amp;gt;app name&amp;lt;/code&amp;gt; checkbox&lt;br /&gt;
# Save the changes&lt;br /&gt;
[[Image:Microsoft365_template_2.png|thumb|none|600px|microsoft365_template_2.png/]]&lt;br /&gt;
&lt;br /&gt;
====Configure the connector with the admin app====&lt;br /&gt;
Now your admins (designated groups or configured user) should have access to the connector admin app. &amp;lt;br&amp;gt;&lt;br /&gt;
* A user with access to the app can now see a new tile in the &#039;&#039;&#039;All Apps&#039;&#039;&#039; area&lt;br /&gt;
* The name depends on the configured &amp;lt;code&amp;gt;app name&amp;lt;/code&amp;gt; from the PBX Manager plugin&lt;br /&gt;
[[Image:Microsoft365_admin_app_1.png|thumb|none|600px|microsoft365_admin_app_1.png/]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====Configuration of the Contact Search=====&lt;br /&gt;
* For the contact search you select &#039;&#039;&#039;Configuration for Contact Search&#039;&#039;&#039; in the admin app&lt;br /&gt;
# &#039;&#039;&#039;ClientIDContactSearch&#039;&#039;&#039; - Please insert the Application ID (Client ID) from Azure Portal from the in preparation created Contact Search app&lt;br /&gt;
# &#039;&#039;&#039;TenantContactSearch&#039;&#039;&#039; - Please insert the Directory ID (Tenant) from Azure Portal from the in preparation created Contact Search app&lt;br /&gt;
# &#039;&#039;&#039;ClientSecretContactSearch&#039;&#039;&#039; - Please insert the shared secret from the in preparation created Contact Search app&lt;br /&gt;
# &#039;&#039;&#039;NotificationURL&#039;&#039;&#039; - You need to specify the address Microsoft can send presence updates to&lt;br /&gt;
## You need to make sure that you define a URL where you can reach your App Platform from the public internet &amp;lt;code&amp;gt;public.dns&amp;lt;/code&amp;gt;&lt;br /&gt;
## Next you need the domain you have configured in the app instance before (3.2.2) &amp;lt;code&amp;gt;your.domain&amp;lt;/code&amp;gt;&lt;br /&gt;
## Next you need the name of the instance you have configured before (3.2.2) &amp;lt;code&amp;gt;microsoft365&amp;lt;/code&amp;gt;&lt;br /&gt;
## The URL will always be terminated by &amp;lt;code&amp;gt;subscriptions&amp;lt;/code&amp;gt;&lt;br /&gt;
##* &amp;lt;code&amp;gt;https://public.dns/your.domain/microsoft365/subscriptions&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Related Articles==&lt;br /&gt;
[[Reference16r1:Concept App Service Connector for Microsoft 365|Concept App Service Connector for Microsoft 365]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Howto16r1:Configure User Presence Sync by Connector for Microsoft365]] &amp;lt;br/&amp;gt;&lt;br /&gt;
[[Howto16r1:Configure Calendar Presence Sync by Connector for Microsoft365]] &amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Howto|{{PAGENAME}}]]&lt;/div&gt;</summary>
		<author><name>Tfu</name></author>
	</entry>
	<entry>
		<id>https://wiki.innovaphone.com/index.php?title=Reference16r1:Apps/PbxManager/App_RemoteControl&amp;diff=78227</id>
		<title>Reference16r1:Apps/PbxManager/App RemoteControl</title>
		<link rel="alternate" type="text/html" href="https://wiki.innovaphone.com/index.php?title=Reference16r1:Apps/PbxManager/App_RemoteControl&amp;diff=78227"/>
		<updated>2025-10-10T10:23:04Z</updated>

		<summary type="html">&lt;p&gt;Tfu: Created page with &amp;quot;The Remote Control PBX Manager plug-in can be used to create and configure the required App object. In addition, the App object can be assigned to specific configuration templates, if any exist. Services licences can also be configured  == Add an App == ;Name :The &amp;#039;&amp;#039;name&amp;#039;&amp;#039; displayed for the App object which must be unique. &amp;#039;&amp;#039;(The field is prefilled with &amp;quot;Remote Control&amp;quot;, you can leave it as it is)&amp;#039;&amp;#039;  ;SIP :The &amp;#039;&amp;#039;sip&amp;#039;&amp;#039; of the App object which must be unique.The sip-id for...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Remote Control PBX Manager plug-in can be used to create and configure the required App object. In addition, the App object can be assigned to specific configuration templates, if any exist. Services licences can also be configured&lt;br /&gt;
&lt;br /&gt;
== Add an App ==&lt;br /&gt;
;Name&lt;br /&gt;
:The &#039;&#039;name&#039;&#039; displayed for the App object which must be unique. &#039;&#039;(The field is prefilled with &amp;quot;Remote Control&amp;quot;, you can leave it as it is)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
;SIP&lt;br /&gt;
:The &#039;&#039;sip&#039;&#039; of the App object which must be unique.The sip-id for the App Object, which must be unique. &#039;&#039;(The field is prefilled with &amp;quot;remotecontrol&amp;quot;, you can leave it as it is)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
;Config templates &lt;br /&gt;
:If config templates exist, they will be listed with a checkbox. Tick the template of your choice to deploy the application.&lt;br /&gt;
&lt;br /&gt;
;Licences&lt;br /&gt;
:Number of purchased licences to configure (leave empty if no licenses purchased)&lt;br /&gt;
&lt;br /&gt;
==Related Articles==&lt;br /&gt;
* [[{{NAMESPACE}}:Concept App Remote Control]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Concept App Remote Control]]&lt;/div&gt;</summary>
		<author><name>Tfu</name></author>
	</entry>
	<entry>
		<id>https://wiki.innovaphone.com/index.php?title=Reference16r1:Concept_App_Remote_Control&amp;diff=78222</id>
		<title>Reference16r1:Concept App Remote Control</title>
		<link rel="alternate" type="text/html" href="https://wiki.innovaphone.com/index.php?title=Reference16r1:Concept_App_Remote_Control&amp;diff=78222"/>
		<updated>2025-10-10T09:37:44Z</updated>

		<summary type="html">&lt;p&gt;Tfu: Created page with &amp;quot;Apps Category:Concept App Remote Control == Applies to == * innovaphone PBX from version 15r1 == Requirements == * innovaphone PBX * innovaphone Application Platform (minimum version 130006) * V15r1 * myApps for Windows.  * Remote Control Client for external participants &amp;#039;&amp;#039;&amp;#039;Note : in v15r1 the Remote Control Client is only available for Windows&amp;#039;&amp;#039;&amp;#039;  == Overview == Remote Control is an application to access a remote PC.  &amp;lt;br/&amp;gt;The application can be...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Concept|Apps]]&lt;br /&gt;
[[Category:Concept App Remote Control]]&lt;br /&gt;
== Applies to ==&lt;br /&gt;
* innovaphone PBX from version 15r1&lt;br /&gt;
== Requirements ==&lt;br /&gt;
* innovaphone PBX&lt;br /&gt;
* innovaphone Application Platform (minimum version 130006)&lt;br /&gt;
* V15r1&lt;br /&gt;
* myApps for Windows. &lt;br /&gt;
* Remote Control Client for external participants &#039;&#039;&#039;Note : in v15r1 the Remote Control Client is only available for Windows&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
Remote Control is an application to access a remote PC. &lt;br /&gt;
&amp;lt;br/&amp;gt;The application can be used by the IT department to provide remote support or it could also be used as a collaborative tool for remote work.&lt;br /&gt;
&lt;br /&gt;
== Licensing == &lt;br /&gt;
&lt;br /&gt;
* For the [[Reference15r1:Concept_App_Remote_Control#Features|licensed features]] you will need to order the &#039;&#039;&#039;Service(innovaphone-remotecontrol)&#039;&#039;&#039; license, order number : &#039;&#039;02-00050-015&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;The application includes one session by default&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
=== For new v15r1 installation === &lt;br /&gt;
The Remote Control App is automatically installed by the installer and will be deployed in the &#039;&#039;&#039;Config User&#039;&#039;&#039; template &lt;br /&gt;
=== With the Settings App - AP app installer plug-in === &lt;br /&gt;
[[File:Ap_app_installer.png]]&lt;br /&gt;
&lt;br /&gt;
Go to the Settings App and open the &#039;&#039;&#039;&amp;quot;AP app installer&amp;quot;&#039;&#039;&#039; plugin. On the right panel, the App Store will be shown. &#039;&#039;Hint : if you access it for the first time, you will need to accept the &amp;quot;Terms of Use of the innovaphone App Store&amp;quot;&#039;&#039;&lt;br /&gt;
* In the search field located on the top right corner of the store, search for &#039;&#039;&#039;&amp;quot;remote control&amp;quot;&#039;&#039;&#039; and click on it&lt;br /&gt;
* Select the proper firmware version, here &#039;&#039;&#039;&amp;quot;v15&amp;quot;&#039;&#039;&#039; and click on install&lt;br /&gt;
* Tick &amp;quot;I accept the terms of use&amp;quot; and continue by clicking on the install yellow button&lt;br /&gt;
* Wait until the install has been finished&lt;br /&gt;
* Close and open the PBX manager to refresh the list of the available coloured AP plugin&lt;br /&gt;
* Click on the &#039;&#039;&#039;&amp;quot;AP remotecontrol&amp;quot;&#039;&#039;&#039; and click on &#039;&#039;&#039;&amp;quot; + Add an App&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
* The &#039;&#039;&#039;&amp;quot;Name&amp;quot;&#039;&#039;&#039; display name field &#039;&#039;(all characters allowed)&#039;&#039; and the &#039;&#039;&#039;&amp;quot;SIP&amp;quot;&#039;&#039;&#039; administration field &#039;&#039;(no spaces, no capital letters)&#039;&#039; are prefilled, you can leave them as they are. &lt;br /&gt;
* Tick the appropriate template to distribute the App&lt;br /&gt;
* Enter the amount of purchased licenses&lt;br /&gt;
* Click OK to save the settings and a green check mark will be shown to inform you that the configuration is good&lt;br /&gt;
&lt;br /&gt;
== Apps ==&lt;br /&gt;
=== Remote Control (remotecontrol) ===&lt;br /&gt;
This is the standard UI App for Remote Control.&lt;br /&gt;
Parameters:&lt;br /&gt;
;Websocket: Connection between the PBX and the App Platform. the App Platform receives the number of licences via this connection.&lt;br /&gt;
;PbxSignal: Protocol to register to the PBX and do signalling with the JSON signalling protocol (necessary to retrieve the TURN server data from the PBX)&lt;br /&gt;
;PbxApi: App notification and presence monitoring  of in-app user list&lt;br /&gt;
&lt;br /&gt;
== Concept ==&lt;br /&gt;
[[Image: Rcrounded.png]]&lt;br /&gt;
&lt;br /&gt;
A user (viewer) sends a request to another user (sharer) to access the sharer&#039;s PC, the sharer accepts the session and begins to share their desktop with the viewer.&lt;br /&gt;
&amp;lt;br /&amp;gt;The viewer is also automatically given control of the mouse and keyboard. Remote sessions are also possible between companies using myApps or not.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Features ===&lt;br /&gt;
&lt;br /&gt;
Here are the features available in the Remote Control App&lt;br /&gt;
&lt;br /&gt;
;Included features&lt;br /&gt;
:&lt;br /&gt;
* App notification to start a session&lt;br /&gt;
* Multiple monitor support: Viewers can switch between desktops by clicking on the monitor icons&lt;br /&gt;
* Direction of control: Change the direction of sharing, a viewer would become a sharer&lt;br /&gt;
* Screen scaling: Two different views of the remote desktop, original size or resized&lt;br /&gt;
* Notifications: On the remote PC, if the sharer does not have the remote control open or is busy with another session, the person requesting a session will be notified within the Remote Control App&lt;br /&gt;
* Text copy &amp;amp; paste support in both directions&lt;br /&gt;
* Support for different keyboard layouts &lt;br /&gt;
&lt;br /&gt;
;Licensed features&lt;br /&gt;
:&lt;br /&gt;
* Support with participants outside your organisation&lt;br /&gt;
** Between 2 different myApps installation using Remote Control App &#039;&#039;(e.g 2 different companies)&#039;&#039; via a session link.&lt;br /&gt;
** Without myApps with the [[Reference15r1:Concept_App_Remote_Control#With_the_Remote_Control_Client_msi_application|Remote Control Client]].&lt;br /&gt;
* Share/Join session&lt;br /&gt;
** Generate a session link from Remote Control App and share it&lt;br /&gt;
** Join a session by entering a link&lt;br /&gt;
* Multiple sessions:&lt;br /&gt;
**If you need more than one session (e.g many viewers for one sharer, more than one parallel session)&lt;br /&gt;
&lt;br /&gt;
=== Remote Control with participants outside your organisation  ===&lt;br /&gt;
====With the Remote Control Client external application====&lt;br /&gt;
The Remote Control Client allows you to establish a remote session with people who are not part of your myApps environment. &#039;&#039;E.g. : external participants such as your customers&#039;&#039;. External participants see the myApps user&#039;s screen sharing.&lt;br /&gt;
* Client compatible with Windows only&lt;br /&gt;
* Easy to install, download client via a session link:&lt;br /&gt;
**Open the shared session link in a web browser and get the &#039;&#039;remoteControl.exe&#039;&#039;&lt;br /&gt;
**Open the previously downloaded file on your computer&lt;br /&gt;
**Enter your name, info and session link &#039;&#039;(same link that is used to download the client)&#039;&#039;&lt;br /&gt;
**Click on Join Session&lt;br /&gt;
&#039;&#039;Note : from 15r1sr2 we introduced a new, lighter client that requires less effort to install and use. The new client also offers a new possibility of joining sessions with elevated admin rights for users who are not admins on their computers. &#039;&#039;&lt;br /&gt;
&lt;br /&gt;
====With your myApps Remote Control App====&lt;br /&gt;
It is possible to establish a remote session between 2 organisations using myApps and having the Remote Control App installed. In the App you can also join/share a session with a link.&lt;br /&gt;
*Compatible only between myApps Windows clients&lt;br /&gt;
*Easy to use:&lt;br /&gt;
**User A from company &amp;quot;xyz.com&amp;quot; opens his Remote Control App in myApps and clicks on &#039;&#039;&#039;Share session&#039;&#039;&#039;&lt;br /&gt;
**User A copies the link and sends it to User B&lt;br /&gt;
**User B from company &amp;quot;abc.com&amp;quot; opens his Remote Control App in myApps, clicks on &#039;&#039;&#039;Join session&#039;&#039;&#039; and pastes the link received from User A into the &#039;&#039;&#039;Session link text field&#039;&#039;&#039;&lt;br /&gt;
**User A will receive a Join Session notification to accept&lt;br /&gt;
**User A will see User B shared session&lt;br /&gt;
&lt;br /&gt;
=== Technical overview ===&lt;br /&gt;
[[Image:Remote-control_technical-overview.png]]&lt;br /&gt;
*Note: SCTP packets are routed through the TURN server and therefore the transmission is not peer-to-peer if the TURN server is selected from the ICE candidate.&lt;br /&gt;
&lt;br /&gt;
=== Technical data ===&lt;br /&gt;
* The maximum bitrate is 1.2Mbits for the users who is sending its desktop UI. The viewer just sends mouse and keyboards events&lt;br /&gt;
* Remote Control App is using the SCTP protocol with a fix UDP port range between [https://wiki.innovaphone.com/index.php?title=Howto:What_Ports_are_used_for_Signaling_and_Voice_Traffic_in_SIP_and_H.323%3F#Application_Sharing_(RTP)| 50200-50299]  within the myApps client. Same range as the Application Sharing feature&lt;br /&gt;
*Same port range is used by the Remote Control Client msi application&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
When you open a support ticket, you will be asked to provide us with debugging data of your issue. You can also send us screenshots/videos of the behavior you are reporting. Do not forget to send us also the PBX default configuration file. &lt;br /&gt;
&lt;br /&gt;
=== Trace flags of the App instance on the App Platform === &lt;br /&gt;
Select the corresponding App instance of the Remote Control App service and click on the &#039;&#039;&#039;Diagnostics button&#039;&#039;&#039;. Tick the following trace flags:&lt;br /&gt;
*App&lt;br /&gt;
*Database&lt;br /&gt;
&lt;br /&gt;
=== Trace flags of the myAPPS Client ===&lt;br /&gt;
Go to the myApps &#039;&#039;&#039;Burger menu&#039;&#039;&#039;, click on &#039;&#039;&#039;more&#039;&#039;&#039;, and then click the &#039;&#039;&#039;magnifying glass&#039;&#039;&#039;. Tick the following trace flag:&lt;br /&gt;
*AppSharing&lt;br /&gt;
&lt;br /&gt;
=== Trace of the Remote Control Client ===&lt;br /&gt;
Do a right click on the app try icon and click on &#039;&#039;open trace folder&#039;&#039; (&#039;&#039;default path C:\Users\[YourUser]\AppData\Local\innovaphone\RemoteControl&#039;&#039;), get the whole content in a zip file.&lt;br /&gt;
&lt;br /&gt;
==Known issues== &lt;br /&gt;
*Push notifications on sharer&#039;s smartphone : if a viewer wants to start a remote session with a sharer who does not have the Remote Control App open on their PC, a push notification is triggered on the sharer&#039;s myApps mobile phone (if installed).&lt;br /&gt;
&lt;br /&gt;
==Related Articles==&lt;br /&gt;
* [[{{NAMESPACE}}:Apps/PbxManager/App RemoteControl]]&lt;br /&gt;
[[Category:Apps/PbxManager/App RemoteControl]]&lt;/div&gt;</summary>
		<author><name>Tfu</name></author>
	</entry>
	<entry>
		<id>https://wiki.innovaphone.com/index.php?title=Howto16r1:Configure_OAuth2_E-Mail&amp;diff=78220</id>
		<title>Howto16r1:Configure OAuth2 E-Mail</title>
		<link rel="alternate" type="text/html" href="https://wiki.innovaphone.com/index.php?title=Howto16r1:Configure_OAuth2_E-Mail&amp;diff=78220"/>
		<updated>2025-10-09T13:34:16Z</updated>

		<summary type="html">&lt;p&gt;Tfu: /* General Information */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{FIXME|reason=This product is in the beta phase and is not yet finished}}&lt;br /&gt;
&lt;br /&gt;
The innovaphone PBX and apps can be configured to send E-Mails for various subjects and purposes. Major E-Mail providers intent to discontinue the username/password authentication schemes in favour of OAuth2. PBX and Apps version 16r1 does support OAuth2 authentication for SMTP. Here is a step by step guide how to set up OAuth2 support in Microsoft 365 through the Azure Portal and how to set it up on a Google Gmail account in the Google Cloud Console.&lt;br /&gt;
&lt;br /&gt;
== General Information ==&lt;br /&gt;
Most of the large email providers offer the possibility to define an app that is allowed to gain access of a certain scope like SMTP. &amp;lt;br&amp;gt;&lt;br /&gt;
It assigns a Client ID / Client Secret.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Authorization for sending from the mail account needs to be given one time either:&amp;lt;br&amp;gt;&lt;br /&gt;
* By providing resource owner username/password. Sending this to the token endpoint results in an access token and long term refresh token.&lt;br /&gt;
* By interactive authorization via a popup dialogue that is loaded from the authorization endpoint. After the credentials are verified, the dialogue redirects to the redirect URI with an authorization code that is traded to an access token and refresh token.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
The access token is sent for authentication in SMTP. It needs regular refresh, which will be done automatically.&lt;br /&gt;
&lt;br /&gt;
=== Modes ===&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Exchange&#039;&#039;&#039;: Microsoft, with interactive authorization&lt;br /&gt;
* &#039;&#039;&#039;Microsoft 365&#039;&#039;&#039;: Microsoft, without interactive authorization (Resource owner and password has to be filled)&lt;br /&gt;
* &#039;&#039;&#039;Gmail&#039;&#039;&#039;: Google, with interactive authorization&lt;br /&gt;
* &#039;&#039;&#039;Google Service Account&#039;&#039;&#039;:  Google, without interactive authorization (Client e-mail, Private Key ID and Private Key of the service account must be provided)&lt;br /&gt;
* &#039;&#039;&#039;Client secret post&#039;&#039;&#039;: Generic configuration where all parameters of the client secret post OAuth2 flow can be set.&lt;br /&gt;
* &#039;&#039;&#039;Private key jwt&#039;&#039;&#039;: Generic configuration where all parameters of the private key jwt OAuth2 flow can be set.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Example Redirect URIs ===&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;PBX&#039;&#039;&#039;: &amp;lt;nowiki&amp;gt;https://example-pbx.domain.com/OAUTH2-CLIENT/auth.htm&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Reporting&#039;&#039;&#039;: &amp;lt;nowiki&amp;gt;https://example-ap.domain.com/domain.com/reporting/auth.htm&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Fax&#039;&#039;&#039;: &amp;lt;nowiki&amp;gt;https://example-ap.domain.com/domain.com/fax/auth.htm&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Users&#039;&#039;&#039;: &amp;lt;nowiki&amp;gt;https://example-ap.domain.com/domain.com/usersapp/auth.htm&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Connect&#039;&#039;&#039;: &amp;lt;nowiki&amp;gt;https://example-ap.domain.com/domain.com/messages/auth.htm&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;AP Manager&#039;&#039;&#039;: &amp;lt;nowiki&amp;gt;https://example-ap.domain.com/manager/auth.htm&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Microsoft 365 ==&lt;br /&gt;
=== Azure Portal ===&lt;br /&gt;
Log in to Microsoft Azure Portal (https://portal.azure.com) and go to Microsoft Entra ID.&lt;br /&gt;
[[File:AzureMicrosoftEntraID.png|none|thumb|600x600px|/AzureMicrosoftEntraID.png|/AzureMicrosoftEntraID.png]]&lt;br /&gt;
Add a new app registration to create client credentials.&lt;br /&gt;
[[File:AzureAddAppRegistration.png|none|thumb|600x600px|/AzureAddAppRegistration.png|/AzureAddAppRegistration.png]]&lt;br /&gt;
Register the application and maybe already fill in the redirect URI for Web based application type to path OAUTH2-CLIENT/auth.htm at the PBX.&lt;br /&gt;
[[File:AzureRegisterAnApplication.png|none|thumb|600x600px|/AzureRegisterAnApplication.png|/AzureRegisterAnApplication.png]]&lt;br /&gt;
App registration is complete. Client ID and tenant needs to be configured at the PBX and every app that will be sending e-mails.&lt;br /&gt;
[[File:AzureApp.png|none|thumb|600x600px|/AzureApp.png|/AzureApp.png]]&lt;br /&gt;
Create a client secret. Note that expiry is limited to no longer than 2 years. The client secret must be renewed before expiry and the new secret configured and interactive authorisation carried out again to ensure continuous operation.&lt;br /&gt;
[[File:AzureAddClientSecret.png|none|thumb|600x600px|/AzureAddClientSecret.png|/AzureAddClientSecret.png]]&lt;br /&gt;
Copy the client secret. It also needs to be configured at the PBX and every app that will be sending e-mails.&lt;br /&gt;
[[File:AzureCopyClientSecret.png|none|thumb|600x600px|/AzureCopyClientSecret.png|/AzureCopyClientSecret.png]]&lt;br /&gt;
Add permissions located in APIs my organization uses.&lt;br /&gt;
[[File:AzureAddApiPermissionMyOrganization.png|none|thumb|600x600px|/AzureAddApiPermissionMyOrganization.png|/AzureAddApiPermissionMyOrganization.png]]&lt;br /&gt;
More precisely located in Office 365 Exchange Online.&lt;br /&gt;
[[File:AzureAddApiPermissionExchange.png|none|thumb|600x600px|/AzureAddApiPermissionExchange.png|/AzureAddApiPermissionExchange.png]]&lt;br /&gt;
And there in the application permissions.&lt;br /&gt;
[[File:AzureAddApiExchangeApplication.png|none|thumb|600x600px|/AzureAddApiExchangeApplication.png|/AzureAddApiExchangeApplication.png]]&lt;br /&gt;
Namely SMTP Mail.Send.&lt;br /&gt;
[[File:AzureAddApiSendMailAsUser.png|none|thumb|600x600px|/AzureAddApiSendMailAsUser.png|/AzureAddApiSendMailAsUser.png]]&lt;br /&gt;
Grant admin permission for Mail.Send.&lt;br /&gt;
[[File:AzureGrantApiPermissions.png|none|thumb|600x600px|/AzureGrantApiPermissions.png|/AzureGrantApiPermissions.png]]&lt;br /&gt;
API permissions are now granted.&lt;br /&gt;
[[File:AzureApiPermissionsGranted.png|none|thumb|600x600px|/AzureApiPermissionsGranted.png|/AzureApiPermissionsGranted.png]]&lt;br /&gt;
Tell all redirect URIs that the PBX and the apps will be using during interactive authorization.&lt;br /&gt;
[[File:AzureRedirectUris.png|none|thumb|600x600px|/AzureRedirectUris.png|/AzureRedirectUris.png]]&lt;br /&gt;
Allow public client flows of OAuth2. Resource Owner Password Credentials Flow has the advantage that it doesn&#039;t need interactive authorization.&lt;br /&gt;
[[File:AzureAllowPublicClientFlows.png|none|thumb|600x600px|/AzureAllowPublicClientFlows.png|/AzureAllowPublicClientFlows.png]]&lt;br /&gt;
&lt;br /&gt;
=== Microsoft 365 admin center ===&lt;br /&gt;
Log in to the Microsoft 365 admin center (https://admin.cloud.microsoft).&lt;br /&gt;
[[File:MS365AdminCenter.png|none|thumb|600x600px|/MS365AdminCenter.png|/MS365AdminCenter.png]]&lt;br /&gt;
Make sure that Microsoft 365 licenses are assigned to your user.&lt;br /&gt;
[[File:MS365UserLicenses.png|none|thumb|600x600px|/MS365UserLicenses.png|/MS365UserLicenses.png]]&lt;br /&gt;
Set your user active.&lt;br /&gt;
[[File:MS365ActiveUsers.png|none|thumb|600x600px|/MS365ActiveUsers.png|/MS365ActiveUsers.png]]&lt;br /&gt;
Locate the Mail tab of your user.&lt;br /&gt;
[[File:MS365UserEMail.png|none|thumb|600x600px|/MS365UserEMail.png|/MS365UserEMail.png]]&lt;br /&gt;
Allow authenticated SMTP.&lt;br /&gt;
[[File:MS365AuthenticatedSMTP.png|none|thumb|600x600px|/MS365AuthenticatedSMTP.png|/MS365AuthenticatedSMTP.png]]&lt;br /&gt;
&lt;br /&gt;
=== Exchange admin center ===&lt;br /&gt;
Login to the Exchange admin center (https://admin.exchange.microsoft.com).&lt;br /&gt;
[[File:ExchangeAdminCenter.png|none|thumb|600x600px|/ExchangeAdminCenter.png|/ExchangeAdminCenter.png]]&lt;br /&gt;
Remove deactivation of the SMTP AUTH protocol.&lt;br /&gt;
[[File:ExchangeRemoveDeavtivatedOAuth2.png|none|thumb|600x600px|/ExchangeRemoveDeavtivatedOAuth2.png|/ExchangeRemoveDeavtivatedOAuth2.png]]&lt;br /&gt;
&lt;br /&gt;
=== PBX Example configuration === &lt;br /&gt;
With this Microsoft setup the OAuth2 configuration for the resource owner password credentials flow can be filled in as follows. &lt;br /&gt;
[[File:OAuth2ResourceOwnerPasswordCredentials.png|none|thumb|600x600px|/OAuth2ResourceOwnerPasswordCredentials.png|/OAuth2ResourceOwnerPasswordCredentials.png]]&lt;br /&gt;
For interactive authorization this is the OAuth2 configuration. Authorize e-mail access one time and send a test mail to verify everything went well.&lt;br /&gt;
[[File:OAuth2InteractiveAuthorization.png|none|thumb|600x600px|/OAuth2InteractiveAuthorization.png|/OAuth2InteractiveAuthorization.png]]&lt;br /&gt;
&lt;br /&gt;
== Gmail ==&lt;br /&gt;
=== Preparations === &lt;br /&gt;
Login to the Google Cloud Console (https://console.cloud.google.com), select a project, New project.&lt;br /&gt;
[[File:GoogleSelectProject.png|none|thumb|600x600px|/GoogleSelectProject.png|/GoogleSelectProject.png]]&lt;br /&gt;
Create the project.&lt;br /&gt;
[[File:GoogleCreateProject.png|none|thumb|600x600px|/GoogleCreateProject.png|/GoogleCreateProject.png]]&lt;br /&gt;
Client credentials will be created in this project.&lt;br /&gt;
[[File:GoogleProjectCreated.png|none|thumb|600x600px|/GoogleProjectCreated.png|/GoogleProjectCreated.png]]&lt;br /&gt;
From the library specify the APIs needed to access.&lt;br /&gt;
[[File:GoogleApisServicesFromLibrary.png|none|thumb|600x600px|/GoogleApisServicesFromLibrary.png|/GoogleApisServicesFromLibrary.png]]&lt;br /&gt;
These are in the Gmail API.&lt;br /&gt;
[[File:GoogleApisServicesApiLibrary.png|none|thumb|600x600px|/GoogleApisServicesApiLibrary.png|/GoogleApisServicesApiLibrary.png]]&lt;br /&gt;
Choose the Gmail API and enable it.&lt;br /&gt;
[[File:GoogleGmailApis.png|none|thumb|600x600px|/GoogleGmailApis.png|/GoogleGmailApis.png]]&lt;br /&gt;
Credentials need to be created.&lt;br /&gt;
[[File:GoogleGmailApiAdded.png|none|thumb|600x600px|/GoogleGmailApiAdded.png|/GoogleGmailApiAdded.png]]&lt;br /&gt;
Invoke the help me choose wizard.&lt;br /&gt;
[[File:GoogleCreateCredentialsHelpMeChoose.png|none|thumb|600x600px|/GoogleCreateCredentialsHelpMeChoose.png|/GoogleCreateCredentialsHelpMeChoose.png]]&lt;br /&gt;
User data access is needed.&lt;br /&gt;
[[File:GoogleCredentialsUserData.png|none|thumb|600x600px|/GoogleCredentialsUserData.png|/GoogleCredentialsUserData.png]]&lt;br /&gt;
Configure the consent screen of the interactive authorization.&lt;br /&gt;
[[File:GoogleOAuthConsentScreen.png|none|thumb|600x600px|/GoogleOAuthConsentScreen.png|/GoogleOAuthConsentScreen.png]]&lt;br /&gt;
Specify the permissions that need to be authorized by the user.&lt;br /&gt;
[[File:GoogleOAuthScopes.png|none|thumb|600x600px|/GoogleOAuthScopes.png|/GoogleOAuthScopes.png]]&lt;br /&gt;
Its mail.google.com in general.&lt;br /&gt;
[[File:GoogleScopeMailGoogleCom.png|none|thumb|600x600px|/GoogleScopeMailGoogleCom.png|/GoogleScopeMailGoogleCom.png]]&lt;br /&gt;
And its to send email on the users behalf.&lt;br /&gt;
[[File:GoogleScopeAuthGmailSend.png|none|thumb|600x600px|/GoogleScopeAuthGmailSend.png|/GoogleScopeAuthGmailSend.png]]&lt;br /&gt;
These are the scopes needed.&lt;br /&gt;
[[File:GoogleScopes.png|none|thumb|600x600px|/GoogleScopes.png|/GoogleScopes.png]]&lt;br /&gt;
Ask client credentials for Web type application.&lt;br /&gt;
[[File:GoogleOAuthClientID.png|none|thumb|600x600px|/GoogleOAuthClientID.png|/GoogleOAuthClientID.png]]&lt;br /&gt;
Tell all redirect URIs that the PBX and the apps will be using during interactive authorization.&lt;br /&gt;
[[File:GoogleRedirectURIs.png|none|thumb|600x600px|/GoogleRedirectURIs.png|/GoogleRedirectURIs.png]]&lt;br /&gt;
Download the credentials. This json file contains all information for OAuth2 configuration.&lt;br /&gt;
[[File:GoogleClientCredentialsDownload.png|none|thumb|600x600px|/GoogleClientCredentialsDownload.png|/GoogleClientCredentialsDownload.png]]&lt;br /&gt;
Customize the OAuth consent screen&lt;br /&gt;
[[File:GoogleOAuthConsentScreenSettings.png|none|thumb|600x600px|/GoogleOAuthConsentScreenSettings.png|/GoogleOAuthConsentScreenSettings.png]]&lt;br /&gt;
Start the customization wizard.&lt;br /&gt;
[[File:GoogleConsentScreenWizard.png|none|thumb|600x600px|/GoogleConsentScreenWizard.png|/GoogleConsentScreenWizard.png]]&lt;br /&gt;
Choose which users may authorize.&lt;br /&gt;
[[File:GoogleAudienceExternal.png|none|thumb|600x600px|/GoogleAudienceExternal.png|/GoogleAudienceExternal.png]]&lt;br /&gt;
Google workspace users may choose internal audience. Users not in Google workspace proceed with external.&lt;br /&gt;
[[File:GoogleContactInformation.png|none|thumb|600x600px|/GoogleContactInformation.png|/GoogleContactInformation.png]]&lt;br /&gt;
Add a test user.&lt;br /&gt;
[[File:GoogleTestUserAdded.png|none|thumb|600x600px|/GoogleTestUserAdded.png|/GoogleTestUserAdded.png]]&lt;br /&gt;
&lt;br /&gt;
=== PBX Example configuration === &lt;br /&gt;
The OAuth2 parameters can be filled in with the information from the json file downloaded above. Authorize e-mail access one time and send a test mail to verify everything went well.&lt;br /&gt;
[[File:OAuth2InteractiveGmail.png|none|thumb|600x600px|/OAuth2InteractiveGmail.png|/OAuth2InteractiveGmail.png]]&lt;br /&gt;
&lt;br /&gt;
== Generic ==&lt;br /&gt;
&lt;br /&gt;
For other e-mail providers the client secret post OAuth2 flow may be configured in a generic way. Details need to be supplied by the e-mail provider.&lt;br /&gt;
&lt;br /&gt;
For the Microsoft 365 setup above it would be as follows with Token endpoint &#039;&#039;&amp;lt;nowiki&amp;gt;https://login.microsoftonline.com/af326a34-169c-469e-946b-1ef57925306b/oauth2/v2.0/token&amp;lt;/nowiki&amp;gt;&#039;&#039; Authorization URL &#039;&#039;&amp;lt;nowiki&amp;gt;https://login.microsoftonline.com/af326a34-169c-469e-946b-1ef57925306b/oauth2/v2.0/authorize?scope=https://outlook.office.com/SMTP.Send&amp;lt;/nowiki&amp;gt; offline_access&#039;&#039; The configuration appends &#039;&#039;&amp;amp;response_type=code&amp;amp;prompt=consent&amp;amp;login_hint=...&amp;amp;redirect_uri=...&amp;amp;client_id=...&#039;&#039; automatically.[[File:OAuth2ClientSecretPost.png|none|thumb|600x600px|/OAuth2ClientSecretPost.png|/OAuth2ClientSecretPost.png]]&lt;br /&gt;
For the Gmail example above the generic confguration would be like this with Token endpoint &#039;&#039;&amp;lt;nowiki&amp;gt;https://oauth2.googleapis.com/token&amp;lt;/nowiki&amp;gt;&#039;&#039; Authorization URL &#039;&#039;&amp;lt;nowiki&amp;gt;https://accounts.google.com/o/oauth2/auth?access_type=offline&amp;amp;scope=https://mail.google.com/&amp;lt;/nowiki&amp;gt;&#039;&#039; The configuration appends &#039;&#039;&amp;amp;response_type=code&amp;amp;prompt=consent&amp;amp;login_hint=...&amp;amp;redirect_uri=...&amp;amp;client_id=...&#039;&#039; automatically.&lt;br /&gt;
[[File:OAith2ClientSecretPostGmail.png|none|thumb|600x600px|/OAith2ClientSecretPostGmail.png|/OAith2ClientSecretPostGmail.png]]&lt;br /&gt;
The private key jwt OAuth2 flow can be configured generically as well.[[File:OAuth2PrivateKeyJWT.png|none|thumb|600x600px|/OAuth2PrivateKeyJWT.png|/OAuth2PrivateKeyJWT.png]]&lt;br /&gt;
&lt;br /&gt;
== Related Articles ==&lt;br /&gt;
* [[Reference16r1:PBX/Config/Authentication]]&lt;br /&gt;
* [[Reference16r1:Apps/PbxManager/Email]]&lt;br /&gt;
* [[Reference16r1:Concept App Connect#E-Mail configuration]]&lt;br /&gt;
* [[Reference16r1:Concept App Service Fax#Mail Configuration (SMTP_Server)]]&lt;br /&gt;
* [[Reference16r1:Concept App Service Reports#Configuration]]&lt;br /&gt;
* [[Reference16r1:Concept App Service Users#Users Admin App (innovaphone-usersadmin)]]&lt;br /&gt;
* [[Reference16r1:Concept App Platform#SMTP]]&lt;/div&gt;</summary>
		<author><name>Tfu</name></author>
	</entry>
</feed>