├── .DS_Store
├── README.md
├── package.json
├── plugin.xml
├── src
├── android
│ └── Sms.java
├── ios
│ ├── Sms.h
│ └── Sms.m
└── wp8
│ └── Sms.cs
└── www
└── sms.js
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hazems/cordova-sms-plugin/2041f0a0f26e92b1e807d52f2dc2c905536c542f/.DS_Store
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Notice:
2 | ====================
3 | This plugin is one of the examples of the ["JavaScript Mobile Application Development"](https://www.packtpub.com/web-development/javascript-native-mobile-apps-development) book which can be reached at:
4 | [http://www.amazon.com/JavaScript-Native-Mobile-Apps-Development/dp/1783554177/](http://www.amazon.com/JavaScript-Native-Mobile-Apps-Development/dp/1783554177/)
5 | [https://www.packtpub.com/web-development/javascript-native-mobile-apps-development](http://www.amazon.com/JavaScript-Native-Mobile-Apps-Development/dp/1783554177/)
6 |
7 | Sms Custom Cordova Plugin:
8 | ====================
9 | This plugin allows you to send SMS message to a specific phone number for Android, iOS and Windows Platform 8. Here is an example below:
10 |
11 |
12 | var messageInfo = {
13 | phoneNumber: "xxxxxxxxxx",
14 | textMessage: "This is a test message"
15 | };
16 |
17 | sms.sendMessage(messageInfo, function(message) {
18 | console.log("success: " + message);
19 | }, function(error) {
20 | console.log("code: " + error.code + ", message: " + error.message);
21 | });
22 |
23 | As you notice you just need to call *sms.sendMessage(messageInfo, successCallback, failureCallback)*:
24 |
25 | * *messageInfo* is a JSON object which contains phoneNumber and textMessage attributes.
26 | * *sucessCallback* is a callback function which will be called if the send SMS operation succeeds.
27 | * *errorCallback* is a callback function which will be called if the send SMS operation fails.
28 |
29 | Installing the plugin
30 | ---
31 | In order to install the plugin you can:
32 |
33 | Install it from NPM registry as follows:
34 |
35 | npm i hazems-cordova-plugin-sms
36 |
37 |
38 | or simply use the following Cordova CLI command:
39 |
40 | cordova plugin add https://github.com/hazems/cordova-sms-plugin.git
41 |
42 | or
43 |
44 | cordova plugin add com.jsmobile.plugins.sms
45 |
46 |
47 |
48 | Important Note
49 | ---
50 | For iOS and Windows Phone platforms, it is not possible to send SMS directly without opening the default device SMS application. This means that the API will only open and track the SMS application events (cancel, successful sending, un-successful sending, ...etc) in iOS platform. For Windows Phone 8, the plugin will only open the SMS application without tracking its events because tracking SMS application events is not currently applicable in Windows 8 platform.
51 |
52 | Test Client
53 | ---
54 | You can reach the test client of this plugin here:
55 | [https://github.com/hazems/cordova-sms-plugin-test/ ](https://github.com/hazems/cordova-sms-plugin-test/)
56 |
57 | Used Resources
58 | ---
59 | Special Thanks to [appcoda.com]() for helping me in implementing the iOS part of this plugin:
60 |
61 | [http://www.appcoda.com/ios-programming-send-sms-text-message/ ](http://www.appcoda.com/ios-programming-send-sms-text-message/)
62 |
63 | Licence
64 | ---
65 | It is Apache License, Version 2.0. Feel free to fork the project and send pull requests if you have any.
66 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "hazems-cordova-plugin-sms",
3 | "version": "0.0.2",
4 | "description": "A plugin for sending sms messages",
5 | "cordova": {
6 | "id": "com.jsmobile.plugins.sms",
7 | "platforms": [
8 | "android",
9 | "ios",
10 | "wp8"
11 | ]
12 | },
13 | "repository": {
14 | "type": "git",
15 | "url": "git+https://github.com/hazems/cordova-sms-plugin.git"
16 | },
17 | "keywords": [
18 | "cordova",
19 | "plugins",
20 | "sms",
21 | "ecosystem:cordova",
22 | "cordova-android",
23 | "cordova-ios",
24 | "cordova-wp8"
25 | ],
26 | "author": "Hazem Saleh",
27 | "license": "Apache 2.0",
28 | "bugs": {
29 | "url": "https://github.com/hazems/cordova-sms-plugin/issues"
30 | },
31 | "homepage": "https://github.com/hazems/cordova-sms-plugin#readme"
32 | }
33 |
--------------------------------------------------------------------------------
/plugin.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | sms
4 | A plugin for sending sms messages
5 | Apache 2.0
6 | cordova,plugins,sms
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/src/android/Sms.java:
--------------------------------------------------------------------------------
1 | package com.jsmobile.plugins.sms;
2 |
3 | import org.apache.cordova.CordovaPlugin;
4 | import org.apache.cordova.CallbackContext;
5 | import org.apache.cordova.PluginResult;
6 | import org.apache.cordova.PluginResult.Status;
7 | import org.json.JSONArray;
8 | import org.json.JSONException;
9 | import org.json.JSONObject;
10 |
11 | import android.app.Activity;
12 | import android.app.PendingIntent;
13 | import android.content.BroadcastReceiver;
14 | import android.content.Context;
15 | import android.content.Intent;
16 | import android.content.IntentFilter;
17 | import android.content.pm.PackageManager;
18 | import android.telephony.SmsManager;
19 |
20 | /**
21 | * This class echoes a string called from JavaScript.
22 | */
23 | //Changed from CDNsms to sms
24 | public class Sms extends CordovaPlugin {
25 | private static final String SMS_GENERAL_ERROR = "SMS_GENERAL_ERROR";
26 | private static final String NO_SMS_SERVICE_AVAILABLE = "NO_SMS_SERVICE_AVAILABLE";
27 | private static final String SMS_FEATURE_NOT_SUPPORTED = "SMS_FEATURE_NOT_SUPPORTED";
28 | private static final String SENDING_SMS_ID = "SENDING_SMS";
29 |
30 | @Override
31 | public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
32 | if (action.equals("sendMessage")) {
33 | String phoneNumber = args.getString(0);
34 | String message = args.getString(1);
35 |
36 | boolean isSupported = getActivity().getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
37 |
38 | if (! isSupported) {
39 | JSONObject errorObject = new JSONObject();
40 |
41 | errorObject.put("code", SMS_FEATURE_NOT_SUPPORTED);
42 | errorObject.put("message", "SMS feature is not supported on this device");
43 |
44 | callbackContext.sendPluginResult(new PluginResult(Status.ERROR, errorObject));
45 | return false;
46 | }
47 |
48 | this.sendSMS(phoneNumber, message, callbackContext);
49 |
50 | return true;
51 | }
52 |
53 | return false;
54 | }
55 |
56 | private void sendSMS(String phoneNumber, String message, final CallbackContext callbackContext) throws JSONException {
57 | PendingIntent sentPI = PendingIntent.getBroadcast(getActivity(), 0, new Intent(SENDING_SMS_ID), 0);
58 |
59 | getActivity().registerReceiver(new BroadcastReceiver() {
60 | @Override
61 | public void onReceive(Context context, Intent intent) {
62 | switch (getResultCode()) {
63 | case Activity.RESULT_OK:
64 | callbackContext.sendPluginResult(new PluginResult(Status.OK, "SMS message is sent successfully"));
65 | break;
66 | case SmsManager.RESULT_ERROR_NO_SERVICE:
67 | try {
68 | JSONObject errorObject = new JSONObject();
69 |
70 | errorObject.put("code", NO_SMS_SERVICE_AVAILABLE);
71 | errorObject.put("message", "SMS is not sent because no service is available");
72 |
73 | callbackContext.sendPluginResult(new PluginResult(Status.ERROR, errorObject));
74 | } catch (JSONException exception) {
75 | exception.printStackTrace();
76 | }
77 | break;
78 | default:
79 | try {
80 | JSONObject errorObject = new JSONObject();
81 |
82 | errorObject.put("code", SMS_GENERAL_ERROR);
83 | errorObject.put("message", "SMS general error");
84 |
85 | callbackContext.sendPluginResult(new PluginResult(Status.ERROR, errorObject));
86 | } catch (JSONException exception) {
87 | exception.printStackTrace();
88 | }
89 |
90 | break;
91 | }
92 | }
93 | }, new IntentFilter(SENDING_SMS_ID));
94 |
95 | SmsManager sms = SmsManager.getDefault();
96 |
97 | sms.sendTextMessage(phoneNumber, null, message, sentPI, null);
98 | }
99 |
100 | private Activity getActivity() {
101 | return this.cordova.getActivity();
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/src/ios/Sms.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 |
4 | @interface Sms : CDVPlugin {
5 | // Member variables go here.
6 |
7 | }
8 |
9 | @property(strong) NSString* callbackID;
10 | - (void)sendMessage:(CDVInvokedUrlCommand*)command;
11 | @end
--------------------------------------------------------------------------------
/src/ios/Sms.m:
--------------------------------------------------------------------------------
1 | /********* Sms.m Cordova Plugin Implementation *******/
2 |
3 | #import "Sms.h"
4 |
5 | @implementation Sms
6 |
7 | - (void)sendMessage:(CDVInvokedUrlCommand*)command
8 | {
9 | CDVPluginResult* pluginResult = nil;
10 | NSString* phoneNumber = [command.arguments objectAtIndex:0];
11 | NSString* textMessage = [command.arguments objectAtIndex:1];
12 |
13 | self.callbackID = command.callbackId;
14 |
15 | if (![MFMessageComposeViewController canSendText]) {
16 | NSMutableDictionary* returnInfo = [NSMutableDictionary dictionaryWithCapacity:2];
17 |
18 | [returnInfo setObject:@"SMS_FEATURE_NOT_SUPPORTED" forKey:@"code"];
19 | [returnInfo setObject:@"SMS feature is not supported on this device" forKey:@"message"];
20 |
21 | pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:returnInfo];
22 |
23 | [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
24 |
25 | return;
26 | }
27 |
28 | MFMessageComposeViewController *composeViewController = [[MFMessageComposeViewController alloc] init];
29 | composeViewController.messageComposeDelegate = self;
30 |
31 | NSMutableArray *recipients = [[NSMutableArray alloc] init];
32 |
33 | [recipients addObject:phoneNumber];
34 |
35 | [composeViewController setBody:textMessage];
36 | [composeViewController setRecipients:recipients];
37 |
38 | [self.viewController presentViewController:composeViewController animated:YES completion:nil];
39 | }
40 |
41 | // Handle the different situations of MFMessageComposeViewControllerDelegate
42 | - (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result {
43 | BOOL succeeded = NO;
44 | NSString* errorCode = @"";
45 | NSString* message = @"";
46 |
47 | switch(result) {
48 | case MessageComposeResultSent:
49 | succeeded = YES;
50 | message = @"Message sent";
51 | break;
52 | case MessageComposeResultCancelled:
53 | message = @"Message cancelled";
54 | errorCode = @"SMS_MESSAGE_CANCELLED";
55 | break;
56 | case MessageComposeResultFailed:
57 | message = @"Message Compose Result failed";
58 | errorCode = @"SMS_MESSAGE_COMPOSE_FAILED";
59 | break;
60 | default:
61 | message = @"Sms General error";
62 | errorCode = @"SMS_GENERAL_ERROR";
63 | break;
64 | }
65 |
66 | [self.viewController dismissViewControllerAnimated:YES completion:nil];
67 |
68 | if (succeeded == YES) {
69 | [super writeJavascript:[[CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:message]
70 | toSuccessCallbackString:self.callbackID]];
71 | } else {
72 | NSMutableDictionary* returnInfo = [NSMutableDictionary dictionaryWithCapacity:2];
73 |
74 | [returnInfo setObject:errorCode forKey:@"code"];
75 | [returnInfo setObject:message forKey:@"message"];
76 |
77 | [super writeJavascript:[[CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:returnInfo]
78 | toErrorCallbackString:self.callbackID]];
79 | }
80 | }
81 |
82 | @end
83 |
--------------------------------------------------------------------------------
/src/wp8/Sms.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Microsoft.Phone.Tasks;
3 | using WPCordovaClassLib.Cordova;
4 | using WPCordovaClassLib.Cordova.Commands;
5 | using WPCordovaClassLib.Cordova.JSON;
6 |
7 | namespace WPCordovaClassLib.Cordova.Commands
8 | {
9 | public class Sms : BaseCommand
10 | {
11 |
12 | public void sendMessage(string options)
13 | {
14 | string[] optValues = JsonHelper.Deserialize(options);
15 | String number = optValues[0];
16 | String message = optValues[1];
17 |
18 | SmsComposeTask sms = new SmsComposeTask();
19 |
20 | sms.To = number;
21 | sms.Body = message;
22 |
23 | sms.Show();
24 |
25 | //Since there is no way to track SMS application events in WP8, always send Ok status.
26 | DispatchCommandResult(new PluginResult(PluginResult.Status.OK, "Success"));
27 | }
28 | }
29 | }
--------------------------------------------------------------------------------
/www/sms.js:
--------------------------------------------------------------------------------
1 | var smsExport = {};
2 |
3 | smsExport.sendMessage = function(messageInfo, successCallback, errorCallback) {
4 | if (messageInfo == null || typeof messageInfo !== 'object') {
5 |
6 | if (errorCallback) {
7 | errorCallback({
8 | code: "INVALID_INPUT",
9 | message: "Invalid Input"
10 | });
11 | }
12 |
13 | return;
14 | }
15 |
16 | var phoneNumber = messageInfo.phoneNumber;
17 | var textMessage = messageInfo.textMessage || "";
18 |
19 | if (! phoneNumber) {
20 | console.log("Missing Phone Number");
21 |
22 | if (errorCallback) {
23 | errorCallback({
24 | code: "MISSING_PHONE_NUMBER",
25 | message: "Missing Phone number"
26 | });
27 | }
28 |
29 | return;
30 | }
31 |
32 | cordova.exec(successCallback, errorCallback, "Sms", "sendMessage", [phoneNumber, textMessage]);
33 | };
34 |
35 | module.exports = smsExport;
36 |
--------------------------------------------------------------------------------