The idea is to send reports via SMS using online SMS providers. Users need to provide one or several phone numbers and a SMS authorization token.
So far, we have identified three different kinds of reports. Here are the candidate templates :
from=Report Virtual-drums.com Daily text=Yesterday, 150 visits (+15%), 555 pages (+22%), Goals: X conversions (-XX%), Revenue: xx (-xx%).
from=Report Virtual-drums.com Daily text=Yesterday (Jan 21st): virtual-drums.com: 150 visits (+15%), 555 pages (+22%), Goals: X conversions (-XX%), Revenue: xx (-xx%). forum.piwik.org: 600 visits (-12%), 32 pages (+2%), mamamia.fr: 330 visits (+1%), 555 pages (+22%), Ecommerce Revenue: 34$ (-60%) from 45 orders (+111%)
Online SMS providers with open APIs provide a SMS authorization token to registered users.
Within Piwik, this token will be manageable one of two ways :
In this case, it is the responsibility of the super user to provide the token in the SMS management user interface.
It is the only user who has the right to consult the number of remaining credits.
In this case, it is the responsibility of each user to provide the token.
Each user has access to the number of remaining credits.
Deciding between the two modes of management is done by the super user with the following options in the SMS management UI :
- (x) Allow other users to create and manage their own SMS account. - ( ) Allow users with view or admin access to send SMS reports using your SMS credit.
The second option is the default.
When a token is typed-in by the user, a call to the SMS API will be performed to validate the token and display the amount of remaining credit. The token will not be stored if it can't be validated.
The user will have the ability to display the number of remaining credits in the SMS management pages. A message will be displayed in the report and SMS management pages when no credit are left in the account.
The token can not be modified. To change an already validated token the user will have to remove it and add a new one.
If the token is not provided
When the token is managed by the super user and a standard user accesses the SMS management page, display "SMS reports are not properly configured, please contact your administrator".
Within the SMS management UI, each user can manage one or several phone numbers. A phone number will be selectable within the report creation and edition forms only if it has been validated. To validate a phone number, a token is sent via SMS after requesting it in the SMS management page. This token is then typed-in by the user.
Here is the candidate SMS validation template :
Code is 54321. To validate your phone number and receive Piwik SMS reports please copy this code in the form accessible via Piwik > Settings > SMS.
The validation token does not expire.
Phone numbers can not be modified. To change an already validated number the user will have to remove it and add a new one.
The UI will provide a list of countries to automatically assign the international extension number. The country corresponding to the current language will be selected as the default value.
The phone number input field accepts only numbers.
A report can be created and edited without assigning phone numbers. The report list will display a warning message and the user won't be able to send the report.
In the report page, when the user has not validated at least one number :
SMS reports are still editable, the form can be saved without a selected phone number but the following message will be displayed in the edit form: "The list of phone numbers is empty because you did not activate a phone number". A link will be provided for quick access.
The SMS management page will be added in "Settings".
USERNAME__MobileMessagingSettings = array( 'PhoneNumbers' => array( '003354827548' => NULL, // NULL : phone number is activated '00542857842754' => 52123, // !NULL : validation token value ), 'ProviderAuthToken' => 'f4e8za4al', // Only if Super User or if MobileMessagingSettings.DelegatedManagement is set to TRUE )
MobileMessagingSettings.DelegatedManagement = TRUE // True if users can manage their own SMS account
See the following for phone number formatting: http://www.mediaburst.co.uk/blog/convert-a-mobile-number-into-international-format/
Does this feature really make sense in times of smartphones / email / analytic apps / nearby constant wifi / EDGE / 3g / 4g connectivity?
IMO, sending a SMS would absolutely make sense in context of #1486 (any alert is triggered for a website), because an alert often indicates that urgent action is required.
I'd rather see Alerts and push notifications, but we don't dictate what others work on here. The only thing we should decide is whether this is included in the core distribution or not.
I think it makes sense because not all the world is connected like EU/North america is (3g, constant wifi do not exist in most places in the world). SMS is huge is Asia, Africa, south america, etc.
Also, this ticket will build all the SMS logic handling code which will then be reused for Custom Alerts #1486 where, as mentionned, it will be even more interesting and useful.
It will be included in the core but disabled by default.
"DelegatedManagement" => TRUE // True if users can manage their own SMS account
I don;t think this is stored per user. Instead it is stored as a general Option value.
Otherwise, proposal looks great, looking forward to seeing it!
Maybe you want to use something fancy for the country selector,see this cool jquery plugin: http://baymard.com/labs/country-selector
Btw for the country selector, please use existing country translations. Try to default to the country of the selected language. Later, we might reuse this website selector in other places :)
Now that plugins can have their own config files (#2871), I was wondering what is the best solution to store the phone numbers and SMS API tokens for the SMSManager plugin.
Do they belong in the database in the option table or in the new local config file ?
Is it only a question of being able to replicate this data easily when using multiple Piwik instances or is there other factors to weight-in ?
Yes, it depends. In this case, I would say database because:
+1 with database storage of phone numbers and tokens, in the "piwik_option" table.
There's a very high probability this plugin will be used to send alerts.
Could you please confirm 'SMSManager' is the name that makes the most sense?
Updated report description for more clarity + Proposal to use MultiSites.getAll and a new MultiSites.get to fetch the data to use in the SMS reports. The advantage of doing that would be to not have to process the % evolution in the SMS manager implementation. it would be better to leave all data processing to the MultiSites.get* API. Thoughts?
We currently have one type of report : e-mail.
We now would like to implement a new type : sms.
While doing so, we would like to refactor the existing PDFReport plugin so it can manage both types, and possibly more in the future.
The idea is to use the hooking/event mechanism to allow other plugins to add new types of reports.
We already know that e-mail and sms reports share some properties but they do also have specifics ones.
shared properties :
e-mail specific properties :
The first question we need to answer is how do we manage persistence.
There are many known academic anwsers on how to store polymorphic objects in a relational database.
one table with nullable fields
Have one table, piwik_report, with all the fields required by all the report types. Fields that are not shared by all reports types are nullable (e.g: email me, display format).
one table per report type
Have one table per report type, piwik_report_email, piwik_report_sms. Shared properties are duplicated, specifics properties are isolated in their own table.
one table for shared properties, one smaller table for each report types
Have one table, piwik_report, with all the shared properties. Have one smaller table, piwik_report_email, will the email type specific properties (email me, display format). This table has a foreign key linking to piwik_report. Same goes for piwik_report_sms.
Here are two less academic ways to solve this issue :
one table with a JSON encoded parameter field
Have one table, piwik_report, with all the shared properties and a field called 'parameters'. This field would contain the JSON encoded specific properties.
Have one table, piwik_report, with all the shared properties. Have another table, piwik_report_parameters. This table would be as follow : report id, parameter name, parameter value.
The JSON parameters array seems a good idea because it doesn't add a new table.
It's not obvious what the best solution is... Because it's quite easy to add new fields on Piwik update, the "one table with nullable fields " is also do-able...
I think I would implement it with the JSON solution still, thoughts?
(In ) fixes #2708
Julien, Wonderful patch! Thank you for this work.
Really nice refactoring and well written code.
// <a class='mention' href='https://github.com/review'>@review</a> this is not optimal in terms of performance: those metrics should not be retrieved in the first place
Agreed.. but that is technical debt I suppose.
<ecommerce_revenue_evolution>$ 0</ecommerce_revenue_evolution>` -
I think this would be caused by the revenue beautifying code in Piwik::getPrettyValue - it shouldn't be called on money when metric contains 'evolution' ;)
Output= Fatal error: Call to a member function getColumns() on a non-object in piwik\svn\trunk\core\API\ResponseBuilder.php on line 176
Tuesday 3 July 2012. 2 Visits (+100%), 3 Actions (+100%)<?xml version="1.0" encoding="utf-8" ?> <result> <success message="ok" /> </result>
The <?XML response shouldn't be in the .sms output I believe this is a bug?
//@review the length of the SMS text is limited by Mediaburst. Here, we truncate the SMS content because MultiSites.getAll can return a lot of sites. Is this the proper way to handle this case?
[long](too)- it will take 10 letters but worth to convey the message clearly that is cut and we know it. Otherwise users might think "A bug" rather than what it is "A missing feature" :)
// @review is this the correct way to store calling codes or should we use GLOBALS like in core/DataFiles/Countries.php?
It looks good - we used GLOBALS but could have used the static class solution instead.
//@review sms can only contain one report, we currently silently discard all reports except the first one, is this ok or should we raise an exception?
It sounds fine to me
//@review when a wrong phone number is supplied we silently discard it, should an exception be raised?
I think that if they submit 1 phone number and that it is wrong then it should be throwing an exception. If they submnit many and only 1 is wrong then it's OK not to say anything?
Api credentials and phone numbers should be removed when the plugin is deleted, not really when it's just deactivated. There is a method uninstall() on the Plugin class, but currently the UI does not allow to delete a plugin. So I think it's better to not delete API credentials on deactivate.
reset() expects parameter 1 to be array, boolean given in piwik\svn\trunk\plugins\MobileMessaging\MobileMessaging.php on line 163
It would be great to improve the UI. I have some ideas see below. Also will have more once the UI works for me (see below for the bug i experience preventing signing in mediaburst)
Ideally yes it should be in that file, but we haven't been enforcing this greatly.
Add new DIV to describe the SMS provider'
I propose that we add a text such as the following:
You can use Mediaburst.co.uk to send SMS Reports from Piwik. * First, [https://secure.mediaburst.co.uk/signup/piwik signup to Mediaburst] * Pay for some SMS to your account * Fill in your Mediaburst account details in Piwik. About Mediaburst * Mediabursts text message API gives you fast, reliable high quality worldwide SMS delivery, over 450 networks in every corner of the globe. * Cost per SMS message is ~0.08USD (0.06EUR). * Most countries and networks are supported and will receive the text messages, but a few networks are currently not supported in Nigeria, Colombia (Comcel), Bangladesh, Belgium (Movistar), Gibraltar, Greece(Cosmoat), Hungry (Panafon).
This text could be returned as a getter on the provider class.
Looking forward to seeing further small changes suggested in this ticket!
As a conclusion, I will say that this is a great new feature(s), and again Big Kuddos to you for the vision and the very nice implementation!!
(In ) Refs #2708 Using Piwik_Common::json* instead of core PHP to avoid annoying PHP bugs with old php builds
Phone numbers admin
After adding a phone number, write "We just sent a SMS to this number with a code: please enter this code below and click "Validate"."
Edit Report UI
(In ) refs #2708
(In ) refs #2708 fixing integration tests failing after r6727
Very cool, thanks for doing all changes! :)
I will also commit a few small changes
(In ) Refs #2708
(In ) refs #2708
displaying website name in SMS content even when MultiSites.getAll returns one website
(In ) refs #2708 fixing regression introduced in r6758
I noticed an inefficiency in the Report generation.
I notice that when I run the following SMS "Single site" report with debug enabled:
with, in the config file:
[log] log_only_when_debug_parameter = 1 logger_message = "screen"
It outputs on screen: http://pastebin.com/8TyxhpAr
As you can see when generating one SMS reports it first loads all archives from the DB for ALL websites. The SMS was a "single website" so it should only query this site data. I havent looked at the code please let me know if you need help or more info! :)
NB: I tried generating a PDF that didn't contain the "All websites dashboard" and it does not do the extra requests for other websites, so maybe it's a problem with SMS only?
(In ) refs #2708 blacklisting MobileMessaging plugin from API integration tests
In the future, I think it would be cool to ask during the installation process if users want to send SMS reports, with a checkbox, and if so enable the MobileMessaging plugin, to maximise number of users who know about this feature.
Kuddos Julien for this great new feature!