# \[Userscript\] WK Real Numbers

**URL:** <https://community.wanikani.com/t/userscript-wk-real-numbers/10713>\
**Category:** API And Third-Party Apps\
**Created:** [November 13, 2015, 11:07pm UTC](https://community.wanikani.com/t/userscript-wk-real-numbers/10713 "2015-11-13T23:07:29Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Mempo](https://sea1.discourse-cdn.com/wanikanicommunity/user_avatar/community.wanikani.com/mempo/32/4886_2.png) [@Mempo](https://community.wanikani.com/u/Mempo)\
**Post date:** [November 13, 2015, 3:07pm UTC](https://community.wanikani.com/t/userscript-wk-real-numbers/10713/1 "2015-11-13T15:07:29Z")

</div>

WaniKani Real Numbers is a userscript written by penx. However, due to updates to WK the original script no longer works, so i’ve created this topic to officially adopt the script. Not all people look beyond the original post and because it still contains a broken and outdated link, a lot of people comment they need help, or that the script isn’t working. Because these problems can be avoided, i’d like this topic to replace the original one.  
  
The main purpose of this user script is to turn this:

![](https://global.discourse-cdn.com/wanikanicommunity/original/2X/0/0a270c0f76862f94afb7dd90daf6aba80496cd09.png)

into this:

![](https://global.discourse-cdn.com/wanikanicommunity/original/2X/9/941bc01d766cec6099b03d9b04baa4f755b48cde.png)

**Latest version:&nbsp;** v4  
  
**Download and more info**** :** [https://greasyfork.org/en/scripts/11244-wanikani-real-numbers](https://greasyfork.org/en/scripts/11244-wanikani-real-numbers)   
  
**Known issues:**

- None!

**Credits:**  

- Original script: penx
- Contributions by: srfacanha

  
If you encounter any problems, please let me know below!

---

<div class="post-metadata">

**Author:** ![caffeine](https://cdck-file-uploads-global.s3.dualstack.us-west-2.amazonaws.com/wanikanicommunity/original/3X/f/d/fd4c154120954695f788402f3bcf4e616499bc2d.png) [@caffeine](https://community.wanikani.com/u/caffeine)\
**Post date:** [January 22, 2016, 3:01pm UTC](https://community.wanikani.com/t/userscript-wk-real-numbers/10713/2 "2016-01-22T15:01:15Z")

</div>

This works on Chrome w/Tampermonkey, but I can’t seem to get this working on Firefox 43.0.4 w/Greasemonkey. My stats show up as blank (I see empty grey circles when the script is enabled).

On Chrome, it looks like I changed the first line of main() from this:

```
      var apikey = GM_getValue('apikey');

```

to this (obviously not my real apikey):

```
      var apikey = '1234567890';

```

However, when I make the same change to the WK Real Numbers script on Firefox, it doesn’t work.

I’m curious though – how is code like “var apikey = GM\_getValue(‘apikey’);” supposed to work? It seems like there should be a way of setting a Greasemonkey variable named apikey through some browser interface. I overwrote the code in Chrome, and it worked, but where are we supposed to set the value of apikey if we didn’t overwrite that first line of code?

Also, I assume the real magic of the script happens here:

```
	if(numberReviews.innerHTML == "42+" || numberLessons.innerHTML == "42+"){
		
		if(apikey){
					
			if(doneReviews){
			
				$.getJSON('https://www.wanikani.com/api/v1/user/'+ apikey +'/study-queue', function(data){
					setTimeout(function() {
						if(data.error){
							alert("API Error: "+data.error.message);
						}else{
							GM_setValue("numberReviews", data.requested_information.reviews_available);
							GM_setValue("numberLessons", data.requested_information.lessons_available);
							GM_setValue("doneReviews", false);
							displayReal(numberReviews, numberLessons);
						}
					}, 0);
				});
				
			}else{

```

How can I test each line of this code. For example, is it possible to print a javascript dialogue window with the results of numberReviews? A javascript dialogue box that tells me the operation timed out?

---

<div class="post-metadata">

**Author:** ![Mempo](https://sea1.discourse-cdn.com/wanikanicommunity/user_avatar/community.wanikani.com/mempo/32/4886_2.png) [@Mempo](https://community.wanikani.com/u/Mempo)\
**Post date:** [January 22, 2016, 4:27pm UTC](https://community.wanikani.com/t/userscript-wk-real-numbers/10713/3 "2016-01-22T16:27:16Z")

</div>

![httpbloghellodesigncomwp-contentuploads200807hello-coffeejpg](https://global.discourse-cdn.com/wanikanicommunity/original/3X/1/1/11bdc5c09f3cf1aea4403aeffe0c493f62136d96.jpg)  
  
How are you here caffeine ? I just drank you 5 minutes ago??  
  
But let’s be serious for a second.  
  
GM\_\* functions are to be avoided as much as possible because in my experience, they have very shitty cross-browser capabilities.  
Theoretically, the GM\_getValue(…) function would store a value in the local storage of your browser. This way, it only has to store your api key once, which is very convenient. Strangely, the GM\_\* functions usually work fine in Firefox, and fail in Chrome.  
  
It’s very odd replacing the code only worked in Chrome though. It’s  
possible to provide dialogue windows with the output or timeout, but not  
practical for end users (unless you’d want to solve the issue yourself,  
but I’m guessing that _if_ you could, you’d already know about such dialogue windows).  
  
I’ll try to reproduce your problem and come up with a solution for you. I’ll probably just rewrite the script so it doesn’t use these functions any more so future problems are avoided.  
  
EDIT: I could just go ahead and solve the problem, but I’ll only be able to test it within 12 hours (minimum) because I currently have no reviews.

---

<div class="post-metadata">

**Author:** ![caffeine](https://cdck-file-uploads-global.s3.dualstack.us-west-2.amazonaws.com/wanikanicommunity/original/3X/f/d/fd4c154120954695f788402f3bcf4e616499bc2d.png) [@caffeine](https://community.wanikani.com/u/caffeine)\
**Post date:** [January 22, 2016, 6:16pm UTC](https://community.wanikani.com/t/userscript-wk-real-numbers/10713/4 "2016-01-22T18:16:01Z")

</div>

Hey Mempo! &nbsp;Thanks for the reply! &nbsp; I assume my one paragraph of squished-together text actually parses into separate paragraphs for you? &nbsp; I just see one giant paragraph which I’d be amazed if anybody actually read!  
  
I don’t know a lick of Javascript, but I’m usually pretty quick at picking up new languages. &nbsp; I managed to isolate the problem, but I don’t know enough to resolve it. &nbsp; The main function has the structure of:

> function main()
> 
> {
> 
> &nbsp; &nbsp;&nbsp;var apikey = ‘something’;
> 
> &nbsp; &nbsp; alert(“Script started”)  
>   
> 
> &nbsp; &nbsp;&nbsp;if(&nbsp;! apikey ) {  
> &nbsp; &nbsp; &nbsp; &nbsp; alert(“apikey is undefined”)
> 
> &nbsp; &nbsp; &nbsp; &nbsp; // Do stuff if apikey is undefined (cut for brevity)
> 
> &nbsp; &nbsp; }
> 
>   
> 
> alert(“A”);
> 
> var doneReviews = GM\_getValue(“doneReviews”, true);
> 
> alert(“B”);
> 
> var lastUpdate &nbsp;= GM\_getValue(“lastUpdate”, “0”);
> 
> var currentTime = new Date().getTime();

The result?  
  
“Script started” gets printed. &nbsp;“A” gets printed. &nbsp; &nbsp;However,&nbsp;“B” doesn’t get printed!  
  
The script doesn’t seem to return from the call to GM\_getValue(“doneReviews”, true). &nbsp; You wrote that&nbsp;GM\_getValue(…)&nbsp; stores info as browser local storage – I did some research. &nbsp;It gets stored in a SQLite DB that belongs to Greasemonkey. &nbsp;I’m wondering something… &nbsp;does this script need to run something like  
  

> GM\_setValue(“doneReviews”, 0);

in order to instantiate the variable in the SQLite DB before we can the variable back using  
  

> GM\_getValue(“doneReviews”, true)

What do you think? &nbsp; While I wait for your reply, I’ll try to find this SQLite DB and see if I can find a utility to allow me to poke through it and look at the values.

---

<div class="post-metadata">

**Author:** ![caffeine](https://cdck-file-uploads-global.s3.dualstack.us-west-2.amazonaws.com/wanikanicommunity/original/3X/f/d/fd4c154120954695f788402f3bcf4e616499bc2d.png) [@caffeine](https://community.wanikani.com/u/caffeine)\
**Post date:** [January 22, 2016, 6:56pm UTC](https://community.wanikani.com/t/userscript-wk-real-numbers/10713/5 "2016-01-22T18:56:29Z")

</div>

I just found the location of the WK Real Numbers scripts:  
  
C:\Users\p\AppData\Roaming\Mozilla\Firefox\Profiles\uc44rzdq.default\gm\_scripts\WaniKani\_Real\_Numbers  
  
I see two files:

1. WK\_Real\_Numbers.user.js
2. jquery-1.8.3.min.js

From my reading, there should be a sqlite DB file in gm\_scripts. &nbsp; I see WaniKanify.db, but I don’t see any file named WaniKani\_Real\_Numbers.db in gm\_scripts. &nbsp; Should it exist?  
  
A missing DB file would certainly explain a failed call to GM\_getValue (although I would’ve hoped that Greasemonkey would issue a major complaint if it tried to grab a DB file that didn’t exist rather than silently fail!)

---

<div class="post-metadata">

**Author:** ![Mempo](https://sea1.discourse-cdn.com/wanikanicommunity/user_avatar/community.wanikani.com/mempo/32/4886_2.png) [@Mempo](https://community.wanikani.com/u/Mempo)\
**Post date:** [January 22, 2016, 7:49pm UTC](https://community.wanikani.com/t/userscript-wk-real-numbers/10713/6 "2016-01-22T19:49:43Z")

</div>

![httplh4ggphtcom-GAoYWtkE4ScVRAmNvSBsgIAAAAAAABUBU9nIwPB70xswcoffee252520I252527ve252520come252520to252520talk252520to252520you252520again_thumb25255B125255Dpngimgmax800](https://global.discourse-cdn.com/wanikanicommunity/original/3X/2/2/22a48b082f1ffcc6cc2d7037774e50dab2cf23fb.png)  
  
I never wondered about the internal workings of those functions actually.  
It’s very strange that the script fails after that function call. If an entry is not found it should return the default value.   
For&nbsp; _var doneReviews = GM\_getValue(“doneReviews”, true);&nbsp;_ &nbsp; that should be ‘true’.  
  
I wouldn’t meddle with that DB too much though. As I said earlier, I’ll just change those parts so it never has to use GM\_\* functions.   
  
PS: nope, your first post is a block of text. Not easy to read ;p

---

<div class="post-metadata">

**Author:** ![Mempo](https://sea1.discourse-cdn.com/wanikanicommunity/user_avatar/community.wanikani.com/mempo/32/4886_2.png) [@Mempo](https://community.wanikani.com/u/Mempo)\
**Post date:** [January 22, 2016, 7:59pm UTC](https://community.wanikani.com/t/userscript-wk-real-numbers/10713/7 "2016-01-22T19:59:09Z")

</div>

Replace the entire script with the code below and let me know if it works  
  
  
// ==UserScript==  
// @name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WaniKani Real Numbers  
// @namespace&nbsp;&nbsp; mempo  
// @author&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Mempo  
// @description Replaces 42+ with the real number using WaniKani API  
// @include&nbsp;&nbsp;&nbsp;&nbsp; [http://www.wanikani.com/](http://www.wanikani.com/)  
_// @include&nbsp;&nbsp;&nbsp;&nbsp; [https://www.wanikani.com/](https://www.wanikani.com/)_  
// @version&nbsp;&nbsp;&nbsp;&nbsp; 3  
// @grant&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; none  
// @run-at&nbsp;&nbsp;&nbsp; document-end  
// ==/UserScript==  
  
function main() {  
&nbsp; console.log(‘START OF WRN’);  
&nbsp; //var apikey = GM\_getValue(‘apikey’);  
&nbsp; var apiKey = localStorage.getItem(‘apiKey’);  
&nbsp; if (!apiKey) {  
&nbsp;&nbsp;&nbsp; if (window.location.href.indexOf(‘account’) != - 1) {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retrieveAPIkey();  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; apiKey = localStorage.getItem(‘apiKey’);  
&nbsp;&nbsp;&nbsp; } else {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var okcancel = confirm(‘WaniKani Real Numbers has no API key entered!\nPress OK to go to your settings page and retrieve your API key!’);  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (okcancel == true) {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; window.location = ‘[https://www.wanikani.com/account’](https://www.wanikani.com/account');  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }  
&nbsp;&nbsp;&nbsp; }  
&nbsp; }  
&nbsp;   
&nbsp; var doneReviews = Boolean(localStorage.getItem(‘WRN\_doneReviews’) || true);  
&nbsp; var lastUpdate = Number(localStorage.getItem(‘WRN\_lastUpdate’) || 0);  
&nbsp; //var doneReviews = GM\_getValue(‘doneReviews’, true);  
&nbsp; //var lastUpdate = GM\_getValue(‘lastUpdate’, ‘0’);  
&nbsp; var currentTime = new Date().getTime();  
&nbsp; if ((currentTime - lastUpdate) \> 120000) {  
&nbsp;&nbsp;&nbsp; localStorage.setItem(‘WRN\_lastUpdate’, currentTime.toString());  
&nbsp;&nbsp;&nbsp; doneReviews = true;  
&nbsp; }  
&nbsp; if (window.location.href.indexOf(‘review’) != - 1 || window.location.href.indexOf(‘lesson’) != - 1) {  
&nbsp;&nbsp;&nbsp; localStorage.setItem(‘WRN\_doneReviews’, “true”);  
&nbsp; } else {  
&nbsp;&nbsp;&nbsp; var numberReviews = document.getElementsByClassName(‘reviews’) [0].getElementsByTagName(‘span’) [0];  
&nbsp;&nbsp;&nbsp; var numberLessons = document.getElementsByClassName(‘lessons’) [0].getElementsByTagName(‘span’) [0];  
&nbsp;&nbsp;&nbsp; if (numberReviews.innerHTML == ‘42+’ || numberLessons.innerHTML == ‘42+’) {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (apiKey) {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (doneReviews) {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $.getJSON(‘[https://www.wanikani.com/api/user/](https://www.wanikani.com/api/user/)’ + apiKey + ‘/study-queue’, function (data) {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; setTimeout(function () {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (data.error) {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; alert('API Error: ’ + data.error.message);  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; localStorage.setItem(‘WRN\_numberReviews’, data.requested\_information.reviews\_available);  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; localStorage.setItem(‘WRN\_numberLessons’, data.requested\_information.lessons\_available);  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; localStorage.setItem(‘WRN\_doneReviews’, “”);  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; displayReal(numberReviews, numberLessons);  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }, 0);  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; });  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; displayReal(numberReviews, numberLessons);  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }  
&nbsp;&nbsp;&nbsp; }  
&nbsp; }  
}  
window.addEventListener(‘load’, main, false);  
//GM\_registerMenuCommand(‘WaniKani Real Numbers: Manually enter API key’, setAPIkey, null, null, ‘R’);  
//GM\_registerMenuCommand(‘WaniKani Real Numbers: Reset API key’, resetAPIkey, null, null, ‘e’);  
function resetAPIkey() {  
&nbsp; GM\_deleteValue(‘apikey’);  
&nbsp; alert(‘WaniKani Real Numbers API key reset!’);  
}  
  
function retrieveAPIkey() {  
&nbsp; for(var i=0;i\<document.getElementsByClassName(‘span6’).length;i++){  
&nbsp;&nbsp;&nbsp; if(document.getElementsByClassName(‘span6’)[i].getAttribute(‘placeholder’)==“Key has not been generated”)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; apiKey = document.getElementsByClassName(‘span6’) [i].getAttribute(‘value’);  
&nbsp; }  
&nbsp; alert('WaniKani Real Numbers API key set to: ’ + apiKey);  
&nbsp; if (apiKey) {  
&nbsp;&nbsp;&nbsp; localStorage.setItem(‘apiKey’, apiKey);  
&nbsp;&nbsp;&nbsp; localStorage.setItem(‘WRN\_doneReviews’, ‘true’);  
&nbsp;&nbsp;&nbsp; //GM\_setValue(‘apikey’, apikey);  
&nbsp;&nbsp;&nbsp; //GM\_setValue(‘doneReviews’, true);  
&nbsp; }  
}  
  
function setAPIkey() {  
&nbsp; var apiKey = prompt(‘Enter API key for WaniKani Real Numbers:’);  
&nbsp; if (apiKey) {  
&nbsp;&nbsp;&nbsp; localStorage.setItem(‘apiKey’, apiKey);  
&nbsp;&nbsp;&nbsp; localStorage.setItem(‘WRN\_doneReviews’, true);  
&nbsp;&nbsp;&nbsp; //GM\_setValue(‘apikey’, apikey);  
&nbsp;&nbsp;&nbsp; //GM\_setValue(‘doneReviews’, true);  
&nbsp; }  
}  
  
function displayReal(numberReviews, numberLessons) {  
&nbsp; numberReviews.innerHTML = localStorage.getItem(‘WRN\_numberReviews’);  
&nbsp; numberLessons.innerHTML = localStorage.getItem(‘WRN\_numberLessons’);  
&nbsp;   
&nbsp; [//numberReviews.innerHTML](https://numberReviews.innerHTML) = GM\_getValue(‘numberReviews’);  
&nbsp; [//numberLessons.innerHTML](https://numberLessons.innerHTML) = GM\_getValue(‘numberLessons’);  
}

---

<div class="post-metadata">

**Author:** ![Subtractem](https://sea1.discourse-cdn.com/wanikanicommunity/user_avatar/community.wanikani.com/subtractem/32/4392_2.png) [@Subtractem](https://community.wanikani.com/u/Subtractem)\
**Post date:** [January 22, 2016, 8:08pm UTC](https://community.wanikani.com/t/userscript-wk-real-numbers/10713/8 "2016-01-22T20:08:31Z")

</div>

This thread delights me. I have another date with caffeine in just a moment, I think I hear the water boiling.

---

<div class="post-metadata">

**Author:** ![caffeine](https://cdck-file-uploads-global.s3.dualstack.us-west-2.amazonaws.com/wanikanicommunity/original/3X/f/d/fd4c154120954695f788402f3bcf4e616499bc2d.png) [@caffeine](https://community.wanikani.com/u/caffeine)\
**Post date:** [January 22, 2016, 9:02pm UTC](https://community.wanikani.com/t/userscript-wk-real-numbers/10713/9 "2016-01-22T21:02:31Z")

</div>

> Subtractem said... This thread delights me. I have another date with caffeine in just a moment, I think I hear the water boiling.

&nbsp;Jesus... you're right. &nbsp; That's what I'm missing right now. &nbsp; It's been a couple of hours since I had my last cup. &nbsp;I'm gonna need another one before going back to Javascript debugging! &nbsp; :-) &nbsp; Thank you for the gentle&nbsp;reminder!

---

<div class="post-metadata">

**Author:** ![caffeine](https://cdck-file-uploads-global.s3.dualstack.us-west-2.amazonaws.com/wanikanicommunity/original/3X/f/d/fd4c154120954695f788402f3bcf4e616499bc2d.png) [@caffeine](https://community.wanikani.com/u/caffeine)\
**Post date:** [January 22, 2016, 9:36pm UTC](https://community.wanikani.com/t/userscript-wk-real-numbers/10713/10 "2016-01-22T21:36:11Z")

</div>

Whoa! &nbsp; That went way better than expected – flawless!  
  
I installed the script, it automagically got my API key, and just worked right out of the box.  
  
You weren’t kidding when you said that GM\_\* functions are to be avoided! &nbsp; Why do they exist when&nbsp;localStorage.(get|set)Item works so flawlessly?  
  
Hey – thank you!! &nbsp; I’m going back to Tokyo for ~6 months this year. &nbsp;If I see you there, consider drinks on me! &nbsp; I’m a very promiscuous person when it comes to web browsers. &nbsp;I like to cat around between FF and Chrome, and you’ve put them back on equal footing for me. &nbsp;:)

---

<div class="post-metadata">

**Author:** ![Mempo](https://sea1.discourse-cdn.com/wanikanicommunity/user_avatar/community.wanikani.com/mempo/32/4886_2.png) [@Mempo](https://community.wanikani.com/u/Mempo)\
**Post date:** [January 22, 2016, 9:50pm UTC](https://community.wanikani.com/t/userscript-wk-real-numbers/10713/11 "2016-01-22T21:50:37Z")

</div>

> caffeine said... Whoa! &nbsp; That went way better than expected -- flawless!  
>   
> I installed the script, it automagically got my API key, and just worked right out of the box.

Aaah, how beautiful when software does exactly what it's supposed to...  

> You weren't kidding when you said that GM\_\* functions are to be avoided! &nbsp; Why do they exist when&nbsp;localStorage.(get|set)Item works so flawlessly?

The localStorage API is something that was introduced in HTML5 (I think), so it's new compared to the Greasemonkey functions. It's now a standard implemented by all browsers. And those GM functions surely worked at some point (still do in Firefox mostly), but since Chrome had some updates things are a bit wonky. So not the best choice any more if you want to develop for multiple browsers ;p  

> Hey -- thank you!! &nbsp; I'm going back to Tokyo for ~6 months this year. &nbsp;If I see you there, consider drinks on me! &nbsp; I'm a very promiscuous person when it comes to web browsers. &nbsp;I like to cat around between FF and Chrome, and you've put them back on equal footing for me. &nbsp;:)

&nbsp;![httpsmediagiphycommedia10aIbqnbAbjX9egiphygif](upload://zOHxKikDLigiwa2BYgbcRt2KWdJ.gif)  
  
Never been to Japan actually ;p  
Just glad to help someone!

---

<div class="post-metadata">

**Author:** ![rfindley](https://sea1.discourse-cdn.com/wanikanicommunity/user_avatar/community.wanikani.com/rfindley/32/35202_2.png) [@rfindley](https://community.wanikani.com/u/rfindley)\
**Post date:** [January 23, 2016, 12:25am UTC](https://community.wanikani.com/t/userscript-wk-real-numbers/10713/12 "2016-01-23T00:25:45Z")

</div>

The GM functions also store values that can be accessed across multiple pages, whereas localstorage (for security reasons, because the web page itself can access them) can’t be accessed from a different site or between http and https. &nbsp;For that reason, GM is nice for things like global setting.

---

<div class="post-metadata">

**Author:** ![caffeine](https://cdck-file-uploads-global.s3.dualstack.us-west-2.amazonaws.com/wanikanicommunity/original/3X/f/d/fd4c154120954695f788402f3bcf4e616499bc2d.png) [@caffeine](https://community.wanikani.com/u/caffeine)\
**Post date:** [January 23, 2016, 2:10am UTC](https://community.wanikani.com/t/userscript-wk-real-numbers/10713/13 "2016-01-23T02:10:29Z")

</div>

I just stumbled across something:  
  
[http://wiki.greasespot.net/@grant](http://wiki.greasespot.net/@grant)  
  
Should there be two lines at the top that say:  
  
// @grant&nbsp;GM\_setValue  
// @grant GM\_getValue  
  
When I add these two lines at the top of the script, I get a little further. &nbsp; Your change is obviously the right way to go, but I’m sure this is partially to blame for why the script didn’t work for me on Firefox to begin with. &nbsp; The call to GM\_getValue() actually succeeds when I use the proper @grant directive.  
  
In the end, it doesn’t matter. &nbsp;The only reason why I’m asking is because I’m honestly curious, and I would like to learn how to write Greasemonkey scripts some day. &nbsp;:-)  
  
BTW, Japan is awesome. &nbsp;You should definitely try &nbsp;making it out there. &nbsp;It’ll blow your head right off, especially if you can manage to see it from the eyes of someone who lives there temporarily, as opposed to a tourist. &nbsp; Especially as a foreigner. &nbsp;They are so gracious, and we’re given a lot of slack. &nbsp; My coworkers say that I’m given “free pass” to behave poorly because it’s expected that foreigners are crude. &nbsp; &nbsp;By “free pass” they usually mean things like getting to work by 10am, talking (in a low voice) on the trainride home, trying to strike up a conversation with a girl on the street. &nbsp; It’ll blow your mind how hard they try at everything there. &nbsp;Everybody – no matter how important or unimportant their job is, they always give 100% and treat their job with dignity and respect.

---

<div class="post-metadata">

**Author:** ![Mempo](https://sea1.discourse-cdn.com/wanikanicommunity/user_avatar/community.wanikani.com/mempo/32/4886_2.png) [@Mempo](https://community.wanikani.com/u/Mempo)\
**Post date:** [January 23, 2016, 8:11am UTC](https://community.wanikani.com/t/userscript-wk-real-numbers/10713/14 "2016-01-23T08:11:12Z")

</div>

> caffeine said... I just stumbled across something:  
>   
> [http://wiki.greasespot.net/@grant](http://wiki.greasespot.net/@grant)  
>   
> Should there be two lines at the top that say:  
>   
> // @grant&nbsp;GM\_setValue  
> // @grant GM\_getValue  
>   
> When I add these two lines at the top of the script, I get a little further. &nbsp; Your change is obviously the right way to go, but I'm sure this is partially to blame for why the script didn't work for me on Firefox to begin with. &nbsp; The call to GM\_getValue() actually succeeds when I use the proper @grant directive.  
>   
> In the end, it doesn't matter. &nbsp;The only reason why I'm asking is because I'm honestly curious, and I would like to learn how to write Greasemonkey scripts some day. &nbsp;:-)  
>   
> BTW, Japan is awesome. &nbsp;You should definitely try &nbsp;making it out there. &nbsp;It'll blow your head right off, especially if you can manage to see it from the eyes of someone who lives there temporarily, as opposed to a tourist. &nbsp; Especially as a foreigner. &nbsp;They are so gracious, and we're given a lot of slack. &nbsp; My coworkers say that I'm given "free pass" to behave poorly because it's expected that foreigners are crude. &nbsp; &nbsp;By "free pass" they usually mean things like getting to work by 10am, **talking (in a low voice) on the trainride home**, trying to strike up a conversation with a girl on the street. &nbsp; It'll blow your mind how hard they try at everything there. &nbsp;Everybody -- no matter how important or unimportant their job is, they always give 100% and treat their job with dignity and respect.

&nbsp;Of course if you want to use GM functions, you should include the @grant, but I deleted them in the latest version because I no longer used them. But they were there in the original script, so that's not the problem.  
  
And you're saying people aren't even allowed to talk on the train? OK GUYS, I'm going to Japan. Seems like the place for me ;p

---

<div class="post-metadata">

**Author:** ![Mempo](https://sea1.discourse-cdn.com/wanikanicommunity/user_avatar/community.wanikani.com/mempo/32/4886_2.png) [@Mempo](https://community.wanikani.com/u/Mempo)\
**Post date:** [January 23, 2016, 8:14am UTC](https://community.wanikani.com/t/userscript-wk-real-numbers/10713/15 "2016-01-23T08:14:33Z")

</div>

> rfindley said... The GM functions also store values that can be accessed across multiple pages, whereas localstorage (for security reasons, because the web page itself can access them) **can't be accessed from a different site** or between http and https. &nbsp;For that reason, GM is nice for things like global setting.

&nbsp;Yea... That was something really weird. I had several tabs open and decided to check my apiKey value and it didn't work on other websites :/  
But hey, as long as it works on wanikani.com/\*  
As you said, for security reasons, it's maybe even for the better.

---

<div class="post-metadata">

**Author:** ![anon57647474](https://cdck-file-uploads-global.s3.dualstack.us-west-2.amazonaws.com/wanikanicommunity/original/3X/f/d/fd4c154120954695f788402f3bcf4e616499bc2d.png) [@anon57647474](https://community.wanikani.com/u/anon57647474)\
**Post date:** [January 23, 2016, 11:52pm UTC](https://community.wanikani.com/t/userscript-wk-real-numbers/10713/16 "2016-01-23T23:52:36Z")

</div>

This is the first script I am trying to use. &nbsp;Tampermonkey is installed and the code is in there, but it says it needs my API key. &nbsp;I have it, but don’t know what to do with it…

---

<div class="post-metadata">

**Author:** ![anon57647474](https://cdck-file-uploads-global.s3.dualstack.us-west-2.amazonaws.com/wanikanicommunity/original/3X/f/d/fd4c154120954695f788402f3bcf4e616499bc2d.png) [@anon57647474](https://community.wanikani.com/u/anon57647474)\
**Post date:** [January 23, 2016, 11:56pm UTC](https://community.wanikani.com/t/userscript-wk-real-numbers/10713/17 "2016-01-23T23:56:40Z")

</div>

Oh, nevermind. &nbsp;I got it. &nbsp;:D &nbsp;Yay!

---

<div class="post-metadata">

**Author:** ![aniustaluwis](https://sea1.discourse-cdn.com/wanikanicommunity/user_avatar/community.wanikani.com/aniustaluwis/32/7463_2.png) [@aniustaluwis](https://community.wanikani.com/u/aniustaluwis)\
**Post date:** [August 3, 2016, 7:39pm UTC](https://community.wanikani.com/t/userscript-wk-real-numbers/10713/18 "2016-08-03T19:39:31Z")

</div>

Added this script. Thank you so much!

---

<div class="post-metadata">

**Author:** ![squashedmos](https://sea1.discourse-cdn.com/wanikanicommunity/user_avatar/community.wanikani.com/squashedmos/32/7422_2.png) [@squashedmos](https://community.wanikani.com/u/squashedmos)\
**Post date:** [December 22, 2016, 5:36am UTC](https://community.wanikani.com/t/userscript-wk-real-numbers/10713/19 "2016-12-22T05:36:07Z")

</div>

Yeah… so… I’ve tried to use this a couple of times and I just can’t get it to work. I’ve tried manually inserting my api key into the code but first, I don’t seem to find the place where it fits and, second, I simply don’t know if there is a particular sintaxis in which to put it. All I get is “API Error: User does not exist.” every time I load a WK page, no prompt to introduce my api nor anything else.  
  
I’m using Firefox 50.1.0 and Greasemonkey 3.9. I also have a couple of other scripts for WK but I see no reason for the to interfere with this one… but of course I wouldn’t really know  
  
&nbsp;

 ![](https://global.discourse-cdn.com/wanikanicommunity/original/3X/2/c/2c669dde28fa92e6f5509b82ecc9b7b5f53c8cd5.jpg)

---

<div class="post-metadata">

**Author:** ![rfindley](https://sea1.discourse-cdn.com/wanikanicommunity/user_avatar/community.wanikani.com/rfindley/32/35202_2.png) [@rfindley](https://community.wanikani.com/u/rfindley)\
**Post date:** [December 22, 2016, 5:45am UTC](https://community.wanikani.com/t/userscript-wk-real-numbers/10713/20 "2016-12-22T05:45:17Z")

</div>

> squashedmos said... Yeah... so... I've tried to use this a couple of times and I just can't get it to work.

You probably have an old API key in you browser storage. &nbsp;But even if that's not the problem try the following:  
  
Open the Javascript console (press F12 and select the Console tab)  
Paste the following command (with your API key inserted, and be sure there aren't any spaces around you API key) and press enter:  
  
localStorage.setItem('apiKey', 'enter\_your\_apikey\_here');

[Next page](https://community.wanikani.com/t/userscript-wk-real-numbers/10713.md?page=2)
