I am trying to send a template message via gupshup using their unified single sendmessage API endpoint https://api.gupshup.io/sm/api/v1/msg
We have a template message approved with the relevant wording in it, and specified that there should be an attachment. When we try and send the attachment it fails with the following message, (1005) Message sending failed as user is inactive for session message and template did not match
Within the message element which is encoded JSON I have tried the a couple of options, all of which reject with the same message as above.
innerJson = { "isHSM": "true", "type": "file", "url": fileURL + location, "filename": filename, "text": message }
innerJson = { "isHSM": "true", "type": "file", "url": fileURL + location, "filename": filename, "caption": message }
innerJson = { "type": "file", "url": fileURL + location, "filename": filename, "text": message }
innerJson = { "type": "file", "url": fileURL + location, "filename": filename, "caption": message }
Can't find any explicit examples in the gupshup documentation of how to do this.
I send you a link with the correct endpoint for sending templates.
Also here's an example of how to use it in node.js:
const sendTemplateWhatsapp = (templateId, phone, media, callbackFunc) => {
innerJson = { "type":"file","url":"your_url" }
const params = new URLSearchParams()
params.append('channel', 'whatsapp');
params.append('source', waba_number);
params.append('destination', phone);
params.append('src.name', waba_name);
params.append('template', templateId);
params.append('message', JSON.stringify(innerJson));
const config = {
headers: {
'apikey': 'your_apikey',
'Content-Type': 'application/x-www-form-urlencoded'
}
}
axios.post('http://api.gupshup.io/sm/api/v1/template/msg', params, config)
.then((result) => {
console.log('Template sent to whatsapp');
callbackFunc(result.data);
})
.catch((err) => {
console.log(err);
callbackFunc(err);
})
}
Hope this helps
Related
const manager = Manager.getInstance()
manager.chatClient.on('messageAdded', payload => {
console.log('payload', payload) // it is correct
console.log('payload state attributes', payload.state.attributes)
})
Attributes are correct on chrome's console log
{
"body": "",
"media": null,
"attributes": {
"media": "https://api.twilio.com/2010-04-01/Accounts/ACfba1ba518fcc2321c11142f4041efa23/Messages/MM762e5ab98a2adde2970303db9ab6f4ba/Media/ME77ada464c9d50d6441501abf7bbd45c3",
"mediaType": "image/jpeg"
},
}
But with payload.state.attributes, the attributes changed to:
{
"proxied": true
[[Prototype]]: Object
}
Finally, figured it out after reading the Twilio flex "source code" from "node_module". If reason of "attributes" included from "updateReasons", then we can get the { media, mediaType } from "message.state.attributes".
I cannot find this mentioned anywhere from Twilio's documents.
manager.chatClient.on('messageUpdated', ({ message, updateReasons }) => {
console.log('message', message)
console.log('updateReasons', updateReasons)
})
I am using the the following Graph API URL to retrieve the filename(s) attached to an email:
https://graph.microsoft.com/v1.0/me/messages/*/attachments
however, it is no longer returning the attached filename(s) for '.msg' files. The file extension is missing. Please see below example returns:
{
"#odata.context": "https://graph.microsoft.com/v1.0/$metadata#users('')/messages('')/attachments",
"value": [
{
"#odata.type": "#microsoft.graph.itemAttachment",
"id": "*",
"lastModifiedDateTime": "2021-08-13T11:21:29Z",
"name": "Original Email",
"contentType": null,
"size": 45795,
"isInline": false
}
]
}
Where as it is for other file types:
{
"#odata.context": "https://graph.microsoft.com/v1.0/$metadata#users('')/messages('')/attachments",
"value": [
{
"#odata.type": "#microsoft.graph.fileAttachment",
"#odata.mediaContentType": "application/octet-stream",
"id": "",
"lastModifiedDateTime": "2021-08-13T11:14:07Z",
"name": "Original Email.mht",
"contentType": "application/octet-stream",
"size": 54693,
"isInline": false,
"contentId": null,
"contentLocation": null,
"contentBytes": ""
}
]
}
NB: sensitive info has been redacted (*).
I can see that the #odata.type is returned differently:
#odata.type": "#microsoft.graph.itemAttachment
#odata.type": "#microsoft.graph.fileAttachment
I'm not sure why this is, the email is attached in the same way.
In both of the above cases, using Outlook, I sent myself an email, saved it to my local filesystem, created another email, attached the previously saved file and sent myself the new email with the saved email attached. Then made the request using the stated URL (and many other variations).
I have looked all over and no request URL that I have used returns the file extension for this type.
Is there a way to return the filename for '.msg' files?
Edit: this is how (java) I'm getting the filename for Attachment(s) (except ReferenceAttachment as I'm not handling them)
public String getCurrentAttachmentName()
{
String fileName = null;
if (currentAttachment instanceof FileAttachment)
{
fileName = currentAttachment.name;
} else if (currentAttachment instanceof ItemAttachment)
{
if (null != currentAttachment.contentType)
{
fileName = currentAttachment.name;
} else
{// outlook email or contact etc., add extension
ItemAttachment itemAttachment = (ItemAttachment) currentAttachment;
if (itemAttachment.item instanceof Contact)
{
fileName = currentAttachment.name + ".vcf";
} else if (itemAttachment.item instanceof Message)
{
fileName = currentAttachment.name + ".eml";
} else if (itemAttachment.item instanceof Event)
{
fileName = currentAttachment.name + ".ics";
} else
{
fileName = currentAttachment.name + ".bin"; // should be unreachable but just in case.
}
}
}
// looping does not allow ReferenceAttachment so we don't need to handle that type
return fileName;
}
MS graph differentiates the attachments at resource level ie fileAttachment resource type and itemAttachment resource type
Even though attached the same way, the contact, event, or message attachments belong to itemAttachment resource type and have different props from the file attachments.
I am using graph API to add message rule which is forward a mail from user's inbox. Rule is getting added but mails are not forwarding to specified id.
Here are some details:
var data = {
"displayName": "From partner",
"sequence": 1,
"isEnabled": true,
"conditions": {
"isAutomaticForward": true
},
"actions": {
"forwardTo": [
{
"emailAddress": {
"name": "recipient name ",
"address": "email address"
}
}
],
"stopProcessingRules": true
}
}
axios.post("https://graph.microsoft.com/v1.0/users/{userId}/mailFolders/inbox/messageRules", data,
{
headers: {
"Authorization": "Bearer " + access_token
}
}
)
.then(response => {
console.log(response.data)
})
.catch(err => {
console.log(err.response)
})
Response is as expected but mails are not forwarding.
I tried the above payload, steps and it works for me!!
(1) Create a new rule using Graph API
POST https://graph.microsoft.com/v1.0/me/mailFolders/inbox/messageRules
Content-type: application/json
{
"displayName": "From partner",
"sequence": 2,
"isAutomaticForward": true,
"actions": {
"forwardTo": [
{
"emailAddress": {
"name": "Alex Wilbur",
"address": "AlexW#contoso.onmicrosoft.com"
}
}
],
"stopProcessingRules": true
}
}
(2) Test whether the rule is working or not.
Result: It's working as expected
(3) Check that the above rule shows or not (as part of Outlook.office.com or Outlook UI's rule section)
Adding a snapshot that i captured from Outlook.office.com, mailbox settings!!
Whenever i tried to attach attachment with TFS WorkItem via REST call, attachment size is 0KB.
First I upload an attachment in Attachment Store using below code.
https://{instance}/DefaultCollection/_apis/wit/attachments?api-version=1.0&filename="{fileName}"
I send data in bytes array through rest call. and after this i attach that attachment with workitem.
Attaching attachment is success but size of an attachment is zero KB
Is there is an issue with TFS or something i am doing wrong?
I am using C# language for programming and REST Sharp for accessing VSTS APIs
Dim restClient = New RestClient("Server URL")
restClient.Authenticator = New HttpBasicAuthenticator("UserId", "Password")
Dim request = New RestRequest("API_Name", Method.POST)
request.AlwaysMultipartFormData = False
request.AddParameter(String.Format("{0}; charset=utf-8", contentType), File.ReadAllBytes(filePath), ParameterType.RequestBody)
request.RequestFormat = DataFormat.Json
Dim response As IRestResponse = restClient.Execute(request)
Return response
I am sending file data in bytes.
Attaching Attachment with WorkItem.
Dim restClient = New RestClient(ACCESS_URL)
restClient.Authenticator = New HttpBasicAuthenticator(USER_NAME, PASSWORD)
Dim request = New
RestRequest("CollectionName}/_apis/wit/workitems/{WorkItem_ID}", Method.PATCH)
request.AddParameter("application/json-patch+json; charset=utf-8",
"post_Data", ParameterType.RequestBody)
request.RequestFormat = DataFormat.Json
Dim response As IRestResponse = restClient.Execute(request)
Return response
Post_Data is an json string which take this type of data
[{
"op": "add",
"path": "/relations/-",
"value": {
"rel": "AttachedFile",
"url": "AttachementURI",
}]
You missed "attributes" section in the Post_Data, try with below:
[{
"op": "add",
"path": "/relations/-",
"value": {
"rel": "AttachedFile",
"url": "AttachementURI",
"attributes": {
}
}]
I can reproduce this issue when keep the { file-contents } as empty.
So, make sure you have specified the { file-contents }.
To attach a file to a work item, upload the attachment to the
attachment store, then attach it to the work item. See Add an attachment for details.
Upload an attachment:
POST https://{instance}/DefaultCollection/_apis/wit/attachments?api-version={version}&filename=Spec.txt
Content-Type: application/octet-stream
{ file-contents }
Add an attachment for specific work item:
PATCH https://fabrikam-fiber-inc.visualstudio.com/DefaultCollection/_apis/wit/workitems/299?api-version=1.0
Content-Type: application/json-patch+json
[
{
"op": "test",
"path": "/rev",
"value": 3
},
{
"op": "add",
"path": "/fields/System.History",
"value": "Adding the necessary spec"
},
{
"op": "add",
"path": "/relations/-",
"value": {
"rel": "AttachedFile",
"url": "https://fabrikam-fiber-inc.visualstudio.com/DefaultCollection/_apis/wit/attachments/098a279a-60b9-40a8-868b-b7fd00c0a439?fileName=Spec.txt",
"attributes": {
"comment": "Spec for the work"
}
}
}
]
See below C# sample to upload and add the attachment for a work item:
C# (UploadTextFile method)
C# (AddAttachment method)
On a site I'm developing I embed videos from YouTube and want to get the video title and its description.
How do I get that information?
You can do it with oembed.
Example:
http://www.youtube.com/oembed?url=http%3A//youtube.com/watch%3Fv%3DM3r2XDceM6A&format=json
Youtube API V2.0 has been deprecated. It shows some wrong value for title "youtube.com/devicesupport" . pLease switch on to API V3.0
YOu can refer the following PHP code and modify yours in js or jquery as per your needs..
function youtube_title($id) {
$id = 'YOUTUBE_ID';
// returns a single line of JSON that contains the video title. Not a giant request.
$videoTitle = file_get_contents("https://www.googleapis.com/youtube/v3/videos?id=".$id."&key=YOUR_API_KEY&fields=items(id,snippet(title),statistics)&part=snippet,statistics");
// despite # suppress, it will be false if it fails
if ($videoTitle) {
$json = json_decode($videoTitle, true);
return $json['items'][0]['snippet']['title'];
} else {
return false;
}
}
update:
Jquery code to get the title-
$.getJSON('https://www.googleapis.com/youtube/v3/videos?id={VIDEOID}&key={YOUR API KEY}&part=snippet&callback=?',function(data){
if (typeof(data.items[0]) != "undefined") {
console.log('video exists ' + data.items[0].snippet.title);
} else {
console.log('video not exists');
}
});
To get the DESCRIPTION element, you need to access the gdata version of the video's info, and you can return json using alt=json on the path. In this case, oHg5SJYRHA0 is the video ID, found at the end of the url of the video you're working with on YouTube, e.g.
www.youtube.com/watch?v=oHg5SJYRHA0
http://gdata.youtube.com/feeds/api/videos/oHg5SJYRHA0?v=2&alt=json&prettyprint=true
(the prettyprint is formatting to make that easy to read, you don't need it for what you're doing)
You can grab the JSON, add it into a variable and access it using jQuery:
var youTubeURL = 'http://gdata.youtube.com/feeds/api/videos/oHg5SJYRHA0?v=2&alt=json';
var json = (function() {
var json = null;
$.ajax({
'async': false,
'global': false,
'url': youTubeURL,
'dataType': "json",
'success': function(data) {
json = data;
}
});
return json;
})();
Then access it using object notation:
alert("Title: " + json.entry.title.$t +"\nDescription:\n " + json.entry.media$group.media$description.$t + "\n");
gdata is no longer available
you can use the following instead
https://www.googleapis.com/youtube/v3/videos?part=snippet&id=(Video_ID)&key=(API_Key)
I read this topic a bit in delay.
I did something like this using jSON and YT API's
$json = json_decode( file_get_contents("http://gdata.youtube.com/feeds/api/videos/".$rs['vid']."?v=2&prettyprint=true&alt=jsonc") );
Note: $rs['vid'] is the video ID dinamically retrived from my DB.
Once you put the contents in the handle $json you can retrive like this:
$json->data->description;
$json->data->title;
use var_dump( $json ) to view all values you can access.
I'd start by taking a look at Youtube Data API to get what you want: http://code.google.com/apis/youtube/getting_started.html#data_api
GData is deprecated, but one can still get the video description by calling this endpoint:
https://www.googleapis.com/youtube/v3/videos?part=snippet&id=[video_id]&key=[api_key]
It will return a response of the form:
{
"kind": "youtube#videoListResponse",
"etag": "\"...\"",
"pageInfo": {
"totalResults": 1,
"resultsPerPage": 1
},
"items": [
{
"kind": "youtube#video",
"etag": "\"...\"",
"id": "...",
"snippet": {
"publishedAt": "...",
"channelId": "...",
"title": "...",
"description": "...",
"thumbnails": { ... },
"channelTitle": "...",
"tags": [ ... ],
"categoryId": "...",
"liveBroadcastContent": "...",
"localized": {
"title": "...",
"description": "..."
},
"defaultAudioLanguage": "..."
}
}
]
}
The description can be found at items.localized.description.