Azure / Microsoft365R

R SDK for interacting with Microsoft 365 APIs
Other
308 stars 42 forks source link

list_emails search option broken #159

Closed SHogenboom closed 1 year ago

SHogenboom commented 1 year ago

I have code which worked just fine for about a year - but all of a sudden returns a very illegible error:

Error: parse error: premature EOF
                                       {"@odata.context":"https://grap
                     (right here) ------^

The code segment which causes the problem is listed below. The full package code is available via https://github.com/SHogenboom/yOUrEmail

# Get submissions
  submissions_from_system <-
    # Access the outlook environment
    outlook$
    # Get the submissions folder's content (defaults to inbox)
    get_folder(folder_name = submissions_folder)$
    # Retrieve only the emails from the submission system
    list_emails(
      search =
        glue::glue(
          "from:{submissions_email}",
          dplyr::case_when(
            email_status == "all" ~ "",
            email_status == "read" ~ " AND isread:yes",
            email_status == "unread" ~ " AND isread:no"
          )
        )
    )

I’m not sure why the issue occurs because when I remove the email adress the error persists, but when I provide an ininformative string for the ‘from’ field - no error occurs.

Any help would be greatly appreciated!

hongooi73 commented 1 year ago

That looks like an error from jsonlite; your email address may have some funny characters in it. Please post the exact code you ran and the errors you got.

SHogenboom commented 1 year ago

I tried two options both caused a problem:

  1. The code as it worked for about a year:

    # Get submissions
    submissions_from_system <-
    # Access the outlook environment
    outlook$
      # Get the submissions folder's content (defaults to inbox)
      get_folder(folder_name = submissions_folder)$
      # Retrieve only the emails from the submission system
      list_emails(search = “from:submit@oupsy.nl AND isread:no")
  2. Without the email adress (because of the ‘@‘ in the error message):

# Get submissions
  submissions_from_system <-
    # Access the outlook environment
    outlook$
      # Get the submissions folder's content (defaults to inbox)
      get_folder(folder_name = submissions_folder)$
      # Retrieve only the emails from the submission system
      list_emails(search = “isread:no")

Both result in the same error described above. The code works when I remove the search parameter and only list_emails()

hongooi73 commented 1 year ago

First, there's a smart quote in there. Double-check that you haven't got this in your code that you're submitting.

I can run a list including a search parameter without problems. How many emails do you have in that folder? It's possible that the search is running into problems with too many emails.

SHogenboom commented 1 year ago

Sorry about the quote, that is just a typing error when adjusting the code in the reply. There are only normal quotes in the actual code.

There are 7 emails in the folder - so highly doubt scoping is the issue.

What version of R are you on? I haven’t yet updated to the most recent version. I’m still on R version 4.2.1 (2022-06-23). Then again, the code worked fine until about two weeks ago.

hongooi73 commented 1 year ago

Try running the search, but add in the n argument to limit the number of returned objects

folder$list_emails(search="...", n=1)
folder$list_emails(search="...", n=2)
...

until you get an error. This might help in narrowing down where exactly the problem occurs.

SHogenboom commented 1 year ago

The error occurs straight from n=1.

hongooi73 commented 1 year ago

Ok, I get the same error when running this query on my inbox:

inb$list_emails(search="isread:yes")

In my case there are no unread emails, so it should just be returning everything. Although... where did you find the 'isread' property? It doesn't show up in the list at https://learn.microsoft.com/en-us/graph/search-query-parameter?tabs=http#using-search-on-message-collections

SHogenboom commented 1 year ago

Not sure where I got the parameter from… I may have derived it from some other examples. I do remember it took a lot of tweaking the syntax. However, it has worked for a couple of months and only stopped working two weeks ago. In addition, the ‘from’ parameter which is listed does not work either - even when applied alone. So that’s not the issue I think

hongooi73 commented 1 year ago

After some digging with the low-level AzureGraph functions, it looks like the underlying Graph API is trying to throw an error but screwing it up:

ot <- get_personal_outlook()
inb <- ot$get_inbox()
z <- inb$do_operation("messages", options=list(`$search`='"from:hong"'),
    http_status_handler="pass")
httr::content(z, as="text")

[1] "{\"@odata.context\":\"https://graph.microsoft.com/beta/$metadata#users('d6279dff955d6a0e')/mailFolders('AQMkADAwATM3ZmYAZS04MGFjLWMwYWQtMDACLTAwCgAuAAADIPDHp8XbYUynn1y8tTMabwEAkyaf9Qh6Bk28Itk1AVbwXwAAAgEMAAAA')/messages\",\"value\":[{\"error\":{\"code\":\"ErrorInvalidIdMalformed\",\"message\":\"Id is malformed.\"}}"

That string is malformed JSON, it's missing a couple of closing braces/brackets. Also, if it's communicating an error, it shouldn't be returning a HTTP 200 code.

The error only happens with immutable message IDs turned on, which has always been the default in this package. My guess is that MS made a change in the Graph backend which is causing this problem; it should only be temporary.

I'll add an option to turn immutable IDs off, but for now your best bet is to retrieve all the emails and do the filtering locally. All the email properties are available under email_object$properties.

hongooi73 commented 1 year ago

https://github.com/microsoftgraph/microsoft-graph-docs-contrib/issues/106

hongooi73 commented 1 year ago

https://github.com/Azure/Microsoft365R/commit/8c6991f7136cd487b413774aec10850165c54cf0

SHogenboom commented 1 year ago

Thanks for digging deeper! Have implemented your suggested solution for now. That works well as long as I keep the folder a minimal size.