It appears that only Yammer announcements get pushed to mobile. Is it possible to post an announcement to a group (or Company Wide) via the Yammer API?
Yes, you can do it setting the broadcast parameter to true, as described on https://developer.yammer.com/v1.0/docs/messages-json-post
A little late, but the following API call seems to create an announcement:
yam.platform.request({
url: "messages.json",
method: "POST",
data: {
"body": "Example message",
"log_data[publisher_type]": "yam.ui.publisher.global.AnnouncementPublisher",
"log_data[publisher_source]": "group",
"log_data[number_of_recipients]": "1",
"invited_user_ids": "",
"skip_body_notifications": "true",
"group_id": "54321",
"is_rich_text": "true",
"message_type": "announcement",
"title": "Example title"
},
success: function () {
// Do something else
},
error: function (error) {
console.log(error);
}});
Related
Im working on a chrome extension using manifest V3. A core functionality of the extension is to enable users to send data from a website to the REST API of my django application, where the user is already logged in. While testing locally everything was fine, however when I went to test in staging, I found that with HTTPS django requires a "referer" in the POST header for CSRF protection.
From what I found chrome extensions just don't attach that header. So I tried the declarativeNetRequest API using the following code. However this only works when I open the URL in a tab. When fetch is called to post to the same URL, the rule is not matched. Is this the correct way to force a referer header when using fetch in V3? Thanks!
manifest.json:
...
"permissions": [
...
"declarativeNetRequestWithHostAccess",
"declarativeNetRequestFeedback"
],
"declarative_net_request": {
"rule_resources": [{
"id": "ruleset_1",
"enabled": true,
"path": "rules.json"
}]
},
...
rules.json:
[
{
"id": 1,
"priority": 1,
"action": {
"type": "modifyHeaders",
"requestHeaders": [
{
"header": "Referer",
"operation": "set",
"value": "whatever"
}
]
},
"condition": {
"urlFilter": "https://api.myserver.com",
"resourceTypes": [
"main_frame"
]
}
}
]
background.js:
...
chrome.declarativeNetRequest.onRuleMatchedDebug.addListener(function (m) {
console.log('match:', m);
});
function post_data() {
fetch(link, {
method: 'POST',
headers: {
'Accept': 'application/json, application/xml, text/plain, text/html, *.*',
'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8',
'X-CSRFToken': csrf_token.value
},
body: JSON.stringify(text)
})
.then(response => console.log(response))
.catch(error => console.log('Error:', error))
return true;
}
...
You need to replace main_frame with xmlhttprequest, which is a type both for XHR and fetch.
Also, limit this rule to requests made by your extension. It can be done by specifying the extension's id in domains. Since the id may change during development, we'll set the rule dynamically.
Remove declarative_net_request from manifest.json.
Add the following code in background.js:
chrome.runtime.onInstalled.addListener(async () => {
const rules = [{
id: 1,
action: {
type: 'modifyHeaders',
requestHeaders: [{
header: 'Referer',
operation: 'set',
value: 'whatever',
}],
},
condition: {
domains: [chrome.runtime.id],
urlFilter: '|https://api.myserver.com/',
resourceTypes: ['xmlhttprequest'],
},
}];
await chrome.declarativeNetRequest.updateDynamicRules({
removeRuleIds: rules.map(r => r.id),
addRules: rules,
});
});
I'm building a slack app using the slack Bolt API, and I want to open modals from my App's home page when a button on the home page is clicked.
Here's the relevant bit of the action listener that is connected to the button:
app.action("follow-users-button", async ({ ack, payload, client }) => {
await ack();
console.log("app_home opening keyusermodal");
// await block_actions.unfollowKeyuser(action);
console.log("payload = " + JSON.stringify(payload));
await client.views.open({
trigger_id: payload.trigger_id,
Here's what I get on my terminal when I click that button:
payload = {"action_id":"follow-users-button","block_id":"2JW","text":{"type":"plain_text","text":"Users","emoji":true},"value":"click_me_123","type":"button","action_ts":"1642280065.631917"}
[ERROR] bolt-app missing required field: trigger_id
The JSON there is the action payload.
However, according to the Slack docs, this payload should be much larger. Here's the sample payload from Slack's Block Kit Builder:
{
"type": "block_actions",
"user": {
"id": "U02NF0A8D9T",
"username": "person",
"name": "person",
"team_id": "T02NTJ0UDP3"
},
"api_app_id": "A02",
"token": "Shh_its_a_seekrit",
"container": {
"type": "message",
"text": "The contents of the original message where the action originated"
},
"trigger_id": "12466734323.1395872398",
"team": {
"id": "T02NTJ0UDK3",
"domain": "4most-r637660"
},
"enterprise": null,
"is_enterprise_install": false,
"state": {
"values": {}
},
"response_url": "https://www.postresponsestome.com/T123567/1509734234",
"actions": [
{
"type": "button",
"block_id": "QdL",
"action_id": "button-action",
"text": {
"type": "plain_text",
"text": "Click Me",
"emoji": true
},
"value": "click_me_123",
"action_ts": "1642279809.506518"
}
]
}
As you can see, I'm only receiving the actions element in my payload. Where's the rest of it? Why isn't it coming over? I need the trigger_id to open a modal (not having it causes the error), and getting things like user_id would be extremely helpful for my app.
Thanks in advance!
When working with the Bolt JS framework, the expected way to parse the action payload to get the trigger id is body.trigger_id.
I am doing a project in ASP.NET Core. My requirement is, I want to integrate PayPal as the payment gateway.
User can see set of items, with BUY NOW button, and when a button is clicked, i want to send that item's name and cost to paypal so it will charge the amount from the user.
When the payment is successful, I want paypal to redirect to one of Controller method and save that transaction.
Now my problem is,
I am not sure if I am using the correct API.
Even though I use that API, I get an error with 400 code
I use below code to generate the token.
$.ajax({
url: 'https://api.sandbox.paypal.com/v1/oauth2/token',
datatype: 'json',
type: 'POST',
beforeSend: function (xhr) {
xhr.setRequestHeader('Authorization', 'Basic ' + btoa('client ID and secret'));
},
data: {
'grant_type': 'client_credentials',
});
The above function is giving me a key and using that, i do the below API call. Now I am not sure if the below API is correct for this purpose.
$.ajax({
url: 'https://api.sandbox.paypal.com/v1/payments/payment',
type: 'POST',
headers: {
'Content-Type':'application/json',
'Authorization': 'Bearer ' + accessToken
},
data: {
"intent": "sale",
"payer": {
"payment_method": "paypal"
},
"transactions": [
{
"amount": {
"total": "30.11",
"currency": "USD",
"details": {
"subtotal": "30.00",
"tax": "0.07",
"shipping": "0.03",
"handling_fee": "1.00",
"shipping_discount": "-1.00",
"insurance": "0.01"
}
},
"description": "The payment transaction description.",
"custom": "EBAY_EMS_90048630024435",
"invoice_number": "48787589673",
"payment_options": {
"allowed_payment_method": "INSTANT_FUNDING_SOURCE"
},
"soft_descriptor": "ECHI5786786",
"item_list": {
"items": [
{
"name": "hat",
"description": "Brown hat.",
"quantity": "5",
"price": "3",
"tax": "0.01",
"sku": "1",
"currency": "USD"
}
],
"shipping_address": {
"recipient_name": "Brian Robinson",
"line1": "4th Floor",
"line2": "Unit #34",
"city": "San Jose",
"country_code": "US",
"postal_code": "95131",
"phone": "011862212345678",
"state": "CA"
}
}
}
],
"note_to_payer": "Contact us for any questions on your order.",
"redirect_urls": {
"return_url": "https://example.com/return",
"cancel_url": "https://example.com/cancel"
}
Above API call is the exact example in the PayPal developer's website itself but however it gives me the following error:
{"name":"AUTHENTICATION_FAILURE","message":"Authentication failed due to invalid authentication credentials or a missing Authorization header.","links":[{"href":"https://developer.paypal.com/docs/api/overview/#error","rel":"information_link"}]}
Is this the correct API that I should use or is there any other? Please help me on this.
Thank you.
Through many searches I've gotten the script in question to work as expected. If the user clicks on a button on my web page then a contact will be created in their Google Contact list (if authorized).
The problem I'm left with is that the authorization never expires. In that once successfully authorized the user can press the button many times, even come back to the page later in a different session, and it will never ask for authorization again.
Perhaps this is the intended behavior of the GoogleAPI but for my intended purpose I don't expect any more than 1 click and I would expect if the user came back to my page at a later time that they would be asked to authorize again.
Is this possible? I've tried the following ...
gapi.auth.signOut();
gapi.auth2.signOut();
gapi.auth2.disconnect();
revoking the token (see end of post)
... with no success.
Code can be found here:
https://jsfiddle.net/brian_hill/chvtmmjr/7/
function addContact(entry) {
var config = {
'client_id': '403037917634-qproaer1g5gcq83c941heo4q07olol23.apps.googleusercontent.com',
'scope': 'https://www.google.com/m8/feeds',
'cookie_policy': 'single_host_origin'
};
gapi.auth.authorize(config, function() {
insert(config, entry);
});
}
function insert(config, entry) {
gapi.client.request({
'method': 'POST',
'path': '/m8/feeds/contacts/default/full/',
'headers': {
'GData-Version': 3.0
},
'body': {
'entry': [entry]
},
'callback': function(data) {
if (data.hasOwnProperty('entry')) {
var msg = "Your Google Contacts have been updated to include ";
window.alert(msg.concat(data.entry.title.$t))
} else {
var msg = "Contact information could not be added for "
window.alert(msg.concat(entry.title.$t))
}
}
});
}
And the HTML
<script src="https://apis.google.com/js/platform.js" async defer></script>
<script src="https://apis.google.com/js/client.js"></script>
<body style="background-color:rgba(32, 177, 17, 0.3);">
<p>
The button below will add a contact to your GMail contacts</p>
<div style="width:150px">
<script>
function addJohn() {
var entry = {
"category": [{
"scheme": "http:\/\/schemas.google.com\/g\/2005#kind",
"term": "http:\/\/schemas.google.com\/contact\/2008#contact"
}],
"title": {
"type": "text",
"$t": "John Doe"
},
"content": [{
"type": "text",
"$t": "[Automatically Created]"
}],
"gd$email": [{
"rel": "http:\/\/schemas.google.com\/g\/2005#other",
"address": "john.doe#abcd.com",
"primary": "true"
}],
"gd$postalAddress": [{
"rel": "http:\/\/schemas.google.com\/g\/2005#home",
"$t": "123 Main Street\nOttawa, ON\nCanada"
}],
"gd$phoneNumber": [{
"rel": "http:\/\/schemas.google.com\/g\/2005#home",
"$t": "555.123.4567",
"primary": "true"
}]
};
addContact(entry);
}
function addJane() {
var entry = {
"category": [{
"scheme": "http:\/\/schemas.google.com\/g\/2005#kind",
"term": "http:\/\/schemas.google.com\/contact\/2008#contact"
}],
"title": {
"type": "text",
"$t": "Jane Doe"
},
"content": [{
"type": "text",
"$t": "[Automatically Created]"
}],
"gd$email": [{
"rel": "http:\/\/schemas.google.com\/g\/2005#other",
"address": "jane.doe#abcd.com",
"primary": "true"
}],
"gd$postalAddress": [{
"rel": "http:\/\/schemas.google.com\/g\/2005#home",
"$t": "321 Unknown Street\nOttawa, ON\nCanada"
}],
"gd$phoneNumber": [{
"rel": "http:\/\/schemas.google.com\/g\/2005#home",
"$t": "555.765.4321",
"primary": "true"
}]
};
addContact(entry);
}
</script>
<button onclick="addJohn();">Add Contact - John</button>
<button onclick="addJane();">Add Contact - Jane</button>
</div>
</body>
(Note: Due to the nature of the GoogleAPI authorization process, it doesn't appear to work through JS Fiddle on either Chrome or Firefox --- I did get it to work on Microsoft Edge).
Thanks in advance,
Brian
PS. Adding my attempt for using the 'revoke' option. Which still doesn't work (I still don't get re-prompted for authorization) but also sometimes it works (updates addresses) and sometimes it doesn't.
function addContact(entry) {
var config = {
'client_id': '403037917634-qproaer1g5gcq83c941heo4q07olol23.apps.googleusercontent.com',
'scope': 'https://www.google.com/m8/feeds',
'cookie_policy': 'single_host_origin'
};
gapi.auth.authorize(config, function() {
insert(config, entry);
}).then(signOut);
}
function signOut() {
$.ajax({
'type': 'GET',
'url': 'https://accounts.google.com/o/oauth2/revoke?token=' +
gapi.auth.getToken().access_token,
'async': false,
'contentType': "application/json",
'dataType': 'jsonp',
'success': function (nullResponse) {
window.alert('Disconnected');
},
'error': function (e) {
// Handle the error
console.log(e);
}
});
}
function insert(config, entry) {
gapi.client.request({
'method': 'POST',
'path': '/m8/feeds/contacts/default/full/',
'headers': {
'GData-Version': 3.0
},
'body': {
'entry': [entry]
},
'callback': function(data) {
if (data.hasOwnProperty('entry')) {
var msg = "Your Google Contacts have been updated to include ";
window.alert(msg.concat(data.entry.title.$t))
} else {
var msg = "Contact information could not be added for "
window.alert(msg.concat(entry.title.$t))
}
}
});
}
Try using the Revoke token instruction in OAuth 2.0:
In some cases a user may wish to revoke access given to an application. A user can revoke access by visiting Account Settings. It is also possible for an application to programmatically revoke the access given to it. Programmatic revocation is important in instances where a user unsubscribes or removes an application. In other words, part of the removal process can include an API request to ensure the permissions granted to the application are removed.\
To programmatically revoke a token, your application makes a request to https://accounts.google.com/o/oauth2/revoke and includes the token as a parameter:
curl -H "Content-type:application/x-www-form-urlencoded" \
https://accounts.google.com/o/oauth2/revoke?token={token}
I am having a problem fixing this error. May be someone can explain what is going on here:
I am getting JSON back from server:
d3.json(fullpath, function (json)
{
graphData = json;
if (graphData.nodes.length == 0)
{
$.jnotify("Sorry there is no data for graph. Please include social media type in search.");
}
drawGraph();
});
here is part of the json:
"nodes": [{
"id": 1,
"userID": 1,
"profile_image_url": "images/twitterimage_1.jpg",
"description": "user1 desc",
"name": "user 1",
"location": "Berlin",
"statuses_count": 5,
"followers_count": 1
}
,
{
"id": 2,
"userID": 2,
"profile_image_url": "images/twitterimage_2.png",
"description": "user2343434 desc",
"name": "user 2",
"location": "Berlin",
"statuses_count": 6,
"followers_count": 2
}
then on this line: 'if (graphData.nodes.length == 0)' I do have this error:
'Error: Unable to get value of the property 'nodes': object is null or undefined'
And this is only in IE, not a problem in Chrome or Firefox.
Please help!
thanks!
ok. the problem was in this line:
d3.json(fullpath, function (json)
Do you know that IE does json asynchronously be DEFAULT?
and Chrome/Firefox does this call synchronously?
So, the work around is to switch to .ajax call from jquery library:
$.ajax({
url: dataPath,
dataType: 'json',
async: false,
data: null,
success: function (response)
{
}
thanks!