AtlatestRenderedmarkdown
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

ModuleDescription
(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 dict

Authentication

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

OperationScope
Modify channelchannel:manage:broadcast
Read stream keychannel:read:stream_key
Manage schedulechannel:manage:schedule
Read followersmoderator:read:followers
Read subscriberschannel:read:subscriptions
Send chat messagesuser:write:chat
Read chat messages (EventSub)user:read:chat
Create clipsclips:edit
Extension analyticsanalytics:read:extensions
Game analyticsanalytics:read:games

Building

sigil deps install
sigil build

Testing

sigil test

Dependencies

  • sigil-stdlib
  • sigil-http
  • sigil-json
  • sigil-oauth