twitch-rs / twitch_api Goto Github PK
View Code? Open in Web Editor NEWRust library for talking with the Twitch API aka. "Helix", TMI and more! Use Twitch endpoints fearlessly!
License: Apache License 2.0
Rust library for talking with the Twitch API aka. "Helix", TMI and more! Use Twitch endpoints fearlessly!
License: Apache License 2.0
When using paginated endpoints it's not always best to put it in a giant vector first and then return it like it's done currently. Often the items, for example followers, need to be processed in some way on their own (like storing old followers in a file). For this it's better to stream the items into the file (in this case).
So being able to do something like this would be nice:
async fn save_followers(file) -> AnyResult {
let mut stream = client.stream_followers(...);
while let Some(follower) = stream.try_next().await? {
file.save_follower(&follower).await;
}
Ok(())
}
merged into the
aes
crate
Details | |
---|---|
Status | unmaintained |
Package | aes-soft |
Version | 0.6.4 |
URL | RustCrypto/block-ciphers#200 |
Date | 2021-04-29 |
The aes-soft
crate has been merged into the aes
crate. The new repository
location is at:
<https://github.com/RustCrypto/block-ciphers/tree/master/aes>
AES-NI is now autodetected at runtime on i686
/x86-64
platforms.
If AES-NI is not present, the aes
crate will fallback to a constant-time
portable software implementation.
To force the use of a constant-time portable implementation on these platforms,
even if AES-NI is available, use the new force-soft
feature of the aes
crate to disable autodetection.
See advisory page for additional details.
it's not the prettiest, probably better hosted as a gh page or on wiki
Implement a better way to do releases.
I think I'd want a script that does the following
$bump crates_to_update <release|major|minor|patch>
To test this I think it's safest to work in another repo and setup a local crates registry. If act worked on wsl with actions-rs it would be really easy to test, but currently there's an error with cargo action not finding binaries.
I'll chime in here if I make any progress on this.
Use https://lib.rs/crates/serde_ignored if needed
Not entirely sure how to implement this in a non breaking expected way, but should be possible to define secondary functions.
While using the crate, I noticed some requests will be rejected by twitch because empty. For example:
get_users::GetUsersRequest::builder()
.id(vec![])
.login(vec![])
.build();
will be rejected. But in this case, the response will be empty. Would it be desirable to bypass the entire call and immediately returns a response in this case?
Or, looking at the RequestGet
trait, it seems maybe it would be better to detect this error when parsing the response and recover?
What do you think?
Provide C-bindings for structs and maybe client functions.
Possibly also python
stdweb is unmaintained
Details | |
---|---|
Status | unmaintained |
Package | stdweb |
Version | 0.4.20 |
URL | koute/stdweb#403 |
Date | 2020-05-04 |
The author of the stdweb
crate is unresponsive.
Maintained alternatives:
See advisory page for additional details.
The struct UsersFollow currently contains total
which should be in the Response root json object as of the example in twitch docs:
{
"total": 12345, // <-- The actual field is here
"data":
[
{
"from_id": "171003792",
"from_login": "iiisutha067iii",
"from_name": "IIIsutha067III",
"to_id": "23161357",
"to_name": "LIRIK",
"followed_at": "2017-08-22T22:55:24Z"
// <-- Right now the library looks for it here
},
{
"from_id": "113627897",
"from_login": "birdman616",
"from_name": "Birdman616",
"to_id": "23161357",
"to_name": "LIRIK",
"followed_at": "2017-08-22T22:55:04Z"
// <-- And also here
},
// ...
],
"pagination":{
"cursor": "eyJiIjpudWxsLCJhIjoiMTUwMzQ0MTc3NjQyNDQyMjAwMCJ9"
}
}
Get Webhook Subscriptions also does the same thing but is currently ignored in the library. There might be other examples.
This is mainly to make it less "heavy" to use the library with only the types
module, with no need for serialization. May not do this, but it could be good to have.
Currently, all doc items are modified on changes to commit.
This should be prevented by somehow referencing a file in the header instead of directly putting the commit in there.
e.g
#[derive(serde::Deserialize)]
pub struct MyResp {
pub user_id: twitch_api2::types::UserId,
pub user_name: String,
}
let resp: MyResp = client.req_get_custom(req, &token).await?.data;
// I'm not sure if this should be a `Response<MyResp>` or if that is even possible.
// I suspect not since Response requires T to be <Request>::Response.
// Could move that requirement to impls only, but not sure how that would affect compile error messages.
This could allow references in responses, and if the user only cares about some fields (or there are new fields not available yet in this library), only get those specific fields.
blocked on
By looking at the README, I assumed that this crate was only planning to cover Helix and TMI, but when working on #26, I noticed there was a branch for implementing PubSub, and an issue for supporting graphql. Just so I avoid duplicate work, or know whether to make feature addition PR's here, can you enumerate what all you intend to cover/not cover?
https://github.com/Emilgardis/twitch_api2/blob/master/src/pubsub/mod.rs#L212-L216
It's not possible to pass in more than one topic to listen to.
Currently eventsub::Payload
only parses the notification
message type (all the event types) and has a hardcoded behavior for the VerificationRequest
(which has a webhook_callback_verification
type in the header) mashed in.
However, there is no such hardcoded thing for the revocation
message, which is sent by Twich when for whatever reason the subscription was revoked, and the json they send contains a single subscription: EventSubSubscription
field, such object is not parsable by the Payload::parse
, although it is valid to expect it to come from Twitch
See https://dev.twitch.tv/docs/eventsub#subscription-revocation
use all features on docsrs and show how to use them,
also need to make to make reqwest
feature able to work with reqwest_client
4c5a7b8 added a result function to post requests. This should be added to all specific request traits together with an "assemble" function, making it fully possible to just use the structs and do the sending yourself.
I think this would help @Waridley also with their endeavours ;) separating twitch_api2 and twitch_oauth2
This would mean all the abstraction done in this crate with the Response
struct for helix would not be completely arcane and useless for external libs.
This would enable a function fn(R,&str)
to retrieve a http::Request<Vec<u8>>
for your R: helix::Request
to use with your implementation/client, including a token, and a function to parse a http::Response<Vec<u8>>
and push out a valid Result<helix::Response<R, D>, SomeError>
where the data
field on response hold your collection of responses according to D
Add some methods to https://github.com/Emilgardis/twitch_api2/blob/9fedcebc3bad19cee4887c8b16871afba25f90a1/src/types.rs#L32-L34
Specifically:
This should help immensely with stability
I also want to see what happens with integration into the sphere. Might do something myself.
https://blog.twitch.tv/en/2020/12/17/introducing-the-twitch-command-line-interface-tool/
Howdy!
It appears as if the Twitch API will sometimes return null
for the tag_ids
field in helix::Stream
after using get_followed_streams()
for whatever reason.
It has occurred twice now within the span of a couple hours, although I unfortunately no longer have access to the first error message.
The second occurred with https://www.twitch.tv/xfsn_saber (I'm unsure if the specific stream actually matters), as upon running it once more ~thirty seconds afterwards, it ran without issue.
Something interesting to note, is that their stream also had "viewer_count": 0
, but every other field was normal.
The relevant error message:
Error { path: Path { segments: [Map { key: "data" }, Seq { index: 28 }, Map { key: "tag_ids" }] }, original: Error("invalid type: null, expected a sequence", line: 1, column: 14545) }, https://api.twitch.tv/helix/streams/followed?user_id=19957417, 200))
Using v0.5.0.
Cheers!
net2
crate has been deprecated; usesocket2
instead
Details | |
---|---|
Status | unmaintained |
Package | net2 |
Version | 0.2.34 |
URL | deprecrated/net2-rs@3350e38 |
Date | 2020-05-01 |
The net2
crate has been deprecated
and users are encouraged to considered socket2
instead.
See advisory page for additional details.
I'm using twitch_api2 0.5.0-alpha. My code:
let client = reqwest::Client::new();
let twitch_api_client = TwitchClient::with_client(client);
let req = GetBroadcasterSubscriptionsRequest::builder()
.broadcaster_id(broadcaster.id.clone())
.user_id(vec![msg.sender.id.clone()])
.build();
debug!("{:?}", req);
let req = tokio::spawn(async move {
twitch_api_client.helix.req_get(req, &token).await
}).await;
match req {
Ok(r) => {
println!("{:?}", r)
},
Err(e) => println!("{:?}", e),
}
Output
2021-02-27 23:55:53,173 DEBUG [reqwest::async_impl::client] response '200 OK' for https://api.twitch.tv/helix/subscriptions?broadcaster_id=637140207&user_id=637140207
Err(HelixRequestGetError(DeserializeError("{\"data\":[{\"broadcaster_id\":\"637140207\",\"broadcaster_login\":\"stuck_overflow\",\"broadcaster_name\":\"stuck_overflow\",\"gifter_id\":\"\",\"gifter_login\":\"\",\"gifter_name\":\"\",\"is_gift\":false,\"plan_name\":\"Channel Subscription (stuck_overflow): $24.99 Sub\",\"tier\":\"3000\",\"user_id\":\"637140207\",\"user_name\":\"stuck_overflow\",\"user_login\":\"stuck_overflow\"}]}", Error("unknown field `broadcaster_login`, expected one of `broadcaster_id`, `broadcaster_name`, `is_gift`, `tier`, `plan_name`, `user_id`, `user_name`", line: 1, column: 58), https://api.twitch.tv/helix/subscriptions?broadcaster_id=637140207&user_id=637140207)))
Attempting to run this library with the version 1 version of Tokio yields the following error:
thread 'main' panicked at 'not currently running on the Tokio runtime.', {..}/tokio-0.2.24/src/runtime/handle.rs:118:28
Considering tokio released its v1 maybe it's time to upgrade the version of tokio as well.
Started work on making everything use references instead of allocating on multiple places
https://github.com/twitch-rs/twitch_api/tree/references
This solution should work, but I'm not sure the approach is good.
I'd want requests to be able to take references, and responses return them too.
Suggestions for how to avoid unnecessary allocations in responses hugely appreciated!
Moderation
POST https://api.twitch.tv/helix/moderation/enforcements/status
Check AutoMod StatusGET https://api.twitch.tv/helix/moderation/banned
Get Banned UsersGET https://api.twitch.tv/helix/moderation/banned/events
Get Banned EventsGET https://api.twitch.tv/helix/moderation/moderators
Get ModeratorsGET https://api.twitch.tv/helix/moderation/moderators/events
Get Moderator EventsChannels
POST https://api.twitch.tv/helix/channels/commercial
Start CommercialGET https://api.twitch.tv/helix/channels
Get Channel InformationPATCH https://api.twitch.tv/helix/channels
Modify Channel InformationAnalytics
GET https://api.twitch.tv/helix/analytics/extensions
Get Extension AnalyticsGET https://api.twitch.tv/helix/analytics/games
Get Game AnalyticsBits
GET https://api.twitch.tv/helix/bits/cheermotes
Get CheermotesGET https://api.twitch.tv/helix/bits/leaderboard
Get Bits LeaderboardExtensions
GET https://api.twitch.tv/helix/extensions/transactions
Get Extension TransactionsClips
POST https://api.twitch.tv/helix/clips
Create ClipGET https://api.twitch.tv/helix/clips
Get ClipsEntitlements
POST https://api.twitch.tv/helix/entitlements/upload
Create Entitlement Grants Upload URLGET https://api.twitch.tv/helix/entitlements/codes
Get Code StatusPOST https://api.twitch.tv/helix/entitlements/code
Redeem CodeGames
GET https://api.twitch.tv/helix/games/top
Get Top GamesGET https://api.twitch.tv/helix/games
Get GamesSearch
GET https://api.twitch.tv/helix/search/categories
Search CategoriesGET helix/search/channels
Search Channelsstarted_at
, tag_ids
). See sample response for distinction.Streams
https://api.twitch.tv/helix/streams/key
Get Stream KeyGET https://api.twitch.tv/helix/streams
Get StreamsPOST https://api.twitch.tv/helix/streams/markers
Create Stream MarkerGET https://api.twitch.tv/helix/streams/markers
Get Stream MarkersGET https://api.twitch.tv/helix/streams/tags
Get Stream Tagsdata
field containing an array of tag elements.PUT https://api.twitch.tv/helix/streams/tags
Replace Stream TagsSubscriptions
GET https://api.twitch.tv/helix/subscriptions
Get Broadcaster SubscriptionsTags
GET https://api.twitch.tv/helix/tags/streams
Get All Stream TagsUsers
POST https://api.twitch.tv/helix/users/follows
Create User FollowsDELETE https://api.twitch.tv/helix/users/follows
Delete User FollowsGET https://api.twitch.tv/helix/users
Get UsersGET https://api.twitch.tv/helix/users/follows
Get Users FollowsPUT https://api.twitch.tv/helix/users
Update UserGET https://api.twitch.tv/helix/users/extensions/list
Get User ExtensionsGET https://api.twitch.tv/helix/users/extensions
Get User Active ExtensionsPUT https://api.twitch.tv/helix/users/extensions
Update User ExtensionsVideos
GET https://api.twitch.tv/helix/videos
Get VideosWebhooks
GET https://api.twitch.tv/helix/webhooks/subscriptions
Get Webhook SubscriptionsHypetrain
GET https://api.twitch.tv/helix/hypetrain/events
Get Hype Train Eventsspin is no longer actively maintained
Details | |
---|---|
Status | unmaintained |
Package | spin |
Version | 0.5.2 |
URL | mvdnes/spin-rs@7516c80 |
Date | 2019-11-21 |
The author of the spin
crate does not have time or interest to maintain it.
Consider the following alternatives (all of which support no_std
):
conquer-once
lock_api
(a subproject of parking_lot
)
spinning_top
spinlock crate built on lock_api
spinning
See advisory page for additional details.
crate has been renamed to
cipher
Details | |
---|---|
Status | unmaintained |
Package | block-cipher |
Version | 0.7.1 |
URL | RustCrypto/traits#337 |
Date | 2020-10-15 |
This crate has been renamed from block-cipher
to cipher
.
The new repository location is at:
<https://github.com/RustCrypto/traits/tree/master/cipher>
See advisory page for additional details.
merged into the
aes
crate
Details | |
---|---|
Status | unmaintained |
Package | aesni |
Version | 0.10.0 |
URL | RustCrypto/block-ciphers#200 |
Date | 2021-04-29 |
The aesni
crate has been merged into the aes
crate. The new repository
location is at:
<https://github.com/RustCrypto/block-ciphers/tree/master/aes>
AES-NI is now autodetected at runtime on i686
/x86-64
platforms.
If AES-NI is not present, the aes
crate will fallback to a constant-time
portable software implementation.
To prevent this fallback (and have absence of AES-NI result in an illegal
instruction crash instead), continue to pass the same RUSTFLAGS which were
previously required for the aesni
crate to compile:
RUSTFLAGS=-Ctarget-feature=+aes,+ssse3
See advisory page for additional details.
Currently, this crate uses the builder pattern to assure a stable API i.e https://github.com/Emilgardis/twitch_api2/blob/e1ba9faff6c72b92f271a888b480a016c334b82a/src/helix/channels.rs#L82-L88
I decided to do it this way due to Twitch not guaranteeing a stable API themselves on documented items, so marking structs as #[non_exhaustive]
and using a builder seems better.
However, sometimes this makes things harder to use, as typed-builder
does not exactly make structs more accessible.
While this is done for stability, I feel like some structs don't lend themselves to the builder pattern, like the above example.
I want to solve this somehow, without sacrificing API stability.
To do that I think what needs to be done is creating methods for common usages of requests.
Example:
impl GetChannelInformationRequest {
pub fn get_channel(broadcaster: String) -> GetChannelInformationRequest {
GetChannelInformationRequest::builder().broadcaster_id(broadcaster).build()
}
}
impl GetGamesRequest {
pub fn get_game(id: types::CategoryId) -> GetGamesRequest {
GetGamesRequest::builder().id(vec![id]).build()
}
}
There is the crate derive_builder
that could help also.
cpuid-bool
has been renamed tocpufeatures
Details | |
---|---|
Status | unmaintained |
Package | cpuid-bool |
Version | 0.2.0 |
URL | RustCrypto/utils#381 |
Date | 2021-05-06 |
Please use the `cpufeatures`` crate going forward:
<https://github.com/RustCrypto/utils/tree/master/cpufeatures>
There will be no further releases of cpuid-bool
.
See advisory page for additional details.
The braided types introduced in #133 should derive
#[aliri_braid::braid(serde)]
#[cfg_attr(feature = "sqlx", derive(sqlx::Type), sqlx(transparent))]
#[cfg_attr(feature = "diesel", derive(diesel::FromSqlRow, diesel::AsExpression),]
pub struct UserName;
#[cfg(feature = "diesel")]
impl<DB> diesel::serialize::ToSql<diesel::sql_types::Text, DB> for UserName
where
DB: diesel::Backend,
String: diesel::serialize::ToSql<diesel::sql_types::Text, DB>,
{
fn to_sql<W: std::io::Write>(&self, out: &mut diesel::serialize::Output<W, DB>) -> diesel::serialize::Result {
(self as &str).to_sql(out)
}
}
#[cfg(feature = "diesel")]
impl<ST, DB> diesel::deserialize::FromSql<ST, DB> for UserName
where
DB: Backend,
String: diesel::deserialize::FromSql<ST, DB>,
{
fn from_sql(bytes: Option<&DB::RawValue>) -> diesel::deserialize::Result<Self> {
<String as FromSql<ST, DB>>::from_sql(bytes).map(UserName::new)
}
}
/// diesel::Queryable, etc...
This will allow users to use the braids better when using sqlx or diesel, exposing the types as strings.
Diesel has support for these with #[diesel(deserialize_as = "sql_types::Text")]
on Queryable
and #[diesel(serialize_as = "String")]
on Insertable
, not super nice but should work.
Should look into these crates and/or rust core/std if it would be possible to make this easier on library authors. For example, I can imagine a trait Stringable
, which defines a thing which can be represented as a String/&str.
This is unfortunate, because I really like the idea of wrapping the types like this, but the lack of support in the ecosystem is saddening.
Best scenario, would be for sqlx to support a similar macro attr like serde/diesel remote derive or serialize_with and deserialize_with
Hey there,
I love your really nice and clean work on the client abstraction with possible multiple clients to use and traits for Request
, RequestGet
etc.
I'm writing a backend that makes requests to multiple different APIs and I'm planning to use your client and request abstractions for this while only implementing the request
traits for these APIs.
What came to my mind was, if it wouldn't be nice, to publish the client
and request trait
s in an external crate as api-client
, so people would just need to implement the request traits for the corresponding API and could use any client they want to pull the data.
Do you think this is a reasonable thing to do? I think this could be really valuable for the community, as that would make implementing crates for all kinds of APIs much easier. I could also imagine (long-term) porting the outdated kraken
Twitch API crate to this foundation (and PR it here), while we could publish the whole thing then under https://crates.io/crates/twitch_api where I would like to add you as an owner as well. Would be lovely to have a wholesome crate of the Twitch API (as you are making your way to it).
Make notification payload parsing able to be circumvented, returning serde_json::Value
or just event type and version.
it's not really working, not sure why
Most if not all error states are catched by https://github.com/Emilgardis/twitch_api2/blob/35d4a5be8f633665abce733800412c332e33ccc0/src/helix/mod.rs#L491-L504 etc
rendering https://github.com/Emilgardis/twitch_api2/blob/35d4a5be8f633665abce733800412c332e33ccc0/src/helix/users/create_user_follows.rs#L95-L98 unnecessary
This is not really helpful
the buildscript shouldn't be needed anymore, right now it's only used for doc_cfg
, I should be able to bump msrv to get the other nightly
gate:
https://github.com/Emilgardis/twitch_api2/blob/8861142c4504f23393170fa577ab3a855c23a6cc/src/lib.rs#L3
This should improve build time.
I can make docs.rs and CI set --cfg nightly
and document how to use it when building local docs.
I tried to search for a term that does not exists, this results in the error below:
The Term I search was Mitttttttttttt
Error: HelixRequestGetError(DeserializeError("{\"data\":null,\"pagination\":{}}", Error("invalid type: null, expected a sequence", line: 1, column: 12), https://api.twitch.tv/helix/search/categories?query=Mitttttttttttt&first=20))
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.