Background
When I use Outlook client to send a mail with inline image.
The image in html email looks like this, which has cid:
<img size="100" src="cid:3bb599fc-f3eb-465b-af83-aa6a495f563a" style="max-width:100%">
When I use
GET /me/messages/{messageId}/attachments
The contentId in the result returned matched the cid in html.
{
"value": [
{
"#odata.type": "#microsoft.graph.fileAttachment",
"id": "aaa",
"lastModifiedDateTime": "2017-11-30T09:32:09Z",
"name": "image.png",
"contentType": "image/png",
"size": 100,
"isInline": true,
"contentId": "3bb599fc-f3eb-465b-af83-aa6a495f563a",
"contentLocation": null,
"contentBytes": "validBase64Bytes"
}
]
}
Using Microsoft Graph API
Now I am trying to use Microsoft Graph API to add inline image.
POST /me/messages/{messageId}/attachments
{
"#odata.type": "#microsoft.graph.fileAttachment",
"name": "1.jpg",
"isInline": true,
"contentBytes": "validBase64Bytes"
}
However, the contentId is null in the result returned.
{
"#odata.type": "#microsoft.graph.fileAttachment",
"id": "aaa",
"lastModifiedDateTime": "2017-11-30T09:35:50Z",
"name": "1.jpg",
"contentType": "image/jpeg",
"size": 100,
"isInline": true,
"contentId": null,
"contentLocation": null,
"contentBytes": "validBase64Bytes"
}
And if I set contentId manually in POST
POST /me/messages/{messageId}/attachments
{
"#odata.type": "#microsoft.graph.fileAttachment",
"name": "1.jpg",
"isInline": true,
"contentId": "myContentId",
"contentBytes": "validBase64Bytes"
}
It will return the error
{
"error": {
"code": "BadRequest",
"message": "Unable to read JSON request payload. Please ensure Content-Type header is set and payload is of valid JSON format.",
"innerError": {
"request-id": "36e95f0a-ad75-46c6-b86c-d585a150b96d",
"date": "2017-11-30T09:37:41"
}
}
}
So how to add inline image correctly?
Weird, I tried to run the exact same code again, it won't give me any error now.
POST /me/messages/{messageId}/attachments
{
"#odata.type": "#microsoft.graph.fileAttachment",
"name": "1.jpg",
"isInline": true,
"contentId": "myContentId",
"contentBytes": "validBase64Bytes"
}
Not sure whether it is a temporary issue. I will inform Microsoft team to check the log.
If I am wrong for how to use the API, please definitely point out. Thanks.
I will leave it here for future people to save some time to implement adding inline image.
Related
I was using identity verification feature from Docusign with envelopes. Previously, envelopes are working fine without it. Then I enabled this feature and searched on the Docusign API Documentation, how to implement this feature. I got the necessary details like authentication token, workflow id. Try to hit the endpoint using Post request. Everything's fine but having issues in the body part of the post request getting invalid phone number response. Thank you for your time! Please help!
//Post request endpoint
https://demo.docusign.net/restapi/v2.1/accounts/f8594d59-9d52-xxxx-xxxx-xxxxxxxxxxxx/envelopes
//header
Authorization: Bearer {accestoken}
Content-Type: application/json
Acces: application/json
//request body
{
"accountId": "f8594d59-9d52-xxxx-xxxx-xxxxxxxxxxxx",
"templateId": "4e2ba389-5d26-xxxx-xxxx-xxxxxxxxxxxx",
"emailSubject": "Please sign the contract",
"templateRoles": [
{
"roleName": "Sender",
"name": "Name",
"email": "fName.lName#xyz.com",
"identityVerification": {
"workflowId": "c368e411-1592-xxxx-xxxx-xxxxxxxxxxxx",
"steps": null,
"inputOptions": [
{
"name": "phone_number_list",
"valueType": "PhoneNumberList",
"phoneNumberList": [
{
"countryCode": "1",
"number": "8956324511"
}
]
}
]
}
},
{
"roleName": "Customer",
"name": "cFName",
"email": "cFName.cLName#gmail.com"
}
],
"status": "sent"
}
//Response
{
"errorCode": "PHONE_NUMBER_INVALID",
"message": "Phone number is not valid."
}
//Expected Response can vary
{
"envelopeId": "e8342cd0-ea2b-xxxx-xxxx-xxxxxxxxxx",
"uri": "/envelopes/e8342cd0-ea2b-xxxx-xxxx-xxxxxxxxxx",
"statusDateTime": "2023-01-13T05:22:35.0100000Z",
"status": "sent"
}
According to https://www.areacodehelp.com/where/area_code_895.shtml area code 895 is not valid.
Try with a valid phone number to confirm the issue, but to me it looks like the number you used here is indeed not a valid phone number.
PS
If you meant to use a number in Azerbaijan, you need to change the country code from "1" to "895" as it's a country code for a different country (the way you have is if for the USA)
So, basically what I found is ID verification won't work with template roles because of the syntax compatibility. But it will work with composite templates, I made it work with composite template.
Additionally, both of the methods are compatible idVerification or phoneAuthentication. I am using idVerification for the first Signer and phone Authentication for the second signer
Docusign docs have more methods as well like sms auth, etc. Explore it from these links:
https://developers.docusign.com/docs/esign-rest-api/how-to/phone-auth/
https://developers.docusign.com/docs/esign-rest-api/reference/envelopes/envelopes/create/
Check examples, in my usecase I explored Generic JSON Request/Response
Thanks for all the support from Inbar and the community!
{
"accountId": "f8594d59-9d52-xxxx-xxxx-xxxxxxxxxx",
"emailSubject": "Please sign the contract",
"status": "sent",
"compositeTemplates": [
{
"compositeTemplateId": "1",
"serverTemplates": [
{
"sequence": "1",
"templateId": "4e2ba389-5d26-xxxx-xxxx-xxxxxxxxxx"
}
],
"inlineTemplates": [
{
"sequence": "2",
"recipients": {
"signers": [
{
"roleName": "Sender",
"recipientId": "1",
"name": "Name",
"email": "fName.lName#xyz.com",
"identityVerification": {
"workflowId": "c368e411-1592-xxxx-xxxx-xxxxxxxxxx",
"steps": null,
"inputOptions": [
{
"name": "phone_number_list",
"valueType": "PhoneNumberList",
"phoneNumberList": [
{
"countryCode": "1",
"number": "1234567890"
}
]
}
]
}
},
{
"roleName": "Customer",
"recipientId": "2",
"name": "cName",
"email": "cfName.clName#gmail.com",
"phoneAuthentication": {
"senderProvidedNumbers": [
"+11234567890"
],
"recipMayProvideNumber": false
},
"idCheckConfigurationName": "Phone Auth $"
}
]
}
}
]
}
]
}
Note: Use valid phone number!
I'm trying to send new users / new customres of my WooCommerce store into the rental management app current-rms.com as new Organisations / new contacts. Since Current RMS does not have a native Zap, I am trying to use the generic Webhook zap that Zapier maintains.
Specifically, I'd like to see the sent JSON body in Zapier posts that I make during the setup and testing of the Zap after clicking "Make a Zap!". The Task History is not detailed enough nor does it show hits during test and setup, since it's not live yet.
My trigger is a WooCommerce New Customer. This is working with Zapier WooCommerce Plugin and webhooks OK.
My action is the generic Zapier "Webhooks" Zap. The label "instant" appears next to it in the list at /app/zaps and it is "off".
One version uses JSON PAYLOAD as the action.
Another version uses CUSTOM PAYLOAD as the action.
Wrap request in array is YES.
Unflatten is YES.
My API key and subdomain are in the app URL as query strings and working OK.
When I hit test I get:
We had trouble sending your test through.
The app returned "Invalid JSON - missing or invalid entry for 'member'". This usually happens when your Zap is missing a required field or a field value isn't in a recognized format.
We made a request to api.current-rms.com and received (400) Bad Request.
Official docs are at: https://api.current-rms.com/doc#members-members-post
Logging available at Current RMS side
Part of the authentication of Current RMS involves knowing the domain of the account you are trying to access, in my case its therockfactory due to it being an account for my company https://therockfactory.net/
https://api.current-rms.com/api/v1/members?apikey=APIKEYCENSORED&subdomain=therockfactory
which returns the following when I use the correct API key:
{"webhook_logs":[],"meta":{"total_row_count":0,"row_count":0,"page":1,"per_page":20}}
Maybe if I could see the actual hit that Zapier is posting to Current I could wrap my confused brain around it better? What me worry.
The hit should look somewhat similar to this example, but I've not been able to locate it so far... (in Zapier)
Headers
Content-Type: application/json
Body
{
"member": {
"name": "Chris Bralton",
"description": "Pictures and leaned back was strewn at one would rather more. People don't want of his own means of one hand! Unless it from our pioneer has he fallen tree but that ever stronger and a. Hid among us against the full of verdure through by my eyes.",
"active": true,
"bookable": false,
"location_type": 0,
"locale": "en-GB",
"membership_type": "Contact",
"lawful_basis_type_id": 10001,
"sale_tax_class_id": 1,
"purchase_tax_class_id": 1,
"tag_list": [
"[\"Red\", \"Blue\", \"Green\"]"
],
"custom_fields": {},
"membership": {},
"primary_address": {
"name": "Chris Branson",
"street": "16 The Triangle",
"postcode": "NG2 1AE",
"city": "Nottingham",
"county": "Nottinghamshire",
"country_id": "1",
"country_name": "United Kingdom",
"type_id": 3001,
"address_type_name": "Primary",
"created_at": "2015-06-29T10:00:00.000Z",
"updated_at": "2015-06-29T10:30:00.000Z"
},
"emails": [
{
"address": "abigail.parker#ggmail.co.uk",
"type_id": 4001,
"email_type_name": "Work",
"id": 1
}
],
"phones": [
{
"number": "+44 115 9793399",
"type_id": 6001,
"phone_type_name": "Work",
"id": 1
}
],
"links": [
{
"address": "www.facebook.com/profile.php?id=566828251",
"type_id": 5002,
"link_type_name": "Facebook",
"id": 1
}
],
"addresses": [
{
"name": "Chris Branson",
"street": "16 The Triangle",
"postcode": "NG2 1AE",
"city": "Nottingham",
"county": "Nottinghamshire",
"country_id": "1",
"country_name": "United Kingdom",
"type_id": 3002,
"address_type_name": "Billing",
"created_at": "2017-06-29T10:00:00.000Z",
"updated_at": "2017-06-29T10:30:00.000Z",
"id": 1
}
],
"service_stock_levels": [
{
"item_id": 10,
"store_id": 1,
"member_id": 1,
"asset_number": "Chris Bralton",
"serial_number": "",
"location": "",
"stock_type": 3,
"stock_category": 60,
"quantity_held": "1.0",
"quantity_allocated": "0.0",
"quantity_unavailable": "0.0",
"quantity_on_order": "0.0",
"starts_at": "",
"ends_at": "",
"icon": {
"iconable_id": 85,
"id": 1,
"image_file_name": "abigail.jpeg",
"url": "https://s3.amazonaws.com/current-rms-development/64a0ccd0-5fbd-012f-2201-60f847290680/icons/46/original/abigail.jpeg",
"thumb_url": "https://s3.amazonaws.com/current-rms-development/64a0ccd0-5fbd-012f-2201-60f847290680/icons/46/thumb/abigail.jpeg",
"created_at": "2015-06-29T10:00:00.000Z",
"updated_at": "2015-06-29T10:30:00.000Z",
"iconable_type": "StockLevel"
},
"custom_fields": {},
"id": 487,
"item_name": "Sound Engineer",
"store_name": "Nottingham",
"stock_type_name": "Service",
"stock_category_name": "Resource"
}
],
"day_cost": "",
"hour_cost": "",
"distance_cost": "",
"flat_rate_cost": "",
"icon": {
"image": ""
},
"child_members": [
{
"relatable_id": 317,
"relatable_type": "Member",
"related_id": 25,
"related_type": "Member"
}
],
"parent_members": [
{
"relatable_id": 317,
"relatable_type": "Member",
"related_id": 25,
"related_type": "Member"
}
]
}
}
UPDATE: After reading my chosen answer I was able to see what Zapier was sending:
[
{
"member[emails_attributes][0][address]": "test#test.co.nz",
"member[membership_type]": "Organisation",
"member[name]": "Testafari Testing"
}
]
You can send your webhook to a tool like this one to inspect the payloads that are being sent from anywhere on the internet: https://requestbin.com/
You can find more help in regards to using Webhooks by Zapier and other ideas on how you can troubleshoot issues stemming from its use: https://zapier.com/apps/webhook/help#inspect-the-requests
I have code that is creating Google calendar entries (recurring events) using the Google calendar API. This is working fine. Now I am trying to add exceptions to certain instances. I've got it working for deleted instances (by using the EXDATE parameter) but I'm having trouble changing the date/time of an instance. I am following the instructions found here:
https://developers.google.com/google-apps/calendar/recurringevents
After I create the basic recurring event, I retrieve a list of all instances. For testing, I am pulling out the entire section of json that applies to the instance I want to change, for example:
{
"kind": "calendar#event",
"etag": "\"3032281375946000\"",
"id": "_69j3ge9iccp68or1c8p3ac1nccpm8p356gpj8pb66koj2c32c5h0_20180130T203000Z",
"status": "confirmed",
"htmlLink": "https://www.google.com/calendar/event?eid=XzY5ajNnZTlpY2NwNjhvcjFjOHAzYWMxbmNjcG04cDM1NmdwajhwYjY2a29qMmMzMmM1aDBfMjAxODAxMzBUMjAzMDAwWiBqbWNrYXk5MzUxQG0",
"created": "2018-01-16T20:08:56.000Z",
"updated": "2018-01-17T00:13:59.277Z",
"summary": "Recurring test with deletes and changes",
"description": "\n",
"location": "SEattle",
"creator": {
"email": "jmckay9351#gmail.com",
"displayName": "Jeffrey McKay",
"self": true
},
"organizer": {
"email": "jmckay9351#gmail.com",
"displayName": "Jeffrey McKay",
"self": true
},
"start": {
"dateTime": "2018-01-30T13:30:00-08:00"
},
"end": {
"dateTime": "2018-01-30T14:00:00-08:00"
},
"recurringEventId": "_69j3ge9iccp68or1c8p3ac1nccpm8p356gpj8pb66koj2c32c5h0",
"originalStartTime": {
"dateTime": "2018-01-30T12:30:00-08:00"
},
"iCalUID": "2f892c2dcab2507c3dde434ef5110bab",
"sequence": 0,
"reminders": {
"useDefault": false,
"overrides": [{
"method": "popup",
"minutes": 15
}]
}
}
Then I do a http PUT of this data to this URL:
https://www.googleapis.com/calendar/v3/calendars/jmckay9351#gmail.com/events/_69j3ge9iccp68or1c8p3ac1nccpm8p356gpj8pb66koj2c32c5h0_20180130T203000Z
What I get back is a http error 400, and the error message in the returned json is "Missing end time". I get the same response regardless of how much or little data I feed into the PUT. Any idea what I'm doing wrong here?
OK I've got this working now - I don't understand what was wrong with my libcurl PUT code, but I changed it to be a POST with a custom request of "PUT" and that seemed to get to data correctly uploaded.
I would like to handle assertion property content according to below responses, for both success and failure.
Success response:
{
"task": "userLogin",
"response": {
"code": 0,
"status": "success",
"error_message": "",
"success_message": "",
"data": {
"userId": "65",
"username": "indian",
"email": "test#gmail.com",
"token": "b0aef6139ffdc1041e01f7587a0dcf61",
"userType": "trial",
"profile_picture": "test.png"
}
}
}
Failure response: will have only the data node missing, and remaining nodes will be present.
"data":
{
"userId": "65",
"username": "indian",
"email": "test#gmail.com",
"token": "b0aef6139ffdc1041e01f7587a0dcf61",
"userType": "trial",
"profile_picture": "test.png"
}
You can use a very simple XPath assertion, keeping in mind that internally SoapUI converts everything into XML representation.
XPath:
exists(//*:data)
Expected:
true
Update based on your comments.
Your original requirement was not clear. The node is present it is just empty. In that case the XPath assertion would be:
empty(//*:data)
Expected:
false
Handy XPath reference.
can anyone help in finding xpath of 'tenantId' which is in JSON response given below
{
"statusCode": "200",
"errorParams": null,
"payLoad": {
"UGX:XCD": {
"id": 42802,
"fromCurrency": {
"tenantId": "2a610af6-2e42-4a78-8e04-98755e2c6113",
"code": "UGX",
"name": "Ugandan Shilling",
"isoCode": "UGX",
"active": true,
"enabled": true,
"flagModifiedName": false,
"erpId": null,
"createdOn": 1427155200000,
"fieldLibraryStatus": "DRAFT",
"userId": null
},
"toCurrency": {
"tenantId": "2a610af6-2e42-4a78-8e04-98755e2c6113",
"code": "XCD",
"name": "East Caribbean Dollar",
"isoCode": "XCD",
"active": true,
"enabled": true,
"flagModifiedName": true,
"erpId": null,
"createdOn": 1427155200000,
"fieldLibraryStatus": "DRAFT",
"userId": "c7f68b05-044d-44e1-8fc5-0f97a4ece91b"
},
"rate": 33,
"inverseRate": 0.0303,
"createdOn": 1434025926983,
"modifiedOn": 1434326400000,
"active": true,
"purpose": "cmd",
"enabled": true,
"tenantFlag": true,
"erpId": null
}
How to traverse till 'tenantId' ??
Thanks in Advance.
SoapUI internally converts almost anything to XML. You will have to use the ResponseAsXml property. In the GUI, if you click on the XML tab, you can see this representation.
Something like the following should work:
${test_step#ResponseAsXml#//*:fromCurrency/*:tenantId}
${test_step#ResponseAsXml#//*:toCurrency/*:tenantId}
If you want to handle this using groovy, then extend SOAPUI with GSON.jar library provided by Google.
this library specially written to handle the JSON objects.
With this you can rip every individual objects and its attribute-values easily how complex may the JSON object be, a nice add-on to work with.