pFad - Phone/Frame/Anonymizer/Declutterfier! Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

URL: http://github.com/twitchdev/channel-points-node-sample/pull/4.patch

+ return false + } + } + + } + + async validateToken() { + try { + await axios.get(`https://id.twitch.tv/oauth2/validate`, { + headers: this.headers + }) + + return true + } catch (err) { + console.log('Invalid token. Please get a new token using twitch token -u -s "channel:manage:redemptions user:edit:follows"'); + return null + } + } + + async GetUserIdTwitch() { + try { + const responseTwitch_id = await axios.get(`https://id.twitch.tv/oauth2/validate`, { + headers: this.headers + }) + + return responseTwitch_id.data.user_id + } catch (err) { + return null + } + } + + async getCustomRewards() { + try { + // user_id + const userId = await this.GetUserIdTwitch() + + if (userId !== null) { + const responseTwitch_CustomRewards = await axios.get(`https://api.twitch.tv/helix/channel_points/custom_rewards?broadcaster_id=${userId}`, { + headers: this.headers + }) + + return responseTwitch_CustomRewards.data + } + + return `UserId null` + } catch (error) { + console.log(error.response.data.message); + return null + } + } + + async addCustomReward() { + try { + const userId = await this.GetUserIdTwitch() + + const reponseTwtich_AddCustomReward = await axios.post(`https://api.twitch.tv/helix/channel_points/custom_rewards?broadcaster_id=${userId}`, this.customRewardBody, { + headers: this.headers + }) + + return { + rewardId: reponseTwtich_AddCustomReward.data[0].id, + success: true + } + } catch (error) { + console.log(error.response.data.message); + return false + } + } + + async pollForRedemptions() { + try { + const userId = await this.GetUserIdTwitch() + const data = await this.addCustomReward() + + const responseTwitch_PollForRedemptions = await axios.post(`https://api.twitch.tv/helix/channel_points/custom_rewards/redemptions?broadcaster_id=${userId}&reward_id=${data.rewardId}&status=UNFULFILLED`, { + headers: this.headers + }) + + let redemptions = responseTwitch_PollForRedemptions.data + let successfulRedemptions = [] + let failedRedemptions = [] + + for (let redemption of redemptions) { + // can't follow yourself :) + if (redemption.broadcaster_id == redemption.user_id) { + failedRedemptions.push(redemption.id) + continue + } + // if failed, add to the failed redemptions + if (await this.followUser(redemption.broadcaster_id, redemption.user_id) == false) { + failedRedemptions.push(redemption.id) + continue + } + // otherwise, add to the successful redemption list + successfulRedemptions.push(redemption.id) + } + + // do this in parallel + await Promise.all([ + this.fulfillRewards(successfulRedemptions, "FULFILLED"), + this.fulfillRewards(failedRedemptions, "CANCELED") + ]) + + console.log(`Processed ${successfulRedemptions.length + failedRedemptions.length} redemptions.`) + + // instead of an interval, we wait 15 seconds between completion and the next call + setTimeout(this.pollForRedemptions, 15 * 1000) + } catch (error) { + console.log("Unable to fetch redemptions.") + } + } + + async fulfillRewards(ids, status) { + // if empty, just cancel + if (ids.length == 0) { + return + } + + // transforms the list of ids to ids=id for the API call + ids = ids.map(v => `id=${v}`) + + const userId = await this.GetUserIdTwitch() + const data = await this.addCustomReward() + + try { + await axios.patch(`https://api.twitch.tv/helix/channel_points/custom_rewards/redemptions?broadcaster_id=${userId}&reward_id=${data.rewardId}&${ids.join("&")}`, { + headers: this.headers, + json: { + status: status + } + }) + } catch (error) { + console.log(error) + } + } + +} + +module.exports = TwitchTools \ No newline at end of file diff --git a/src/index.js b/src/index.js new file mode 100644 index 0000000..14bcf88 --- /dev/null +++ b/src/index.js @@ -0,0 +1,40 @@ +const TwitchTools = require("./Class/TwitchTools"); +require("dotenv").config() + +const customRewardBody = { + title: "Sample: Follow me!", + prompt: "Follows the requesting user!", + cost: 10 * 1000 * 1000, + is_enabled: true, + is_global_cooldown_enabled: true, + global_cooldown_seconds: 10 * 60, +} + +const ToolsTwitch = new TwitchTools(process.env.TwitchAccessToken, process.env.TwitchClientId, customRewardBody) + +// main function - sets up the reward and sets the interval for polling +const main = async () => { + if (await ToolsTwitch.validateToken() === null) return + let rewardId = "" + + let rewards = await ToolsTwitch.getCustomRewards() + if (rewards !== null) { + rewards.forEach(v => { + // since the title is enforced as unique, it will be a good identifier to use to get the right ID on cold-boot + if (v.title == customRewardBody.title) { + rewardId = v.id + } + }) + } else { + console.log("The streamer does not have access to Channel Points. They need to be a Twitch Affiliate or Partner."); + } + // if the reward isn't set up, add it + if (rewardId == "" && await ToolsTwitch.addCustomReward() === false) { + return + } + + ToolsTwitch.pollForRedemptions() +} + +// start the script +main() \ No newline at end of file diff --git a/test/test.js b/test/test.js new file mode 100644 index 0000000..8310e9c --- /dev/null +++ b/test/test.js @@ -0,0 +1,23 @@ +const TwitchTools = require("../src/Class/TwitchTools"); + +// customRewardBody +const customRewardBody = { + title: "Sample: Follow me!", + prompt: "Follows the requesting user!", + cost: 10 * 1000 * 1000, + is_enabled: true, + is_global_cooldown_enabled: true, + global_cooldown_seconds: 10 * 60, +} + + +const ToolsTwitch = new TwitchTools('10z462rarqn42whrqd0cbpuhfyifdk','faxsoydixvpqrncuis1a76u6czvxhr') + +// test validadeToken +// ToolsTwitch.GetUserIdTwitch().then((res) => console.log(res)) + +// test getCustomRewards +// ToolsTwitch.getCustomRewards().then(res => console.log(res)) + +// test addCustomReward +ToolsTwitch.addCustomReward(customRewardBody).then(res => console.log(res)) \ No newline at end of file pFad - Phonifier reborn

Pfad - The Proxy pFad © 2024 Your Company Name. All rights reserved.





Check this box to remove all script contents from the fetched content.



Check this box to remove all images from the fetched content.


Check this box to remove all CSS styles from the fetched content.


Check this box to keep images inefficiently compressed and original size.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy