Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
unixpickle
GitHub Repository: unixpickle/kahoot-hack
Path: blob/master/kahoot/info.go
10110 views
1
package kahoot
2
3
import (
4
"bytes"
5
"encoding/json"
6
"errors"
7
"fmt"
8
"net/http"
9
)
10
11
// QuizChoice represents a possible answer for a QuizQuestion.
12
type QuizChoice struct {
13
Answer string `json:"answer"`
14
Correct bool `json:"correct"`
15
}
16
17
// QuizVideo is an optional video for a QuizQuestion.
18
type QuizVideo struct {
19
FullUrl string `json:"fullUrl"`
20
Id string `json:"id"`
21
StartTime float64 `json:"startTime"`
22
EndTime float64 `json:"endTime"`
23
Service string `json:"service"`
24
}
25
26
// QuizQuestion is a question in a quiz.
27
type QuizQuestion struct {
28
NumberOfAnswers int `json:"numberOfAnswers"`
29
Image string `json:"image"`
30
Video QuizVideo `json:"video"`
31
Question string `json:"question"`
32
QuestionFormat int `json:"questionFormat"`
33
Time int `json:"time"`
34
Points bool `json:"points"`
35
Choices []QuizChoice `json:"choices"`
36
Resources string `json:"resources"`
37
Type string `json:"type"`
38
}
39
40
// QuizMetadata stores metadata about a quiz.
41
type QuizMetadata struct {
42
Resolution string `json:"resolution"`
43
Moderation QuizModeration `json:"moderation"`
44
}
45
46
// QuizModeration stores moderator information for a quiz.
47
type QuizModeration struct {
48
FlaggedTimestamp float64 `json:"flaggedTimestamp"`
49
TimestampResolution float64 `json:"timestampResolution"`
50
Resolution string `json:"resolution"`
51
}
52
53
type userToken struct {
54
Email string `json:"email"`
55
PublicAccess bool `json:"public_access"`
56
PrimaryUsage string `json:"primary_usage"`
57
BannersShown map[string]int `json:"banners_shown"`
58
Metadata map[string]string `json:"metadata"`
59
Picture string `json:"picture"`
60
Uuid string `json:"uuid"`
61
Activated bool `json:"activated"`
62
Created int64 `json:"created"`
63
Modified int64 `json:"modified"`
64
Type string `json:"type"`
65
Username string `json:"username"`
66
Birthday []int `json:"birthday"`
67
}
68
69
type token struct {
70
AccessToken string `json:"access_token"`
71
Expires int64 `json:"expires"`
72
User userToken `json:"user"`
73
Roles []string `json:"roles"`
74
CountryCode string `json:"countryCode"`
75
CampaignAttributes map[string]string `json:"campaignAttributes"`
76
}
77
78
// QuizInfo stores information about a quiz, including
79
// the correct answers.
80
type QuizInfo struct {
81
Uuid string `json:"uuid"`
82
QuizType string `json:"quizType"`
83
Cover string `json:"cover"`
84
Modified int64 `json:"modified"`
85
Creator string `json:"creator"`
86
Audience string `json:"audience"`
87
Title string `json:"title"`
88
Description string `json:"description"`
89
Type string `json:"type"`
90
Created int64 `json:"created"`
91
Language string `json:"language"`
92
CreatorPrimaryUsage string `json:"creator_primary_usage"`
93
Questions []QuizQuestion `json:"questions"`
94
Image string `json:"image"`
95
Video QuizVideo `json:"video"`
96
Metadata QuizMetadata `json:"metadata"`
97
Resources string `json:"resources"`
98
CreatorUsername string `json:"creator_username"`
99
Visibility int64 `json:"visibility"`
100
}
101
102
// AccessToken returns an access token from the
103
// kahoot rest api.
104
func AccessToken(email, password string) (string, error) {
105
client := &http.Client{}
106
rawauth := map[string]string{"username": email, "password": password, "grant_type": "password"}
107
authentication, err := json.Marshal(rawauth)
108
if err != nil {
109
return "", err
110
}
111
request, err := http.NewRequest("POST", "https://create.kahoot.it/rest/authenticate", bytes.NewReader(authentication))
112
request.Header.Add("content-type", "application/json")
113
response, err := client.Do(request)
114
if err != nil {
115
return "", err
116
}
117
defer response.Body.Close()
118
receivedtoken := &token{}
119
err = json.NewDecoder(response.Body).Decode(receivedtoken)
120
if err != nil {
121
return "", err
122
}
123
if receivedtoken.User.Activated == false {
124
return "", errors.New("401 unauthorized error:email or password is incorrect")
125
}
126
return receivedtoken.AccessToken, nil
127
}
128
129
// QuizInformation returns all quiz information for a
130
// specific kahoot id.
131
func QuizInformation(token, quizid string) (*QuizInfo, error) {
132
client := &http.Client{}
133
request, err := http.NewRequest("GET", fmt.Sprintf("https://create.kahoot.it/rest/kahoots/%s", quizid), nil)
134
if err != nil {
135
return nil, err
136
}
137
request.Header.Add("content-type", "application/json")
138
request.Header.Add("authorization", token)
139
response, err := client.Do(request)
140
if err != nil {
141
return nil, err
142
}
143
defer response.Body.Close()
144
kahootquiz := &QuizInfo{}
145
err = json.NewDecoder(response.Body).Decode(kahootquiz)
146
if err != nil {
147
return nil, err
148
}
149
return kahootquiz, nil
150
}
151
152