first commit
This commit is contained in:
commit
ced1e97857
8
.gitignore
vendored
Normal file
8
.gitignore
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
.DS_Store
|
||||||
|
|
||||||
|
# Generated by package manager
|
||||||
|
#node_modules/
|
||||||
|
|
||||||
|
# Generated by Cordova
|
||||||
|
#/plugins/
|
||||||
|
/platforms/
|
12
README.md
Normal file
12
README.md
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
sixtyfour (The App)
|
||||||
|
==============
|
||||||
|
A messaging bridge between Matrix and 8x8 utilizing Android's Notification intents and a [maubot plugin](https://git.umycode.com/dave/maubot-sixtyfour)
|
||||||
|
|
||||||
|
WARNING: This is a total hack. Consider it a proof of concept rather than a production ready app
|
||||||
|
|
||||||
|
You will need to set up a project for Google Cloud Messaging to make this work ([more information](https://cloud.ibm.com/docs/mobilepush?topic=mobilepush-push_step_1))
|
||||||
|
|
||||||
|
License
|
||||||
|
------------
|
||||||
|
|
||||||
|
Some of the code I borrowed specifies their own copy license. For any other code assume it falls under [WTFPL](http://www.wtfpl.net/txt/copying/)
|
31
config.xml
Normal file
31
config.xml
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<?xml version='1.0' encoding='utf-8'?>
|
||||||
|
<widget id="com.umycode.sixtyfour" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
|
||||||
|
<name>SixtyFour</name>
|
||||||
|
<description>
|
||||||
|
8x8 to Matrix bridge
|
||||||
|
</description>
|
||||||
|
<author email="dave@umycode.com" href="http://cordova.io">
|
||||||
|
Dave Umrysh
|
||||||
|
</author>
|
||||||
|
<content src="index.html" />
|
||||||
|
<access origin="*" />
|
||||||
|
<allow-intent href="http://*/*" />
|
||||||
|
<allow-intent href="https://*/*" />
|
||||||
|
<allow-intent href="tel:*" />
|
||||||
|
<allow-intent href="sms:*" />
|
||||||
|
<allow-intent href="mailto:*" />
|
||||||
|
<allow-intent href="geo:*" />
|
||||||
|
<platform name="android">
|
||||||
|
<allow-intent href="market:*" />
|
||||||
|
<resource-file src="google-services.json" target="/app/google-services.json" />
|
||||||
|
</platform>
|
||||||
|
<platform name="ios">
|
||||||
|
<allow-intent href="itms:*" />
|
||||||
|
<allow-intent href="itms-apps:*" />
|
||||||
|
</platform>
|
||||||
|
<plugin name="cordova-plugin-reply-to-notification" spec="git+https://git.umycode.com/dave/cordova-plugin-reply-to-notification.git" />
|
||||||
|
<plugin name="cordova-plugin-background-mode" spec="git+https://git.umycode.com/dave/cordova-plugin-run-in-background.git" />
|
||||||
|
<plugin name="phonegap-plugin-push" spec="2.3.0" />
|
||||||
|
<plugin name="cordova-plugin-device" spec="2.0.3" />
|
||||||
|
<plugin name="cordova-plugin-whitelist" spec="1.3.4" />
|
||||||
|
</widget>
|
41
package.json
Normal file
41
package.json
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
{
|
||||||
|
"name": "com.umycode.sixtyfour",
|
||||||
|
"displayName": "SixtyFour",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "An app that bridges 8x8 and Matrix",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"ecosystem:cordova"
|
||||||
|
],
|
||||||
|
"author": "Apache Cordova Team",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"devDependencies": {
|
||||||
|
"cordova-android": "^9.0.0",
|
||||||
|
"cordova-plugin-background-mode": "git+https://git.umycode.com/dave/cordova-plugin-run-in-background.git",
|
||||||
|
"cordova-plugin-device": "^2.0.3",
|
||||||
|
"cordova-plugin-whitelist": "^1.3.4",
|
||||||
|
"cordova-support-google-services": "^1.3.2",
|
||||||
|
"phonegap-plugin-multidex": "^1.0.0",
|
||||||
|
"phonegap-plugin-push": "^2.3.0",
|
||||||
|
"cordova-plugin-reply-to-notification": "git+https://git.umycode.com/dave/cordova-plugin-reply-to-notification.git"
|
||||||
|
},
|
||||||
|
"cordova": {
|
||||||
|
"plugins": {
|
||||||
|
"cordova-plugin-whitelist": {},
|
||||||
|
"cordova-plugin-background-mode": {},
|
||||||
|
"phonegap-plugin-push": {
|
||||||
|
"ANDROID_SUPPORT_V13_VERSION": "27.+",
|
||||||
|
"FCM_VERSION": "17.0.+"
|
||||||
|
},
|
||||||
|
"cordova-plugin-device": {},
|
||||||
|
"cordova-plugin-reply-to-notification": {}
|
||||||
|
},
|
||||||
|
"platforms": [
|
||||||
|
"android"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"dependencies": {}
|
||||||
|
}
|
110
www/css/index.css
Normal file
110
www/css/index.css
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
* {
|
||||||
|
-webkit-tap-highlight-color: rgba(0,0,0,0); /* make transparent link selection, adjust last value opacity 0 to 1.0 */
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
-webkit-touch-callout: none; /* prevent callout to copy image, etc when tap to hold */
|
||||||
|
-webkit-text-size-adjust: none; /* prevent webkit from resizing text to fit */
|
||||||
|
-webkit-user-select: none; /* prevent copy paste, to allow, change 'none' to 'text' */
|
||||||
|
background-color:#E4E4E4;
|
||||||
|
background-image:linear-gradient(to bottom, #A7A7A7 0%, #E4E4E4 51%);
|
||||||
|
font-family: system-ui, -apple-system, -apple-system-font, 'Segoe UI', 'Roboto', sans-serif;
|
||||||
|
font-size:12px;
|
||||||
|
height:100vh;
|
||||||
|
margin:0px;
|
||||||
|
padding:0px;
|
||||||
|
/* Padding to avoid the "unsafe" areas behind notches in the screen */
|
||||||
|
padding: env(safe-area-inset-top, 0px) env(safe-area-inset-right, 0px) env(safe-area-inset-bottom, 0px) env(safe-area-inset-left, 0px);
|
||||||
|
text-transform:uppercase;
|
||||||
|
width:100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Portrait layout (default) */
|
||||||
|
.app {
|
||||||
|
background:url(../img/logo.png) no-repeat center top; /* 170px x 200px */
|
||||||
|
position:absolute; /* position in the center of the screen */
|
||||||
|
left:50%;
|
||||||
|
top:50%;
|
||||||
|
height:50px; /* text area height */
|
||||||
|
width:225px; /* text area width */
|
||||||
|
text-align:center;
|
||||||
|
padding:180px 0px 0px 0px; /* image height is 200px (bottom 20px are overlapped with text) */
|
||||||
|
margin:-115px 0px 0px -112px; /* offset vertical: half of image height and text area height */
|
||||||
|
/* offset horizontal: half of text area width */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Landscape layout (with min-width) */
|
||||||
|
@media screen and (min-aspect-ratio: 1/1) and (min-width:400px) {
|
||||||
|
.app {
|
||||||
|
background-position:left center;
|
||||||
|
padding:75px 0px 75px 170px; /* padding-top + padding-bottom + text area = image height */
|
||||||
|
margin:-90px 0px 0px -198px; /* offset vertical: half of image height */
|
||||||
|
/* offset horizontal: half of image width and text area width */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size:24px;
|
||||||
|
font-weight:normal;
|
||||||
|
margin:0px;
|
||||||
|
overflow:visible;
|
||||||
|
padding:0px;
|
||||||
|
text-align:center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.event {
|
||||||
|
border-radius:4px;
|
||||||
|
color:#FFFFFF;
|
||||||
|
font-size:12px;
|
||||||
|
margin:0px 30px;
|
||||||
|
padding:2px 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.event.listening {
|
||||||
|
background-color:#333333;
|
||||||
|
display:block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.event.received {
|
||||||
|
background-color:#4B946A;
|
||||||
|
display:none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#deviceready.ready .event.listening { display: none; }
|
||||||
|
#deviceready.ready .event.received { display: block; }
|
||||||
|
|
||||||
|
@keyframes fade {
|
||||||
|
from { opacity: 1.0; }
|
||||||
|
50% { opacity: 0.4; }
|
||||||
|
to { opacity: 1.0; }
|
||||||
|
}
|
||||||
|
|
||||||
|
.blink {
|
||||||
|
animation:fade 3000ms infinite;
|
||||||
|
-webkit-animation:fade 3000ms infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@media screen and (prefers-color-scheme: dark) {
|
||||||
|
body {
|
||||||
|
background-image:linear-gradient(to bottom, #585858 0%, #1B1B1B 51%);
|
||||||
|
}
|
||||||
|
}
|
BIN
www/img/logo.png
Normal file
BIN
www/img/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 21 KiB |
24
www/index.html
Normal file
24
www/index.html
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="Content-Security-Policy" content="default-src 'self' data: blob: gap://ready file://* cdvfile://* *; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'">
|
||||||
|
<meta name="format-detection" content="telephone=no">
|
||||||
|
<meta name="msapplication-tap-highlight" content="no">
|
||||||
|
<meta name="viewport" content="initial-scale=1, width=device-width, viewport-fit=cover">
|
||||||
|
<meta name="color-scheme" content="light dark">
|
||||||
|
<link rel="stylesheet" href="css/index.css">
|
||||||
|
<title>sixyfour</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="app">
|
||||||
|
<h1>SixyFour</h1>
|
||||||
|
<div id="deviceready" class="blink">
|
||||||
|
<p class="event listening">Connecting to Device</p>
|
||||||
|
<p class="event received">Device is Ready</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script src="cordova.js"></script>
|
||||||
|
<script src="js/index.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
176
www/js/index.js
Normal file
176
www/js/index.js
Normal file
@ -0,0 +1,176 @@
|
|||||||
|
var my_8x8_name = "Dave Umrysh";
|
||||||
|
var hostUrl = "https://matrix.example.com"; // Location of your Matrix server
|
||||||
|
var webhook_secret = "UGfmxJyv49Sus2Y32dE7juXYMvp"; // Random key you set in your sixtyfour matrix bot
|
||||||
|
var instance_name = "sixtyfourinstance";
|
||||||
|
|
||||||
|
var android_id = "";
|
||||||
|
var devicePlatform = "";
|
||||||
|
|
||||||
|
document.addEventListener('deviceready', onDeviceReady, false);
|
||||||
|
|
||||||
|
function onDeviceReady() {
|
||||||
|
// Cordova is now initialized. Have fun!
|
||||||
|
|
||||||
|
console.log('Running cordova-' + cordova.platformId + '@' + cordova.version);
|
||||||
|
document.getElementById('deviceready').classList.add('ready');
|
||||||
|
|
||||||
|
|
||||||
|
android_id = device.uuid;
|
||||||
|
devicePlatform = device.platform;
|
||||||
|
|
||||||
|
cordova.plugins.backgroundMode.on('activate', function() {
|
||||||
|
cordova.plugins.backgroundMode.disableWebViewOptimizations();
|
||||||
|
});
|
||||||
|
cordova.plugins.backgroundMode.enable();
|
||||||
|
cordova.plugins.backgroundMode.disableBatteryOptimizations();
|
||||||
|
|
||||||
|
// Set up the GCM
|
||||||
|
setUpGCM();
|
||||||
|
|
||||||
|
startListening();
|
||||||
|
}
|
||||||
|
|
||||||
|
function startListening(){
|
||||||
|
|
||||||
|
replyToNotification.listen(function(n){
|
||||||
|
console.log("Received notification " + JSON.stringify(n) );
|
||||||
|
|
||||||
|
if(n.package == "org.vom8x8.sipua"){
|
||||||
|
// Check for rooms
|
||||||
|
if(n.title == my_8x8_name){
|
||||||
|
// This was my message out
|
||||||
|
// Post to the bot channel
|
||||||
|
var who_sent_it = n.title.replaceAll("\r\n","").replaceAll("\r","").replaceAll("\n","").replaceAll('"','\"');
|
||||||
|
var params = JSON.stringify({ "secret": webhook_secret, "message": "**"+who_sent_it+"**: "+n.text.replaceAll("\r\n","").replaceAll("\r","").replaceAll("\n","").replaceAll('"','\"') });
|
||||||
|
postToMatrix(hostUrl+"/_matrix/maubot/plugin/"+instance_name+"/webhook/r0?room=%21aaaaaaaaaaaaaaaaaa:matrix.example.com",params);
|
||||||
|
}else if(n.title == "John Smith"){
|
||||||
|
var who_sent_it = n.title.replaceAll("\r\n","").replaceAll("\r","").replaceAll("\n","").replaceAll('"','\"');
|
||||||
|
var params = JSON.stringify({ "secret": webhook_secret, "message": "**"+who_sent_it+"**: "+n.text.replaceAll("\r\n","").replaceAll("\r","").replaceAll("\n","").replaceAll('"','\"') });
|
||||||
|
postToMatrix(hostUrl+"/_matrix/maubot/plugin/"+instance_name+"/webhook/r0?room=%21bbbbbbbbbbbbbbbbbb:matrix.example.com",params);
|
||||||
|
|
||||||
|
|
||||||
|
// Add other DM rooms here
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}else if(n.conversationTitle == "Room #1"){
|
||||||
|
var who_sent_it = n.title.replaceAll("Room #1: ","").replaceAll("\r\n","").replaceAll("\r","").replaceAll("\n","").replaceAll('"','\"');
|
||||||
|
var params = JSON.stringify({ "secret": webhook_secret, "message": "**"+who_sent_it+"**: "+n.text.replaceAll("\r\n","").replaceAll("\r","").replaceAll("\n","").replaceAll('"','\"') });
|
||||||
|
postToMatrix(hostUrl+"/_matrix/maubot/plugin/"+instance_name+"/webhook/r0?room=%21ccccccccccccccccc:matrix.example.com",params);
|
||||||
|
|
||||||
|
|
||||||
|
// Add other rooms here
|
||||||
|
|
||||||
|
|
||||||
|
}else{
|
||||||
|
var who_sent_it = n.title.replaceAll("All Company: ","").replaceAll("\r\n","").replaceAll("\r","").replaceAll("\n","").replaceAll('"','\"');
|
||||||
|
var params = JSON.stringify({ "secret": webhook_secret, "message": "**"+who_sent_it+"**: "+n.text.replaceAll("\r\n","").replaceAll("\r","").replaceAll("\n","").replaceAll('"','\"') });
|
||||||
|
postToMatrix(hostUrl+"/_matrix/maubot/plugin/"+instance_name+"/webhook/r0?room=%21dddddddddddddddd:matrix.example.com",params);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}, function(e){
|
||||||
|
console.log("Notification Error " + e);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function postTo8x8(room,message){
|
||||||
|
var room_name = "";
|
||||||
|
|
||||||
|
if(room == "!bbbbbbbbbbbbbbbbbb:matrix.example.com"){
|
||||||
|
room_name = "John Smith";
|
||||||
|
|
||||||
|
// Add other DM rooms here
|
||||||
|
|
||||||
|
|
||||||
|
}else if(room == "!ccccccccccccccccc:matrix.example.com"){
|
||||||
|
room_name = "Room #1";
|
||||||
|
|
||||||
|
|
||||||
|
// Add other rooms here
|
||||||
|
|
||||||
|
|
||||||
|
}else if(room == "!dddddddddddddddd:matrix.example.com"){
|
||||||
|
room_name = "All Company";
|
||||||
|
}
|
||||||
|
|
||||||
|
if(room_name != ""){
|
||||||
|
var temp = {
|
||||||
|
"room_name":room_name,
|
||||||
|
"message":message
|
||||||
|
};
|
||||||
|
replyToNotification.replytonotification(temp, function (s) {
|
||||||
|
// Send errors to the bot channel
|
||||||
|
console.log(s);
|
||||||
|
|
||||||
|
var params = JSON.stringify({ "secret": webhook_secret, "message": "**8x8 Error**: "+s.replaceAll("\r\n","").replaceAll("\r","").replaceAll("\n","").replaceAll('"','\"') });
|
||||||
|
postToMatrix(hostUrl+"/_matrix/maubot/plugin/"+instance_name+"/webhook/r0?room=%21aaaaaaaaaaaaaaaaaa:matrix.example.com",params);
|
||||||
|
}, function (e) {
|
||||||
|
console.log(e);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function postToMatrix(url,message){
|
||||||
|
var http = new XMLHttpRequest();
|
||||||
|
http.open("POST", url, true);
|
||||||
|
//Send the proper header information along with the request
|
||||||
|
http.setRequestHeader("Content-type", "application/json");
|
||||||
|
|
||||||
|
//http.onreadystatechange = function() {
|
||||||
|
// console.log(http.status+"|"+http.responseText);
|
||||||
|
//};
|
||||||
|
|
||||||
|
http.send(message);
|
||||||
|
console.log("sent message to matrix")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function setUpGCM(){
|
||||||
|
if(typeof device !== 'undefined'){
|
||||||
|
pushNotification = PushNotification.init({
|
||||||
|
android: {},
|
||||||
|
ios: {
|
||||||
|
alert: "true",
|
||||||
|
badge: "true",
|
||||||
|
sound: "true",
|
||||||
|
clearBadge: "true"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
pushNotification.on('registration', function(data) {
|
||||||
|
window.localStorage.setItem("gcm_key", data.registrationId);
|
||||||
|
// Try to send it off
|
||||||
|
sendGCMtoServer();
|
||||||
|
});
|
||||||
|
|
||||||
|
pushNotification.on('notification', function(data) {
|
||||||
|
// data.message,
|
||||||
|
// data.title,
|
||||||
|
// data.count,
|
||||||
|
// data.sound,
|
||||||
|
// data.image,
|
||||||
|
// data.additionalData
|
||||||
|
postTo8x8(data.title,data.message);
|
||||||
|
});
|
||||||
|
|
||||||
|
pushNotification.on('error', function(e) {
|
||||||
|
console.log("error: "+e.message);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function sendGCMtoServer(){
|
||||||
|
var gcm_key = window.localStorage.getItem("gcm_key");
|
||||||
|
|
||||||
|
if(gcm_key == null || gcm_key == ""){
|
||||||
|
setUpGCM();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(gcm_key != null && gcm_key != ""){
|
||||||
|
// Send to server
|
||||||
|
var params = JSON.stringify({ "secret": webhook_secret, "gcm": gcm_key });
|
||||||
|
postToMatrix(hostUrl+"/_matrix/maubot/plugin/"+instance_name+"/webhook/r1?gcm",params);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user