New Plugin: PushNotifications
This plugin allows to send push notifications to nymea:app without the need to go through nymea:cloud. This is useful for users that prefer to not have a cloud account at all and improves privacy and server costs as it cuts out one server hop of the messages.
This commit is contained in:
parent
6e781113e5
commit
5ccc29a205
16
debian/control
vendored
16
debian/control
vendored
@ -638,6 +638,21 @@ Description: nymea.io plugin for Pushbullet
|
|||||||
This package will install the nymea.io plugin for sending messages via Pushbullet.
|
This package will install the nymea.io plugin for sending messages via Pushbullet.
|
||||||
|
|
||||||
|
|
||||||
|
Package: nymea-plugin-pushnotifications
|
||||||
|
Architecture: any
|
||||||
|
Depends: ${shlibs:Depends},
|
||||||
|
${misc:Depends},
|
||||||
|
nymea-plugins-translations,
|
||||||
|
Description: nymea.io plugin to send Push notifications
|
||||||
|
The nymea daemon is a plugin based IoT (Internet of Things) server. The
|
||||||
|
server works like a translator for devices, things and services and
|
||||||
|
allows them to interact.
|
||||||
|
With the powerful rule engine you are able to connect any device available
|
||||||
|
in the system and create individual scenes and behaviors for your environment.
|
||||||
|
.
|
||||||
|
This package will install the nymea.io plugin for sending messages via GCM, APNs and UBPorts
|
||||||
|
|
||||||
|
|
||||||
Package: nymea-plugin-solarlog
|
Package: nymea-plugin-solarlog
|
||||||
Architecture: any
|
Architecture: any
|
||||||
Depends: ${shlibs:Depends},
|
Depends: ${shlibs:Depends},
|
||||||
@ -1071,6 +1086,7 @@ Depends: nymea-plugin-anel,
|
|||||||
nymea-plugin-openweathermap,
|
nymea-plugin-openweathermap,
|
||||||
nymea-plugin-philipshue,
|
nymea-plugin-philipshue,
|
||||||
nymea-plugin-pushbullet,
|
nymea-plugin-pushbullet,
|
||||||
|
nymea-plugin-pushnotifications,
|
||||||
nymea-plugin-wakeonlan,
|
nymea-plugin-wakeonlan,
|
||||||
nymea-plugin-tasmota,
|
nymea-plugin-tasmota,
|
||||||
nymea-plugin-tplink,
|
nymea-plugin-tplink,
|
||||||
|
|||||||
1
debian/nymea-plugin-pushnotifications.install.in
vendored
Normal file
1
debian/nymea-plugin-pushnotifications.install.in
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
usr/lib/@DEB_HOST_MULTIARCH@/nymea/plugins/libnymea_integrationpluginpushnotifications.so
|
||||||
@ -42,6 +42,7 @@ PLUGIN_DIRS = \
|
|||||||
osdomotics \
|
osdomotics \
|
||||||
philipshue \
|
philipshue \
|
||||||
pushbullet \
|
pushbullet \
|
||||||
|
pushnotifications \
|
||||||
shelly \
|
shelly \
|
||||||
solarlog \
|
solarlog \
|
||||||
systemmonitor \
|
systemmonitor \
|
||||||
|
|||||||
31
pushnotifications/README.md
Normal file
31
pushnotifications/README.md
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
# Push Notifications
|
||||||
|
|
||||||
|
This plugin allows to send push notifications to mobile devices.
|
||||||
|
|
||||||
|
## Supported platforms
|
||||||
|
|
||||||
|
* Android (using Firebase Cloud Messaging)
|
||||||
|
* iOS (using Firebase Cloud Messaging)
|
||||||
|
* Ubuntu/UBPorts Phone
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
A push notification device token is required during setup. For Android *and* iOS, a Firebase
|
||||||
|
token is required. Note that native iOS push tokens are not supported as the Apple Push Notification
|
||||||
|
Service (APNs) does not allow sending messages in such a distributed manner, however, Firebase is available
|
||||||
|
for iOS too. On Ubuntu, the UBPorts push services are used.
|
||||||
|
|
||||||
|
## More
|
||||||
|
|
||||||
|
During setup, the token, the push service system and a client id needs to be provided. The token is normally
|
||||||
|
obtained by the operating system. The push service should be selected from GCM, APNs or UBPorts. The client id
|
||||||
|
must a unique per client and as persistent as possible.
|
||||||
|
|
||||||
|
> Note: Even when using APNs, the token must be obtained using the Firebase SDK as plain APNs does not support sending push notifications from a distributed setup like nymea, but always requires a centralized server on the internet handling all messages.
|
||||||
|
|
||||||
|
|
||||||
|
As it is impossible for an end user to obtain this token, a client app should prefill all the parameters
|
||||||
|
when setting up a push notification thing. Normally, push tokens expire after a while (for instance when
|
||||||
|
the user clears app data, when the operating system decides to cycle tokens etc). In this case, the client
|
||||||
|
app should reconfigure its own push notification thing, updating the token with the new one. The client ID
|
||||||
|
parameter schould be used to find the appropriate thing to reconfigure.
|
||||||
256
pushnotifications/integrationpluginpushnotifications.cpp
Normal file
256
pushnotifications/integrationpluginpushnotifications.cpp
Normal file
@ -0,0 +1,256 @@
|
|||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* Copyright 2013 - 2020, nymea GmbH
|
||||||
|
* Contact: contact@nymea.io
|
||||||
|
*
|
||||||
|
* This file is part of nymea.
|
||||||
|
* This project including source code and documentation is protected by
|
||||||
|
* copyright law, and remains the property of nymea GmbH. All rights, including
|
||||||
|
* reproduction, publication, editing and translation, are reserved. The use of
|
||||||
|
* this project is subject to the terms of a license agreement to be concluded
|
||||||
|
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
|
||||||
|
* under https://nymea.io/license
|
||||||
|
*
|
||||||
|
* GNU Lesser General Public License Usage
|
||||||
|
* Alternatively, this project may be redistributed and/or modified under the
|
||||||
|
* terms of the GNU Lesser General Public License as published by the Free
|
||||||
|
* Software Foundation; version 3. This project is distributed in the hope that
|
||||||
|
* it will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||||
|
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this project. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* For any further details and any questions please contact us under
|
||||||
|
* contact@nymea.io or see our FAQ/Licensing Information on
|
||||||
|
* https://nymea.io/license/faq
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
#include "integrationpluginpushnotifications.h"
|
||||||
|
#include "plugininfo.h"
|
||||||
|
|
||||||
|
#include "network/networkaccessmanager.h"
|
||||||
|
#include "nymeasettings.h"
|
||||||
|
|
||||||
|
#include <QJsonDocument>
|
||||||
|
|
||||||
|
// Example payload for Firebase + GCM
|
||||||
|
//{
|
||||||
|
// "android": {
|
||||||
|
// "notification": {
|
||||||
|
// "sound": "default"
|
||||||
|
// },
|
||||||
|
// "priority": "high"
|
||||||
|
// },
|
||||||
|
// "data": {
|
||||||
|
// "body": "text",
|
||||||
|
// "title": "title"
|
||||||
|
// },
|
||||||
|
// "to": "<client token>"
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
// Example payload for Firebase + APNs
|
||||||
|
//{
|
||||||
|
// "apns": {
|
||||||
|
// "headers": {
|
||||||
|
// "apns-priority": "10"
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// "notification": {
|
||||||
|
// "body": "text",
|
||||||
|
// "sound": "default",
|
||||||
|
// "title": "title"
|
||||||
|
// },
|
||||||
|
// "to": "<client token>"
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
IntegrationPluginPushNotifications::IntegrationPluginPushNotifications(QObject* parent): IntegrationPlugin (parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
IntegrationPluginPushNotifications::~IntegrationPluginPushNotifications()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void IntegrationPluginPushNotifications::setupThing(ThingSetupInfo *info)
|
||||||
|
{
|
||||||
|
Thing *thing = info->thing();
|
||||||
|
|
||||||
|
QString token = thing->paramValue(pushNotificationsThingTokenParamTypeId).toString();
|
||||||
|
QString pushService = thing->paramValue(pushNotificationsThingServiceParamTypeId).toString();
|
||||||
|
QString clientId = thing->paramValue(pushNotificationsThingClientIdParamTypeId).toString();
|
||||||
|
|
||||||
|
qCDebug(dcPushNotifications()) << "Setting up push notifications" << thing->name() << "(" << clientId << ") for service" << pushService << "with token" << (token.mid(0, 5) + "******");
|
||||||
|
|
||||||
|
if (token.isEmpty()) {
|
||||||
|
//: Error setting up thing
|
||||||
|
info->finish(Thing::ThingErrorMissingParameter, QT_TR_NOOP("The token must not be empty."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
QStringList availablePushServices = {"FB-GCM", "FB-APNs", "UBPorts"};
|
||||||
|
if (!availablePushServices.contains(pushService)) {
|
||||||
|
//: Error setting up thing
|
||||||
|
info->finish(Thing::ThingErrorMissingParameter, QT_TR_NOOP("The push service must not be empty."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// In case of Firebase, check if we have the required API key
|
||||||
|
if (pushService.startsWith("FB") && apiKeyStorage()->requestKey("firebase").data("apiKey").isEmpty()) {
|
||||||
|
//: Error setting up thing
|
||||||
|
info->finish(Thing::ThingErrorAuthenticationFailure, QT_TR_NOOP("Firebase server API key not installed."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
info->finish(Thing::ThingErrorNoError);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IntegrationPluginPushNotifications::executeAction(ThingActionInfo *info)
|
||||||
|
{
|
||||||
|
Thing *thing = info->thing();
|
||||||
|
Action action = info->action();
|
||||||
|
|
||||||
|
qCDebug(dcPushNotifications()) << "Executing action" << action.actionTypeId() << "for" << thing->name() << thing->id().toString();
|
||||||
|
|
||||||
|
QString token = thing->paramValue(pushNotificationsThingTokenParamTypeId).toString();
|
||||||
|
QString pushService = thing->paramValue(pushNotificationsThingServiceParamTypeId).toString();
|
||||||
|
|
||||||
|
QString title = action.param(pushNotificationsNotifyActionTitleParamTypeId).value().toString();
|
||||||
|
QString body = action.param(pushNotificationsNotifyActionBodyParamTypeId).value().toString();
|
||||||
|
|
||||||
|
if (token.isEmpty()) {
|
||||||
|
return info->finish(Thing::ThingErrorAuthenticationFailure, QT_TR_NOOP("Push notifications need to be reconfigured."));
|
||||||
|
}
|
||||||
|
|
||||||
|
QNetworkRequest request;
|
||||||
|
QVariantMap payload;
|
||||||
|
|
||||||
|
if (pushService.startsWith("FB")) {
|
||||||
|
|
||||||
|
ApiKey apiKey = apiKeyStorage()->requestKey("firebase");
|
||||||
|
if (apiKey.data("apiKey").isEmpty()) {
|
||||||
|
info->finish(Thing::ThingErrorAuthenticationFailure, QT_TR_NOOP("Firebase server API key not installed."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
request = QNetworkRequest(QUrl("https://fcm.googleapis.com/fcm/send"));
|
||||||
|
request.setRawHeader("Authorization", "key=" + apiKey.data("apiKey"));
|
||||||
|
request.setRawHeader("Content-Type", "application/json");
|
||||||
|
|
||||||
|
payload.insert("to", token.toUtf8().trimmed());
|
||||||
|
|
||||||
|
QVariantMap notification;
|
||||||
|
notification.insert("title", title);
|
||||||
|
notification.insert("body", body);
|
||||||
|
|
||||||
|
if (pushService == "FB-GCM") {
|
||||||
|
|
||||||
|
QVariantMap soundMap;
|
||||||
|
soundMap.insert("sound", "default");
|
||||||
|
|
||||||
|
QVariantMap android;
|
||||||
|
android.insert("priority", "high");
|
||||||
|
android.insert("notification", soundMap);
|
||||||
|
|
||||||
|
payload.insert("android", android);
|
||||||
|
payload.insert("data", notification);
|
||||||
|
|
||||||
|
} else if (pushService == "FB-APNs") {
|
||||||
|
|
||||||
|
notification.insert("sound", "default");
|
||||||
|
|
||||||
|
QVariantMap headers;
|
||||||
|
headers.insert("apns-priority", "10");
|
||||||
|
QVariantMap apns;
|
||||||
|
apns.insert("headers", headers);
|
||||||
|
|
||||||
|
payload.insert("notification", notification);
|
||||||
|
payload.insert("apns", apns);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} else if (pushService == "UBPorts") {
|
||||||
|
request = QNetworkRequest(QUrl("https://push.ubports.com/notify"));
|
||||||
|
request.setRawHeader("Content-Type", "application/json");
|
||||||
|
|
||||||
|
QVariantMap card;
|
||||||
|
card.insert("icon", "notification");
|
||||||
|
card.insert("summary", title);
|
||||||
|
card.insert("body", body);
|
||||||
|
card.insert("popup", true);
|
||||||
|
card.insert("persist", true);
|
||||||
|
|
||||||
|
QVariantMap notification;
|
||||||
|
notification.insert("card", card);
|
||||||
|
notification.insert("vibrate", true);
|
||||||
|
notification.insert("sound", true);
|
||||||
|
|
||||||
|
QVariantMap data;
|
||||||
|
data.insert("notification", notification);
|
||||||
|
|
||||||
|
payload.insert("data", data);
|
||||||
|
payload.insert("appid", "io.guh.nymeaapp_nymea-app");
|
||||||
|
payload.insert("expire_on", QDateTime::currentDateTime().toUTC().addMSecs(1000 * 60 * 10).toString(Qt::ISODate));
|
||||||
|
payload.insert("token", token.toUtf8().trimmed());
|
||||||
|
}
|
||||||
|
|
||||||
|
qCDebug(dcPushNotifications()) << "Sending notification" << request.url().toString() << qUtf8Printable(QJsonDocument::fromVariant(payload).toJson());
|
||||||
|
QNetworkReply *reply = hardwareManager()->networkManager()->post(request, QJsonDocument::fromVariant(payload).toJson(QJsonDocument::Compact));
|
||||||
|
connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater);
|
||||||
|
connect(reply, &QNetworkReply::finished, info, [reply, pushService, info, this]{
|
||||||
|
if (reply->error() != QNetworkReply::NoError) {
|
||||||
|
qCWarning(dcPushNotifications()) << "Push message sending failed for" << info->thing()->name() << info->thing()->id() << reply->errorString() << reply->error();
|
||||||
|
emit info->finish(Thing::ThingErrorHardwareNotAvailable);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray data = reply->readAll();
|
||||||
|
|
||||||
|
QJsonParseError error;
|
||||||
|
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error);
|
||||||
|
if (error.error != QJsonParseError::NoError) {
|
||||||
|
qCWarning(dcPushNotifications()) << "Error reading reply from server for" << info->thing()->name() << info->thing()->id().toString() << error.errorString();
|
||||||
|
qCWarning(dcPushNotifications()) << qUtf8Printable(data);
|
||||||
|
info->finish(Thing::ThingErrorHardwareFailure);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariantMap replyMap = jsonDoc.toVariant().toMap();
|
||||||
|
// qDebug(dcPushNotifications) << qUtf8Printable(jsonDoc.toJson());
|
||||||
|
|
||||||
|
if (pushService == "FB-GCM" || pushService == "FB-APNs") {
|
||||||
|
if (replyMap.value("success").toInt() != 1) {
|
||||||
|
|
||||||
|
// While GCM seems rock solid, APNs fails rather often with Internal Server Error.
|
||||||
|
// According to Firebase support this is "expected" and one should retry with a exponential back-off timer.
|
||||||
|
// As we only have 30 secs until the info times out, let's try repeatedly until the info object dies.
|
||||||
|
// In my tests, so far it succeeded every time on the second attempt.
|
||||||
|
// https://stackoverflow.com/questions/63382257/firebase-messaging-fails-sporadically-with-internal-error
|
||||||
|
if (replyMap.value("results").toList().count() > 0 && replyMap.value("results").toList().first().toMap().value("error").toString() == "InternalServerError") {
|
||||||
|
qCDebug(dcPushNotifications()) << "Sending push message failed. Retrying...";
|
||||||
|
executeAction(info);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// On any other error, bail out...
|
||||||
|
qCWarning(dcPushNotifications()) << "Error sending push notification:" << qUtf8Printable(jsonDoc.toJson());
|
||||||
|
info->finish(Thing::ThingErrorHardwareFailure);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else if (pushService == "UBPorts") {
|
||||||
|
if (!replyMap.value("ok").toBool()) {
|
||||||
|
qCWarning(dcPushNotifications()) << "Error sending push notification:" << qUtf8Printable(jsonDoc.toJson());
|
||||||
|
info->finish(Thing::ThingErrorHardwareFailure);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
qCDebug(dcPushNotifications()) << "Message sent successfully";
|
||||||
|
info->finish(Thing::ThingErrorNoError);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
55
pushnotifications/integrationpluginpushnotifications.h
Normal file
55
pushnotifications/integrationpluginpushnotifications.h
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* Copyright 2013 - 2020, nymea GmbH
|
||||||
|
* Contact: contact@nymea.io
|
||||||
|
*
|
||||||
|
* This file is part of nymea.
|
||||||
|
* This project including source code and documentation is protected by
|
||||||
|
* copyright law, and remains the property of nymea GmbH. All rights, including
|
||||||
|
* reproduction, publication, editing and translation, are reserved. The use of
|
||||||
|
* this project is subject to the terms of a license agreement to be concluded
|
||||||
|
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
|
||||||
|
* under https://nymea.io/license
|
||||||
|
*
|
||||||
|
* GNU Lesser General Public License Usage
|
||||||
|
* Alternatively, this project may be redistributed and/or modified under the
|
||||||
|
* terms of the GNU Lesser General Public License as published by the Free
|
||||||
|
* Software Foundation; version 3. This project is distributed in the hope that
|
||||||
|
* it will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||||
|
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this project. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* For any further details and any questions please contact us under
|
||||||
|
* contact@nymea.io or see our FAQ/Licensing Information on
|
||||||
|
* https://nymea.io/license/faq
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
#ifndef INTEGRATIONPLUGINPUSHNOTIFICATIONS_H
|
||||||
|
#define INTEGRATIONPLUGINPUSHNOTIFICATIONS_H
|
||||||
|
|
||||||
|
#include "integrations/integrationplugin.h"
|
||||||
|
|
||||||
|
class IntegrationPluginPushNotifications: public IntegrationPlugin
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
Q_PLUGIN_METADATA(IID "io.nymea.IntegrationPlugin" FILE "integrationpluginpushnotifications.json")
|
||||||
|
Q_INTERFACES(IntegrationPlugin)
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit IntegrationPluginPushNotifications(QObject *parent = nullptr);
|
||||||
|
~IntegrationPluginPushNotifications() override;
|
||||||
|
|
||||||
|
void setupThing(ThingSetupInfo *info) override;
|
||||||
|
void executeAction(ThingActionInfo *info) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QHash<ThingClassId, ParamTypeId> m_tokenParamTypeIds;
|
||||||
|
QByteArray m_firebaseServerToken;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
68
pushnotifications/integrationpluginpushnotifications.json
Normal file
68
pushnotifications/integrationpluginpushnotifications.json
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
{
|
||||||
|
"displayName": "Push Notifications",
|
||||||
|
"name": "pushNotifications",
|
||||||
|
"id": "fdcea3b3-8d79-4fbb-8101-1ab45d71cedb",
|
||||||
|
"apiKeys": [ "firebase" ],
|
||||||
|
"vendors": [
|
||||||
|
{
|
||||||
|
"displayName": "nymea GmbH",
|
||||||
|
"name": "nymea",
|
||||||
|
"id": "2062d64d-3232-433c-88bc-0d33c0ba2ba6",
|
||||||
|
"thingClasses": [
|
||||||
|
{
|
||||||
|
"id": "f0dd4c03-0aca-42cc-8f34-9902457b05de",
|
||||||
|
"name": "pushNotifications",
|
||||||
|
"displayName": "Push Notifications",
|
||||||
|
"createMethods": ["user"],
|
||||||
|
"interfaces": ["notifications"],
|
||||||
|
"paramTypes": [
|
||||||
|
{
|
||||||
|
"id": "3cb8e30e-2ec5-4b4b-8c8c-03eaf7876839",
|
||||||
|
"name": "service",
|
||||||
|
"displayName": "Push service",
|
||||||
|
"type": "QString",
|
||||||
|
"allowedValues": ["FB-GCM", "FB-APNs", "UBPorts"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "12ec06b2-44e7-486a-9169-31c684b91c8f",
|
||||||
|
"name": "token",
|
||||||
|
"displayName": "access token",
|
||||||
|
"type": "QString"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "d76da367-64e3-4b7d-aa84-c96b3acfb65e",
|
||||||
|
"name": "clientId",
|
||||||
|
"displayName": "Client ID",
|
||||||
|
"type": "QString"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"actionTypes": [
|
||||||
|
{
|
||||||
|
"id": "ed9a0196-6c24-4e05-9cbc-c6834de38005",
|
||||||
|
"name": "notify",
|
||||||
|
"displayName": "notify",
|
||||||
|
"paramTypes": [
|
||||||
|
{
|
||||||
|
"id": "3b5e195c-9f96-4f2f-a654-f17ed77c02ee",
|
||||||
|
"name": "title",
|
||||||
|
"displayName": "title",
|
||||||
|
"type": "QString",
|
||||||
|
"inputType": "TextLine",
|
||||||
|
"defaultValue": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "074c4c7c-037f-45ac-ab2f-f7aea3f84bde",
|
||||||
|
"name": "body",
|
||||||
|
"displayName": "body",
|
||||||
|
"type": "QString",
|
||||||
|
"inputType": "TextArea",
|
||||||
|
"defaultValue": ""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
13
pushnotifications/pushnotifications.pro
Normal file
13
pushnotifications/pushnotifications.pro
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
include(../plugins.pri)
|
||||||
|
|
||||||
|
TARGET = $$qtLibraryTarget(nymea_integrationpluginpushnotifications)
|
||||||
|
|
||||||
|
QT+= network
|
||||||
|
|
||||||
|
SOURCES += \
|
||||||
|
integrationpluginpushnotifications.cpp
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
integrationpluginpushnotifications.h
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,72 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!DOCTYPE TS>
|
||||||
|
<TS version="2.1">
|
||||||
|
<context>
|
||||||
|
<name>IntegrationPluginPushNotifications</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../integrationpluginpushnotifications.cpp" line="71"/>
|
||||||
|
<source>The token must not be empty.</source>
|
||||||
|
<extracomment>Error setting up thing</extracomment>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../integrationpluginpushnotifications.cpp" line="76"/>
|
||||||
|
<source>The push service must not be empty.</source>
|
||||||
|
<extracomment>Error setting up thing</extracomment>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../integrationpluginpushnotifications.cpp" line="96"/>
|
||||||
|
<source>Push notifications need to be reconfigured.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>pushNotifications</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../../../build-nymea-plugins-Desktop-Debug/pushnotifications/plugininfo.h" line="28"/>
|
||||||
|
<location filename="../../../build-nymea-plugins-Desktop-Debug/pushnotifications/plugininfo.h" line="31"/>
|
||||||
|
<source>Push Notifications</source>
|
||||||
|
<extracomment>The name of the ThingClass ({f0dd4c03-0aca-42cc-8f34-9902457b05de})
|
||||||
|
----------
|
||||||
|
The name of the plugin pushNotifications ({fdcea3b3-8d79-4fbb-8101-1ab45d71cedb})</extracomment>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../../build-nymea-plugins-Desktop-Debug/pushnotifications/plugininfo.h" line="34"/>
|
||||||
|
<source>Push service</source>
|
||||||
|
<extracomment>The name of the ParamType (ThingClass: pushNotifications, Type: thing, ID: {3cb8e30e-2ec5-4b4b-8c8c-03eaf7876839})</extracomment>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../../build-nymea-plugins-Desktop-Debug/pushnotifications/plugininfo.h" line="37"/>
|
||||||
|
<source>access token</source>
|
||||||
|
<extracomment>The name of the ParamType (ThingClass: pushNotifications, Type: thing, ID: {12ec06b2-44e7-486a-9169-31c684b91c8f})</extracomment>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../../build-nymea-plugins-Desktop-Debug/pushnotifications/plugininfo.h" line="40"/>
|
||||||
|
<source>body</source>
|
||||||
|
<extracomment>The name of the ParamType (ThingClass: pushNotifications, ActionType: notify, ID: {074c4c7c-037f-45ac-ab2f-f7aea3f84bde})</extracomment>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../../build-nymea-plugins-Desktop-Debug/pushnotifications/plugininfo.h" line="43"/>
|
||||||
|
<source>notify</source>
|
||||||
|
<extracomment>The name of the ActionType ({ed9a0196-6c24-4e05-9cbc-c6834de38005}) of ThingClass pushNotifications</extracomment>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../../build-nymea-plugins-Desktop-Debug/pushnotifications/plugininfo.h" line="46"/>
|
||||||
|
<source>nymea GmbH</source>
|
||||||
|
<extracomment>The name of the vendor ({2062d64d-3232-433c-88bc-0d33c0ba2ba6})</extracomment>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../../build-nymea-plugins-Desktop-Debug/pushnotifications/plugininfo.h" line="49"/>
|
||||||
|
<source>title</source>
|
||||||
|
<extracomment>The name of the ParamType (ThingClass: pushNotifications, ActionType: notify, ID: {3b5e195c-9f96-4f2f-a654-f17ed77c02ee})</extracomment>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
</TS>
|
||||||
@ -0,0 +1,72 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!DOCTYPE TS>
|
||||||
|
<TS version="2.1">
|
||||||
|
<context>
|
||||||
|
<name>IntegrationPluginPushNotifications</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../integrationpluginpushnotifications.cpp" line="71"/>
|
||||||
|
<source>The token must not be empty.</source>
|
||||||
|
<extracomment>Error setting up thing</extracomment>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../integrationpluginpushnotifications.cpp" line="76"/>
|
||||||
|
<source>The push service must not be empty.</source>
|
||||||
|
<extracomment>Error setting up thing</extracomment>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../integrationpluginpushnotifications.cpp" line="96"/>
|
||||||
|
<source>Push notifications need to be reconfigured.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>pushNotifications</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../../../build-nymea-plugins-Desktop-Debug/pushnotifications/plugininfo.h" line="28"/>
|
||||||
|
<location filename="../../../build-nymea-plugins-Desktop-Debug/pushnotifications/plugininfo.h" line="31"/>
|
||||||
|
<source>Push Notifications</source>
|
||||||
|
<extracomment>The name of the ThingClass ({f0dd4c03-0aca-42cc-8f34-9902457b05de})
|
||||||
|
----------
|
||||||
|
The name of the plugin pushNotifications ({fdcea3b3-8d79-4fbb-8101-1ab45d71cedb})</extracomment>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../../build-nymea-plugins-Desktop-Debug/pushnotifications/plugininfo.h" line="34"/>
|
||||||
|
<source>Push service</source>
|
||||||
|
<extracomment>The name of the ParamType (ThingClass: pushNotifications, Type: thing, ID: {3cb8e30e-2ec5-4b4b-8c8c-03eaf7876839})</extracomment>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../../build-nymea-plugins-Desktop-Debug/pushnotifications/plugininfo.h" line="37"/>
|
||||||
|
<source>access token</source>
|
||||||
|
<extracomment>The name of the ParamType (ThingClass: pushNotifications, Type: thing, ID: {12ec06b2-44e7-486a-9169-31c684b91c8f})</extracomment>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../../build-nymea-plugins-Desktop-Debug/pushnotifications/plugininfo.h" line="40"/>
|
||||||
|
<source>body</source>
|
||||||
|
<extracomment>The name of the ParamType (ThingClass: pushNotifications, ActionType: notify, ID: {074c4c7c-037f-45ac-ab2f-f7aea3f84bde})</extracomment>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../../build-nymea-plugins-Desktop-Debug/pushnotifications/plugininfo.h" line="43"/>
|
||||||
|
<source>notify</source>
|
||||||
|
<extracomment>The name of the ActionType ({ed9a0196-6c24-4e05-9cbc-c6834de38005}) of ThingClass pushNotifications</extracomment>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../../build-nymea-plugins-Desktop-Debug/pushnotifications/plugininfo.h" line="46"/>
|
||||||
|
<source>nymea GmbH</source>
|
||||||
|
<extracomment>The name of the vendor ({2062d64d-3232-433c-88bc-0d33c0ba2ba6})</extracomment>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../../build-nymea-plugins-Desktop-Debug/pushnotifications/plugininfo.h" line="49"/>
|
||||||
|
<source>title</source>
|
||||||
|
<extracomment>The name of the ParamType (ThingClass: pushNotifications, ActionType: notify, ID: {3b5e195c-9f96-4f2f-a654-f17ed77c02ee})</extracomment>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
</TS>
|
||||||
Loading…
x
Reference in New Issue
Block a user