11

I'm trying to track user activity as they go through my shiny app. I have functions placed at specific locations which write lines to a temporary file. What I want is to have a function which is called when the user session ends.

According to the documentation:

> ?session
> onSessionEnded(callback)  
      Registers a function to be called after the client has disconnected. Returns a function that can be called with no arguments to cancel the registration.

I tried to use this:

session$onSessionEnded(function(x){
  a = read_csv(shinyActivityTmpFile_000)
  write_csv(a,'C:\\Users\\xxxx\\Desktop\\test.csv')
})

But nothing happened. shinyActivityTmpFile_000 is a global file reference. As the user clicks buttons and does stuff, the app is writing out to this file in a CSV format. I'm just trying to move it from temporary storage to permanent storage. Ultimately I'd like the function to write it to a database but for testing I'm just trying to get a function that will run when the app is closed.

What am I missing here?

Mark
  • 4,387
  • 2
  • 28
  • 48

2 Answers2

21

Hi I don't know how you construct the shinyActivityTmpFile file, but for using onSessionEnded you can look at this exemple, it write in a file the datetime when an app is launched and when the app is closed :

library("shiny")
ui <- fluidPage(
  "Nothing here"
)
server <- function(input, output, session) {
  # This code will be run once per user
  users_data <- data.frame(START = Sys.time())

  # This code will be run after the client has disconnected
  session$onSessionEnded(function() {
    users_data$END <- Sys.time()
    # Write a file in your working directory
    write.table(x = users_data, file = file.path(getwd(), "users_data.txt"),
                append = TRUE, row.names = FALSE, col.names = FALSE, sep = "\t")
  })
}
shinyApp(ui = ui, server = server)

If you use a server with authentication, you can retrieve the username with :

users_data <- data.frame(USERS = session$user, START = Sys.time())
Victorp
  • 13,636
  • 2
  • 51
  • 55
  • 1
    Is there any way to specify only one session to do something when the session ends. For example `session$onSessionEnded( function(){ if(userID==1) cat("Do Something Wild") }) ` – Jordan Mar 02 '18 at 21:01
  • @Jordan please check my answer – Clemsang Oct 09 '19 at 07:36
0

Based on @Victorp answer and reply to the comment about arguments to session$onSessionEnded. It is possible to add an argument to the function using a default parameter:

server <- function(input, output, session) {
  # This code will be run once per user
  users_data <- data.frame(USERS = session$user, START = Sys.time())

  # This code will be run after the client has disconnected
  session$onSessionEnded(function(userID = users_data$USERS) {
      if(userID==1){
          users_data$END <- Sys.time()
          # Write a file in your working directory
          write.table(x = users_data, file = file.path(getwd(), "users_data.txt"),
                      append = TRUE, row.names = FALSE, col.names = FALSE, sep = "\t")
      }
  })
}
shinyApp(ui = ui, server = server)
Clemsang
  • 5,053
  • 3
  • 23
  • 41