How to get Sender IP using Microsoft Graph API? - microsoft-graph-api

I have been trying to get Sender IP from the response provided by the following :-
GET https://graph.microsoft.com/v1.0/me/messages/AAMkADhAAAW-VPeAAA=/?$select=internetMessageHeaders.
The response which I get has multiple Receiver tags as shown below :-
{
"#odata.context":"<some-value>",
"#odata.etag":"<some-value>",
"id":"<some-value>",
"internetMessageHeaders":[
{
"name":"MIME-Version",
"value":"1.0"
},
{
"name":"Content-Type",
"value":"multipart/report"
},
{
"name":"x-custom-header-group-name",
"value":"Washington"
},
{
"name":"x-custom-header-group-id",
"value":"WA001"
},
{
"name":"Receiver",
"value":"<some-ip>"
},
{
"name":"Receiver",
"value":"<some-ip>"
},
]
}
How do I get the actual origin Sender IP of the Mail using Graph API?
Is there any other way of getting the Sender IP using Graph API apart from the method mentioned above?

The Graph API response looks something similar to the following and the Authentication-Results gives me the relevant origin Sender IP -
{
"#odata.context":"<some-value>",
"#odata.etag":"<some-value>",
"id":"<some-value>",
"internetMessageHeaders":[
{
"name":"MIME-Version",
"value":"1.0"
},
{
"name":"Content-Type",
"value":"multipart/report"
},
{
"name":"x-custom-header-group-name",
"value":"Washington"
},
{
"name":"x-custom-header-group-id",
"value":"WA001"
},
{
"name":"Receiver",
"value":"<some-ip>"
},
{
"name":"Receiver",
"value":"<some-ip>"
},
{
"name":"Authentication-Results",
"value":"spf=pass (sender ip is <some-ip>)...,"
}
]
}
Now, all you need is a regex to extract -
Get the value present in Authentication-Results
Use the Regex - \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3} to extract IP, use the first occurence of the match with regex.

Related

Not able to retrieve the spreadsheet id from workspace add-on

I'm developing a workspace add-on with alternate runtime; I configured the add-on to work with spreadsheets and I need to retrieve the spreadsheet id when the user opens the add-on. For test purposes I created a cloud function that contains the business logic.
My deployment.json file is the following:
{
"oauthScopes": ["https://www.googleapis.com/auth/spreadsheets.currentonly", "https://www.googleapis.com/auth/drive.file"],
"addOns": {
"common": {
"name": "My Spreadsheet Add-on",
"logoUrl": "https://cdn.icon-icons.com/icons2/2070/PNG/512/penguin_icon_126624.png"
},
"sheets": {
"homepageTrigger": {
"runFunction": "cloudFunctionUrl"
}
}
}
}
However, the request I receive seems to be empty and without the id of the spreadsheet in which I am, while I was expecting to have the spreadsheet id as per documentation
Is there anything else I need to configure?
The relevant code is quite easy, I'm just printing the request:
exports.getSpreadsheetId = function addonsHomePage (req, res) { console.log('called', req.method); console.log('body', req.body); res.send(createAction()); };
the information showed in the log is:
sheets: {}
Thank you
UPDATE It's a known issue of the engineering team, here you can find the ticket
The information around Workspace Add-ons is pretty new and the documentation is pretty sparse.
In case anyone else comes across this issue ... I solved it in python using CloudRun by creating a button that checks for for the object then if there is no object it requests access to the sheet in question.
from flask import Flask
from flask import request
app = Flask(__name__)
#app.route('/', methods=['POST'])
def test_addon_homepage():
req_body = request.get_json()
sheet_info = req_body.get('sheets')
card = {
"action": {
"navigations": [
{
"pushCard": {
"sections": [
{
"widgets": [
{
"textParagraph": {
"text": f"Hello {sheet_info.get('title','Auth Needed')}!"
}
}
]
}
]
}
}
]
}
}
if not sheet_info:
card = create_file_auth_button(card)
return card
def create_file_auth_button(self, card):
card['action']['navigations'][0]['pushCard']['fixedFooter'] = {
'primaryButton': {
'text': 'Authorize file access',
'onClick': {
'action': {
'function': 'https://example-cloudrun.a.run.app/authorize_sheet'
}
}
}
}
return card
#app.route('/authorize_sheet', methods=['POST'])
def authorize_sheet():
payload = {
'renderActions': {
'hostAppAction': {
'editorAction': {
'requestFileScopeForActiveDocument': {}
}
}
}
}
return payload

Accessing a specific item in a JSON return in Rails

I have this JSON from the NHL API, and I tried to access the value gamesPlayed:
"teams"=>[
{
"id"=>5,
"name"=>"Pittsburgh Penguins",
"link"=>"/api/v1/teams/5",
"venue"=>{
"id"=>5034,
"name"=>"PPG Paints Arena",
"link"=>"/api/v1/venues/5034",
"city"=>"Pittsburgh",
"timeZone"=>{
"id"=>"America/New_York",
"offset"=>-5,
"tz"=>"EST"
}
},
"abbreviation"=>"PIT",
"teamName"=>"Penguins",
"locationName"=>"Pittsburgh",
"division"=>{
"id"=>18,
"name"=>"Metropolitan",
"nameShort"=>"Metro",
"link"=>"/api/v1/divisions/18",
"abbreviation"=>"M"
},
"conference"=>{
"id"=>6,
"name"=>"Eastern",
"link"=>"/api/v1/conferences/6"
},
"franchise"=>{
"franchiseId"=>17,
"teamName"=>"Penguins",
"link"=>"/api/v1/franchises/17"
},
"teamStats"=>[
{
"type"=>{
"displayName"=>"statsSingleSeason"
},
"splits"=>[
{
"stat"=>{
"gamesPlayed"=>16,
"wins"=>7,
"losses"=>6,
"ot"=>3,
"pts"=>17,
"ptPctg"=>"53.1",
"goalsPerGame"=>3.313,
"goalsAgainstPerGame"=>3.063,
"evGGARatio"=>1.0833,
"powerPlayPercentage"=>"23.4",
"powerPlayGoals"=>11.0,
"powerPlayGoalsAgainst"=>8.0,
"powerPlayOpportunities"=>47.0,
"penaltyKillPercentage"=>"84.0",
"shotsPerGame"=>32.625,
"shotsAllowed"=>33.6875,
"winScoreFirst"=>0.6,
"winOppScoreFirst"=>0.167,
"winLeadFirstPer"=>0.5,
"winLeadSecondPer"=>1.0,
"winOutshootOpp"=>0.333,
"winOutshotByOpp"=>0.444,
"faceOffsTaken"=>1035.0,
"faceOffsWon"=>534.0,
"faceOffsLost"=>501.0,
"faceOffWinPercentage"=>"51.6",
"shootingPctg"=>10.2,
"savePctg"=>0.909
},
"team"=>{
"id"=>5,
"name"=>"Pittsburgh Penguins",
"link"=>"/api/v1/teams/5"
}
},
{
"stat"=>{
"wins"=>"24th",
"losses"=>"15th",
"ot"=>"9th",
"pts"=>"24th",
"ptPctg"=>"19th",
"goalsPerGame"=>"8th",
"goalsAgainstPerGame"=>"19th",
"evGGARatio"=>"11th",
"powerPlayPercentage"=>"10th",
"powerPlayGoals"=>"22nd",
"powerPlayGoalsAgainst"=>"4th",
"powerPlayOpportunities"=>"31st",
"penaltyKillOpportunities"=>"1st",
"penaltyKillPercentage"=>"6th",
"shotsPerGame"=>"12th",
"shotsAllowed"=>"27th",
"winScoreFirst"=>"15th",
"winOppScoreFirst"=>"27th",
"winLeadFirstPer"=>"27th",
"winLeadSecondPer"=>"7th",
"winOutshootOpp"=>"25th",
"winOutshotByOpp"=>"25th",
"faceOffsTaken"=>"25th",
"faceOffsWon"=>"19th",
"faceOffsLost"=>"6th",
"faceOffWinPercentage"=>"8th",
"savePctRank"=>"13th",
"shootingPctRank"=>"12th"
},
"team"=>{
"id"=>5,
"name"=>"Pittsburgh Penguins",
"link"=>"/api/v1/teams/5"
}
}
]
}
],
"shortName"=>"Pittsburgh",
"officialSiteUrl"=>"http://pittsburghpenguins.com/",
"franchiseId"=>17,
"active"=>true
}
}
I am working in ruby on rails and would like to access the gamesPlayed value.
So far I have:
url = 'https://statsapi.web.nhl.com/api/v1/teams/5?expand=team.stats'
uri = URI(url)
response = Net::HTTP.get(uri)
response = JSON.parse(response)
#awayteamgamesplayed = response["teams"][0]["teamStats"]["stat"]["gamesPlayed"]
I can get to the team name using: response["teams"][away_team]["name"] but cant't work out gamesPlayed.
But it doesn't seem to work for gamesPlayed.
Value of teamStats is an Array. You need to access it via an index.
Same for splits
response["teams"][0]["teamStats"][0]["splits"][0]["stat"]["gamesPlayed"]
# => 16
teamStats is an array try this
response["teams"][0]["teamStats"][0]["stat"]["gamesPlayed"]

Elasticsearch validate API explain query terms from more like this against single field getting highlighted terms

I have an index, with effectively the converted word or pdf document plain text "document_texts", built on a Rails stack the ActiveModel is DocumentText using the elasticsearch rails gems, for model, and API. I want to be able to match similar word documents or pdf's based on the document text
I have been able to match documents against each other by using
response = DocumentText.search \
query: {
filtered: {
query: {
more_like_this: {
ids: ["12345"]
}
}
}
}
But I want to see HOW did the result set get queried, what were the query terms used to match the documents
Using the elasticsearch API gem I can do the following
client=Elasticsearch::Client.new log:true
client.indices.validate_query index: 'document_texts',
explain: true,
body: {
query: {
filtered: {
query: {
more_like_this: {
ids: ['12345']
}
}
}
}
}
But I get this in response
{"valid":true,"_shards":{"total":1,"successful":1,"failed":0},"explanations":[{"index":"document_texts","valid":true,"explanation":"+(like:null -_uid:document_text#12345)"}]}
I would like to find out how did the query get built, it uses upto 25 terms for the matching, what were those 25 terms and how can I get them from the query?
I'm not sure if its possible but I would like to see if I can get the 25 terms used by elasticsearches analyzer and then reapply the query with boosted values on the terms depending on my choice.
I also want to highlight this in the document text but tried this
response = DocumentText.search \
from: 0, size: 25,
query: {
filtered: {
query: {
more_like_this: {
ids: ["12345"]
}
},
filter: {
bool: {
must: [
{match: { documentable_type: model}}
]
}
}
}
},
highlight: {
pre_tags: ["<tag1>"],
post_tags: ["</tag1>"],
fields: {
doc_text: {
type_name: {
content: {term_vector: "with_positions_offsets"}
}
}
}
}
But this fails to produce anything, I think I was being rather hopeful. I know that this should be possible but would be keen to know if anyone has done this or the best approach. Any ideas?
Including some stop words just for anyone else out there this will give an easy way for it to show the terms used for the query. It doesnt solve the highlight issue but can give the terms used for the mlt matching process. Some other settings are used just to show
curl -XGET 'http://localhost:9200/document_texts/document_text/_validate/query?rewrite=true' -d '
{
"query": {
"filtered": {
"query": {
"more_like_this": {
"ids": ["12345"],
"min_term_freq": 1,
"max_query_terms": 50,
"stop_words": ["this","of"]
}
}
}
}
}'
https://github.com/elastic/elasticsearch-ruby/pull/359
Once this is merged this should be easier
client.indices.validate_query index: 'document_texts',
rewrite: true,
explain: true,
body: {
query: {
filtered: {
query: {
more_like_this: {
ids: ['10538']
}
}
}
}
}

What am I doing wrong in this QBO v3 Reports API query?

When I use the following query, I get a good response (with only the first 5 days of May, so apparently the default is not 'This Fiscal Year-to-date' as the documentation suggests, but I digress):
https://quickbooks.api.intuit.com/v3/company/0123456789/reports/CustomerSales
When I add parameters, I get an oauth exception. For example:
https://quickbooks.api.intuit.com/v3/company/0123456789/reports/CustomerSales?start_date='2013-01-01'&end_date='2014-05-06'
Gives me this:
{
"Fault": {
"type": "AUTHENTICATION",
"Error": [
{
"Message": "message=Exception authenticating OAuth; errorCode=003200; statusCode=401",
"code": "3200"
}
]
},
"requestId": "[redacted]",
"time": "[redacted]"
}
This gives me the same result:
https://quickbooks.api.intuit.com/v3/company/0123456789/reports/CustomerSales?date_macro='This Fiscal Year'
So does this:
https://quickbooks.api.intuit.com/v3/company/148305798/reports/CustomerSales?accounting_method='Accrual'
I figure I'm missing something small. I'm not changing any of the headers or any of the other request details...just the url.
I tried without the single quotes around the dates and other params too.
What am I breaking?
Are you including the data to the right of the ? in the URL in the "base" string and are you sorting it with the other parameters?
I've tried this report using java devkit.
It worked fine for me. PFB details.
Request URI - https://quickbooks.api.intuit.com/v3/company/1092175540/reports/CustomerSales?accounting_method=Accrual&start_date=2014-01-01&requestid=61234ddb7e14ce2a5fe4e2f0318b31c&minorversion=1&
My test company file is empty.. That's why got the following JSON response.
{
"Header":{
"Time":"2014-05-06T20:42:08.783-07:00",
"ReportName":"CustomerSales",
"ReportBasis":"Accrual",
"StartPeriod":"2014-05-01",
"EndPeriod":"2014-05-06",
"SummarizeColumnsBy":"Total",
"Currency":"USD"
},
"Columns":{
"Column":[
{
"ColTitle":"",
"ColType":"Customer"
}
]
},
"Rows":{
"Row":[
{
"ColData":[
{
"value":"TOTAL"
}
],
"group":"GrandTotal"
}
]
}
}
JAVA code
void testCustomerSalesReport(Context context) {
Config.setProperty(Config.SERIALIZATION_RESPONSE_FORMAT, "json");
ReportService service = new ReportService(context);
service.setStart_date("2014-01-01");
service.setAccounting_method("Accrual");
Report report = null;
try {
report = service.executeReport(ReportName.CUSTOMERSALES.toString());
} catch (FMSException e) {
e.printStackTrace();
}
}
API Doc Ref - https://developer.intuit.com/docs/0025_quickbooksapi/0050_data_services/reports/customersales
Hope it will be useful.
Thanks

How to make elasticsearch add the timestamp field to every document in all indices?

Elasticsearch experts,
I have been unable to find a simple way to just tell ElasticSearch to insert the _timestamp field for all the documents that are added in all the indices (and all document types).
I see an example for specific types:
http://www.elasticsearch.org/guide/reference/mapping/timestamp-field/
and also see an example for all indices for a specific type (using _all):
http://www.elasticsearch.org/guide/reference/api/admin-indices-put-mapping/
but I am unable to find any documentation on adding it by default for all documents that get added irrespective of the index and type.
Elasticsearch used to support automatically adding timestamps to documents being indexed, but deprecated this feature in 2.0.0
From the version 5.5 documentation:
The _timestamp and _ttl fields were deprecated and are now removed. As a replacement for _timestamp, you should populate a regular date field with the current timestamp on application side.
You can do this by providing it when creating your index.
$curl -XPOST localhost:9200/test -d '{
"settings" : {
"number_of_shards" : 1
},
"mappings" : {
"_default_":{
"_timestamp" : {
"enabled" : true,
"store" : true
}
}
}
}'
That will then automatically create a _timestamp for all stuff that you put in the index.
Then after indexing something when requesting the _timestamp field it will be returned.
Adding another way to get indexing timestamp. Hope this may help someone.
Ingest pipeline can be used to add timestamp when document is indexed. Here, is a sample example:
PUT _ingest/pipeline/indexed_at
{
"description": "Adds indexed_at timestamp to documents",
"processors": [
{
"set": {
"field": "_source.indexed_at",
"value": "{{_ingest.timestamp}}"
}
}
]
}
Earlier, elastic search was using named-pipelines because of which 'pipeline' param needs to be specified in the elastic search endpoint which is used to write/index documents. (Ref: link) This was bit troublesome as you would need to make changes in endpoints on application side.
With Elastic search version >= 6.5, you can now specify a default pipeline for an index using index.default_pipeline settings. (Refer link for details)
Here is the to set default pipeline:
PUT ms-test/_settings
{
"index.default_pipeline": "indexed_at"
}
I haven't tried out yet, as didn't upgraded to ES 6.5, but above command should work.
You can make use of default index pipelines, leverage the script processor, and thus emulate the auto_now_add functionality you may know from Django and DEFAULT GETDATE() from SQL.
The process of adding a default yyyy-MM-dd HH:mm:ss date goes like this:
1. Create the pipeline and specify which indices it'll be allowed to run on:
PUT _ingest/pipeline/auto_now_add
{
"description": "Assigns the current date if not yet present and if the index name is whitelisted",
"processors": [
{
"script": {
"source": """
// skip if not whitelisted
if (![ "myindex",
"logs-index",
"..."
].contains(ctx['_index'])) { return; }
// don't overwrite if present
if (ctx['created_at'] != null) { return; }
ctx['created_at'] = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
"""
}
}
]
}
Side note: the ingest processor's Painless script context is documented here.
2. Update the default_pipeline setting in all of your indices:
PUT _all/_settings
{
"index": {
"default_pipeline": "auto_now_add"
}
}
Side note: you can restrict the target indices using the multi-target syntax:
PUT myindex,logs-2021-*/_settings?allow_no_indices=true
{
"index": {
"default_pipeline": "auto_now_add"
}
}
3. Ingest a document to one of the configured indices:
PUT myindex/_doc/1
{
"abc": "def"
}
4. Verify that the date string has been added:
GET myindex/_search
An example for ElasticSearch 6.6.2 in Python 3:
from elasticsearch import Elasticsearch
es = Elasticsearch(hosts=["localhost"])
timestamp_pipeline_setting = {
"description": "insert timestamp field for all documents",
"processors": [
{
"set": {
"field": "ingest_timestamp",
"value": "{{_ingest.timestamp}}"
}
}
]
}
es.ingest.put_pipeline("timestamp_pipeline", timestamp_pipeline_setting)
conf = {
"settings": {
"number_of_shards": 2,
"number_of_replicas": 1,
"default_pipeline": "timestamp_pipeline"
},
"mappings": {
"articles":{
"dynamic": "false",
"_source" : {"enabled" : "true" },
"properties": {
"title": {
"type": "text",
},
"content": {
"type": "text",
},
}
}
}
}
response = es.indices.create(
index="articles_index",
body=conf,
ignore=400 # ignore 400 already exists code
)
print ('\nresponse:', response)
doc = {
'title': 'automatically adding a timestamp to documents',
'content': 'prior to version 5 of Elasticsearch, documents had a metadata field called _timestamp. When enabled, this _timestamp was automatically added to every document. It would tell you the exact time a document had been indexed.',
}
res = es.index(index="articles_index", doc_type="articles", id=100001, body=doc)
print(res)
res = es.get(index="articles_index", doc_type="articles", id=100001)
print(res)
About ES 7.x, the example should work after removing the doc_type related parameters as it's not supported any more.
first create index and properties of the index , such as field and datatype and then insert the data using the rest API.
below is the way to create index with the field properties.execute the following in kibana console
`PUT /vfq-jenkins
{
"mappings": {
"properties": {
"BUILD_NUMBER": { "type" : "double"},
"BUILD_ID" : { "type" : "double" },
"JOB_NAME" : { "type" : "text" },
"JOB_STATUS" : { "type" : "keyword" },
"time" : { "type" : "date" }
}}}`
the next step is to insert the data into that index:
curl -u elastic:changeme -X POST http://elasticsearch:9200/vfq-jenkins/_doc/?pretty
-H Content-Type: application/json -d '{
"BUILD_NUMBER":"83","BUILD_ID":"83","JOB_NAME":"OMS_LOG_ANA","JOB_STATUS":"SUCCESS" ,
"time" : "2019-09-08'T'12:39:00" }'

Resources