MagicMirror Forum
    • Recent
    • Tags
    • Unsolved
    • Solved
    • MagicMirror² Repository
    • Documentation
    • 3rd-Party-Modules
    • Donate
    • Discord
    • Register
    • Login
    A New Chapter for MagicMirror: The Community Takes the Lead
    Read the statement by Michael Teeuw here.

    MMM-Todoist - Your todoist tasks on your mirror

    Scheduled Pinned Locked Moved Productivity
    76 Posts 37 Posters 98.3k Views 39 Watching
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • J Offline
      jsp196
      last edited by

      Follow-up question - I’ve been trying to put all the config options in both the MMM-Todoist file and the config.js file (commenting them on and off as needed) but it’s not working. Is there a way for me to find a LOG of what Todoist is responding with so I know if it’s working? I’m a relative beginner but am hoping there’s a place for me to look and diagnose what’s not working.

      T 1 Reply Last reply Reply Quote 0
      • T Offline
        tkotz8621 @jsp196
        last edited by

        @jsp196 A possible reason for your tasks not displaying is if you have any tasks with no due dates, there is a known bug in MMM-Todoist that will not display any of the tasks. I have a fork at https://github.com/tkotz8105/MMM-Todoist that corrects the bug. I hope it solves your issue.

        J 1 Reply Last reply Reply Quote 0
        • J Offline
          jsp196 @tkotz8621
          last edited by jsp196

          @tkotz8621 Thanks. I had tried that but I just went through and deleted all the MMM-Todoist files, started over with your fork and now it works.

          One other question - if I want to change the color of this module, is the CSS entry .module.MMM-Todoist? And has anyone had any luck with it working in custom.css or does it need to go into main.css?

          Thanks!

          1 Reply Last reply Reply Quote 0
          • L Offline
            Lange
            last edited by

            Have anyone added a feature where it shows duedate?

            T 1 Reply Last reply Reply Quote 0
            • T Offline
              tkotz8621 @Lange
              last edited by

              @Lange Good idea… I thought about looking to adding it as an option set in config file. It may be a few weeks before I can maybe start to take a look at it.

              1 Reply Last reply Reply Quote 1
              • D Offline
                djsunrise19
                last edited by djsunrise19

                I want to extend the module a little bit:

                • Project Name as header
                • Project color in front of the name / the todos
                • reminder icon behind the todo (due date like the discussion above)

                I tried a few things (from @tidus5 within the fetcher). But I can’t get it to work. Any hints / ideas?

                tidus5T 1 Reply Last reply Reply Quote 0
                • tidus5T Offline
                  tidus5 @djsunrise19
                  last edited by

                  @djsunrise19 Hello

                  i’m on holiday. Can send you the files when i’m back. you need to change the fetcher indeed.

                  Have a nice day

                  1 Reply Last reply Reply Quote 0
                  • tidus5T Offline
                    tidus5
                    last edited by yawns

                    This is my code
                    it’s based on 2 users (i badly commented the code)

                    /* Magic Mirror
                     * Fetcher
                     *
                     *
                     * By Michael Teeuw http://michaelteeuw.nl edited for Wunderlist by Paul-Vincent Roll
                     * Edited again for Todoist by Chris Brooker
                     * 
                     * MIT Licensed.
                     */
                    
                    var request = require("request");
                    
                    /* Fetcher
                     * Responsible for requesting an update on the set interval and broadcasting the data.
                     *
                     * attribute listID string - ID of the Wunderlist list.
                     * attribute reloadInterval number - Reload interval in milliseconds.
                     */
                     
                     	function dateDiff(date1, date2){
                        var diff = {}                           // Initialisation du retour
                        var tmp = date2 - date1;
                     
                        tmp = Math.floor(tmp/1000);             // Nombre de secondes entre les 2 dates
                        diff.sec = tmp % 60;                    // Extraction du nombre de secondes
                     
                        tmp = Math.floor((tmp-diff.sec)/60);    // Nombre de minutes (partie entière)
                        diff.min = tmp % 60;                    // Extraction du nombre de minutes
                     
                        tmp = Math.floor((tmp-diff.min)/60);    // Nombre d'heures (entières)
                        diff.hour = tmp % 24;                   // Extraction du nombre d'heures
                         
                        tmp = Math.floor((tmp-diff.hour)/24);   // Nombre de jours restants
                        diff.day = tmp;
                         
                        return diff;
                    }
                    
                    var Fetcher = function(listID, reloadInterval, accessToken, clientID) {
                     var self = this;
                     if (reloadInterval < 1000) {
                    	reloadInterval = 1000;
                     }
                    
                     var reloadTimer = null;
                     var items = [];
                    
                     var fetchFailedCallback = function() {};
                     var itemsReceivedCallback = function() {};
                    
                     /* private methods */
                    
                     /* fetchTodos()
                    	* Request the new items.
                    	*/
                    
                     var fetchTodos = function() {
                    	clearTimeout(reloadTimer);
                    	reloadTimer = null;
                    
                    	request({
                    		url: "https://todoist.com/API/v7/sync/",
                    		method: "POST",
                    		headers: { 
                    			'content-type': 'application/x-www-form-urlencoded',
                    			'cache-control': 'no-cache' 
                    		},
                    		form: { 
                    				token: accessToken,
                    				sync_token: '*',
                    				resource_types: '["items"]' 
                    		}
                    	 },
                    	 
                    	 
                    	 function(error, response, body) {
                    		if (!error && response.statusCode == 200) {
                             items = [];
                    		 for (var i = 0; i < JSON.parse(body).items.length; i++) {
                    			 if (JSON.parse(body).items[i].project_id == listID) {
                    		
                    		donneetableau = JSON.parse(body).items[i];
                    		onbalance = [];
                    		icontodo = [];
                    		assignedname = [];
                    		datedueretour = [];
                    		contentretour = [];
                    		assignedtodoname = [];
                    		checkedretour = [];
                    		
                    		
                    		if (donneetableau.priority == '1') {icontodo ='<i></i> '}
                    		else if (donneetableau.priority == '2') {icontodo ='<i></i> '}
                    		else if (donneetableau.priority == '3') {icontodo ='<i></i> '}
                    		else {icontodo ='<i></i> '}
                    
                    		if (donneetableau.assigned_by_uid == 'XXXXXXXX') {assignedname ='(XXXXX)'}//TEST  first XXX UID second XXXX yourname
                    		else if (donneetableau.assigned_by_uid == 'XXXXXXX') {assignedname ='(XXXXXX)'}//TEST  first XXX UID second XXXX yourname
                    		else {assignedname ='Inconnu'};
                    		
                    		if (donneetableau.due_date_utc) 
                    			{
                    				date1 = new Date();
                    				date2 = new Date(donneetableau.due_date_utc);
                    				diff = dateDiff(date1, date2);
                    								
                    				if (diff.day = '1') {datedueretour += diff.day + 'd <i></i> ';}
                    				else if (diff.hour >= '1') {datedueretour += diff.hour + 'h <i></i> ';}		
                    				else {datedueretour += diff.min + 'min <i></i> ';};						
                    
                    
                    			}
                    		else {datedueretour =''};
                    		
                    		contentretour = donneetableau.content;
                    		
                    		if (donneetableau.responsible_uid ) {
                    		if (donneetableau.responsible_uid == 'XXXXXXX') {
                    		assignedtodoname ='<i></i> '
                    		} ////YOUR UID USER
                    		
                    		else if (donneetableau.responsible_uid == 'XXXXXXX') {assignedtodoname ='<i></i> '}
                    		else {assignedtodoname ='Inconnu'};  // YOUR UID USER
                    		} else { assignedtodoname ='' };
                    		
                    		checkedretour = donneetableau.checked;
                    		onbalance +=assignedtodoname + icontodo + datedueretour + contentretour;
                    		items.push(onbalance);	
                    				//items.split('\n');
                    				 //priority.push(JSON.parse(body).priority[i].priority);	
                    				 //datedue.push(JSON.parse(body).datedue[i].due_date_utc);	
                    
                    			 }
                    		 }
                    		 self.broadcastItems();
                    		 scheduleTimer();
                    		}
                    	 });
                    
                     };
                    
                     /* scheduleTimer()
                    	* Schedule the timer for the next update.
                    	*/
                    
                     var scheduleTimer = function() {
                    	//console.log('Schedule update timer.');
                    	clearTimeout(reloadTimer);
                    	reloadTimer = setTimeout(function() {
                    	 fetchTodos();
                    	}, reloadInterval);
                     };
                    
                     /* public methods */
                    
                     /* setReloadInterval()
                    	* Update the reload interval, but only if we need to increase the speed.
                    	*
                    	* attribute interval number - Interval for the update in milliseconds.
                    	*/
                     this.setReloadInterval = function(interval) {
                    	if (interval > 1000 && interval < reloadInterval) {
                    	 reloadInterval = interval;
                    	}
                     };
                    
                     /* startFetch()
                    	* Initiate fetchTodos();
                    	*/
                     this.startFetch = function() {
                    	fetchTodos();
                     };
                    
                     /* broadcastItems()
                    	* Broadcast the exsisting items.
                    	*/
                     this.broadcastItems = function() {
                    	if (items.length
                    
                    1 Reply Last reply Reply Quote 0
                    • C Offline
                      Cupola
                      last edited by Cupola

                      Dumb question, how do you exactly generate the access token? I’m a little bit confused…
                      From pm2 logs, I read:
                      ** Message: console message: http://localhost:8080/modules/MMM-Todoist//MMM-Todoist.js @199: SyntaxError: Unexpected token ‘>’
                      I used the access token generated from here, but I’m not sure about the process, which App service URL did you use? Which OAuth redirect URL? And last which token is the right one? I can see three of them
                      Thanks in advance

                      pyrosmileyP 1 Reply Last reply Reply Quote 1
                      • pyrosmileyP Offline
                        pyrosmiley @Cupola
                        last edited by

                        @Cupola

                        Not a dumb question, don’t worry! Oauth2 can be super confusing, and everyone does it a little differently which is… frustrating at best.

                        The Access Token you need is the 3rd one, what they refer to as your Test Token on the page. (The idea behind this is that with OA2, each would-be client has to use its ID and Secret to ask for specific account access for each account it wants to see. They basically did that process for you once, for testing or personal things like this that only need your account.)

                        You don’t need to worry about the OAuth redirect URL or the App Service URL. I have each filled with http://127.0.0.1 but I don’t think either are required at all.

                        Hopefully this gets you up and running!

                        1 Reply Last reply Reply Quote 0
                        • 1
                        • 2
                        • 3
                        • 4
                        • 5
                        • 6
                        • 7
                        • 8
                        • 4 / 8
                        • First post
                          Last post
                        Enjoying MagicMirror? Please consider a donation!
                        MagicMirror created by Michael Teeuw.
                        Forum managed by Sam, technical setup by Karsten.
                        This forum is using NodeBB as its core | Contributors
                        Contact | Privacy Policy