{"id":18488410,"url":"https://github.com/ColeWalker/twitch-graphql","last_synced_at":"2025-04-08T21:30:27.997Z","repository":{"id":56177774,"uuid":"291365159","full_name":"ColeWalker/twitch-graphql","owner":"ColeWalker","description":"A GraphQL wrapper for the twitch api","archived":false,"fork":false,"pushed_at":"2020-11-22T15:11:44.000Z","size":830,"stargazers_count":14,"open_issues_count":14,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-04-23T22:09:49.186Z","etag":null,"topics":["graphql","graphql-modules","hacktoberfest","jest","jest-tests","twitch","twitch-api","typescript","wrapper","yarn"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ColeWalker.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-08-29T23:25:23.000Z","updated_at":"2024-01-29T08:35:41.000Z","dependencies_parsed_at":"2022-08-15T14:10:25.579Z","dependency_job_id":null,"html_url":"https://github.com/ColeWalker/twitch-graphql","commit_stats":null,"previous_names":["colewalker/twitch-graphql-server"],"tags_count":21,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ColeWalker%2Ftwitch-graphql","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ColeWalker%2Ftwitch-graphql/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ColeWalker%2Ftwitch-graphql/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ColeWalker%2Ftwitch-graphql/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ColeWalker","download_url":"https://codeload.github.com/ColeWalker/twitch-graphql/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247930957,"owners_count":21020140,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["graphql","graphql-modules","hacktoberfest","jest","jest-tests","twitch","twitch-api","typescript","wrapper","yarn"],"created_at":"2024-11-06T12:51:42.042Z","updated_at":"2025-04-08T21:30:27.990Z","avatar_url":"https://github.com/ColeWalker.png","language":"TypeScript","readme":"# Twitch GraphQL\r\n\r\nThis is an open source twitch API graphql wrapper. If you clone this repository you can run it as a full-functioning server. It is also installable as an npm package.\r\n\r\nBy default it will run at `http://localhost:5555/graphql`.\r\n\r\n[Contribution Guidelines](/CONTRIBUTING.md)\r\n\r\n- [Twitch GraphQL](#twitch-graphql)\r\n  - [Environment Variables](#environment-variables)\r\n  - [Authentication via headers](#authentication-via-headers)\r\n    - [Example of client setup](#example-of-client-setup)\r\n  - [Webhooks](#webhooks)\r\n    - [Why?](#why)\r\n    - [Setting up ngrok](#setting-up-ngrok)\r\n  - [Installation and Usage of the NPM Package](#installation-and-usage-of-the-npm-package)\r\n  - [Command line arguments](#command-line-arguments)\r\n  - [Commands](#commands)\r\n  - [Getting a Twitch Refresh Token](#getting-a-twitch-refresh-token)\r\n  - [Schemas Provided](#schemas-provided)\r\n    - [Query](#query)\r\n    - [Subscriber](#subscriber)\r\n    - [User](#user)\r\n    - [UserSubscriberLink](#usersubscriberlink)\r\n    - [Stream](#stream)\r\n    - [StreamUserLink](#streamuserlink)\r\n    - [Game](#game)\r\n    - [GameStreamLink](#gamestreamlink)\r\n  - [PubSubs](#pubsubs)\r\n    - [RedemptionPubSub](#redemptionpubsub)\r\n    - [RedemptionUserLink](#redemptionuserlink)\r\n    - [ChatPubSub](#chatpubsub)\r\n    - [ChatUserLink](#chatuserlink)\r\n    - [BitPubSub](#bitpubsub)\r\n    - [BitUserLink](#bituserlink)\r\n    - [SubscriptionPubSub](#subscriptionpubsub)\r\n    - [SubscriptionPubSubChatLink](#subscriptionpubsubchatlink)\r\n    - [SubscriptionPubSubUserLink](#subscriptionpubsubuserlink)\r\n    - [FollowPubSub](#followpubsub)\r\n    - [FollowPubSubUserLink](#followpubsubuserlink)\r\n\r\n## Environment Variables\r\n\r\nThis project assumes that you already have a Twitch API App set up, and an OAuth token with every scope that you will need. This information will be stored inside of several environment variables in a .env file. If you need a Twitch API Application (for user ID and client secret), information regarding setting one up is [documented in the Twitch API documentation.](https://dev.twitch.tv/docs/api/) If you require an OAuth or refresh token, there is [documentation available in the Twitch API documentation.](https://dev.twitch.tv/docs/authentication) Alternatively, there is a [guide below on how to retrieve a refresh token.](#getting-a-twitch-refresh-token)\r\n\r\n| Variable      | Value                                                                                                    |\r\n| ------------- | -------------------------------------------------------------------------------------------------------- |\r\n| SECRET        | Your application's secret                                                                                |\r\n| USER_ID       | Your application's User ID                                                                               |\r\n| TWITCH_ID     | Your Twitch account's ID                                                                                 |\r\n| REFRESH_TOKEN | The refresh token for your OAuth token                                                                   |\r\n| PORT          | The port that you want to run the server on                                                              |\r\n| GRAPHIQL      | Whether or not you want the server to enable graphiql                                                    |\r\n| WEBHOOK_PORT  | The port that you want to run the webhook listener on                                                    |\r\n| CALLBACK_URL  | The full URL (including http) for twitch to send webhooks to (the URL the webhook port is accessible at) |\r\n\r\n## Authentication via headers\r\n\r\nThis library now supports authentication via request headers. Headers will take priority over environment variables.\r\n\r\n| Variable      | Value                                  |\r\n| ------------- | -------------------------------------- |\r\n| secret        | Your application's secret              |\r\n| user_id       | Your application's User ID             |\r\n| twitch_id     | Your Twitch account's ID               |\r\n| refresh_token | The refresh token for your OAuth token |\r\n\r\nThese items will be stored in the GraphQL modules global context in the same name as they appear in the headers. All of the headers are supported as connectionParams for Subscriptions.\r\n\r\nFor your convenience, the `context` and `onConnect` methods have been provided to automatically set the global context in the expected manner.\r\n\r\n```ts\r\nimport { context, onConnect } from 'twitch-graphql'\r\n\r\nconst server = new ApolloServer({\r\n  schema,\r\n  subscriptions: {\r\n    path: `/subscriptions`,\r\n    onConnect,\r\n  },\r\n  context,\r\n})\r\n```\r\n\r\n### Example of client setup\r\n\r\nHere is an apollo client setup that will just work.\r\n\r\n```ts\r\nconst httpLink = new HttpLink({\r\n  uri: 'http://localhost:5555/graphql',\r\n  headers: {\r\n    twitch_id: 'YOUR_TWITCH_ID',\r\n    refresh_token: 'YOUR_TOKEN',\r\n    secret: 'YOUR_SECRET',\r\n    user_id: 'YOUR_USER_ID',\r\n  },\r\n})\r\n\r\nconst wsLink = new WebSocketLink({\r\n  uri: `ws://localhost:5555/subscriptions`,\r\n  options: {\r\n    reconnect: true,\r\n    connectionParams: {\r\n      twitch_id: 'YOUR_TWITCH_ID',\r\n      refresh_token: 'YOUR_TOKEN',\r\n      secret: 'YOUR_SECRET',\r\n      user_id: 'YOUR_USER_ID',\r\n    },\r\n  },\r\n})\r\n\r\nconst splitLink = split(\r\n  ({ query }) =\u003e {\r\n    const definition = getMainDefinition(query)\r\n    return (\r\n      definition.kind === 'OperationDefinition' \u0026\u0026\r\n      definition.operation === 'subscription'\r\n    )\r\n  },\r\n  wsLink,\r\n  httpLink\r\n)\r\n\r\nconst client = new ApolloClient({\r\n  uri: 'http://localhost:5555/graphql',\r\n  cache: new InMemoryCache(),\r\n  link: splitLink,\r\n})\r\n```\r\n\r\n## Webhooks\r\n\r\nTwitch doesn't have a PubSub for follows yet, so if you need to use the follow subscription, you need to have this server port forwarded and open to outside requests.\r\n\r\n### Why?\r\n\r\nWebhooks work like this:\r\n\r\n1. We tell Twitch we want to be notified whenever a follow happens.\r\n2. Twitch sends us a request telling us they've confirmed that they will do that.\r\n3. Twitch sends us requests with information about any follow event that occurs.\r\n\r\n### Setting up ngrok\r\n\r\nIf you don't want to bother with port forwarding, you can use [ngrok](https://ngrok.com/) to set up a secure tunnel to your server from the outside using the following steps.\r\n\r\n1. Download ngrok\r\n2. Run `./ngrok http PORT` in the directory where ngrok was downloaded, where `PORT` is your `WEBHOOK_PORT` environment variable.\r\n3. ngrok will log an `http` url and an `https` `something.ngrok.io` url in the console window, copy and paste this into the `CALLBACK_URL` environment variable.\r\n\r\nYou will need to repeat this process _each time_ that you restart ngrok.\r\n\r\n## Installation and Usage of the NPM Package\r\n\r\nThis library is also available as a NPM package.\r\n\r\nTo install, run\r\n\r\n`npm install twitch-graphql`\r\n\r\nor\r\n\r\n`yarn add twitch-graphql`\r\n\r\nUsage of the package depends on the structure of your application. If you choose to use [graphql-modules](https://graphql-modules.com/) (Recommended), you can import the modules that you require and add them to your application, complete with authentication.\r\n\r\nEvery module in this library depends on the base module, \"Query\". You will **_ALWAYS NEED TO IMPORT AND USE `QueryModule`_**\r\n\r\nExample:\r\n\r\n```ts\r\nimport express from 'express'\r\nimport http from 'http'\r\nimport { QueryModule } from './schema/query-type-schema'\r\nimport { SubscriberModule } from './schema/subscriber-type-schema'\r\nimport { UserModule } from './schema/user-type-schema'\r\nimport { StreamModule } from './schema/stream-type-schema'\r\nimport { GameModule } from './schema/game-type-schema'\r\nimport { createApplication } from 'graphql-modules'\r\nimport { UserSubscriberLinkModule } from './schema/user-subscriber-link-type-schema'\r\nimport { GameStreamLinkModule } from './schema/game-stream-link-type-schema'\r\nimport { RedemptionPubSubModule } from './schema/redemption-pubsub-type-schema'\r\nimport { StreamUserLinkModule } from './schema/stream-user-link-type-schema'\r\nimport { RedemptionUserLinkModule } from './schema/redemption-pubsub-user-link-type-schema'\r\nimport { ChatPubSubModule } from './schema/chat-pubsub-type-schema'\r\nimport { ApolloServer } from 'apollo-server-express'\r\nimport { ChatUserLinkModule } from './schema/chat-pubsub-user-link-schema'\r\nimport { BitPubSubModule } from './schema/bit-pubsub-type-schema'\r\nimport { BitUserLinkModule } from './schema/bit-pubsub-user-link-schema'\r\nimport { SubscriptionPubSubModule } from './schema/subscription-pubsub-type-schema'\r\nimport { SubscriptionPubSubUserLinkModule } from './schema/subscription-pubsub-user-link-schema'\r\nimport { SubscriptionPubSubChatLinkModule } from './schema/subscription-pubsub-chat-link-schema'\r\nimport { onConnect, context } from './helpers/ServerSetup'\r\nimport { FollowPubSubModule } from './schema/follow-pubsub-type.schema'\r\nconst app = createApplication({\r\n  modules: [\r\n    QueryModule,\r\n    SubscriberModule,\r\n    UserModule,\r\n    StreamModule,\r\n    UserSubscriberLinkModule,\r\n    GameStreamLinkModule,\r\n    GameModule,\r\n    StreamUserLinkModule,\r\n    RedemptionPubSubModule,\r\n    RedemptionUserLinkModule,\r\n    ChatPubSubModule,\r\n    ChatUserLinkModule,\r\n    BitPubSubModule,\r\n    BitUserLinkModule,\r\n    SubscriptionPubSubModule,\r\n    SubscriptionPubSubUserLinkModule,\r\n    SubscriptionPubSubChatLinkModule,\r\n    FollowPubSubModule,\r\n  ],\r\n})\r\napp.createSubscription()\r\n\r\nconst schema = app.createSchemaForApollo()\r\nconst server = new ApolloServer({\r\n  schema,\r\n  introspection: true,\r\n  subscriptions: {\r\n    path: `/subscriptions`,\r\n    onConnect,\r\n  },\r\n  context,\r\n  playground: true,\r\n})\r\n\r\nconst expressApp = express()\r\n\r\nserver.applyMiddleware({ app: expressApp })\r\nconst httpServer = http.createServer(expressApp)\r\nserver.installSubscriptionHandlers(httpServer)\r\n\r\nhttpServer.listen(port, () =\u003e {\r\n  console.log(\r\n    `🚀 Server ready at http://localhost:${port}${server.graphqlPath}`\r\n  )\r\n  console.log(\r\n    `🚀 Subscriptions ready at ws://localhost:${port}${server.subscriptionsPath}`\r\n  )\r\n})\r\n```\r\n\r\nThis example will run a server containing all of the current Twitch API modules.\r\n\r\nAlternatively, you can import the schema and resolvers separately. However, since the resolvers require a grapqhl-modules dependency injection to retrieve authentication information, you may have to rewrite them entirely if you choose to not use grapqhl-modules for your architecture.\r\n\r\nExamples of importing Schema and Resolvers:\r\n\r\n```ts\r\nimport { QuerySchema, QueryResolver } from 'twitch-graphql'\r\nimport { StreamSchema, StreamResolvers } from 'twitch-graphql'\r\nimport { SubscriberSchema, SubscriberResolvers } from 'twitch-graphql'\r\nimport { UserSchema, UserResolvers } from 'twitch-graphql\r\n```\r\n\r\n## Command line arguments\r\n\r\n```\r\n-p, --port The port number that the server should use. Not available with yarn dev. [number]\r\n\r\n-g, --graphiql Enables graphiql. [flag]\r\n```\r\n\r\n## Commands\r\n\r\n| Command    | Action                                                        |\r\n| ---------- | ------------------------------------------------------------- |\r\n| yarn build | Runs typescript compiler, compiles to ./dist                  |\r\n| yarn start | Runs ./dist statically, does not refresh                      |\r\n| yarn dev   | Runs auto refreshing development server                       |\r\n| yarn dev-g | Runs auto refreshing development server with graphiql enabled |\r\n\r\n## Getting a Twitch Refresh Token\r\n\r\nAfter you have set up your twitch application, you can get all of the required keys by doing the following:\r\n\r\n1. Visit the following url: `https://id.twitch.tv/oauth2/authorize?client_id=YOUR APPLICATION CLIENT ID\u0026redirect_uri=http://localhost\u0026response_type=code\u0026scope=channel:read:subscriptions+channel_subscriptions+analytics:read:games+chat:read whispers:read+channel:read:redemptions+bits:read`\r\n2. It will send you to `localhost://code=SOME CODE/other-junk` copy the code only.\r\n3. Paste the code into a POST request at this URL: `https://id.twitch.tv/oauth2/token?client_id=YOUR CLIENT ID\u0026client_secret=YOUR CLIENT SECRET\u0026code=YOUR CODE\u0026grant_type=authorization_code\u0026redirect_uri=http://localhost`\r\n\r\nThis will respond with the refresh token that you need.\r\n\r\n## Schemas Provided\r\n\r\n### Query\r\n\r\nBase schema, all other modules extend this.\r\n\r\n### Subscriber\r\n\r\n```ts\r\nimport { SubscriberModule } from 'twitch-graphql'\r\n```\r\n\r\n```graphql\r\nextend type Query {\r\n  latestSub: Subscriber!\r\n  randomSub: Subscriber!\r\n  allSubs: [Subscriber]!\r\n  subCount: Int!\r\n  getSubscriberByDisplayName(displayName: String!): Subscriber\r\n}\r\n\r\ntype Subscriber {\r\n  cumulativeMonths: Int!\r\n  tier: Int!\r\n  userDisplayName: String!\r\n  userId: String!\r\n  isGift: Boolean!\r\n}\r\n```\r\n\r\n### User\r\n\r\n```ts\r\nimport { UserModule } from 'twitch-graphql'\r\n```\r\n\r\nPlease note that using follows with a high number of maxPages will likely result in rate limiting from twitch.\r\n\r\n```graphql\r\ntype User {\r\n  displayName: String!\r\n  description: String!\r\n  id: String!\r\n  profilePictureURL: String!\r\n  views: Int!\r\n\r\n  follows(maxPages: Int!): FollowConnection\r\n\r\n  getFollowToId(userId: String!): Follow\r\n  getFollowToDisplayName(displayName: String!): Follow\r\n\r\n  followsId(userId: String!): Boolean!\r\n  followsDisplayName(displayName: String!): Boolean!\r\n}\r\n\r\ntype Follow {\r\n  followDateUTC: String!\r\n  followDate: String!\r\n  followerUser: User!\r\n  followedUser: User!\r\n}\r\n\r\ntype FollowConnection {\r\n  total: Int!\r\n  nodes: [Follow]\r\n  cursor: String\r\n}\r\n\r\nextend type Query {\r\n  getUserById(userId: String!): User\r\n  getUserByDisplayName(displayName: String!): User\r\n}\r\n```\r\n\r\n### UserSubscriberLink\r\n\r\n```ts\r\nimport { UserSubscriberLinkModule } from 'twitch-graphql'\r\n```\r\n\r\nThis module extends Subscriber to add the user field. Only use if both modules are being used in your application.\r\n\r\n```graphql\r\nextend type Subscriber {\r\n  user: User!\r\n}\r\n\r\nextend type User {\r\n  isSubscribedToId(userId: String!): Boolean!\r\n  isSubscribedToDisplayName(displayName: String!): Boolean!\r\n\r\n  getSubscriptionToId(userId: String!): Subscriber\r\n  getSubscriptionToDisplayName(displayName: String!): Subscriber\r\n}\r\n```\r\n\r\n### Stream\r\n\r\n```ts\r\nimport { Stream } from 'twitch-graphql'\r\n```\r\n\r\n```graphql\r\ntype Stream {\r\n  language: String!\r\n  gameId: String!\r\n  id: String!\r\n  title: String!\r\n  viewers: Int!\r\n  thumbnailUrl: String!\r\n  userDisplayName: String!\r\n  userId: String!\r\n}\r\n\r\ntype StreamConnection {\r\n  total: Int!\r\n  nodes: [Stream]\r\n  cursor: String\r\n}\r\n\r\nextend type Query {\r\n  getStreams(streamFilter: StreamFilter!, maxPages: Int = 1): StreamConnection\r\n}\r\n\r\ninput StreamFilter {\r\n  gameIds: [String]\r\n  gameNames: [String]\r\n  languages: [String]\r\n  type: StreamType\r\n  userIds: [String]\r\n  userNames: [String]\r\n}\r\n\r\nenum StreamType {\r\n  live\r\n  none\r\n}\r\n```\r\n\r\n### StreamUserLink\r\n\r\n```ts\r\nimport { StreamUserLinkModule } from 'twitch-graphql'\r\n```\r\n\r\nThis module extends Stream to add the user field, and User to add the stream field. Only use if both modules are being used in your application.\r\n\r\n```graphql\r\nextend type User {\r\n  stream: Stream\r\n}\r\n\r\nextend type Stream {\r\n  user: User\r\n}\r\n```\r\n\r\n### Game\r\n\r\n```ts\r\nimport { GameModule } from 'twitch-graphql'\r\n```\r\n\r\n```graphql\r\ntype Game {\r\n  boxArtUrl: String!\r\n  id: String!\r\n  name: String!\r\n}\r\n\r\nextend type Query {\r\n  getGameByName(gameName: String!): Game\r\n}\r\n```\r\n\r\n### GameStreamLink\r\n\r\n```ts\r\nimport { GameStreamLinkModule } from 'twitch-graphql'\r\n```\r\n\r\nThis module extends Stream to add the game field. Only use if both modules are being used in your application.\r\n\r\n```graphql\r\nextend type Stream {\r\n  game: Game\r\n}\r\n```\r\n\r\n## PubSubs\r\n\r\nTwitch PubSubs are supported using [GraphQL Subscriptions.](https://www.apollographql.com/docs/apollo-server/data/subscriptions/)\r\n\r\nCurrently these PubSub modules are in an **experimental** phase, since no unit tests have been written for them, and have only been tested manually.\r\n\r\n### RedemptionPubSub\r\n\r\n```ts\r\nimport { RedemptionPubSubModule } from 'twitch-graphql'\r\n```\r\n\r\n```graphql\r\ntype Redemption {\r\n  userId: String\r\n  id: String\r\n  channelId: String\r\n  userName: String\r\n  userDisplayName: String\r\n  redemptionDate: String\r\n  rewardId: String\r\n  rewardName: String\r\n  rewardPrompt: String\r\n  rewardCost: Int\r\n  rewardIsQueued: String\r\n  rewardImage: String\r\n  message: String\r\n  status: String\r\n}\r\n\r\nextend type Subscription {\r\n  newRedemption: Redemption\r\n}\r\n```\r\n\r\n### RedemptionUserLink\r\n\r\n```ts\r\nimport { RedemptionUserLinkModule } from 'twitch-graphql'\r\n```\r\n\r\n```graphql\r\nextend type Redemption {\r\n  user: User\r\n  channelRedeemedAt: User\r\n}\r\n```\r\n\r\n### ChatPubSub\r\n\r\n```ts\r\nimport { ChatPubSubModule } from 'twitch-graphql'\r\n```\r\n\r\n```graphql\r\ntype Chat {\r\n  message: String\r\n  displayName: String\r\n  channel: String\r\n  userInfo: ChatUser\r\n}\r\n\r\ntype ChatUser {\r\n  userName: String\r\n  displayName: String\r\n  color: String\r\n  userId: String\r\n  userType: String\r\n  isBroadcaster: Boolean\r\n  isSubscriber: Boolean\r\n  isFounder: Boolean\r\n  isMod: Boolean\r\n  isVip: Boolean\r\n}\r\n\r\nextend type Subscription {\r\n  newChat(channel: String!): Chat\r\n}\r\n\r\nextend type Mutation {\r\n  sendChat(channel: String!, message: String!): Boolean\r\n}\r\n```\r\n\r\n### ChatUserLink\r\n\r\n```ts\r\nimport { ChatUserLinkModule } from 'twitch-graphql'\r\n```\r\n\r\n```graphql\r\nextend type Chat {\r\n  user: User\r\n}\r\n```\r\n\r\n### BitPubSub\r\n\r\n```ts\r\nimport { BitPubSubModule } from 'twitch-graphql'\r\n```\r\n\r\n```graphql\r\ntype Bits {\r\n  userId: String\r\n  userName: String\r\n  message: String\r\n  bits: Int\r\n  totalBits: Int\r\n  isAnonymous: Boolean\r\n}\r\n\r\nextend type Subscription {\r\n  newBits: Bits\r\n}\r\n```\r\n\r\n### BitUserLink\r\n\r\n```ts\r\nimport { BitPubSubModule } from 'twitch-graphql'\r\n```\r\n\r\n```graphql\r\nextend type Bit {\r\n  user: User\r\n}\r\n```\r\n\r\n### SubscriptionPubSub\r\n\r\n```ts\r\nimport { SubscriptionPubSubModule } from 'twitch-graphql'\r\n```\r\n\r\n```graphql\r\ntype SubscriptionMessage {\r\n  userId: String\r\n  userName: String\r\n  userDisplayName: String\r\n  streakMonths: Int\r\n  cumulativeMonths: Int\r\n  months: Int\r\n  time: String\r\n  subPlan: String\r\n  isResub: Boolean\r\n  isGift: Boolean\r\n  isAnonymous: Boolean\r\n  gifterId: String\r\n  gifterName: String\r\n  gifterDisplayName: String\r\n  giftDuration: Int\r\n}\r\n\r\nextend type Subscription {\r\n  newSubscription: SubscriptionMessage\r\n}\r\n```\r\n\r\n### SubscriptionPubSubChatLink\r\n\r\n```ts\r\nimport { SubscriptionPubSubChatLinkModule } from 'twitch-graphql'\r\n```\r\n\r\n```graphql\r\nextend type SubscriptionMessage {\r\n  message: Chat\r\n}\r\n```\r\n\r\n### SubscriptionPubSubUserLink\r\n\r\n```ts\r\nimport { SubscriptionPubSubUserLinkModule } from 'twitch-graphql'\r\n```\r\n\r\n```graphql\r\nextend type SubscriptionMessage {\r\n  user: User\r\n  gifterUser: User\r\n}\r\n```\r\n\r\n### FollowPubSub\r\n\r\n```ts\r\nimport { FollowPubSubModule } from 'twitch-graphql'\r\n```\r\n\r\n```graphql\r\ntype FollowSubscription {\r\n  followDate: String\r\n  followedUserDisplayName: String\r\n  followedUserId: String\r\n  userDisplayName: String\r\n  userId: String\r\n}\r\n\r\nextend type Subscription {\r\n  newFollow: FollowSubscription\r\n}\r\n```\r\n\r\n### FollowPubSubUserLink\r\n\r\n```ts\r\nimport { FollowPubSubUserLinkModule } from 'twitch-graphql'\r\n```\r\n\r\n```graphql\r\nextend type FollowSubscription {\r\n  followedUser: User\r\n  followerUser: User\r\n}\r\n```\r\n","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FColeWalker%2Ftwitch-graphql","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FColeWalker%2Ftwitch-graphql","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FColeWalker%2Ftwitch-graphql/lists"}