Conflict 409 error when creating a Google Shared Contact using API - google-api

I'm continually getting a HTTP 409 "Conflict" error when attempting to add a new Google Shared Contact using the API.
I've followed the documentation as closely as possible and have defined the new entry as so:
<atom:entry xmlns:atom='http://www.w3.org/2005/Atom' xmlns:gd='http://schemas.google.com/g/2005'>
<atom:category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/contact/2008#contact' />
<gd:name>
<gd:givenName>Test</gd:givenName>
<gd:familyName>Testerson</gd:familyName>
<gd:fullName>Test Testerson</gd:fullName>
</gd:name>
<atom:content type='text'></atom:content>
<gd:email rel='http://schemas.google.com/g/2005#work' primary='true' address='test.testerson#sample.com.au' displayName='' />
<gd:email rel='http://schemas.google.com/g/2005#home' address='' />
<gd:phoneNumber rel='http://schemas.google.com/g/2005#work' primary='true'>(07) 33331111</gd:phoneNumber>
<gd:phoneNumber rel='http://schemas.google.com/g/2005#mobile'>0411223344</gd:phoneNumber>
<gd:phoneNumber rel='http://schemas.google.com/g/2005#fax'>(07) 33331122</gd:phoneNumber>
<gd:phoneNumber rel='http://schemas.google.com/g/2005#home'></gd:phoneNumber>
<gd:im address='' protocol='http://schemas.google.com/g/2005#GOOGLE_TALK' primary='true' rel='http://schemas.google.com/g/2005#home' />
<gd:structuredPostalAddress rel='http://schemas.google.com/g/2005#work' primary='true'>
<gd:city>Abbey</gd:city>
<gd:street>PO Box 4561</gd:street>
<gd:region>WA</gd:region>
<gd:postcode>6280</gd:postcode>
<gd:country>Australia</gd:country>
<gd:formattedAddress>PO Box 4561, Abbey, WA, 6280, Australia</gd:formattedAddress>
</gd:structuredPostalAddress>
<gd:structuredPostalAddress rel='http://schemas.google.com/g/2005#other'>
<gd:city>Abbey</gd:city>
<gd:street>47 Example Avenue</gd:street>
<gd:region>WA</gd:region>
<gd:postcode>6280</gd:postcode>
<gd:country>Australia</gd:country>
<gd:formattedAddress>47 Example Avenue, Abbey, WA, 6280, Australia</gd:formattedAddress>
</gd:structuredPostalAddress>
<gd:organization rel='http://schemas.google.com/g/2005#other'>
<gd:orgTitle>Guinea Pig</gd:orgTitle>
<gd:orgName>Test Org</gd:orgName>
</gd:organization>
</atom:entry>
I've set up my HTTP request as follows:
lsToken = GetAuthToken()
Set lobjHttp = CreateObject("MSXML2.XMLHTTP")
Call lobjHttp.Open("POST", CS_FEED_DEFAULT, False, "", "")
Call lobjHttp.setRequestHeader("Authorization", "GoogleLogin auth=" + lsToken)
Call lobjHttp.setRequestHeader("Content-type", "application/atom+xml")
Call lobjHttp.Send(lsOut)
In this example CS_FEED_DEFAULT is the shared contact URL and lsOut is my entry as defined above.
After sending this request I get the 409 response and the following response text:
<?xml version='1.0' encoding='UTF-8'?>
<entry xmlns='http://www.w3.org/2005/Atom' xmlns:gContact='http://schemas.google.com/contact/2008' xmlns:batch='http://schemas.google.com/gdata/batch' xmlns:gd='http://schemas.google.com/g/2005'>
<id>http://www.google.com/m8/feeds/contacts/test.com.au/base/47e904e10dd27dd2</id>
<updated>2014-09-17T02:08:39.761Z</updated>
<category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/contact/2008#contact'/>
<title type='text'></title>
<content type='text'></content>
<link rel='http://schemas.google.com/contacts/2008/rel#edit-photo' type='image/*' href='https://www.google.com/m8/feeds/photos/media/test.com.au/47e904e10dd27dd2/1B2M2Y8AsgTpgAmY7PhCfg'/>
<link rel='self' type='application/atom+xml' href='https://www.google.com/m8/feeds/contacts/test.com.au/full/47e904e10dd27dd2'/>
<link rel='edit' type='application/atom+xml' href='https://www.google.com/m8/feeds/contacts/test.com.au/full/47e904e10dd27dd2/1410919719761001'/>
<gd:email rel='http://schemas.google.com/g/2005#work' address='test.testerson#sample.com.au' primary='true'/>
<gd:phoneNumber rel='http://schemas.google.com/g/2005#work' primary='true'>(07) 33331111</gd:phoneNumber>
<gd:phoneNumber rel='http://schemas.google.com/g/2005#mobile'>0411223344</gd:phoneNumber>
<gd:phoneNumber rel='http://schemas.google.com/g/2005#work_fax'>(07) 33331122</gd:phoneNumber>
</entry>
Can anyone offer me any advice on this issue?
Thanks.

According to the contacts API documentation, "409 error can be returned when there is a different contact with the same email address. As for now, google contacts API does not allow two different contacts to share an email address".
Have you been trying to add the same email address twice?

I had the same error because I forgot to Start my previously stopped SQL instance on GCP.

Related

Sending a PDF file in a REST Message

I am trying figure this out any help appreciated. Thanks in advance
The service is a file passthrough that picks up a PDF and then uses the BPL code below to create the rest wrapper and sends the stream data. I am not grabbing the stream from the inbound correctly, "request.Stream" or "request.StreamFC" always produces the following error.
Here is what is sent and returned in the message..
request:
*
<Stream>
15#%Library.FileCharacterStream
</Stream>
response:
<Stream>
Unable to load xml from message: Data at the root level is invalid. Line 1, position 1.
</Stream>
-I think my issue is I am not using the right class by using "%GlobalStreamCharacter", Or the raw PDF CDATA inbound I am not handling correctly
set context.RESTMessage.Stream=##class(%GlobalCharacterStream).%New()
I have tried using different Stream types...File, Binary....but no luck
-The general BPL below
/// BPL Definition
X
Data BPL [ XMLNamespace = "http://www.intersystems.com/bpl" ]
{
<process language='objectscript' request='Ens.StreamContainer' response='Ens.Response'
height='2000' width='2000' >
<context>
.....
.....
....
<code name='Create REST Message' xpos='200' ypos='250' >
<![CDATA[
set context.RESTMessage=##class(EnsLib.HTTP.GenericMessage).%New()
set context.RESTMessage.Stream=##class(%GlobalCharacterStream).%New()
set tSC=context.RESTMessage.Stream.Write(request.StreamFC)
set tSC=context.RESTMessage.HTTPHeaders.SetAt("application/xml","Content-Type")
set tSC=context.RESTMessage.HTTPHeaders.SetAt(context.RESTMessage.Stream.Size,"Content-
Length")
set tSC=context.RESTMessage.HTTPHeaders.SetAt("POST","HttpRequest")
]]>
</code>
You can try this code snippet. I got the answer in the community.
<call name='To application Rest' target='To application REST' async='0'>
<request type='EnsLib.REST.GenericMessage' >
<assign property="callrequest.Stream" value='##class(%Stream.GlobalCharacter).%New()'/>
<assign property="status" value='callrequest.Stream.CopyFrom(request.StreamFC)' action="set" />
<assign property="status" value='callrequest.HTTPHeaders.SetAt("application/xml", "Content-Type")' action="set" />
<assign property="status" value='callrequest.HTTPHeaders.SetAt(callrequest.Stream.Size, "Content-Length")' action="set" />
<assign property="status" value='callrequest.HTTPHeaders.SetAt("POST", "HttpRequest")' action="set" />
</request>
</call>

Can't set a test license token in an Outlook addin

I'm trying to set a test license token in an Outlook add-in. According to the documentation, I have to set it in the SourceLocation in the manifest file:
<Form xsi:type="ItemRead">
<DesktopSettings>
<SourceLocation DefaultValue="https://localhost:3000?et=%3Cr%3E%0A%20%20%3..."/>
<RequestedHeight>250</RequestedHeight>
</DesktopSettings>
</Form>
The problem is, when I try to get the URL query params, it won't work. window.location looks like this:
https://localhost:3000/?et=
Any idea why it's happening?
When I update the source location of the Action ShowTaskpane, it won't start the addin:
<Action xsi:type="ShowTaskpane">
<SourceLocation resid="messageReadTaskPaneUrl" />
</Action>
...
<bt:Url id="messageReadTaskPaneUrl" DefaultValue="https://localhost:3000?et=%3Cr%3E%0A%20%20%...">
If I set it like this, when I start the addin, it says:
Sorry, but we can't start this add-in because it isn't set up properly.
I use the following test token:
<r>
<t
aid="WA907006056"
pid="{4FB601F2-5469-4542-B9FC-B96345DC8B39}"
cid="32F3E7FC559F4F49"
did="{0672BAE9-B41B-48FE-87F1-7F4D3DD3F3B1}"
ts="30"
et="Trial"
ad="2012-01-12T21:58:13Z"
ed="2019-06-30T21:58:13Z"
sd="2012-01-12T00:00:00Z"
test="true"
te="2019-06-30T02:49:34Z" />
<d>VNNAnf36IrkyUVZlihQJNdUUZl/YFEfJOeldWBtd3IM=</d>
</r>
And use the following service to encode the url:
https://www.urlencoder.org/
The problem is with URL encoding. When encoding the token, you have to remove all the new lines. Otherwise, it will throw an error. So, before encoding, take the token...
<r>
<t
aid="WA907006056"
pid="{4FB601F2-5469-4542-B9FC-B96345DC8B39}"
cid="32F3E7FC559F4F49"
did="{0672BAE9-B41B-48FE-87F1-7F4D3DD3F3B1}"
ts="30"
et="Trial"
ad="2012-01-12T21:58:13Z"
ed="2019-06-30T21:58:13Z"
sd="2012-01-12T00:00:00Z"
test="true"
te="2019-06-30T02:49:34Z" />
<d>VNNAnf36IrkyUVZlihQJNdUUZl/YFEfJOeldWBtd3IM=</d>
</r>
and remove all the new lines like this:
<r> <t aid="WA907006056" pid="{4FB601F2-5469-4542-B9FC-B96345DC8B39}" cid="32F3E7FC559F4F49" did="{0672BAE9-B41B-48FE-87F1-7F4D3DD3F3B1}" ts="30" et="Trial" ad="2012-01-12T21:58:13Z" ed="2019-06-30T21:58:13Z" sd="2012-01-12T00:00:00Z" test="true" te="2019-06-30T02:49:34Z" /> <d>VNNAnf36IrkyUVZlihQJNdUUZl/YFEfJOeldWBtd3IM=</d> </r>
Finally encode it and add to all the source locations.

EWS getting phone number from directory folder

I'm querying EWS with DistinguishedFolderId set to Directory. If I add
<t:FieldURI FieldURI="persona:PhoneNumber" />
to the field URIs I don't get the phone number returned. Also if I try to expand the BaseShape to AllProperties I get a failure.
<soap:Body>
<m:FindItem Traversal="Shallow">
<m:ItemShape>
<t:BaseShape>IdOnly</t:BaseShape>
<t:AdditionalProperties>
<t:FieldURI FieldURI="persona:DisplayName" />
</t:AdditionalProperties>
</m:ItemShape>
<m:IndexedPageItemView MaxEntriesReturned="100" Offset="0" BasePoint="Beginning" />
<m:ParentFolderIds>
<t:DistinguishedFolderId Id="directory" />
</m:ParentFolderIds>
</m:FindItem>
</soap:Body>
What I'm trying to do is construct a query which will return me the person (not the contact, I need to look into the directory not the contacts) details with the phone number from the tenant.
Ok - found the answer to this one. FindPeople and FindItems aren't going to return the phone number by default, that's some kind of extension.
See here and here where it was partially answered on msdn forums. The solution proposal is to use the GetPersona method and query each PersonId individually.

Yii2 REST API IIS Object Moved

I am using Yii2 REST with ActiveController to create a new Pessoa(), on Apache works fine , but on IIS 8 an error occurs.
Does anyone know of any configuration in IIS?
REQUEST
Request URL:http://10.192.1.145/api/pessoa
Request Method:POST
Status Code:201 Created
Remote Address:10.192.1.145
Referrer Policy:no-referrer-when-downgrade
RESPONSE
<head><title>Document Moved</title></head>
<body><h1>Object Moved</h1>This document may be found
here</body>{"id":"21"}
I had a similar issue to this. It seems to be related to FastCGI. Not sure about it. I know it happens when setting response headers to 201 http status code (this line in source code) which get changed by IIS later. If you have access to server try those solutions:
W7 Pro IIS 7.5 overwrites PHP Location: Header (solved)
In my case I had only FTP access to server so I overridden the Create Action by something like what follows to force a 200 status code instead of 201:
public function actions()
{
$actions = parent::actions();
unset($actions['create']);
return $actions;
}
public function actionCreate() {
$model = new Pessoa();
$model->load(Yii::$app->getRequest()->getBodyParams(), '');
if ($model->save() === false && !$model->hasErrors()) {
throw new ServerErrorHttpException('Failed to update the object for unknown reason.');
}
return $model;
}
Just in case somebody else needs to keep the status code and remove only the response part added by IIS, this is what I did to solve my problem. You may need adapt it to your needs, though:
<!-- PS: In my case, i just had a one line HEAD and a one line BODY being added. -->
<outboundRules>
<rule name="Remove the tag HEAD" preCondition="isStatus201">
<match filterByTags="None" pattern="^\<head\>.*?$" />
<action type="Rewrite" value="" />
</rule>
<rule name="Remove the tag BODY" preCondition="isStatus201">
<match filterByTags="None" pattern="^\<body\>.*?\</body\>" />
<action type="Rewrite" value="" />
</rule>
<preConditions>
<preCondition name="isStatus201">
<add input="{RESPONSE_STATUS}" pattern="^201$" />
</preCondition>
</preConditions>
</outboundRules>
Tested in IIS 8.5;
Hope it helps somebody else.
In fact, I was able to optimize the RegEx so that a single rule catches all the lines up the closing body tag:
<outboundRules>
<rule name="Remove injected 201 content" preCondition="Status 201">
<match filterByTags="None" pattern="^(?:.*[\r\n]*)*.*</body>" />
<action type="Rewrite" value="" />
</rule>
<preConditions>
<preCondition name="Status 201" patternSyntax="Wildcard">
<add input="{RESPONSE_STATUS}" pattern="201" ignoreCase="false" />
</preCondition>
</preConditions>
</outboundRules>

WSO2 websocket + SockJS - Cross origin requests blocked

Since WSO2 5.0 supports WebSockets, I have written a simple app following by tutorials:
WebSocket Transport
Sending a Message from a WebSocket Client to an HTTP Endpoint
Here's my source view output from WSO2:
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://ws.apache.org/ns/synapse">
<registry provider="org.wso2.carbon.mediation.registry.WSO2Registry">
<parameter name="cachableDuration">15000</parameter>
</registry>
<taskManager provider="org.wso2.carbon.mediation.ntask.NTaskTaskManager"/>
<sequence name="fault">
<!-- Log the message at the full log level with the ERROR_MESSAGE and the ERROR_CODE-->
<log level="full">
<property name="MESSAGE" value="Executing default 'fault' sequence"/>
<property expression="get-property('ERROR_CODE')" name="ERROR_CODE"/>
<property expression="get-property('ERROR_MESSAGE')" name="ERROR_MESSAGE"/>
</log>
<!-- Drops the messages by default if there is a fault -->
<drop/>
</sequence>
<sequence name="main">
<in>
<!-- Log all messages passing through -->
<log level="full"/>
<!-- ensure that the default configuration only sends if it is one of samples -->
<!-- Otherwise Synapse would be an open proxy by default (BAD!) -->
<filter regex="http://localhost:9000.*" source="get-property('To')">
<!-- Send the messages where they have been sent (i.e. implicit "To" EPR) -->
<send/>
</filter>
</in>
<out>
<send/>
</out>
<description>The main sequence for the message mediation</description>
</sequence>
<sequence name="outDispatchSeq">
<log level="full"/>
<respond/>
</sequence>
<sequence name="dispatchSeq">
<switch
source="get-property('websocket.source.handshake.present')" xmlns:ns="http://org.apache.synapse/xsd">
<case regex="true">
<drop/>
</case>
<default>
<call/>
<respond/>
</default>
</switch>
</sequence>
<!-- You can add any flat sequences, endpoints, etc.. to this synapse.xml file if you do
*not* want to keep the artifacts in several files -->
<inboundEndpoint name="test" onError="fault" protocol="ws"
sequence="dispatchSeq" suspend="false">
<parameters>
<parameter name="inbound.ws.port">9091</parameter>
<parameter name="ws.client.side.broadcast.level">0</parameter>
<parameter name="ws.outflow.dispatch.sequence">outDispatchSeq</parameter>
<parameter name="ws.outflow.dispatch.fault.sequence">fault</parameter>
</parameters>
</inboundEndpoint>
</definitions>
I was able to successfully test it with Nett client:
C:\work\servers\netty>java -Durl=ws://localhost:9091/websocket -DsubProtocol="synapse(contentType='application/xml')" -cp netty-example-4.1.4.Final.jar;lib/*;. io.netty.example.http.websocketx.client.WebSocketClient
WebSocket Client connected!
However if I try to test it from JavaScript code I am getting error like:
Do you know what is wrong in my code?
This issue occurs because SockJS internally trying to load the URL using XMLHttpRequest, but Chrome does not allow accessing cross origin content unless the protocol is one of the aforementioned protocols (In this case it is ws://). I have tried a similar scenario with Firefox and it works fine since it doesn't have this Chrome specific limitation.
In this scenario since WSO2 ESB exposes a WebSocket interface to invoke the HTTP Endpoint, you can use native HTML5 WebSocket implementation as follows.
var url = 'ws://localhost:9091/websocket';
var ws = new WebSocket(url);
ws.onopen = function() {
// todo
}
ws.onmessage = function(e) {
// todo
}

Resources