3

Update

This expression will evaluate to show the cause. The only requirement is an emacs with url. As you can see, the result from using curl and that from using the url package is different. Fields upvoted, downvoted, and body_markdown are missing from the url request. What is differing between these two requests, and how can I fix the problem?

I recommend instrumenting the function before evaluating it.

Since this issue is bordering off-topic now, I'm going to post this question on Emacs.SE. The underlying issue though still concerns the API. I believe these two issues have the same cause, but if I should post this as a separate question for tracking purposes, just let me know.

(defconst access-token
  "YOUR ACCESS TOKEN")

(defconst key
  "AN API KEY")

(defun tmp:api-bug (use-curl access-token key)
  "Post a test answer to the formatting sandbox."
  (let ((random-body-1 (md5 (current-time-string)))
        (random-body-2 (md5 (md5 (current-time-string))))
        (method "https://api.stackexchange.com/2.2/questions/3122/answers/add")
        (args
         (mapconcat
          #'identity
          `(,(format "access_token=%s"
                     (replace-regexp-in-string
                      "%" "%%" (url-hexify-string access-token)))
            ,(format "key=%s"
                     (replace-regexp-in-string
                      "%" "%%" (url-hexify-string key)))
            "site=meta"
            "pagesize=100"
            "filter=%%21GoYr1we0U5inG5G7wBg4JBGpbgX%%29C7LDqpy-%%2AbfwPOujOr4SR4W%%29bLNSyYUpQDdTwTj.XChTFB0gfLaAJq0hv"
            "body=this-is-an-answer-test-for-sx.el--%s")
          "&")))

    (if use-curl
        (shell-command-to-string
         (format
          "curl --silent -X POST --data %S %s | gunzip"
          (format args random-body-2)
          method))
      (let ((url-automatic-caching t)
              (url-inhibit-uncompression t)
              (url-request-data (format args random-body-1))
              (url-request-method "post")
              (url-request-extra-headers
               '(("Content-Type" . "application/x-www-form-urlencoded"))))
          (with-current-buffer
              (url-retrieve-synchronously method)
            (goto-char (point-min))
            (search-forward "\n\n")
            (delete-region (point-min) (point))
            (buffer-string))))))

(tmp:api-bug t access-token key)
"{\"items\":[{\"owner\":{\"reputation\":160,\"display_name\":\"Sean Allred\"},\"downvoted\":false,\"upvoted\":false,\"score\":0,\"last_activity_date\":1421684370,\"creation_date\":1421684370,\"answer_id\":247295,\"share_link\":\"http://meta.stackexchange.com/a/247295/188148\",\"body_markdown\":\"this-is-an-answer-test-for-sx.el--e3eeb6228ed9c2c58e5385b73493f0f0\",\"link\":\"http://meta.stackexchange.com/questions/3122//247295#247295\"}],\"has_more\":false,\"quota_max\":10000,\"quota_remaining\":9979,\"page\":1,\"page_size\":100,\"total\":1}"

(tmp:api-bug nil access-token key)
"{\"items\":[{\"owner\":{\"reputation\":160,\"display_name\":\"Sean Allred\"},\"score\":0,\"last_activity_date\":1421684555,\"creation_date\":1421684555,\"answer_id\":247297,\"share_link\":\"http://meta.stackexchange.com/a/247297/188148\",\"link\":\"http://meta.stackexchange.com/questions/3122//247297#247297\"}],\"has_more\":false,\"quota_max\":10000,\"quota_remaining\":9977,\"page\":1,\"page_size\":100,\"total\":1}"

When upvoting an answer via the API, preview=true gives the correct new score value but preview=false does not. When the following expressions are evaluated, we receive different responses.

(sx-method-call "answers"
  :id 7192
  :submethod "upvote"
  :auth 'warn
  :url-method 'post
  :keywords (list (cons 'preview 'true))             ;; NOTE
  :site "emacs")

=>
[((question_id . 7189)
  (answer_id . 7192)
  (creation_date . 1420761994)
  (last_edit_date . 1420762419)
  (last_activity_date . 1420762419)
  (score . 4)
  (is_accepted . t)
  (owner
   (link . "https://emacs.stackexchange.com/users/105/drew")
   (display_name . "Drew")
   (profile_image . "https://www.gravatar.com/avatar/32a8e553d85d193ee5ae1533ce6ec158?s=128&d=identicon&r=PG&f=1")
   (user_type . "registered")
   (user_id . 105)
   (reputation . 6689)))]

versus

(sx-method-call "answers"
  :id 7192
  :submethod "upvote"
  :auth 'warn
  :url-method 'post
  :keywords (list (cons 'preview 'false))            ;; NOTE
  :site "emacs")

=>
[((question_id . 7189)
  (answer_id . 7192)
  (creation_date . 1420761994)
  (last_edit_date . 1420762419)
  (last_activity_date . 1420762419)
  (score . 3)
  (is_accepted . t)
  (owner
   (link . "https://emacs.stackexchange.com/users/105/drew")
   (display_name . "Drew")
   (profile_image . "https://www.gravatar.com/avatar/32a8e553d85d193ee5ae1533ce6ec158?s=128&d=identicon&r=PG&f=1")
   (user_type . "registered")
   (user_id . 105)
   (reputation . 6689)))]

Note the difference:

  • when preview=true, .score=4
  • when preview=false, .score=3

However, the POST does succeed; .score is updated when you re-retrieve the answer:

(sx-method-call "answers"
  :id 7192
  :site "emacs")

=>
[((question_id . 7189)
  (answer_id . 7192)
  (creation_date . 1420761994)
  (last_edit_date . 1420762419)
  (last_activity_date . 1420762419)
  (score . 4)
  (is_accepted . t)
  (owner
   (link . "https://emacs.stackexchange.com/users/105/drew")
   (display_name . "Drew")
   (profile_image . "https://www.gravatar.com/avatar/32a8e553d85d193ee5ae1533ce6ec158?s=128&d=identicon&r=PG&f=1")
   (user_type . "registered")
   (user_id . 105)
   (reputation . 6699)))]

Note that to reproduce the issue with the Elisp examples provided, you must sx-authenticate first.


I cannot figure out how to correctly POST to the API with curl, so feel free to edit this Q to use curl if you know how. As it stands, clone SX -- Stack Exchange for Emacs! (or install M-x package-install RET sx RET from MELPA) and require sx-load.

Cross-reference vermiculus/sx.el#223, Emacs.SE question

1 Answer 1

1

Annoyingly, the problem was here: (url-request-method "post").

Changing that to (url-request-method "POST") fixes everything.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .