Version0.1.0Verifiednot yet verifiedLicenseBSD-3-Clause
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
Read the rest
(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
Clone
$ git clone https://codeberg.org/sigil/sigil-twitch
Releases
v0.1.1 — latest by version, released 1 Apr 2026
All releases — 2 tags in this repository.
Source
One page per file, and every line has a permalink.
Recent commitsAtom
1 Aprcommit
29 Marcommit
Pin dependencies to version tags
0b91018f
29 Marcommit
29 Marcommit
25 Marcommit
25 Marcommit
25 Marcommit
25 Marcommit
25 Marcommit
25 Marcommit
25 Marcommit
61b76706
25 Marcommit
6c21e963
The last 20 commits keep a page here. Everything older lives in the clone.