4

I am attempting to write a C# wrapper for the Twilio Programmable Chat tool. The library provided is for JS clients. I thought that using a tool like ClearScript (V8) would allow me to wrap the js as needed.

The example code on the site is

const Chat = require('twilio-chat');

// Make a secure request to your backend to retrieve an access token.
// Use an authentication mechanism to prevent token exposure to 3rd parties.

const accessToken = '<your accessToken>';

Chat.Client.create(accessToken)
  .then(client => {
   // Use Programmable Chat client
});

so after I initialize

using (var engine = new V8ScriptEngine())
{
  engine.Execute(@"
    const Chat = require('twilio-chat.js');

    const token = 'my token';

    Chat.Client.create(token).then(client=>{
    });
  ");
 }

The program errors on the 'require' line with the error require is not defined. I have read that require is simply returning the module exports so I replaced the require('... with

engine.Execute(@"
    const Chat = ('twilio-chat.js').module.exports;
...

but that errors with Cannot read property 'exports' of undefined'

I got the js file from https://media.twiliocdn.com/sdk/js/chat/releases/4.0.0/twilio-chat.js

How can I get around this or maybe there is a better way. I appreciate any and all insights.

Thanks

Jeff
  • 2,061
  • 4
  • 27
  • 45

1 Answers1

6

I don't know anything about Twilio, but here's how to enable ClearScript's CommonJS module support. This sample loads the script from the web, but you can limit it to the local file system or provide a custom loader:

engine.AddHostType(typeof(Console));
engine.DocumentSettings.AccessFlags = DocumentAccessFlags.EnableWebLoading;
engine.DocumentSettings.SearchPath = "https://media.twiliocdn.com/sdk/js/chat/releases/4.0.0/";
engine.Execute(new DocumentInfo() { Category = ModuleCategory.CommonJS }, @"
    const Chat = require('twilio-chat');
    const token = 'my token';
    Chat.Client.create(token).then(
        client => Console.WriteLine(client.toString()),
        error => Console.WriteLine(error.toString())
    );
");

This successfully loads the Twilio script, which appears to be dependent on other scripts and resources that aren't part of the bare standard JavaScript environment that ClearScript/V8 provides. To get it working, you'll have to augment the search path and possibly expose additional resources manually. As shown, this code prints out ReferenceError: setTimeout is not defined.

BitCortex
  • 3,328
  • 1
  • 15
  • 19
  • 1
    Thank you. This has helped me better understand the ClearScript workings and I got as far as you did. Thank you Thank you Thank you. – Jeff Sep 03 '20 at 12:57
  • @BitCortex - could you expand on 'This sample loads the script from the web, but you can limit it to the local file system or provide a custom loader:' please ? I am interested in loading an initial local script that will then name other local scripts that it requires. In my case the initial script is procedural code and the scripts it will want to load are files representing JS classes to which it refers. So the first script might be wanting to show the salary for an employee, for which it would want to require a class file named emp.js wherein lies an emp class with a showSalary method. – Vanquished Wombat Dec 03 '20 at 16:14
  • 1
    @VanquishedWombat You can use `engine.DocumentSettings.AccessFlags` to enable loading from the web, the file system, or both. You can also change `engine.DocumentSettings.Loader` (or even `engine.DocumentSettings` itself), but that's probably overkill. Check out ClearScript's API documentation. – BitCortex Dec 04 '20 at 13:40
  • @BitCortex Thank you. I had this same issue and I was about to publish a new question, because in my case the "require" points to node.js modules like require('fs') and require('path'), and I'm not sure if those are available outside node.js... not sure if this solution is viable for node.js modules. By the way, I'm going to publish a new question about ClearScript... thanks for sharing your knowledge. – ElektroStudios Jul 09 '23 at 03:42