tmijs / tmi.js

💬 Javascript library for the Twitch Messaging Interface. (Twitch.tv)
https://tmijs.com
MIT License
1.54k stars 217 forks source link

Using API to put values does not appear to actually use a put... #166

Closed Anaerin closed 7 years ago

Anaerin commented 7 years ago

I am using the client.api() functionality, but it appears PUT requests aren't working as expected.

I'm sending as my request object:

{
  "url": "https://api.twitch.tv/kraken/channels/anaerin",
  "method": "PUT",
  "json": true,
  "headers": {
    "Accept": "application/vnd.twitchtv.v3+json",
    "Client-ID": "<OBSCURED>",
    "Authorization": "OAuth <OBSCURED>"
  },
  "body": {
    "channel": {
      "game": "No Man's Sky",
      "status": "You can't take the sky from no man..."
    }
  }
}

Which, according to the documentation for the request library, should execute a PUT of a json-stringified channel object to the API.

And I'm getting in response:

{
  "mature": true,
  "status": "Boom Boom Boom Boom...",
  "broadcaster_language": "en",
  "display_name": "Anaerin",
  "game": "Armored Warfare",
  "language": "en",
  "_id": 18517421,
  "name": "anaerin",
  "created_at": "2010-12-06T01:32:27Z",
  "updated_at": "2016-08-08T03:31:20Z",
  "delay": null,
  "logo": "https://static-cdn.jtvnw.net/jtv_user_pictures/anaerin-profile_image-337ba98d35fa7166-300x300.png",
  "banner": null,
  "video_banner": "https://static-cdn.jtvnw.net/jtv_user_pictures/anaerin-channel_offline_image-3635b267606082a3-1920x1080.jpeg",
  "background": null,
  "profile_banner": "https://static-cdn.jtvnw.net/jtv_user_pictures/anaerin-profile_banner-918bef38d98e2e84-480.jpeg",
  "profile_banner_background_color": "#000000",
  "partner": false,
  "url": "https://www.twitch.tv/anaerin",
  "views": 156,
  "followers": 17,
  "_links": {
    // Truncated for brevity
  }
}

Which contains the previous details, not the newly updated ones.

Any suggestions?

Server configuration

AlcaDesign commented 7 years ago

The utils.merge function overwrites options.method with "GET" for some reason. I suggest requiring the request module outright for now. You could also use the method overwrite option:

{
    /* ... */
    qs: {
        _method: 'put'
    },
    /* ... */
}
Anaerin commented 7 years ago

The method overwrite doesn't work, unfortunately, as the request body is ignored/removed. Fortunately, going around works just fine:

const Request = require("request"); // Temporary, to work around a bug in tmi.js
putAPIValue(url, data, callback) {
    var requestObj = {
        url: url,
        method: "PUT",
        json: true,
        headers: {
            Accept: "application/vnd.twitchtv.v3+json",
            'Client-ID': this.oAuth.clientID,
            Authorization: "OAuth " + this.oAuth.accessToken
        },
        body: data
    }
    // The following call is broken right now: https://github.com/tmijs/tmi.js/issues/166
    // var request = this.tmi.api(requestObj, callback);
    // Use request directly instead, until it's fixed.
    var request = Request(requestObj, callback);
}
AlcaDesign commented 7 years ago

You'll be making a GET request so put your values in qs with the _method override.

client.api({
    baseUrl: 'https://api.twitch.tv/kraken/',
    url: 'channels/alca',
    headers: {
        Accept: 'application/vnd.twitchtv.v3+json',
        'Client-ID': '...',
        Authorization: 'OAuth ...'
    },
    qs: {
        channel: {
            status: 'Playin\' some CS:GO! or whatever',
            game: 'Counter-Strike: Global Offensive',
            delay: 0,
            channel_feed_enabled: true
        },
        _method: 'put'
    }
}, callback);
Anaerin commented 7 years ago

Has this actually been fixed, because I don't see a checkin that deals with it. And in some cases (doing OAuth Authentication, for instance), using the QueryString workaround is undesirable, as the POST sends the client_secret. So rather than using this barely-documented workaround, it would be very nice if it worked as expected.