Skip to content

Commit

Permalink
Merge pull request #85 from IMHarris/master
Browse files Browse the repository at this point in the history
master
  • Loading branch information
Dan-in-CA authored Jul 12, 2024
2 parents 97a3c3b + e7916cf commit e3cdb5f
Show file tree
Hide file tree
Showing 4 changed files with 1,208 additions and 0 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,11 @@ sms_plivo
Allows plugins that are configured to this messaging framework to send SMS and voice messages through the [Plivo](https://www.plivo.com) service.
Requires Python 3 and a Plivo account.

sms_twilio
----------
Allows plugins to send SMS and voice messages through the [Twilio](https://www.twilio.com) service.
Requires Python 3 and a Twilio account.

ssd1306
----------
Plugin for SSD1306 128x64 pixel display connected to I2C interface.
Expand Down
295 changes: 295 additions & 0 deletions sms_twilio/sms_twilio.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,295 @@
$def with(settings, runtime_values)

$var title: $_(u'SIP SMS Twilio Plugin')
$var page: sms_twilio_plugin
<script>

// Initialize behaviors
jQuery(document).ready(function(){

jQuery("#cSubmit").click(function() {
jQuery("#pluginForm").submit();
});
jQuery("button#cCancel").click(function(){
window.location="/";
});
jQuery("button#docButton").click(function(){
window.open("https://github.com/IMHarris/SIP_plugins/wiki/Twilio-SMS", "_blank");
});
});
</script>

<div id="plugin">
<div class="title">Twilio Notifications
<button class="execute" id="docButton" type="button" >$_(u'Help')</button>
</div>

<p>Enable Notifications</p>
<form id="pluginForm" action="${'/sms-twilio-save'}" method="get">

$if not runtime_values["sms-enabled"] and not runtime_values["voice-enabled"]:
</br> </br>
<p>ENABLE_SMS or ENABLE_VOICE must be set as True in sms_twilio.py to enable notifications in this plugin</p>
</br> </br>
<table class="optionList">

<thead>
</thead>
$if runtime_values["sms-enabled"]:
<tr>
<td style='text-transform: none;'>SMS:</td>
<td><input type="checkbox" name="check-sms" id="check-sms" ${"checked" if 'check-sms' in settings else ""}></td>
</tr>
$if runtime_values["voice-enabled"]:
<tr>
<td style='text-transform: none;'>Voice:</td>
<td><input type="checkbox" name="check-voice" id="check-voice" ${"checked" if 'check-voice' in settings else ""}></td>
</tr>

</table></br>

<p>Outgoing Phone Numbers</p>
<table class="optionList">

$if runtime_values["sms-enabled"]:
<tr>
<td style='text-transform: none;'><div id="lbl-sms">SMS:</div></td>
<td><input type="text" name="text-sms-phone" id="text-sms-phone" value="${settings['text-sms-phone'] if 'text-sms-phone' in settings else '' }"></td>
<td> <button type="button" id="btn-test-sms">Test</button></td>
</tr>
$if runtime_values["voice-enabled"]:
<tr>
<td style='text-transform: none;'><div id="lbl-voice">Voice:</div></td>
<td><input type="text" name="text-voice-phone" id="text-voice-phone" value="${settings['text-voice-phone'] if 'text-voice-phone' in settings else ''}"></td>
<td> <button type="button" id="btn-test-voice">Test</button></td>
</tr>
<tr>
<td style='...'><div id="lbl-status">Status:</div></td>
<td colspan="2">
<textarea id="text-status" style="font-family: monospace;" rows="2" cols="35" readonly></textarea>
</td>
</tr>
</table>
<p style='font-size: 0.9em;'>format +15555555555,+15555555555</p></br></br>

<p>Account Setup</p>
<table class="optionList">

<tr>
<td style='text-transform: none;'><div id="lbl-account">Account ID:</div></td>
<td><input type="text" name="text-account-id" id="text-account-id" value="${settings['text-account-id'] if 'text-account-id' in settings else '' }"></td>
</tr>

<tr>
<td style='text-transform: none;'><div id="lbl-auth-token">Auth Token:</div></td>
<td><input type="password" name="text-auth-token" id="text-auth-token" value="${settings['text-auth-token'] if 'text-auth-token' in settings else '' }"></td>
</tr>

<tr>
<td style='text-transform: none;'><div id="lbl-twilio-number">Twilio Number:</div></td>
<td><input type="text" name="text-twilio-number" id="text-twilio-number" value="${settings['text-twilio-number'] if 'text-twilio-number' in settings else '' }"></td>
</tr>

<tr>
<td>
<button type="button" id="btn-validate-credentials">Validate Credentials</button>
</td>

$if runtime_values["voice-enabled"]:
<td> <button type="button" id="btn-create-flow-id">Create/Update Flow</button></td>
</tr>
<tr>
<td style='...'><div id="lbl-status2">Status:</div></td>
<td colspan="2">
<textarea id="text-status2" style="font-family: monospace;" rows="2" cols="35" readonly></textarea>
</td>
</tr>

</table><br>

Pause messaging <input type="checkbox" name="pause-messaging" id="pause-messaging" ${"checked" if 'pause-messaging' in settings else ""}>
<br><br>
</form>

<div class="controls">
<button id="cSubmit" class="submit"><b>$_(u'Submit')</b></button>
<button id="cCancel" class="cancel danger">$_(u'Cancel')</button>
</div>
</div>

<script>
var request = new XMLHttpRequest();
var href = window.location.href;
var apiURL = href.substr(0, href.lastIndexOf("/") + 1) + "sms-twilio-test";
var credentials_validated = false;
var phone_validated = false;
//console.log(myJavascriptVar);

//var myJSONVar = JSON.parse(myJavascriptVar)
//console.log(myJSONVar.sms-enabled);

request.onreadystatechange = function() {
//function called when XHR data is loaded
if (this.readyState == 4 && this.status == 200) {
//let responseText = this.responseText;
let responseJSON = JSON.parse(this.responseText);
if (responseJSON.type === 'ValidateCredentials' || responseJSON.type === 'CreateFlowID') {
document.getElementById("text-status2").textContent = responseJSON.msg;
} else {
document.getElementById("text-status").textContent = responseJSON.msg;
}
}
}
$if runtime_values["sms-enabled"]:
document.getElementById("check-sms").addEventListener("change", fnSMSEnabledChange);
document.getElementById("btn-test-sms").addEventListener("click", fnTestSMS);
txtVariance = getComputedStyle(document.getElementById("text-sms-phone")).getPropertyValue("color");
rgbaTxtVariance = txtVariance.match(/[\d.]+/g);
// If alpha is not there, add it:
if (rgbaTxtVariance.length === 3) {
rgbaTxtVariance.push(1);
}
lblVariance = getComputedStyle(document.getElementById("lbl-sms")).getPropertyValue("color");
rgbaLblVariance = lblVariance.match(/[\d.]+/g);
// If alpha is not there, add it:
if (rgbaLblVariance.length === 3) {
rgbaLblVariance.push(1);
}
fnSMSEnabledChange();
function fnSMSEnabledChange() {
// enable or disable the phone text box based on enable checkbox
let sms_enabled = document.getElementById("check-sms").checked;
document.getElementById("text-sms-phone").disabled = !sms_enabled;
document.getElementById("btn-test-sms").disabled = !sms_enabled;
document.getElementById("text-status").disabled = !sms_enabled;
if (sms_enabled) {
document.getElementById("text-sms-phone").style.color = "rgba(" + rgbaTxtVariance + ")";
document.getElementById("lbl-sms").style.color = "rgba(" + rgbaLblVariance + ")";
document.getElementById("lbl-status").style.color = "rgba(" + rgbaLblVariance + ")";
} else {
document.getElementById("text-sms-phone").style.color = "rgba(0,0,0,0.2)";
document.getElementById("lbl-sms").style.color = "rgba(0,0,0,0.2)";
if (document.getElementById("check-voice")) {
let voice_enabled = document.getElementById("check-voice").checked
document.getElementById("text-status").disabled = !voice_enabled;
if (voice_enabled) {
document.getElementById("lbl-status").style.color = "rgba(" + rgbaLblVariance + ")";
} else {
document.getElementById("lbl-status").style.color = "rgba(0,0,0,0.2)";
}
} else {
document.getElementById("lbl-status").style.color = "rgba(0,0,0,0.2)";
}
}
}

function fnTestSMS() {
// send an SMS test message
document.getElementById("text-status").textContent = "Waiting for response..."
request.open('POST', apiURL, true);
pkg = JSON.parse('{}');
pkg['type'] = 'SMS';
pkg['dest'] = document.getElementById("text-sms-phone").value;
pkg['acct'] = document.getElementById("text-account-id").value;
pkg['auth'] = document.getElementById("text-auth-token").value;
pkg['twilio-num'] = document.getElementById("text-twilio-number").value;
request.send(JSON.stringify((pkg)));
}
$if runtime_values["voice-enabled"]:
document.getElementById("check-voice").addEventListener("change", fnVoiceEnabledChange);
document.getElementById("btn-test-voice").addEventListener("click", fnTestVoice);
document.getElementById("btn-validate-credentials").addEventListener("click", fnValidateCredentials);
document.getElementById("btn-create-flow-id").addEventListener("click", fnCreateFlowID);
txtVariance = getComputedStyle(document.getElementById("text-voice-phone")).getPropertyValue("color");
rgbaTxtVariance = txtVariance.match(/[\d.]+/g);
// If alpha is not there, add it:
if (rgbaTxtVariance.length === 3) {
rgbaTxtVariance.push(1);
}
lblVariance = getComputedStyle(document.getElementById("lbl-voice")).getPropertyValue("color");
rgbaLblVariance = lblVariance.match(/[\d.]+/g);
// If alpha is not there, add it:
if (rgbaLblVariance.length === 3) {
rgbaLblVariance.push(1);
}
fnVoiceEnabledChange();
function fnVoiceEnabledChange() {
// enable or disable the voice text box based on enable checkbox
let voice_enabled = document.getElementById("check-voice").checked;
document.getElementById("text-voice-phone").disabled = !voice_enabled;
document.getElementById("btn-test-voice").disabled = !voice_enabled;
document.getElementById("btn-create-flow-id").disabled = !voice_enabled;
document.getElementById("text-status").disabled = !voice_enabled;
if (voice_enabled) {
document.getElementById("text-voice-phone").style.color = "rgba(" + rgbaTxtVariance + ")";
document.getElementById("lbl-voice").style.color = "rgba(" + rgbaLblVariance + ")";
document.getElementById("lbl-status").style.color = "rgba(" + rgbaLblVariance + ")";
} else {
document.getElementById("text-voice-phone").style.color = "rgba(0,0,0,0.2)";
document.getElementById("lbl-voice").style.color = "rgba(0,0,0,0.2)";
document.getElementById("btn-create-flow-id").disabled = true;
if (document.getElementById("check-sms")) {
let sms_enabled = document.getElementById("check-sms").checked;
document.getElementById("text-status").disabled = !sms_enabled;
if (sms_enabled) {
document.getElementById("lbl-status").style.color = "rgba(" + rgbaTxtVariance + ")";
} else {
document.getElementById("lbl-status").style.color = "rgba(0,0,0,0.2)";
}
} else {
document.getElementById("lbl-status").style.color = "rgba(0,0,0,0.2)";
}
}
}
function fnTestVoice() {
// send an SMS test message
document.getElementById("text-status").textContent = "Waiting for response..."
request.open('POST', apiURL, true);
pkg = JSON.parse('{}');
pkg['type'] = 'Voice';
pkg['dest'] = document.getElementById("text-voice-phone").value;
pkg['acct'] = document.getElementById("text-account-id").value;
pkg['auth'] = document.getElementById("text-auth-token").value;
pkg['twilio-num'] = document.getElementById("text-twilio-number").value;
request.send(JSON.stringify((pkg)));
}
function fnCreateFlowID() {
// create a studio flow on the user's Twilio account
document.getElementById("text-status2").textContent = "Waiting for response..."
request.open('POST', apiURL, true);
pkg = JSON.parse('{}');
pkg['type'] = 'CreateFlowID'
pkg['acct'] = document.getElementById("text-account-id").value;
pkg['auth'] = document.getElementById("text-auth-token").value;
pkg['twilio-num'] = document.getElementById("text-twilio-number").value;
request.send(JSON.stringify((pkg)));
}
function fnValidateCredentials() {
// Validate twilio credentials
console.log("got to validate credentials");
document.getElementById("text-status2").textContent = "Waiting for response...";
request.open('POST', apiURL, true);
pkg = JSON.parse('{}');
pkg['type'] = 'ValidateCredentials';
pkg['acct'] = document.getElementById("text-account-id").value;
pkg['auth'] = document.getElementById("text-auth-token").value;
pkg['twilio-num'] = document.getElementById("text-twilio-number").value;
if (document.getElementById("check-sms")) {
pkg['sms'] = document.getElementById('check-sms').checked;
} else {
pkg['sms'] = false;
}
if (document.getElementById("check-voice")) {
pkg['voice'] = document.getElementById('check-voice').checked;
} else {
pkg['voice'] = false;
}
if ((pkg['sms'] || pkg['voice'])) {
request.send(JSON.stringify((pkg)));
} else {
document.getElementById("text-status2").textContent = "Please enable notifications above."
}

}

</script>
14 changes: 14 additions & 0 deletions sms_twilio/sms_twilio.manifest
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
Description: Support messaging using Twilio.com service.
Copyright 2024
Author: Ian Harris
Email: ianmarcharris@gmail.com
License: GNU GPL 3.0
revision: 1.0

Requirements: Python 3.7

##### List all plugin files below preceded by a blank line [file_name.ext path] relative to SIP directory #####

sms_twilio.py plugins
sms_twilio.html templates
sms_twilio.json data (generated)
Loading

0 comments on commit e3cdb5f

Please sign in to comment.