149 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			Python
		
	
	
			
		
		
	
	
			149 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			Python
		
	
	
# -*- coding: utf-8 -*-
 | 
						|
# Copyright 2015 OpenMarket Ltd
 | 
						|
#
 | 
						|
# Licensed under the Apache License, Version 2.0 (the "License");
 | 
						|
# you may not use this file except in compliance with the License.
 | 
						|
# You may obtain a copy of the License at
 | 
						|
#
 | 
						|
#     http://www.apache.org/licenses/LICENSE-2.0
 | 
						|
#
 | 
						|
# Unless required by applicable law or agreed to in writing, software
 | 
						|
# distributed under the License is distributed on an "AS IS" BASIS,
 | 
						|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
						|
# See the License for the specific language governing permissions and
 | 
						|
# limitations under the License.
 | 
						|
 | 
						|
from synapse.push import Pusher, PusherConfigException
 | 
						|
from synapse.http.client import SimpleHttpClient
 | 
						|
 | 
						|
from twisted.internet import defer
 | 
						|
 | 
						|
import logging
 | 
						|
 | 
						|
logger = logging.getLogger(__name__)
 | 
						|
 | 
						|
 | 
						|
class HttpPusher(Pusher):
 | 
						|
    def __init__(self, _hs, profile_tag, user_name, app_id,
 | 
						|
                 app_display_name, device_display_name, pushkey, pushkey_ts,
 | 
						|
                 data, last_token, last_success, failing_since):
 | 
						|
        super(HttpPusher, self).__init__(
 | 
						|
            _hs,
 | 
						|
            profile_tag,
 | 
						|
            user_name,
 | 
						|
            app_id,
 | 
						|
            app_display_name,
 | 
						|
            device_display_name,
 | 
						|
            pushkey,
 | 
						|
            pushkey_ts,
 | 
						|
            data,
 | 
						|
            last_token,
 | 
						|
            last_success,
 | 
						|
            failing_since
 | 
						|
        )
 | 
						|
        if 'url' not in data:
 | 
						|
            raise PusherConfigException(
 | 
						|
                "'url' required in data for HTTP pusher"
 | 
						|
            )
 | 
						|
        self.url = data['url']
 | 
						|
        self.httpCli = SimpleHttpClient(self.hs)
 | 
						|
        self.data_minus_url = {}
 | 
						|
        self.data_minus_url.update(self.data)
 | 
						|
        del self.data_minus_url['url']
 | 
						|
 | 
						|
    @defer.inlineCallbacks
 | 
						|
    def _build_notification_dict(self, event, tweaks):
 | 
						|
        # we probably do not want to push for every presence update
 | 
						|
        # (we may want to be able to set up notifications when specific
 | 
						|
        # people sign in, but we'd want to only deliver the pertinent ones)
 | 
						|
        # Actually, presence events will not get this far now because we
 | 
						|
        # need to filter them out in the main Pusher code.
 | 
						|
        if 'event_id' not in event:
 | 
						|
            defer.returnValue(None)
 | 
						|
 | 
						|
        ctx = yield self.get_context_for_event(event)
 | 
						|
 | 
						|
        d = {
 | 
						|
            'notification': {
 | 
						|
                'id': event['event_id'],
 | 
						|
                'room_id': event['room_id'],
 | 
						|
                'type': event['type'],
 | 
						|
                'sender': event['user_id'],
 | 
						|
                'counts': {  # -- we don't mark messages as read yet so
 | 
						|
                             # we have no way of knowing
 | 
						|
                    # Just set the badge to 1 until we have read receipts
 | 
						|
                    'unread': 1,
 | 
						|
                    # 'missed_calls': 2
 | 
						|
                },
 | 
						|
                'devices': [
 | 
						|
                    {
 | 
						|
                        'app_id': self.app_id,
 | 
						|
                        'pushkey': self.pushkey,
 | 
						|
                        'pushkey_ts': long(self.pushkey_ts / 1000),
 | 
						|
                        'data': self.data_minus_url,
 | 
						|
                        'tweaks': tweaks
 | 
						|
                    }
 | 
						|
                ]
 | 
						|
            }
 | 
						|
        }
 | 
						|
        if event['type'] == 'm.room.member':
 | 
						|
            d['notification']['membership'] = event['content']['membership']
 | 
						|
            d['notification']['user_is_target'] = event['state_key'] == self.user_name
 | 
						|
        if 'content' in event:
 | 
						|
            d['notification']['content'] = event['content']
 | 
						|
 | 
						|
        if len(ctx['aliases']):
 | 
						|
            d['notification']['room_alias'] = ctx['aliases'][0]
 | 
						|
        if 'sender_display_name' in ctx and len(ctx['sender_display_name']) > 0:
 | 
						|
            d['notification']['sender_display_name'] = ctx['sender_display_name']
 | 
						|
        if 'name' in ctx and len(ctx['name']) > 0:
 | 
						|
            d['notification']['room_name'] = ctx['name']
 | 
						|
 | 
						|
        defer.returnValue(d)
 | 
						|
 | 
						|
    @defer.inlineCallbacks
 | 
						|
    def dispatch_push(self, event, tweaks):
 | 
						|
        notification_dict = yield self._build_notification_dict(event, tweaks)
 | 
						|
        if not notification_dict:
 | 
						|
            defer.returnValue([])
 | 
						|
        try:
 | 
						|
            resp = yield self.httpCli.post_json_get_json(self.url, notification_dict)
 | 
						|
        except:
 | 
						|
            logger.warn("Failed to push %s ", self.url)
 | 
						|
            defer.returnValue(False)
 | 
						|
        rejected = []
 | 
						|
        if 'rejected' in resp:
 | 
						|
            rejected = resp['rejected']
 | 
						|
        defer.returnValue(rejected)
 | 
						|
 | 
						|
    @defer.inlineCallbacks
 | 
						|
    def reset_badge_count(self):
 | 
						|
        d = {
 | 
						|
            'notification': {
 | 
						|
                'id': '',
 | 
						|
                'type': None,
 | 
						|
                'sender': '',
 | 
						|
                'counts': {
 | 
						|
                    'unread': 0,
 | 
						|
                    'missed_calls': 0
 | 
						|
                },
 | 
						|
                'devices': [
 | 
						|
                    {
 | 
						|
                        'app_id': self.app_id,
 | 
						|
                        'pushkey': self.pushkey,
 | 
						|
                        'pushkey_ts': long(self.pushkey_ts / 1000),
 | 
						|
                        'data': self.data_minus_url,
 | 
						|
                    }
 | 
						|
                ]
 | 
						|
            }
 | 
						|
        }
 | 
						|
        try:
 | 
						|
            resp = yield self.httpCli.post_json_get_json(self.url, d)
 | 
						|
        except:
 | 
						|
            logger.exception("Failed to push %s ", self.url)
 | 
						|
            defer.returnValue(False)
 | 
						|
        rejected = []
 | 
						|
        if 'rejected' in resp:
 | 
						|
            rejected = resp['rejected']
 | 
						|
        defer.returnValue(rejected)
 |