A developer plugin for WordPress that enables sharing website links via SMS or Email. It uses Twilio for the SMS service, Amazon SES for the email service, the official WordPress Bit.ly Plugin for url shortening, Timber for email template rendering, and WordPress Multilingual Plugin for translating email content.
Installation using Composer
$1 This package uses Composer Installers to install the package in the Must Use plugins directory (/wp-content/mu-plugins):
composer require nyco/wp-send-me-nyc
Not using Composer? Download an archive of the code and drop it into the mu-plugins directory. However,other dependencies will need to be downloaded and installed separately.
$2 Create a proxy PHP loader file inside the mu-plugins directory, or use the one included with the plugin:
mv wp-content/mu-plugins/wp-send-me-nyc/autoloader-sample.php wp-content/mu-plugins/send-me-nyc.php
The sample autoloader contains the basic code required to initialize the plugin. It will...
- Require all files containing classes and helper functions.
- Initialize the
SMNYC\ContactMe
,SMNYC\SmsMe
, andSMNYC\EmailMe
classes. - Register admin actions for sending a message.
- Register custom post types for custom SMS and Email content (SMNYC Emails and SMNYC SMS).
- Create an admin settings page under Settings > Send Me NYC for configuration.
Note: The SMNYC\SmsMe
and SMNYC\EmailMe
classes extend the SMNYC\ContactMe
class. Any of the three could be extended further or have their properties modified to accommodate custom settings or services.
Each settings section corresponds to a specific service that needs to be configured to work with your WordPress installation. These can be configured in the WordPress admin settings or as PHP constants. If both the WordPress admin setting and the PHP constant setting of the option are set, the WordPress admin setting will be preferred.
Admin Setting | PHP Constant |
---|---|
Settings > Writing > Bitly OAuth Token | SMNYC_WPBITLY_OAUTH_TOKEN |
The official WordPress Bit.ly Plugin is used to manage the API version and authentication to Bit.ly. Once installed, Bit.ly settings can be found under Settings > Writing in the WordPress Admin Menu. Authentication requires access to a Bit.ly account or an Access Token. An Access Token can be generated by a Bit.ly user account in the developer settings. To use Oauth, a token will need to be generated programmatically or via the command line. Review the API authentication documentation for more information.
The PHP Constant SMNYC_WPBITLY_OAUTH_TOKEN
can be used to define the token. This plugin will set the WordPress Bit.ly token automatically and hide the authentication button.
Admin Setting | WordPress Option | PHP Constant |
---|---|---|
Account SID | smnyc_twilio_user |
SMNYC_TWILIO_USER |
Sender Phone Number | smnyc_twilio_from |
SMNYC_TWILIO_FROM |
API Key SID | smnyc_twilio_api_key_sid |
SMNYC_TWILIO_API_KEY_SID |
API Key Secret | smnyc_twilio_api_key_secret |
SMNYC_TWILIO_API_KEY_SECRET |
The Twilio integration uses API Keys that can be generated under the Account > API Keys & Tokens page. Read more about Twilio API keys here.
Admin Setting | WordPress Option | PHP Constant |
---|---|---|
Key | smnyc_aws_user |
SMNYC_AWS_USER |
Secret | smnyc_aws_secret |
SMNYC_AWS_SECRET |
From Email Address | smnyc_aws_from |
SMNYC_AWS_FROM |
Email Display Name (optional) | smnyc_aws_display_name |
SMNYC_AWS_DISPLAY_NAME |
Reply-to (optional) | smnyc_aws_reply |
SMNYC_AWS_REPLY |
Note: This plugin works nicely with the NYCO WordPress Config plugin.
These custom post types are created to store reusable SMS and Email content that is sent in our messages.
An example of post content could include the following;
REMINDER: you may be eligible for these NYC Programs: {{ BITLY_URL }}
The template tag {{ BITLY_URL }}
will be replaced with a shortened Bitly url that is intended to be shared with the recipient. The SMNYC SMS post type does not require any specific templating.
For more dynamic content, you can include an input for sharetext
and include the template tag {{ SHARE_TEXT }}
into the post content.
{{ SHARE_TEXT }} {{ BITLY_URL }}
An example of post content could be the same as the SMS, however, you may not need to use the Bitly shortener for the url. In this case, replace {{ BITLY_URL }}
with {{ URL }}
.
REMINDER: you may be eligible for these NYC Programs: {{ URL }}
The SMNYC Email post type requires a template controller that extends the Timber\Post
class and a Twig file containing the template that will render the content into an HTML email. The sample controller contains a working class that extends Timber\Post
. Move this file to the root of your active theme directory.
mv wp-content/mu-plugins/nyco-wp-send-me-nyc/controllers/smnyc-email-single-sample.php wp-content/themes/theme/smnyc-email.php
The sample email contains a working email twig template. Use this file or create a file within your Timber Views directory called emails/single.twig. This is where the HTML markup for your email will be placed.
Customization
The path to the controller file and class contents can be used as is or modified as needed. By default, SMNYC\EmailMe
requires a file called smnyc-email.php
in the root of the activated WordPress theme that contains the the controller class. However, different path can be passed to the SMNYC\EmailMe
class on instantiation in the auto loader;
$email = new SMNYC\EmailMe('controllers/smnyc-email.php');
Examining the smnyc-email.php
file, we can see that the class has a template constant.
/** The twig template for emails */
const TEMPLATE = 'emails/single.twig';
This is the path inside the views where the email template is stored. Modify the string with a different path if desired. The smnyc-email.php
also contains a method called ->addToPost()
where programmable post content can be added to pass to the view when it is rendered.
WordPress Admin Ajax is used to send data from the front-end to the plugin. The createEndpoints()
method of the instantiated SMNYC\EmailMe
and SMNYC\SmsMe
objects will add ajax actions when the plugin is initialized. Actions using wp_ajax_{$_REQUEST[‘action’]}
and wp_ajax_nopriv_{$_REQUEST[‘action’]}
are registerd. Hidden inputs can be used to configure the data that is sent via the script below.
{# .twig #}
<form action="https://mysite.com/wp-admin/admin-ajax.php" method="post" data-js="smnyc">
<input type="hidden" readonly name="action" value="sms_send" />
<input type="hidden" readonly name="url" value="https://mysite.com/my-url-to-share/" />
<input type="hidden" readonly name="template" value="my-sms-post-template" />
<input type="hidden" readonly name="lan" value="en" />
<input type="hidden" readonly name="sharetext" value="{{ message }}" />
<input type="hidden" readonly name="hash" value="{{ hash }}" />
<input name="to" placeholder="Phone Number" required="true" type="tel" />
<button class="btn btn-primary btn-small" type="submit">Share</button>
</form>
The default actions to use the SMS and Email services are listed below.
Description | Action |
---|---|
Twilio Service SMS send action | sms_send |
Amazon SES Service email send action | email_send |
Name | Value Description |
---|---|
to |
A valid email address (validates against the FILTER_VALIDATE_EMAIL validate filter) or phone number (10 digit number including area code), depending on the action. |
action |
The Ajax action callback name; sms_send or email_send . |
url |
The URL to be shared with the recipient, this is what replaces the contents of the {{ BITLY_URL }} and {{ URL }} in the post content. |
template |
The slug of the SMNYC Post to use as the template for sms or email content. |
lang |
The language code of the template content. This should generally be the same as the current language of the page document. This value is passed to the wpml_object_id filter provided by WPML. |
hash |
Required to prevent CSRF. The plugin ships with a helper function to generate a new hash value to pass to your view. Below is an example of adding a hash to Timber context that is passed to the view template. |
/* php */
// Retrieving a hash using the SMNYC helper function.
$context['hash'] = SMNYC\hash('https://mysite.com/my-to-share/');
Below is an example script that adds a submit event listener to the form, serializes the form data on submit, and passes the data as a JSON object to the Fetch API.
/* JavaScript */
// https://www.npmjs.com/package/form-serialize
import FormSerialize from 'form-serialize';
let FORM = document.querySelector('[data-js="smnyc"]');
FORM.addEventListener('submit', (event) => {
// To send the data with the application/x-www-form-urlencoded header
// we need to use URLSearchParams(); instead of FormData(); which uses
// multipart/form-data
let formData = new URLSearchParams();
// Serialize the form data.
let data = FormSerialize(FORM, {hash: true});
// Iterate over our serialized data and append to formData.
Object.keys(data).map(k => {
formData.append(k, data[k]);
});
// Send the request via the Fetch API.
fetch(FORM.getAttribute('action'), {
method: FORM.getAttribute('method'),
body: formData
}).then(response => response.json())
.then(response => {
// My Response handler
}).catch(data => {
// My Error handler
});
});
Below are various response codes returned by the Email/SMS service and their meaning.
Codes | Meaning |
---|---|
General | |
9 | The hash provided is invalid. See the values table for a description of the SMNYC\hash() usage. |
-1 | The configuration is invalid. |
400 | A URL is missing from the request. See the values table for a full list of required values. |
1 | Missing email address. See the values table for a full list of required values. |
2 | Invalid email address. |
3 | An exception from the Amazon SES service. Reference the PHP SDK docs for error descriptions. |
SMS Errors | |
1 | Missing phone number. See the values table for a full list of required values. |
2 | Invalid phone number. Must be a 10-digit number including area code. The final value should be without spaces, dashed, etc. |
Twilio Response | |
30006 | Unable to send to number provided. |
21611 | The outbox queue is full (please try again later). |
30007 | Invalid message body. |
30009 | Ephemeral errors that a retry might solve. |
... | Reference the Twilio Docs for other errors. |
This action is fired after a message is sent successfully.
...args
String $type
Email/SMS/whatever the class type is.String $to
Recipient of message.String $guid
Session GUID.String $url
URL to that has been shared.String $msg
The body of the message.
add_action('smnyc_message_sent', function($type, $to, $uid, $url, $message) {
// Successful message sent handler
}, 10, 5);
The Mayor's Office for Economic Opportunity is committed to sharing open source software that we use in our products. Feel free to ask questions and share feedback. Interested in contributing? See our open positions on buildwithnyc.github.io. Follow our team on GitHub @nycopportunity and @cityofnewyork:nycopportunity or browse our work on Github.