google wave OnBlipSubmitted - python

I'm trying to create a wave robot, and I have the basic stuff working. I'm trying to create a new blip with help text when someone types #help but for some reason it doesnt create it. I'm getting no errors in the log console, and I'm seeing the info log 'in #log'
def OnBlipSubmitted(properties, context):
# Get the blip that was just submitted.
blip = context.GetBlipById(properties['blipId'])
text = blip.GetDocument().GetText()
if text.startswith('#help') == True:
logging.info('in #help')
blip.CreateChild().GetDocument().SetText('help text')

if it just started working, I have two suggestions...
-->Have you been updating the Robot Version in the constructor? You should change the values as you update changes so that the caches can be updated.
if __name__ == '__main__':
myRobot = robot.Robot('waverobotdev',
image_url = baseurl + 'assets/wave_robot_icon.png',
version = '61', # <-------------HERE
profile_url = baseurl)
-->The server connection between Wave and AppSpot has recently been extremely variable. Sometimes it takes 10+ minutes for the AppSpot server to receive my event, othertimes a few seconds. Verify you're receiving the events you expect.
Edit:
The code you provided looks good, so I wouldn't expect you're doing anything wrong in that respect.

Have you tried using Append() instead of SetText()? That's what I'd do in my C# API - I haven't used the Python API, but I'd imagine it's similar. Here's a sample from my demo robot:
protected override void OnBlipSubmitted(IEvent e)
{
if (e.Blip.Document.Text.Contains("robot"))
{
IBlip blip = e.Blip.CreateChild();
ITextView textView = blip.Document;
textView.Append("Are you talking to me?");
}
}
That works fine.
EDIT: Here's the resulting JSON from the above code:
{
"javaClass": "com.google.wave.api.impl.OperationMessageBundle",
"version": "173784133",
"operations": {
"javaClass": "java.util.ArrayList",
"list": [
{
"javaClass": "com.google.wave.api.impl.OperationImpl",
"type": "BLIP_CREATE_CHILD",
"waveId": "googlewave.com!w+PHAstGbKC",
"waveletId": "googlewave.com!conv+root",
"blipId": "b+Iw_Xw7FCC",
"index": -1,
"property": {
"javaClass": "com.google.wave.api.impl.BlipData",
"annotations": {
"javaClass": "java.util.ArrayList",
"list": []
},
"lastModifiedTime": -1,
"contributors": {
"javaClass": "java.util.ArrayList",
"list": []
},
"waveId": "googlewave.com!w+PHAstGbKC",
"waveletId": "googlewave.com!conv+root",
"version": -1,
"parentBlipId": null,
"creator": null,
"content": "\nAre you talking to me?",
"blipId": "410621dc-d7a1-4be5-876c-0a9d313858bb",
"elements": {
"map": {},
"javaClass": "java.util.HashMap"
},
"childBlipIds": {
"javaClass": "java.util.ArrayList",
"list": []
}
}
},
{
"javaClass": "com.google.wave.api.impl.OperationImpl",
"type": "DOCUMENT_APPEND",
"waveId": "googlewave.com!w+PHAstGbKC",
"waveletId": "googlewave.com!conv+root",
"blipId": "410621dc-d7a1-4be5-876c-0a9d313858bb",
"index": 0,
"property": "Are you talking to me?"
}
]
}
}
How does that compare with the JSON which comes out of your robot?

For some reason it just started working. I think the google wave is spotty.

Related

Using Atlasians Insight API to bring over AWS resources

I'm very new to this API. I've been able to figure out everything in this link up until step 3 ([api docs][1]). I have a sample payload of what we want to import, but I have no idea what the schema/mapping should be. The example provided [here][2], for a hard drive does not make sense to me at all. I've even tried sending the exact payload/mapping from that example and get hit with a 409 error. Any help would be great.
Example of what I want to bring in:
{
"ARN": "arn:aws:codedeploy:ca-central-1:030375219570:deploymentconfig:CodeDeployDefault.LambdaCanary10Percent10Minutes",
"availabilityZone": "Not Applicable",
"awsAccountId": "030375219570",
"awsRegion": "ca-central-1",
"configuration": {
"computePlatform": "Lambda",
"deploymentConfigId": "00000000-0000-0000-0000-000000000008",
"deploymentConfigName": "CodeDeployDefault.LambdaCanary10Percent10Minutes",
"trafficRoutingConfig": {
"timeBasedCanary": {
"canaryInterval": 10,
"canaryPercentage": 10
},
"type": "TimeBasedCanary"
}
},
"configurationItemCaptureTime": "2022-02-09T20:42:23.445Z",
"configurationItemStatus": "ResourceDiscovered",
"configurationItemVersion": "1.3",
"configurationStateId": 1644439343445,
"configurationStateMd5Hash": "",
"relatedEvents": [],
"relationships": [],
"resourceId": "00000000-0000-0000-0000-000000000008",
"resourceName": "CodeDeployDefault.LambdaCanary10Percent10Minutes",
"resourceType": "AWS::CodeDeploy::DeploymentConfig",
"supplementaryConfiguration": {},
"tags": {}
}
If anyone knows how the mapping/schema would look for something like the above, I'm all ears.
thanks
[1]: https://developer.atlassian.com/cloud/assets/imports/workflow/
[2]: https://developer.atlassian.com/cloud/assets/imports/schema-and-mapping/?utm_source=%2Fcloud%2Finsight%2Fimports%2Fschema-and-mapping%2F&utm_medium=301#external-imports-schema-and-mapping

Is it possible to retreive object_story_spec for an ad creative which was not created with that object_story_spec? [Python Facebook API]

I have a set of ad creatives that I retreive through the Facebook Business Python SDK. I need these specifically to retreive the outbound URL when someone clicks on the ad: AdCreative['object_story_spec']['video_data']['call_to_action']['value']['link'].
I use the following call:
adcreatives = set.get_ad_creatives(fields=[
AdCreative.Field.id,
AdCreative.Field.name,
AdCreative.Field.object_story_spec,
AdCreative.Field.effective_object_story_id ,
])
Where set is an ad set.
For some cases, the result looks like this (with actual data removed), which is expected:
<AdCreative> {
"body": "[<BODY>]",
"effective_object_story_id": "[<EFFECTIVE_OBJECT_STORY_ID>]",
"id": "[<ID>]",
"name": "[<NAME>]",
"object_story_spec": {
"instagram_actor_id": "[<INSTAGRAM_ACTOR_ID>]",
"page_id": "[<PAGE_ID>]",
"video_data": {
"call_to_action": {
"type": "[<TYPE>]",
"value": {
"link": "[<LINK>]", <== This is what I need
"link_format": "[<LINK_FORMAT>]"
}
},
"image_hash": "[<IMAGE_HASH>]",
"image_url": "[<IMAGE_URL>]",
"message": "[<MESSAGE>]",
"video_id": "[<VIDEO_ID>]"
}
}
}
While sometimes results look like this:
<AdCreative> {
"effective_object_story_id": "[<EFFECTIVE_OBJECT_STORY_ID>]",
"id": "[<ID>]",
"name": "[<NAME>]",
"object_story_spec": {
"instagram_actor_id": "[<INSTAGRAM_ACTOR_ID>]",
"page_id": "[<PAGE_ID>]"
}
}
According to this earlier question: Can't get AdCreative ObjectStorySpec this is due to the fact that the object_story_spec is not populated if it is linked to a creative, instead of created along with the creative.
However, the video_data (and as such, the link), should be saved somewhere. Is there a way to retreive this? Maybe through effective_object_story_id?
The documentation page for object_story_spec (https://developers.facebook.com/docs/marketing-api/reference/ad-creative-object-story-spec/v12.0) does not have the information I am looking for.

Add a Protected Range to an existing NamedRange

I have an existing worksheet with an existing NamedRange for it and I would like to call the batch_update method of the API to protect that range from being edited by anyone other than the user that makes the batch_update call.
I have seen an example on how to add protected ranges via a new range definition, but not from an existing NamedRange.
I know I need to send the addProtectedRangeResponse request. Can I define the request body with a Sheetname!NamedRange notation?
this_range = worksheet_name + "!" + nrange
batch_update_spreadsheet_request_body = {
'requests': [
{
"addProtectedRange": {
"protectedRange": {
"range": {
"name": this_range,
},
"description": "Protecting xyz",
"warningOnly": False
}
}
}
],
}
EDIT: Given #Tanaike feedback, I adapted the call to something like:
body = {
"requests": [
{
"addProtectedRange": {
"protectedRange": {
"namedRangeId": namedRangeId,
"description": "Protecting via gsheets_manager",
"warningOnly": False,
"requestingUserCanEdit": False
}
}
}
]
}
res2 = service.spreadsheets().batchUpdate(spreadsheetId=ssId, body=body).execute()
print(res2)
But although it lists the new protections, it still lists 5 different users (all of them) as editors. If I try to manually edit the protection added by my gsheets_manager script, it complains that the range is invalid:
Interestingly, it seems to ignore the requestUserCanEdit flag according to the returning message:
{u'spreadsheetId': u'NNNNNNNNNNNNNNNNNNNNNNNNNNNN', u'replies': [{u'addProtectedRange': {u'protectedRange': {u'requestingUserCanEdit': True, u'description': u'Protecting via gsheets_manager', u'namedRangeId': u'1793914032', u'editors': {}, u'protectedRangeId': 2012740267, u'range': {u'endColumnIndex': 1, u'sheetId': 1196959832, u'startColumnIndex': 0}}}}]}
Any ideas?
How about using namedRangeId for your situation? The flow of the sample script is as follows.
Retrieve namedRangeId using spreadsheets().get of Sheets API.
Set a protected range using namedRangeId using spreadsheets().batchUpdate of Sheets API.
Sample script:
nrange = "### name ###"
ssId = "### spreadsheetId ###"
res1 = service.spreadsheets().get(spreadsheetId=ssId, fields="namedRanges").execute()
namedRangeId = ""
for e in res1['namedRanges']:
if e['name'] == nrange:
namedRangeId = e['namedRangeId']
break
body = {
"requests": [
{
"addProtectedRange": {
"protectedRange": {
"namedRangeId": namedRangeId,
"description": "Protecting xyz",
"warningOnly": False
}
}
}
]
}
res2 = service.spreadsheets().batchUpdate(spreadsheetId=ssId, body=body).execute()
print(res2)
Note:
This script supposes that Sheets API can be used for your environment.
This is a simple sample script. So please modify it to your situation.
References:
ProtectedRange
Named and Protected Ranges
If this was not what you want, I'm sorry.
Edit:
In my above answer, I modified your script using your settings. If you want to protect the named range, please modify body as follows.
Modified body
body = {
"requests": [
{
"addProtectedRange": {
"protectedRange": {
"namedRangeId": namedRangeId,
"description": "Protecting xyz",
"warningOnly": False,
"editors": {"users": ["### your email address ###"]}, # Added
}
}
}
]
}
By this, the named range can be modified by only you. I'm using such settings and I confirm that it works in my environment. But if in your situation, this didn't work, I'm sorry.

Python: bitly request

I'm trying to do a basic Bitly shortening URL call. However, I cannot seem to either push the json correctly, or deal with the json response correctly... I omitted some obvious variables for brevity and obfuscated some real values for security purposes.
import requests
import json
bitly_header = {'Authorization':'Bearer
some_long_secret_character_string_here', 'Content-Type':'application/json'}
bitly_data = {
"long_url": ""+long_url+"",
"group_guid": ""+bitly_guid+""
}
short_link_resp =requests.post(bitly_endpoint,data=bitly_data,headers=bitly_header)
short_link_json = short_link_resp.json()
short_link = short_link_json["link"]
Errors is "Key error: 'link'
The json I get from Postman is:
{
"created_at": "1970-01-01T00:00:00+0000",
"id": "bit.ly/2MjdrrG",
"link": "bit.ly/2MjdrrG",
"custom_bitlinks": [],
"long_url": "google.com/",
"archived": false,
"tags": [],
"deeplinks": [],
"references": {
"group": "https://api-ssl.bitly.com/v4/groups/Bi7i8IbM1x9"
}
}
try replace data with json:
short_link_resp =requests.post(bitly_endpoint, json=bitly_data, headers=bitly_header)
see the doc ref.

Elasticsearch prints PUT statements on the console in Python

I have written the following code in Python to use ElasticSearch for performing search on the data:
def main():
start = (time.time())
es = Elasticsearch()
es.indices.create(index='bhar',body = {
"settings":{
"analysis":{
"analyzer":{
"my_stop_analyzer":{
"type":"custom",
"tokenizer":"standard",
"filter":["english_possessive_stemmer","lowercase","english_stop","english_stemmer"]
}
},
"filter":{
"english_stop":{
"type":"stop",
"stopwords":"_english_"
},
"english_stemmer":{
"type":"stemmer",
"name":"english"
},
"english_possessive_stemmer": {
"type": "stemmer",
"language": "possessive_english"
}
}
}
},
"mappings":{
"my_type":{
"properties":{
"test": {
"type":"text",
"analyzer" : "my_stop_analyzer"
}
}
}
}
})
data = {"rid":"1","test": "This data BHX1 Pick Tower extension"}
res = es.index(index='bhar',doc_type='news',id=1,body=data,refresh=True)
query='pick tower'
match = es.search(index="bhar",body = {
"query": {
"match":{
"test":{
"query":query.replace('|',' '),
"operator" :"AND"
}
}
}
}
)
if match['hits']['total']:
print(match['hits']['hits'][0]['_source'])
if __name__ == '__main__':
main()
When I execute this code I get the following output:
PUT http://localhost:9200/bhar [status:400 request:0.027s]
{'rid': '1', 'test': 'This data BHX1 Pick Tower extension'}
How do I control the PUT statement on the screen? Maybe send it to a log file or just not print it on the screen. Any thoughts? Thank you for reading.
Add the following line before executing the elastic search query, then the POST response wont be logged into the log files,
logging.getLogger('elasticsearch').setLevel(logging.ERROR)
The line you see being printed on screen is due to the following logger.info() call in connection/base.py:
def log_request_success(self, method, full_url, path, body, status_code, response, duration):
...
logger.info(
'%s %s [status:%s request:%.3fs]', method, full_url,
status_code, duration
)
If you don't want it to be printed out you simply need to run your code with the switch --logging-level=WARN

Categories

Resources