Gmail contextual gadget doesn't appear after GAM SDK Test install - google-apps-marketplace

I cannot manage to see a contextual gadget in Gmail after Test Install Flow in Google Apps Marketplace SDK.
These are the steps I took to create the project, logged as a domain administrator:
create Google Apps console project
create OAuth2 client
enable GAM SDK
configure the SDK page with COB extension:
Extractor Url: google.com:HelloWorld
GadgetUrl: URL of gadget spec
Extractor param name: Test
Extractor param value: .*
Scopes: Mail - Subject Line, Mail - Message Body
I didn't add any additional Oauth2 scopes than the userinfo.email and userinfo.profile that are already there, and the Universal Navigation link is just a file that redirects to Gmail( since I am trying a very simple variant of the project to see if I can get it to work ).
I press Test Install flow, I am asked to give permissions in a Oauth combined window, I am redirected to my Universal navigation link, then Gmail. The app appears in the Google Apps Admin control panel and seems to have installed successfully, it is ON for all domain users.
I tried Gmail with different domain users, cleared cache, logged out and back in to Gmail, I am probably missing a configuration somewhere.
This is the gadget spec:
<?xml version="1.0" encoding="UTF-8"?>
<Module>
<ModulePrefs title="Title" description="Desc" author="" author_email="" author_location="" scrolling="false" height="20">
<Require feature="dynamic-height"/>
<Require feature="google.contentmatch">
<Param name="extractors">
google.com:HelloWorld
</Param>
</Require>
</ModulePrefs>
<Content type="html" view="card">
<![CDATA[
<script type="text/javascript">
<!-- Fetch the array of content matches. -->
matches = google.contentmatch.getContentMatches();
var matchList = document.createElement('UL');
var listItem;
var extractedText;
for (var match in matches) {
for (var key in matches[match]) {
listItem = document.createElement('LI');
extractedText = document.createTextNode(key + ": " + matches[match][key]);
listItem.appendChild(extractedText); matchList.appendChild(listItem); }
}
document.body.appendChild(matchList);
gadgets.window.adjustHeight(100);
</script>
]]>
</Content>
</Module>

Couple of suggestions -
Use the nocache option to force your Gmail UI to update. Use this link - https://mail.google.com/mail/u/0/?nogadgetcache=1#inbox
Try as a different account on the domain. I've seen some cases where the "developer/admin" inbox takes time to update

Related

Resource Not Found While fetching contacts from MS Graph API

I tried below github sample for Azure AD Authentication and successfully getting access token with proper call back URL.
https://github.com/Microsoft/BotBuilder-Samples/tree/master/samples/csharp_dotnetcore/18.bot-authentication
Modified and Configured Web.config Keys as per my application created in https://apps.dev.microsoft.com
<add key="ActiveDirectory.Mode" value="v1" />
<add key="ActiveDirectory.ResourceId" value="https://graph.microsoft.com" />
<add key="ActiveDirectory.EndpointUrl" value="https://login.microsoftonline.com" />
<add key="ActiveDirectory.Tenant" value="xyz-xyz" />
<add key="ActiveDirectory.ClientId" value="xyz-xyz" />
<add key="ActiveDirectory.ClientSecret" value="xyz-xyz" />
<add key="ActiveDirectory.RedirectUrl" value="http://localhost:3979/api/Callback" />
<add key="ActiveDirectory.Scopes" value="Calendars.Read,Calendars.ReadWrite,Contacts.Read,Contacts.ReadWrite,Mail.Read,Mail.ReadWrite,User.Read" />
I had crossed checked access token that i received jwt.ms. It is a valid token with scopes defined exactly as i defined in web.config.
I am able to get User Profile data from API by passing token but while trying to call "Contacts" of user, I am getting below error.
{
"error": {
"code": "ResourceNotFound",
"message": "Resource could not be discovered.",
"innerError": {
"request-id": "6f0f3ec9-76c9-4662-ac25-0bc73f887268",
"date": "2019-03-02T17:23:35"
}
}
}
Code calling Contact API call.
//Get Logged in user contacts
public async Task<IUserContactsCollectionPage> GetMyContactsAsync()
{
var graphClient = GetAuthenticatedClient();
IUserContactsCollectionPage contacts = await graphClient.Me.Contacts.Request().GetAsync();
return contacts;
}
FYI: Displayed Sign In card in emulator Authorize sample URL is like below
https://login.microsoftonline.com/a76b43b0-3088-4c56-ba0d-01f317b1f18c/oauth2/authorize?resource=https:%2F%2Fgraph.microsoft.com&client_id=XYZ&response_type=code&haschrome=1&redirect_uri=http:%2F%2Flocalhost:3979%2Fapi%2FCallback&x-client-SKU=PCL.Desktop&x-client-Ver=3.13.9.1126&x-client-CPU=x64&x-client-OS=Microsoft+Windows+NT+10.0.16299.0&state=<stateID>
It might happens for many reason one of the very common issue is to required grant permission to your registered app. Make sure you have done following steps accordingly.
Step 1:
Login in to your portal and select your application under app registrations.
Then click on settings see the screen shot below:
Step 2:
Once you clicked Settings new window will come up right side, click on Required Permission menu: see the screen shot below:
Step 3:
Select Required Permission Menu and assign your permission by clicking on Add button
see the snap below:
Step 4:
Click on Select an API option see below:
Final Step:
Select your desired API and checked it which you are like to access for. Once finished the permission click on Done. After this step you can access your required resource / Scope from your application. Hope it will be helpful for you.Thank You.
see the screen shot below:

Calling asmx service from .net core api2

i need to call an old asmx web service (I have not control over)from a .net core web api
is it possible?
thanks
The way I was able to do it was fully update Visual Studio 2017, then get the latest WCF Connected Services extension from here:
https://marketplace.visualstudio.com/items?itemName=WCFCORETEAM.VisualStudioWCFConnectedService
After I did that, I was able to add and call the SOAP service like so.
Right click on Connected Services folder (should appear just below your project) and select Add Connected Service. Then select "Add a WCF web service". Put your asmx url into the URI field, set the name space and click Finish. You will now have the reference set.
An example of what my code does...
If you don't have an authorization header, you can ignore that part:
MySoapClient.EndpointConfiguration endpoint = new MySoapClient.EndpointConfiguration();
MySoapClient myService = new MySoapClient(endpoint, myURL);
AuthorizationSoapHeader MyAuthHeader = new AuthorizationSoapHeader();
MyAuthHeader.AppName = FDSServiceAppName;
MyAuthHeader.AppID = Guid.Parse(MyAppID);
Entry[] entries = MyService.GetUsers().Result;
The accepted answer is 100% correct, but there was one gotcha when trying to add an ASMX Web Service with VS WCF Connected Services that I encountered, but wasn't initially obvious to me.
In my case the web service that I was trying to connect to had disabled the WSDL in the Web.config. I had to remove or comment out the following in the Web.config to allow the metadata to be imported and code scaffolded successfully.
<webServices>
<protocols>
<!-- <remove name="Documentation" /> -->
</protocols>
</webServices>
Once <remove name="Documentation" /> is removed or commented out like the example above, the ASMX service will be able to be added to your project.

Gmail Contextual Gadget Not Visible in Gmail

I am trying to develop one gmail gadget. I have prepared my gadget.xml file after reading all the required peoint mentioned in the google documents. But after that they ask to make a manifest file. But as far I have searched, now we don't need to prepare any manifest file. Now, we can prepare it through Google Apps Marketplace SDK. I have prepared a manifest here and saved it and enabled it from console.developers.google.com.
But after that also, I am not able to see my gadget in Gmail. Please any experienced developer help me in this problem. I trying to solve this problem from long time.
Here is my gadget.xml code:
<?xml version="1.0" encoding="UTF-8"?>
<Module>
<ModulePrefs author="Company Name" height="500" author_email="abc#example.com" author_location="India">
<Require feature="dynamic-height"/>
<Require feature="views" />
<Require feature="google.contentmatch">
<Param name="extractors">google.com:MessageIDExtractor</Param>
<Param name="extractors">google.com:SenderEmailExtractor</Param>
</Require>
</ModulePrefs>
<Content type="html" view="card">
<![CDATA[
<p> Pragmatic Odoo Gmail Integration</p>
<script>console.log('Hello from gadget.')</script>
]]>
</Content>
</Module>
Here is my Google Apps Marketplace SDK settings for gadget:
enter image description here
Pay attention to below hints:
Add an app to chrome web store and link it to your Google project, which you describe contextual gadget, with project ID.Here's a sample of web store manifest.json:
{
"manifest_version": 2,
"name": "Sample App",
"short_name": "Dev",
"version": "1.0.0",
"default_locale": "en",
"description": "Sample app",
"app" : {
"launch" : {
"web_url" : "http://yourcompany.com"
}
},
"icons": {
"128": "icons/128x128-icon.png",
"16": "icons/16x16-icon.png"
},
"container": ["DOMAIN_INSTALLABLE"],
"api_console_project_id": "your-project-id"
}
After publish this app, add it to test Google Domain. Since your gadget is in development stage so, don’t publish your app to Public. There are different "Visibility options" that you can choose.
To disable cache use nogadgetcache=1 (e.g. https://mail.google.com/?nogadgetcache=1)
Login with admin account which you want to test it, otherwise take more time to update manifest.
After Modify “Google Apps Marketplace SDK” click on “Test Installation Flow” to be sure there is no new permission.
I did these part and works for me:
Define google.com:MessageIDExtractor as first extension, however you don’t need that.
I recommend that select every scopes which you want to use in other
extensions here! I don’t know why put it seems the google just ask
these permission for my gadget
Define Param extractor in gadget.xml separately not with comma:
<Require feature="google.contentmatch">
<Param name="extractors">
google.com:MessageIDExtractor
</Param>
<Param name="extractors">
google.com:SenderEmailExtractor
</Param>
</Require>

Xamarin forms open another app using Rivets component

I have to open an app from another app in Xamarin forms. I found the Rivets component which says it can do what i want but I'm not sure what url it refers to.
I looked at http://applinks.org/documentation/ and it says the url I want opened per mobile platform.
My question is, for iOS, what url is it looking for? I thought it was the link to the app in itunes. All that link does is open the app store at the app but doesn't launch the app if it's already installed.
Unless you have control over the Blue Diamond Party app's code or you know that the Blue Diamond Party app has registered one or more custom app links (which are the custom URLs you have read about), you will not be able to open it from your app on iOS. This is the only way to make that work with Rivets. The Blue Diamond Party app would need to register a custom URI of some kind that it would respond to. Then, using Rivets, your app would call that custom URI.
*Edit: To get your app to handle app links from other apps, you can head to the Xamarin's Getting Started Guide (look under the Handling Incoming App Link Navigation heading):
Android does things different than iOS, but for iOS:
Register the custom URI in the Info.plist (not sure if that is the correct XML but it is something like that, check out the link for an image)(the string under CFBundleURLName is just a custom name for your scheme and then you can list multiple schemes in the array under the name):
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>com.bluediamondparty.schemes</string>
<key>CFBundleURLSchemes</key>
<array>
<string>bluediamondparty</string>
</array>
</dict>
</array>
The above XML would register the bluediamondparty as your URI scheme for your app to respond to.
Now, in order for your app to do something when a URI with your custom scheme is run, you override OpenUrl in your AppDelegate (this allows you to put things after your custom URI scheme to, for example, open a specific page or item in your app):
public override bool OpenUrl (UIApplication app, NSUrl url, string srcApp, NSObject annotation) {
var rurl = new Rivets.AppLinkUrl (url.ToString ());
if (rurl.InputUrl.Host.Equals ("play")) {
var gameModeType = rurl.InputQueryParameters ["game_mode_type"];
var c = new ProductViewController (gameModeType, rurl.Referrer);
navController.PushViewController (c, true);
return true;
}
return false;
}
To open the URI from your second app, you might run something like this:
UIApplication.SharedApplication.OpenUrl(new NSUrl("bluediamondparty://play?game_mode_type=survival"));
Finally, you might notice that none of that actually required using the Rivets component... so what does that component actually do for us?! What Rivets actually does is to allow your app to pass in a real URL (such as http://rdio.com/song/12345) and Rivets will go to that page and look for special meta tags that describes how the content on the page is linked to a mobile app that the user might have installed on their device. So on that rdio web page they might have the following meta tag:
<meta property="al:ios:url" content="rdio://song/12345" />
In that meta tag it will list the correct custom URI scheme to attempt to open the Rdio app if the user has it installed and it has registered itself with the custom rdio URI scheme.
The other thing to know is that your app does not have exclusive rights to a URI scheme. So if another app chooses the same URI scheme as you and the user installs both of them, then the last app to be installed will respond to the URI scheme.

Cannot make Gmail contextual gadget work - 2015 API version

I am currently working on a Gmail Contextual Gadget for a non-profit organization.
We followed the official Google tutorials on https://developers.google.com/gmail/contextual_gadgets with the goal of building a Hello World app.
We did the following:
Create an app on https://console.developers.google.com/
Activate Google Marketplace SDK
Activate GMail contextual gadget with appropriate Extractor and Gadget URLs.
Deploy the app for the Non-Profit organization users.
Send us emails containing "Hello World".
However, we are not able to make it work (it should print Hello World below the emails). We checked our servers hosting the XMs, and Google definitely hits our gadget_helloworld.xml file.
Hereby are the files content. Could someone please give a hand on this subject?
It is hard to find up to date documentation on this topic, as a lot of things changed with the Google API. I think it would be helpful for the community to give an open source working sample of code updated on last-2015.
Best,
Content of the Extractor - manifest_helloworld.xml
<?xml version="1.0" encoding="UTF-8"?>
<ApplicationManifest xmlns="http://schemas.google.com/ApplicationManifest/2009">
<script id="tinyhippos-injected" />
<Extension id="HelloWorldExtractor" type="contextExtractor">
<Name>Hello World Extractor</Name>
<Url>google.com:HelloWorld</Url>
<Triggers ref="HelloWorld" />
<Scope ref="emailBody" />
<Scope ref="emailSubject" />
<Container name="mail" />
</Extension>
<Extension id="HelloWorld" type="gadget">
<Name>HelloWorld Gadget</Name>
<Url>XXXX_MY_DOMAIN/gadget_files/gadget_helloworld.xml</Url>
<Container name="mail" />
<!-- Uncomment this to enable Caja. -->
<!-- Param name="caja" value="enabled"/> -->
</Extension>
<Scope id="emailBody">
<Url>tag:google.com,2010:auth/contextual/extractor/BODY</Url>
<Reason>Necessary for reason 1</Reason>
</Scope>
<Scope id="emailSubject">
<Url>tag:google.com,2010:auth/contextual/extractor/SUBJECT</Url>
<Reason>Necessary for reason 2</Reason>
</Scope>
</ApplicationManifest>
Content of the Gadget - gadget_helloworld.xml
<?xml version="1.0" encoding="UTF-8"?>
<Module>
<script id="tinyhippos-injected" />
<ModulePrefs title="Hello World" description="Matches and echoes 'Hello World' string in emails" height="20" author="ACME" author_email="test#example.com" author_location="Bermuda">
<!-- Declare feature dependencies. -->
<!--
This one is not specific to Gmail contextual gadgets.
-->
<Require feature="dynamic-height" />
<!--
The next feature, Caja, is optional, and is supported for
use only within test domains. Uncomment the tag only for
non-production gadgets.
-->
<!-- <Require feature="caja"/> -->
<!--
The next feature, google.contentmatch, is required for all
Gmail contextual gadgets.
<Param> - specify one or more comma-separated extractor IDs in
a param named "extractors". This line is overridden by the extractor ID
in the manifest, but is still expected to be present.
-->
<Require feature="google.contentmatch">
<Param name="extractors">google.com:HelloWorld</Param>
</Require>
</ModulePrefs>
<!--
Define the content type and display location. The settings
"html" and "card" are required for all Gmail contextual gadgets.
-->
<Content type="html" view="card"><![CDATA[<p>Hello World</p>
<script type="text/javascript">
<!-- Fetch the array of content matches. -->
matches = google.contentmatch.getContentMatches();
var matchList = document.createElement('UL');
var listItem;
var extractedText;
<!-- Iterate through the array and display output for each match. -->
for (var match in matches) {
for (var key in matches[match]) {
listItem = document.createElement('LI');
extractedText = document.createTextNode(key + ": " + matches[match][key]);
listItem.appendChild(extractedText);
matchList.appendChild(listItem);
}
}
document.body.appendChild(matchList);
gadgets.window.adjustHeight(100);
</script>]]></Content>
</Module>
I had a similar issue of it not activating and the solution for me was to make the "Extractor param name" set to "hello" and and the "Extractor param value" set to ".*" -- According to the docs the important part is the value field:
If you really do want your gadget to be triggered by all possible
values in the extractor's default output, explicitly set the regular
expression as value=".*". This makes it clear that you have cast a
wide net by design.

Resources