How to expose AdWords to JavaScript via ClearScrip

2019-09-06 10:02发布

Context: VS2015 Community; C#; ClearScript.V8.5.4.5; Google.AdWords.18.25.0

I'm trying to create a scripting environment to do my Budgets. One the C# side, I'm setting up a JScript environment, and exposing all the AdWords types and objects that I need to it, viz

    static JScriptEngine JSengine = null;
    static Dictionary<string, object> Settings = new Dictionary<string, object>();

    static void Main(string[] args)
    {
        if (args.Length < 1)
        {
            Console.WriteLine("engine script.js");
            Environment.Exit(1);
        }
        string scriptSpec = args[0];

        try
        {
            JSengine = new JScriptEngine(WindowsScriptEngineFlags.EnableDebugging | WindowsScriptEngineFlags.EnableJITDebugging);
        }
        catch (Exception exc)
        {
            return;
        }

        // .. others as well e.g. File, Environment etc

        JSengine.AddHostType("AdWordsUser", typeof(AdWordsUser));
        JSengine.AddHostType("AdWordsAppConfig", typeof(AdWordsAppConfig));
        JSengine.AddHostType("BudgetOrderService", typeof(BudgetOrderService));
        JSengine.AddHostType("Selector", typeof(Selector));
        JSengine.AddHostType("Predicate", typeof(Predicate));
        JSengine.AddHostType("BudgetOrderPage", typeof(BudgetOrderPage));
        JSengine.AddHostType("BudgetOrder", typeof(BudgetOrder));
        JSengine.AddHostType("PredicateOperator", typeof(PredicateOperator));
        JSengine.AddHostType("AdWordsService", typeof(AdWordsService));

        JSengine.AddHostObject("Settings", Settings);

        object answer = null;
        string script = File.ReadAllText(scriptSpec);
        try
        {
            answer = JSengine.Evaluate(script);
        }
        catch (ScriptEngineException see)
        {
            Console.WriteLine(see.ErrorDetails);
        }
    }

I've done this kind of thing a few times already, so no surprises there.

The difficulty I'm having at the moment is one the JScript side. The code at this point looks like this:

var user = new AdWordsUser();
user.OAuthProvider.ClientId = "anonymised.apps.googleusercontent.com";
user.OAuthProvider.ClientSecret = "anonymised";
user.OAuthProvider.AccessToken = "";
user.Config.OAuth2RefreshToken = "anonymised";
user.OAuthProvider.RefreshAccessToken();

var config = new AdWordsAppConfig();
config.ClientCustomerId = "anonymised";
config.DeveloperToken = "anonymised";
config.UserAgent = "anonymised";
config.OAuth2ClientId = user.OAuthProvider.ClientId;
config.OAuth2ClientSecret = user.OAuthProvider.ClientSecret;
config.OAuth2AccessToken = user.OAuthProvider.AccessToken;
config.OAuth2RefreshToken = user.Config.OAuth2RefreshToken;

var bos = user.GetService(AdWordsService.v201603.BudgetOrderService);
var bas = bos.getBillingAccounts();

At this point, bos knows nothing about getBillingAccounts. The only way for bos to know about it is to execute

var bos = new BudgetOrderService();

However, then there's no connection then between bos and the values it needs in user, and attempting to execute getBillingAccounts raises an error.

The original C# code from which this derives is

BudgetOrderService bos = (BudgetOrderService)user.GetService(AdWordsService.v201603.BudgetOrderService);
BillingAccount[] bas = bos.getBillingAccounts();

Casting the GetService call to BudgetOrderService seems to be sufficient to make getBillingAccounts visible in bos. However, JScript doesn't let me do that.

So where to from here?

1条回答
聊天终结者
2楼-- · 2019-09-06 10:44

You should be able to do the cast in script code. Try this:

// C#
JSengine.Script.host = new HostFunctions();

Then, in your script:

// JavaScript
var bos = user.GetService(AdWordsService.v201603.BudgetOrderService);
bos = host.cast(BudgetOrderService, bos);

Or you can expose a delegate that does the cast in C# code.

查看更多
登录 后发表回答