Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pbPush sends to multiple devices even when recipients is specified #39

Closed
harrismcgehee opened this issue Feb 3, 2017 · 15 comments
Closed

Comments

@harrismcgehee
Copy link

@harrismcgehee harrismcgehee commented Feb 3, 2017

I'm not sure how to create a reproducible example to show that
pbPost("note", "A Simple Test", "We think this should work.\nWe really do.", recipients = 3L) is sending notifications to "phone" (1L) and "Chrome" (3L). In pbSetup, I set "Chrome" to be the default device.
pbPost("note", "A Simple Test", "We think this should work.\nWe really do.") also sends pushes to both devices.

The verbose output only lists a single device in $target_device_iden.

What else can I provide to help diagnose the issue?

@eddelbuettel
Copy link
Owner

@eddelbuettel eddelbuettel commented Feb 3, 2017

It's tricky. I also have notication mirroring turned on as a Pushbullet feature so everything comes to Chrome anyway so I am not sure.

Maybe the best would be to do what we did before and try tests with curl on the command-line to rule out backend issues. If that behaves differently then we know it is our code.

@eddelbuettel
Copy link
Owner

@eddelbuettel eddelbuettel commented Feb 4, 2017

I poked around using the curl front-end and cut not get it to work. This clearly worked in the past. I am not so sure why it no longer does. :-/

@restonslacker Any idea?

@restonslacker
Copy link
Contributor

@restonslacker restonslacker commented Feb 4, 2017

Just took a quick look and didn't see the issue either. Will look more during kid's nap time.

@restonslacker
Copy link
Contributor

@restonslacker restonslacker commented Feb 4, 2017

Clarify: I was able to reproduce the noted problem, but haven't seen an obvious cause.

@eddelbuettel
Copy link
Owner

@eddelbuettel eddelbuettel commented Feb 4, 2017

My understanding is that the semantics are such that if one or more targets are successfully defined they will get notified. If none are specified, all known device are satisfied.

We seem to always be getting the second behaviour irregardless of the values of device_iden or target_device_iden or receiver_device_iden. Certain approaches leads to reject and error, others just blast to all.

It looks like "their" side to me but I am not 100% sure.

@restonslacker
Copy link
Contributor

@restonslacker restonslacker commented Feb 4, 2017

some more quick testing. ver 0.2.0 did not show this behavior.

i tried switching the change made in 8ccadb9 back, namely using device_iden instead of target_device_iden and the expected behavior returned. however, this seems to run counter to what @eddelbuettel just noted so i guess we need to keep digging.

@eddelbuettel
Copy link
Owner

@eddelbuettel eddelbuettel commented Feb 4, 2017

Is that with CRAN package curl or /usr/bin/curl ? I used the latter yesterday with this simple helper script:

#!/bin/bash

key=$(r -ljsonlite -e 'cat(fromJSON("~/.rpushbullet.json")$key)')
iden=$(r -ljsonlite -e 'cat(fromJSON("~/.rpushbullet.json")[["devices"]][2])')
echo "'${key}' -- '${iden}'"

## curl https://api.pushbullet.com/v2/pushes \
##   -u <your_api_key_here>: \
##   -d device_iden="<your_device_iden_here>" \
##   -d type="note" \
##   -d title="Note title" \
##   -d body="note body" \
##   -X POST

res=$(curl -s https://api.pushbullet.com/v2/pushes -u ${key}: \
      -d device_iden "ujuWgrDEKe4djz99WkCibI" \
      -d type="note" -d title="No Title" -d body="Empty body" \
      -X POST)

echo "${res}"

I tried all possibly permutations I could, no mas.

@restonslacker
Copy link
Contributor

@restonslacker restonslacker commented Feb 4, 2017

the test i described was with cran package curl and the code from RPushbullet 0.3.0. I only have my wife's laptop at the moment so i have all the niceties like git configured but this is the function that i ran. Besides the previously noted change, I added RPushbullet::: in various spots to expose the internal functions.

pbPost2 <- function (type = c("note", "link", "file"), title = "", body = "", 
                     url = "", filetype = "text/plain", recipients, email, channel, 
                     deviceind, apikey = RPushbullet:::.getKey(), devices = RPushbullet:::.getDevices(), verbose = FALSE, 
                     debug = FALSE) 
{
  type <- match.arg(type)
  if (type == "address") {
    warning("Pushes of type 'address' are no longer supported by the Pushbullet ", 
            "service. Attempt to push '", body, "' failed.")
    invisible(return(NA_character_))
  }
  if (!missing(deviceind)) {
    if (missing(recipients) && missing(email) && missing(channel)) {
      warning("Agument 'deviceind' is deprecated. Please use 'recipients'.", 
              call. = FALSE)
      recipients <- deviceind
    }
    else {
      warning("Using 'recipients' (or 'email' or 'channel') and ", 
              "ignoring deprecated 'deviceinds'.", call. = FALSE)
    }
  }
  if (missing(recipients) && missing(email) && missing(channel)) {
    if (debug) 
      message("missing recipient and email and channel")
    recipients <- RPushbullet:::.getDefaultDevice()
    if (recipients == 0) {
      dest <- ""
    }
    else {
      dest <- match(recipients, RPushbullet:::.getNames())
    }
    email <- channel <- NA
  }
  else {
    if (!missing(recipients)) {
      if (is.character(recipients)) {
        dest <- match(recipients, RPushbullet:::.getNames())
      }
      else {
        dest <- recipients
      }
      email <- NA
    }
    else {
      if (!missing(email)) {
        dest <- email
      }
      else {
        dest <- channel
        email <- NA
      }
    }
  }
  if (debug) 
    cat("dest is: ", dest, "\n")
  pburl <- "https://api.pushbullet.com/v2/pushes"
  if (type == "file") {
    if (url != "" && filetype != "") {
      url <- normalizePath(url)
      uploadrequest <- RPushbullet:::.getUploadRequest(filename = url, 
                                         filetype = filetype)
      h <- RPushbullet:::.getCurlHandle(apikey)
      form_list <- list(awsaccesskeyid = uploadrequest$data[["awsaccesskeyid"]], 
                        acl = uploadrequest$data[["acl"]], key = uploadrequest$data[["key"]], 
                        signature = uploadrequest$data[["signature"]], 
                        policy = uploadrequest$data[["policy"]], `content-type` = uploadrequest$data[["content-type"]], 
                        file = curl::form_file(url, filetype))
      curl::handle_setform(h, .list = form_list)
      uploadresult <- curl::curl_fetch_memory(uploadrequest$upload_url, 
                                              h)
      if (uploadresult$status_code != 204) {
        warning("file upload attempt failed with status code: ", 
                uploadresult$status_code)
        return(rawToChar(uploadresult$content))
      }
    }
  }
  ret <- lapply(dest, function(d) {
    if (debug) 
      message(sprintf("in lapply, d is: %s", d))
    if (is.character(d)) {
      if (!is.na(email)) {
        tgt <- list(email = d)
      }
      else {
        tgt <- list(channel_tag = d)
      }
    }
    else if (is.numeric(d)) {
      if (d == 0) 
        tgt <- list()
      else tgt <- list(device_iden = devices[[d]])
    }
    else {
      tgt <- list()
    }
    form_list <- tgt
    switch(type, note = {
      form_list[["type"]] <- "note"
      form_list[["title"]] <- title
      form_list[["body"]] <- body
    }, link = {
      form_list[["type"]] <- "link"
      form_list[["title"]] <- title
      form_list[["body"]] <- body
      form_list[["url"]] <- url
    }, file = {
      form_list[["type"]] <- "file"
      form_list[["file_name"]] <- basename(uploadrequest$file_name)
      form_list[["file_type"]] <- uploadrequest$file_type
      form_list[["file_url"]] <- uploadrequest$file_url
      form_list[["body"]] <- body
    })
    if (verbose) 
      print(form_list)
    RPushbullet:::.createPush(pburl, apikey, form_list)
  })
  invisible(ret)
}

and then used these calls:

pbPost2("note","simple test 01", recipients = 1L)
pbPost2("note","simple test 02", recipients = 2L)
pbPost2("note","simple test default")
pbPost2("note","simple test all", recipients = 0L)
@eddelbuettel
Copy link
Owner

@eddelbuettel eddelbuettel commented Feb 4, 2017

And that worked? Will poke some more later.

@restonslacker
Copy link
Contributor

@restonslacker restonslacker commented Feb 4, 2017

yes, that worked.

the pushbullet documentation is a little confusing, but I think that we want device_iden. From the section on create-push

device_iden - Send the push to a specific device. Appears as target_device_iden on the push. You can find this using the /v2/devices call.

my interpretation is that if you query the service for an already created push, target_device_iden would be in the returned json object.

@eddelbuettel
Copy link
Owner

@eddelbuettel eddelbuettel commented Feb 4, 2017

Right. For some reason I fail to understand, there is a handshake going on with /usr/bin/curl that makes it go to all. I will test your function to see if maybe my Pushbullet account params interfere.

@eddelbuettel
Copy link
Owner

@eddelbuettel eddelbuettel commented Feb 4, 2017

I just renamed your function to localPbPost() in the attic/ folder (not yet committed). Still no joy:

R> fromJSON(localPbPost("note", "simple test 01", recipients="Tablet", debug=TRUE)[[1]])
dest is:  2 
in lapply, d is: 2
$error
$error$code
[1] "invalid_param"

$error$type
[1] "invalid_request"

$error$message
[1] "The param 'device_iden' has an invalid value."

$error$param
[1] "device_iden"

$error$cat
[1] ">:3"


$error_code
[1] "invalid_param"

Warning message:
400: Bad Request - Usually this results from missing a required parameter. 
R> fromJSON(localPbPost("note", "simple test 01", recipients=2L, debug=TRUE)[[1]])
dest is:  2 
in lapply, d is: 2
$error
$error$code
[1] "invalid_param"

$error$type
[1] "invalid_request"

$error$message
[1] "The param 'device_iden' has an invalid value."

$error$param
[1] "device_iden"

$error$cat
[1] ">:3"


$error_code
[1] "invalid_param"

Warning message:
400: Bad Request - Usually this results from missing a required parameter. 
R> 
@eddelbuettel
Copy link
Owner

@eddelbuettel eddelbuettel commented Feb 4, 2017

DOH!!!

The device identifiers in my (old, existing) ~/.rpushbullet.json were no longer the same as those now retrieved by pbSetup(). So no wonder I never got to hit the targeted devices ... as their handles changed.

Will revert the target_device_ind to device_ind. Nice hole I fell into here.

And thanks again for continued help though.

@harrismcgehee
Copy link
Author

@harrismcgehee harrismcgehee commented Feb 4, 2017

Can confirm that this worked! Thanks so much for the quick turn around. I'm very impressed.
And thanks for all of the other work you do with R and Rcpp.

@restonslacker
Copy link
Contributor

@restonslacker restonslacker commented Feb 4, 2017

@eddelbuettel glad I'm not completely crazy. Happy to help when I can.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
3 participants
You can’t perform that action at this time.