来自Magento的苹果推送通知
不是每个人都对这个标题很熟悉,苹果推送通知服务(APNS)是苹果公司为其移动设备(iPhone, iPad …) 提供的基础服务,可以给特定的监听应用发送特定的信息。
对于APNS的正确用法,他们可能需要集成到移动应用程序里,也需要苹果移动层面上发送信息的证书。
我不是一个IOS开发人员,所以我没有资格去写这个故事的移动端,但是,这里还有另一个方面需要被覆盖。我会尽量解释如何利用Magento来发送推送信息到目标移动设备。
使用Magento时思路可以是多样的:当新订单被创建或者客户注册我们可以发推送信息,或者我们可以用在Magento移动端来发送类似通讯的消息……
这篇教程假设你已经参加了苹果开发计划,注册了APNS并集成APNS功能到你的移动应用。
为了在Magento中使用APNS我先要做点准备工作。
从源代码中准备可用的APNS证书
登录到你的苹果开发者网站,下载APNS使用证书。将证书拷贝到你插件文件系统中的,另外记得写下证书的密码。
在数据库中创建自定义的表单来存储独特的标记和其它APNS需要的参数
在我们的APNS表中,我们将为每一个接收推送信息的设备保存独特的标记。这个设备的标记可能是应用启动时移动设备发出的。为了在数据库保存device_token。我们需要创建独立的Magento web服务方法,当移动应用启动时被调用。
我们需要从移动应用发送APNS设备标记到apns_save Web服务方法。在web服务方法中我们应该要对设备标记添加/更新来避免重复。
下面是一个web服务API方法的示例:
<!--?php <br ?-->
/*
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
*/
class Alwayly_Mapy_Model_Core_Apns_Api_V2 extends Mage_Api_Model_Resource_Abstract {
public function setParams($token, $events, $appversion, $period) {
$api_user = Mage::getSingleton('api/session')->getUser();
$userExists = ($api_user && $api_user->getId()) ? true : false;
if (!$userExists) {
$this->_fault('not_exists', 'User does not exist!');
}
if (!$token) {
$this->_fault('data_invalid', 'Device token not set!');
}
if ($token == '') {
$this->_fault('data_invalid', 'Device token invalid!');
}
$collection = Mage::getSingleton('inchoo_mapy/core_apns')->getCollection();
$collection->addFieldToFilter('user_id', $api_user->getId());
$collection->addFieldToFilter('device_token', $token);
$app = explode('-', $appversion);
if (count($app) > 0) {
$collection->addFieldToFilter('app_version',array('like'=>$app[0] . '%'));
} else {
$this->_fault('data_invalid', 'App version not supported!');
}
$param = $collection->getFirstItem();
$currentTime = now();
if ($period < 60) { $period = 60; } $sess_id = Mage::getSingleton('api/session')-
>getSessionId();
$param->setUserId($api_user->getId());
$param->setAppVersion($appversion);
$param->setDeviceToken($token);
$param->setEvents($events);
$param->setStatus('active');
$param->setNotificationPeriod($period);
$param->setUpdatedAt($currentTime);
$param->setLastSession($sess_id);
$param->save();
return true;
}
创建用于发送推送信息的助手
当我们存储设备标记到我们的表里时,我们决定从Magento中何时,发送什么,发送给哪些设备信息的逻辑。当然,也要实现发送-间隔的逻辑来避免垃圾信息。
<!--?php <br ?-->
/*
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
*/
class Alwayly_Mapy_Helper_ApnsLite extends Mage_Core_Helper_Abstract {
const CONFIG_XML_PATH_APPLE_SSL = 'inchoo_mapy/settings/apnsssl';
const CONFIG_XML_PATH_APPLE_FEEDBACK = 'inchoo_mapy/settings/apnsfeedback';
private function _getCertificate() {
return Mage::getBaseDir() . DS . 'app' . DS . 'code' . DS . 'community' . DS .
'Inchoo' . DS . 'Mapy' . DS . 'lib' . DS . 'apple' .
DS . 'certificate' . DS . 'ck_production_lite.pem';
}
public function sendPushNotifications() {
$certificate = $this->_getCertificate();
$devices = $this->_getDevicesForNotification();
$messages = array();
foreach ($devices as $device) {
if ($device['received_at'] == null) {
$now = Zend_Date::now();
$now->sub(1, Zend_Date::HOUR);
$from_time = $now;
} else {
$from_time = new Zend_Date($device['received_at'], Varien_Date::DATETIME_INTERNAL_FORMAT);
}
$data = array();
if (strpos($device['events'], 'new_orders') !== false) {
$result = $this->_getNewOrders($from_time);
$data['orders_sum'] = $result['sales_total'];
$data['orders_count'] = $result['num_orders'];
}
if (strpos($device['events'], 'new_customers') !== false) {
$result = $this->_getNewCustomers($from_time);
$data['customers_count'] = $result['new_customers'];
}
$message = $this->_prepareMessage($data);
if (md5($message) == $device['last_msg_hash']) {
$message = null;
}
$sess_id = $device['last_session'];
$session = Mage::getSingleton('api/session');
$user = Mage::getModel('api/user')->loadBySessId($sess_id);
$user = Mage::getModel('api/user')->loadBySessId($sess_id);
if ((!$session->isLoggedIn($sess_id))||(!$user->hasUserId())) {
$message = null;
$collection = Mage::getModel('inchoo_mapy/core_apns')->getCollection();
$collection->addFieldToFilter('last_session', $sess_id);
foreach ($collection as $val) {
if ($val->getId()) {
$val->setStatus('inactive');
$val->save();
}
}
}
if ($message != null) {
$messages[] = array(
'msg' => $message,
'device' => $device['device_token'],
);
}
}
if (count($messages) > 0) {
$this->_pushMessage($messages, $certificate);
}
}
private function _prepareMessage($data) {
$helper = Mage::helper('inchoo_mapy');
$message = '';
$badge = 0;
$mage_events = array();
if (isset($data['orders_sum'])) {
if ($data['orders_sum'] > 0) {
$message.='Sales total: ' . $helper->currencyToBaseFormat($data['orders_sum']);
}
}
if (isset($data['orders_count'])) {
if ($data['orders_count'] > 0) {
$message.=' Orders count: ' . $data['orders_count'];
$badge+=$data['orders_count'];
$mage_events[] = array('mage_event' => 'new_orders', 'count' => $data['orders_count']);
}
}
if (isset($data['customers_count'])) {
if ($data['customers_count'] > 0) {
$message.=' New customers count: ' . $data['customers_count'];
$badge+=$data['customers_count'];
$mage_events[] = array('mage_event' => 'new_customers', 'count' => $data['customers_count']);
}
}
if ($badge == 0) {
return;
}
$body['aps'] = array(
'sound' => 'tick.caf',
'alert' => $message,
'badge' => (int) $badge,
'mage-events' => $mage_events
);
$payload = json_encode($body);
return $payload;
}
private function _getDevicesForNotification() {
$collection = Mage::getModel('inchoo_mapy/core_apns')->getCollection();
$collection->addFieldToFilter('status', 'active');
$where_expr = 'DATE_ADD(IFNULL(sent_at, DATE_SUB(UTC_TIMESTAMP(), INTERVAL 3600 SECOND )),INTERVAL notification_period
SECOND) $param->save();
}
}
}
}
如果你阅读了代码,你会发现我们有些公用的方法来发送通知。这些方法里我们先读取设备,然后我们再读取个准备信息的数据并在条件满足时发送它们。
- _prepareMessage方法是用来将数据加入到合适的json信息格式
- _pushMessage是信息发送方法
- _checkFeedback用来列出关闭推送信息的苹果设备,我们需要在表中把它们标记为inactive。
电商网站开发服务。