Search code examples
stackexchange-api

Finding out when someone voted for your question on Stack Exchange


Here is a question I posted on a Stack Exchange website: https://math.stackexchange.com/questions/4404052/why-is-the-traveling-salesperson-problem-difficult

Is it possible to see a complete history of when (timestamp) each upvote and downvote occurred?

For example:

  score           timestamp cumulative_score
    10 2024-07-31 17:21:33               10
   -10 2024-08-01 02:55:01                0
   -10 2024-08-01 05:11:04              -10
   -10 2024-08-01 06:28:40              -20
    10 2024-08-01 07:15:45              -10
   -10 2024-08-01 13:21:15              -20

Can this be done with the Stack Overflow API?

The closest thing I found was this: https://math.stackexchange.com/posts/4404052/timeline

enter image description here

But this does not contain the full voting history. I do not need to know which users voted - just the times at which the score changed.

References:

Note: The reason I am asking - I am interested in knowing if the intensity at which scores change on a question can be modelled using a random walk (https://en.wikipedia.org/wiki/Random_walk)


Solution

  • Is it possible to see a complete history of when (timestamp) each upvote and downvote occurred?

    No, that is not possible, for security/privacy reasons. The best you get is a vote tally on a date. That goes for the API /question/timeline endpoint

    const ApiUrl = 'https://api.stackexchange.com/2.3/questions/4404052/timeline?site=math&filter=!bbZvl7Y9jHviql'
    
    const providers = {
       'creation_date': getDateTime
    }
    
    function getValue(v) {
      return v;
    }
    
    function getFieldNames(items) {
         const hdrs = items.reduce( (a, c) => { 
          for(const f in c) {
              a[f] = providers[f] ?? getValue
          }
          return a
       }, {})
       return hdrs;
    }
    
    function addHeaders(hdrs) {
         const head = document.getElementById('head')
         const tr = document.createElement('tr')
         for(const h in hdrs) {
            const th = document.createElement('th')
            th.textContent = h
            tr.appendChild(th)
         }
         head.appendChild(tr)
         return hdrs
    }
    
    function zero(v) {
      return v<10?`0${v}`:v.toString()
    }
    
    function getDate(dt) {
      return `${dt.getUTCFullYear()}-${zero(dt.getUTCMonth()+1)}-${zero(dt.getUTCDay())}`
    }
    
    function getTime(dt) {
      return `${zero(dt.getUTCHours())}:${zero(dt.getUTCMinutes())}:${zero(dt.getUTCSeconds())}`
    }
    
    function getDateTime(v) {
      const d = new Date(v * 1000)
      return `${getDate(d)} ${getTime(d)} `
    }
    
    function addRowForItem(item, hdrs) {
      const tr = document.createElement('tr')
      for(const f in hdrs) {
         const td = document.createElement('td')
         td.textContent = hdrs[f](item[f])
         tr.appendChild(td)
      }
      return tr
    }
    
    function addRows(items, tbody) {
       const hdrs = addHeaders(getFieldNames(items))
       items
         .map(i => addRowForItem(i,hdrs))
         .forEach(i => tbody.appendChild(i))
    }
    
    function addError(err) {
      addRows([err], document.getElementById('list'))
    }
    
    fetch(ApiUrl)
      .then( r => r.json())
      .then( j => j.items ?? [j])
      .then( items => addRows(items, document.getElementById('list')))
      .catch( e => addError(e))
    * {
      font-family: sans-serif;
    }
    
    th, td {
      text-align:right;
      border: solid black 1px;
      padding: 3px;
    }
    <table>
    <thead id='head'>
    </thead>
    <tbody id='list'>
    </tbody>
    </table>

    as well as for the Stack Exchange Data Explorer or data dump for that matter:

    select *
    from votes
    where postid=4404052
    and votetypeid in (1,2,3) -- accept, up, down
    

    By having timestamps with seconds precision would make it too easy to link activity of users to their voting. For the record: not even moderators have access to these timestamps. Even for them voting is anonymous.