Search code examples
javascriptmeteorrocket.chatasynchronous-javascript

API Call in Rocket.Chat Integration


I am trying to further extend the telegram-rocket.chat bridge and need to call some apis for that. For this, rocket.chat exposes a Meteor.js wrapper called HTTP.

This code snippet is an outgoing-hook that processes a message sent by a user, lets me transform the message and pass along the altered text.

The prepare_outgoing_request({request}) gets called by the rocket.chat hook and I'd like to call an API within it that resolves emoji codes to the actual emoji-character: ":see_no_evil: to 🙈"

/** Global Helpers
 *
 * console - A normal console instance
 * _       - An underscore instance
 * s       - An underscore string instance
 * HTTP    - The Meteor HTTP object to do sync http calls
 *           https://docs.meteor.com/api/http.html
 */


class Script {
    request_emojitext(emoji_code) {
       console.log(`called: request_emojitext('${emoji_code}')`);
       const url = `https://www.emojidex.com/api/v1/emoji/${emoji_code}`;
  
       const response = HTTP.call('GET', url);

       console.log(`Emoji Response: ${response.constructor.name} => ${JSON.stringify(response)}`);
      // Emoji Response: Object => {"error":{}}             
       return response;
    }
  
    /**
    	request.params            {object}
     	request.method            {string}
    	request.url               {string}
    	request.headers           {object}
    	*/
    prepare_outgoing_request({ request }) {
      	const emojiResponse = this.request_emojitext('see_no_evil');
      	const emojiCharacter = emojiResponse.content.emoji;
        
        return {
          // https://core.telegram.org/bots/api
          url: `${request.url}&text=${emojiCharacter}`,
          method: 'GET'
        };
    }
}

The Meteor documentation states that:

// Asynchronous call
Meteor.call('foo', 1, 2, (error, result) => { ... });

// Synchronous call
const result = Meteor.call('foo', 1, 2);

/*
On the client, if you do not pass a callback and you are not 
inside a stub, call will return undefined, and you will have 
no way to get the return value of the method. That is because
the client doesn’t have fibers, so there is not actually any 
way it can block on the remote execution of a method.
*/

I am unsure on how to procede here as I'm not entirely comfortable with asynchronous programming yet. How would I block until the result is actually available, or is there a different way of doing this that I am completely missing?


Solution

  • I found the problem through looking at the implementation of the HTTP variable (PR #5876). Plus a feature request for asynchronous calls has been opened (Issue #4775).

    const response = HTTP('GET', 'https://www.emojidex.com/api/v1/emoji/sweat_smile');

    This executes the API call synchronously and returns a result object:

    {
      "result": {
        "statusCode": 200,
        "headers": {
          // ...
        },
        "data": {
          "code": "sweat smile",
          "moji": "😅",
          // ...
        }
      }
    }

    If you want to see the full code you can check it out on Git