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

Add functions to work with calendar events 📆 #28

Open
8 tasks
arthur-shaw opened this issue Jul 1, 2022 · 3 comments
Open
8 tasks

Add functions to work with calendar events 📆 #28

arthur-shaw opened this issue Jul 1, 2022 · 3 comments
Labels
epic 🗻 Epic containing several related issues

Comments

@arthur-shaw
Copy link
Owner

arthur-shaw commented Jul 1, 2022

Objective 🎯

Provide survey managers a means of observing or dictating the schedule of interviews through getting/setting/updating/deleting calendar events associated with interviews and assignments.

User stories 📇

Tasks ⚙️

Set/update/delete events

Write R functions to wrap these GraphQL mutations:

  • Add events to assignments : addAssignmentCalendarEvent
  • Add events to interviews: addInterviewCalendarEvent
  • Delete calendar events: deleteCalendarEvent
  • Update calendar events: updateCalendarEvent

Get events

Consider also either new R functions or extensions to R functions to get calendar event nodes:

  • Get events for assignments: assignments(...) > nodes > calendarEvent
  • Get events for interviews: interviews(...) > nodes > calendarEvent

Documentation ✍️

  • Create section in reference index page
  • Write vignette on working with calendar events
@arthur-shaw arthur-shaw added the enhancement ↔️ New feature or request label Jul 1, 2022
@petbrueck
Copy link

Hi Arthur,

I am also currently looking into R functions/libraries that allow HeadquartersMutation (addUserToMap to be precise).

ghql apparently does not support any mutation, so I guess no chance in adding this to susoapi itself for the moment?

Do you happen to know any R library that one could use/look into in the short-term for an HeadquartersMutation? Tried to find something, but no luck yet.

Current Workaround
Make use of Zurab's ssaw Python library, to be called from R.

@arthur-shaw
Copy link
Owner Author

@petbrueck , I did a deep(-ish) dive on this and discovered the following:

  1. GraphQL requests can be done via simple curl requests
  2. httr can be used to make these requests via R
  3. GraphQL mutations are just requests where the query body includes the mutation instruction

In short, this means that we can perform mutations without ql

Let me touch on each point in turn before wrapping up with a sketch of th way forward and a request for a PR should you work on the map request 😉

1. GraphQL requests can be done via simple curl requests

When I saw this problem, my immediate reflex, like you, was to find other R packages that operate as GraphQL clients. While I found a few--here and (in a way) here--I realized that this problem could probably be solved via other means when I looked at gh's DESCRIPTION file and only saw httr for making requests. When I looked at the source code, I saw that the interface for GitHub's GraphQL API simply captured a query and transmitted it via httr via the correct verb.

To check whether I was understanding right, I did some Googling and discovered others making GraphQL requests with curl (for which httr is a wrapper) here and here)

2. httr can be used to make these requests via R

After a combination of tinkering and searching, I was able to make GraphQL requests via R.

Here's a nice Gist found on the web.

Here's those ideas translated into our context

my_url <- ''
my_user <-  ""
my_password <- ""
my_query <- '{
    questionnaireItems(
        id: "ccb8455d754942329ed10574e1df67fa"
        version: 3
        workspace: "ftf"
        where: {variable: {eq: "v113"}}
    ) {
        entityType
        variable
        label
        options {
        title
        value
        }
    }
    }'

# NOTE: it seems everyting is a POST request for GraphQL
httr::POST( 
    url = my_url,
    # use same approach to authenication as my other GraphQL wrappers--modified slightly
    # - use `add_headers` so I can add a named list of headers
    # - encode user-password pair
    httr::add_headers(
        Authorization = paste0(
            "Basic ", jsonlite::base64_enc(input = paste0(my_user, ":", my_password))
        )
    ),
    # transmit GraphQL query as the body of post 
    # consider it a query
    body = list(query = my_query),
    encode = "json"
)

3. GraphQL mutations are just requests where the query body includes the mutation instruction

After a few misteps--notably, naming the element of the body mutation--I tried simply keeping body = list(query = my_query), and that worked perfectly, to my surprise

Here's some code that updates an existing calendar event:

my_url <- ''
my_user <-  ""
my_password <- ""

my_query <- 'mutation {
        updateCalendarEvent(
            workspace: "primary", 
            publicKey: "8bbefc98-de2b-4317-9152-a4aa9a05f88b", 
            newStart: "2022-07-11T12:13:00"
            startTimezone: "UTC"
            comment: "Do it this time--seriously"
        ) 
        {
            interviewId
            publicKey
        }
        }'

httr::POST( 
    url = my_url,
    httr::add_headers(
        Authorization = paste0(
            "Basic ", jsonlite::base64_enc(input = paste0(my_user, ":", my_password))
        )
    ),
    body = list(query = my_query),
    encode = "json"
)

Next steps

There might be lots of rough edges to smooth, but the code above provides a blueprint for creating wrappers for GraphQL mutations.

(Honestly, the hardest part for me was figuring out how to write correct mutation. After countless false starts, I learned that a mutation needs also to return something. Hence, the mutation above updates a calendar event and returns the GUID for the calendar event. Without a return requested, the mutation doesn't work. Unfortunately, this is probably basic GraphQL knowledge that I failed to acquire while scanning too quickly through online documentation and tutorials 😉 )

If you happen to start work on wrapping any GraphQL mutations, please do submit a PR.

For the moment, I may concentrate on calendar events--which seem like lower hanging fruit for me. Even though I'd never used calendar event, the concept and API interface are fairly straightforward.

If you'd like to collaborate on wrapping the map mutations, let's connect. Honestly, I've never used this functionality. Consequently, I'm facing the dual learning curve of learning how maps work and how to make them work via the API.

@petbrueck
Copy link

Wow, thanks a ton @arthur-shaw for your deep dive and elaborate response! This indeed sounds fantastic!

Since the HeadquarterMutation addUserToMap becomes 'system-critical' day by day in an upcoming project, I will (need to) give it a try.

As a starter, I tried to tackle the query maps(...) to retrieve existing maps on the server. To this end, I (shamelessly) made an almost 1:1 replica of your get_interviews() set of function. See here. Will try to address the mutation later this week. I'll reach out to you seperately!

@arthur-shaw arthur-shaw changed the title Add functions to work with calendar events Add functions to work with calendar events 📆 Feb 3, 2023
@arthur-shaw arthur-shaw moved this to Backlog in susoapi Feb 3, 2023
@arthur-shaw arthur-shaw added epic 🗻 Epic containing several related issues and removed enhancement ↔️ New feature or request labels Feb 3, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
epic 🗻 Epic containing several related issues
Projects
Status: Backlog 📇
Development

No branches or pull requests

2 participants