如何在 Node JS 中使用 Amazon SNS 向 iOS 设备发送 VoIP 推送通知

Posted

技术标签:

【中文标题】如何在 Node JS 中使用 Amazon SNS 向 iOS 设备发送 VoIP 推送通知【英文标题】:How Do I send VoIP push notifications to an iOS device using Amazon SNS in Node JS 【发布时间】:2016-12-23 21:05:20 【问题描述】:

我正在尝试使用名为 sns-mobile 和 Amazon SNS API 的 NodeJS 包从应用服务器直接向 ios 设备发送 VoIP 推送通知。

但是,当我尝试使用以下代码发送 VoIP 推送时,我收到以下错误消息。有人可以建议我哪里出错了,我已经花了将近半天的时间来解决这个问题。

无效参数:JSON 必须包含“默认”条目或 'APNS_VOIP

var iOSApp = new SNS(
      platform: SNS.SUPPORTED_PLATFORMS.IOS,
      region: 'us-west-2',
      apiVersion: '2010-03-31',
      accessKeyId: 'XXXXXXXXXXXXX',
      secretAccessKey: 'XXXXXXXXXXXXX',
      platformApplicationArn: 'arn:aws:sns:us-west-2:3303035XXXXX:app/APNS_VOIP/VoIPPushesApp'
    ); 

iOSApp.addUser('deviceID', 
  JSON.stringify(
   "APNS_VOIP": JSON.stringify(aps:alert:"Hello and have a good day.")
  )
  , function(err, endpointArn) 
  if(err) 
    console.log("The Error is :****: "+JSON.stringify(err, null, 4));
    throw err;
  


  // Send a simple String or data to the client 
  iOSApp.sendMessage(endpointArn, 'Hi There!', function(err, messageId) 
  //iOSApp.sendMessage(endpointArn, messageTest, function(err, messageId) 
    if(err) 
      console.log("The Error in end message is :****: "+JSON.stringify(err, null, 4));
      throw err;
    
    console.log('Message sent, ID was: ' + messageId);
  );
);

【问题讨论】:

【参考方案1】:

这是使用设备 VoIP 令牌向接收设备发送 VoIP 通知的代码。当收到 VoIP 通知时,设备会调用一个名为 didReceiveIncomingPushWithPayload 的函数

var AWS                   =   require('aws-sdk');

// Amazon SNS module
AWS.config.update(
  accessKeyId     : 'XXXXXXXXXXXXXXXX',
  secretAccessKey : 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
  region          : 'us-west-2'
);

var amazonSNS             =   new AWS.SNS();

// 1. Create Platform Endpoint
var createPlatformEndpoint = function(req, res, next)
  var deviceVoipToken = req.deviceVoipToken;  // Obtaining the device VoIP token from the request object

  amazonSNS.createPlatformEndpoint(
    // App in Sandboxmode (ie running on device directly from Xcode)
    PlatformApplicationArn: "arn:aws:sns:us-west-2:xxxxxxxxxxxx:app/APNS_VOIP_SANDBOX/CurieVoip",
    // App in Production mode (ie running on device after archiving and installed on device with a provisioning profile)
    //PlatformApplicationArn: "arn:aws:sns:us-west-2:xxxxxxxxxxxx:app/APNS_VOIP/CurieVoip",
    Token: deviceVoipToken


  , function(err, data) 
    if (err) 
      console.log(err.stack);
      response.json("status": "failure", "statusCode" : 402)
      return;
    
    var endpointArn = data.EndpointArn;
    req.endpointArn = data.EndpointArn; // Passing the EndpointArn to the next function
    next()
  )



// 2. Publish notification
var publishVoipNotification = function(req, res, next)
  var endpointArn = req.endpointArn;

  var payload = 
    default   : 'Hello World, default payload',
    APNS_VOIP : 
      aps: 
        alert: 'Hi there',
        sound: 'default',
        badge: 1
      
    
  ;

  // first have to stringify the inner APNS object...
  payload.APNS = JSON.stringify(payload.APNS);
  // then have to stringify the entire message payload
  payload = JSON.stringify(payload);

  console.log('sending push');
  amazonSNS.publish(
    MessageStructure  : 'json',
    Message           : payload,
    TargetArn         : endpointArn
  , function(err, data) 
    if (err) 
      console.log("Error stack: "+err.stack);
      var message =  "There has been an error in Publishing message via AmazonSNS with error: "+err.stack;
      res.json("status": "failure", "statusCode" : 402, "message" : message)
      return;
    
    next();
  );



// 3. Deleting platform endpoint after sending a voipNotification; Ref: http://docs.aws.amazon.com/AWSjavascriptSDK/latest/AWS/SNS.html#deleteEndpoint-property
var deleteEndpointArn = function(req, res)
  var endpointArn = req.endpointArn;
  var roomName    = req.roomName;

  var params = 
    EndpointArn: endpointArn /* required */
  ;

  amazonSNS.deleteEndpoint(params, function(err, data) 
    if (err)
      var message = "Unable to deleteEndpointArn, with error: "+err.stack;
      res.json("status": "failure", "statusCode" : 400, "message":message)
    
    else
      var message = "Deleted endpointArn successfully";
      res.json("status": "success", "statusCode" : 200, "message":message)

    
  );

router.post('/sendVoipNotificationToReceiver', [createPlatformEndpoint, publishVoipNotification, deleteEndpointArn]);

【讨论】:

它在 nodejs 中不起作用..?你可以解释吗。我如何集成到 nodejs API..?【参考方案2】:
    转到 Amazon SNS 点击手机:推送通知 点击创建平台应用, 如果您想在沙盒上测试 voip 通知,则用户 Apple 凭据“用于沙盒中的开发”请选中此复选框。 推送证书类型 -- Voip 推送证书 上传证书 .P12 文件。 保存表单并复制 ARN

创建 Lambda 函数。下面的代码示例

// Load the AWS SDK for Node.js
var AWS = require('aws-sdk');
// Set region
AWS.config.update(region: 'us-east-1');

var amazonSNS = new AWS.SNS();

const isset = (s) => 
    return typeof s !== typeof undefined ? true : false;
;

exports.handler =  (event, context, callback) => 
    let data = event['body-json'];
    if (isset(data)) 
        let getAction = data['action'];
        let userToken = data['token'];
        let webPayload = data['payload'];

        if (isset(getAction) && getAction == 'APNS_VOIP') 
            amazonSNS.createPlatformEndpoint(
                PlatformApplicationArn: 'YOUR APPLICATION ARN',
                Token: userToken
            , function (err, data1) 
                if (err) 
                    //handle error
                    console.log(err)
                 else 
                    //Publish notification
                    var endpointArn = data1.EndpointArn;
                    console.log("endpointArn",endpointArn);
                    var payload = 
                        default: 'Silent voip push notification',
                        APNS_VOIP: 
                            //aps:webPayload
                            "aps" : 
                                "alert" : 
                                    "title" : "Call Request"
                                ,
                                "data":webPayload,
                                "content-available":1,
                                "category":"GENERAL"
                            
                        
                    ;
                    payload.APNS_VOIP = JSON.stringify(payload.APNS_VOIP);
                    payload = JSON.stringify(payload);
                    amazonSNS.publish(
                        MessageStructure: 'json',
                        Message: payload,
                        MessageAttributes:
                            "AWS.SNS.MOBILE.APNS.PRIORITY":"DataType":"String","StringValue":"10", 
                            "AWS.SNS.MOBILE.APNS.PUSH_TYPE":"DataType":"String","StringValue":"voip" 
                        ,
                        TargetArn: endpointArn
                    , function (err, data2) 
                        if (err) 
                            //handle error
                            console.log(err)
                         else 
                            var params = 
                                EndpointArn: endpointArn /* required */
                            ;
                            //Deleting platform endpoint after sending a voipNotification; 
                            amazonSNS.deleteEndpoint(params, function (err, data3) 
                                if (err) 
                                    //handle error
                                    //console.log(err);
                                    callback(null, 
                                        "status": "error",
                                        "data": [],
                                        "message": []
                                    );
                                 else 
                                    //code success
                                    console.log("delete",data3);
                                    callback(null, 
                                        "status": "Success",
                                        "data": data3,
                                        "message":"notification sent successfully"
                                    );
                                
                            );
                        
                    );
                
            );
        
        else if (isset(getAction) && getAction == 'APNS_VOIP_SANDBOX') 
            amazonSNS.createPlatformEndpoint(
                PlatformApplicationArn: 'YOUR APPLICATION ARN',
                Token: userToken
            , function (err, data1) 
                if (err) 
                    //handle error
                    console.log(err)
                 else 
                    //Publish notification
                    var endpointArn = data1.EndpointArn;
                    console.log("endpointArn",endpointArn);
                    var payload = 
                            default: 'Silent voip push notification',
                            APNS_VOIP_SANDBOX: 
                        "aps" : 
                            "alert" : 
                                "title" : "Call Request"
                            ,
                            "data":webPayload,
                            "content-available":1,
                            "category":"GENERAL"
                        
                    
                        ;
                    payload.APNS_VOIP_SANDBOX = JSON.stringify(payload.APNS_VOIP_SANDBOX);
                    payload = JSON.stringify(payload);
                    amazonSNS.publish(
                        MessageStructure: 'json',
                        Message: payload,
                        MessageAttributes:
                            "AWS.SNS.MOBILE.APNS.PRIORITY":"DataType":"String","StringValue":"10", 
                            "AWS.SNS.MOBILE.APNS.PUSH_TYPE":"DataType":"String","StringValue":"voip" 
                        ,
                        TargetArn: endpointArn
                    , function (err, data2) 
                        if (err) 
                            //handle error
                            console.log(err)
                         else 
                            var params = 
                                EndpointArn: endpointArn /* required */
                            ;
                            //Deleting platform endpoint after sending a voipNotification; Ref: http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/SNS.html#deleteEndpoint-property
                            amazonSNS.deleteEndpoint(params, function (err, data3) 
                                if (err) 
                                    //handle error
                                    //console.log(err);
                                    callback(null, 
                                        "status": "error",
                                        "data": [],
                                        "message": []
                                    );
                                 else 
                                    //code success
                                    console.log("delete",data3);
                                    callback(null, 
                                        "status": "Success",
                                        "data": data3,
                                        "message":"notification sent successfully"
                                    );
                                
                            );
                        
                    );
                
            );
        
        else 
            callback(null, 
                "status": "error",
                "data": [],
                "message": "You have not posted valid data."
            );
        
    

;

https://docs.aws.amazon.com/sns/latest/dg/sns-send-custom-platform-specific-payloads-mobile-devices.html

How Do I send VoIP push notifications to an iOS device using Amazon SNS in Node JS

【讨论】:

以上是关于如何在 Node JS 中使用 Amazon SNS 向 iOS 设备发送 VoIP 推送通知的主要内容,如果未能解决你的问题,请参考以下文章

如何在 AWS 上的 Amazon Linux AMI 中自动启动 node.js 应用程序?

如何使用 node.js、Express 和 knox 将文件从浏览器上传到 Amazon S3? [关闭]

如何使用 Amazon Elastic Beanstalk 在端口 80 上安全地运行 Node.js 服务器?

Ruby/node.js + Amazon SES:是不是有 Amazon SES API?

如何包含适用于 Node.js 的 Amazon EC2 库?

如何在 Amazon Linux 2 平台上使用 Elastic Beanstalk 部署的 Node Js 中实现 gzip 压缩?