AtlatestRenderedmarkdown
sigil-twitch / treeREADME.md
Readme
sigil-twitch
Twitch Helix API client library for Sigil.
Provides functions for stream management, scheduling, analytics, chat interaction, and EventSub real-time events.
Features
- Channel management — get/modify channel info (title, game, tags)
- Stream info — query live streams, get stream keys
- User lookup — find users by ID or login
- Search — search categories and channels
- Schedule — CRUD for recurring/non-recurring schedule segments, vacation mode, iCal export
- Analytics — followers, subscribers, clips, VODs, extension/game analytics
- Chat — send messages, list chatters, manage settings, announcements
- EventSub — WebSocket message parsing, subscription management, convenience helpers
- Pagination — generic cursor-based paginator for any list endpoint
- Record types — typed records for channels, streams, users, clips, videos, schedule segments
Modules
| Module | Description |
|---|---|
(twitch) | Core client, auth, HTTP helpers, channels, streams, users, search, pagination |
(twitch schedule) | Schedule segments, vacation, iCalendar export |
(twitch analytics) | Followers, subscribers, clips, VODs, extension/game analytics |
(twitch chat) | Chat messages, chatters, settings, announcements |
(twitch eventsub) | EventSub WebSocket message parsing, subscription management |
(twitch oauth) | OAuth 2.0 integration via sigil-oauth (token management, auto-refresh) |
Usage
Client Setup
(import (twitch))
;; Create a client with your Twitch credentials
(define client
(twitch-client client-id: "your-client-id"
access-token: "your-oauth-token"))
;; For local development with the Twitch CLI mock server:
(define mock-client
(twitch-client client-id: "test-id"
access-token: "test-token"
base-url: "http://localhost:8080/mock"))OAuth 2.0 Token Management
(import (twitch oauth))
;; Create an OAuth config for Twitch
(define config
(twitch-oauth-config "your-client-id" "your-client-secret"))
;; Load stored tokens (from ~/.config/sigil/twitch/tokens.json)
(define tokens (twitch-load-tokens))
;; Build a client with auto-refresh
(let-values (((client fresh-tokens)
(twitch-ensure-client config tokens (current-second))))
;; client is ready to use with both Client-Id and Bearer headers
(twitch-channel-info client "141981764"))
;; Run the full authorization flow (opens browser, starts callback server)
(define tokens
(oauth-run-authorization-flow config (current-second)))
(twitch-save-tokens tokens)Channel Info
;; Get channel info (returns a list of twitch-channel records)
(let ((channels (twitch-channel-info client "141981764")))
(for-each (lambda (ch)
(display (twitch-channel-title ch)))
channels))
;; Modify channel title and category
(twitch-modify-channel client "141981764"
#{ title: "Building a Twitch bot in Sigil"
game-id: "509670" })Streams
;; Get live streams for specific users
(let ((streams (twitch-streams client
#{ user-login: "twitchdev" })))
(for-each (lambda (s)
(display (twitch-stream-title s))
(display (twitch-stream-viewer-count s)))
streams))Users
;; Look up users by login name
(let ((users (twitch-users client #{ login: "twitchdev" })))
(for-each (lambda (u)
(display (twitch-user-display-name u)))
users))Pagination
;; Auto-paginate through all followers
(import (twitch analytics))
(let ((all-followers
(twitch-paginate
(lambda (cursor)
(let ((params (list
(cons "broadcaster_id" "141981764")
(cons "first" "100")
(cons "after" cursor))))
(twitch-get/json client
(string-append
(twitch-api-url client "channels" "followers")
(build-query-string params)))))
(lambda (item) item) ;; or a custom parse function
10))) ;; max 10 pages
(display (length all-followers)))Schedule
(import (twitch schedule))
;; Get the schedule
(let ((result (twitch-schedule client "141981764")))
(for-each (lambda (seg)
(display (twitch-schedule-segment-title seg)))
(dict-ref result segments:)))
;; Create a recurring weekly segment
(twitch-create-segment client "141981764"
"2026-04-04T18:00:00Z" "America/New_York"
#{ title: "Friday Coding Stream"
duration: 240
category-id: "509670"
is-recurring: #t })Chat
(import (twitch chat))
;; Send a chat message
(twitch-send-chat-message client
"141981764" ;; broadcaster-id
"12345678" ;; sender-id (your user ID)
"Hello from Sigil!")EventSub
(import (twitch eventsub))
;; After connecting to the WebSocket and receiving a welcome message:
(let* ((msg (parse-eventsub-message raw-json))
(session (eventsub-session-from-welcome msg))
(session-id (twitch-eventsub-session-id session)))
;; Subscribe to stream online events
(twitch-subscribe-stream-online client session-id "141981764")
;; Later, when notifications arrive:
(let ((notification (parse-eventsub-message notification-json)))
(when (string=? (eventsub-message-type notification) "notification")
(let ((event (eventsub-notification-event notification))
(type (eventsub-notification-subscription-type notification)))
(display type) ;; "stream.online"
(display event))))) ;; event data dictAuthentication
All Helix API requests require both a Client-Id and a Bearer access token. The twitch-client record holds both and the library adds the appropriate headers to every request automatically.
Required Scopes
| Operation | Scope |
|---|---|
| Modify channel | channel:manage:broadcast |
| Read stream key | channel:read:stream_key |
| Manage schedule | channel:manage:schedule |
| Read followers | moderator:read:followers |
| Read subscribers | channel:read:subscriptions |
| Send chat messages | user:write:chat |
| Read chat messages (EventSub) | user:read:chat |
| Create clips | clips:edit |
| Extension analytics | analytics:read:extensions |
| Game analytics | analytics:read:games |
Building
sigil deps install
sigil buildTesting
sigil testDependencies
- sigil-stdlib
- sigil-http
- sigil-json
- sigil-oauth