I want to build a customer support chat app. There are users and an admin. Below admin there are multiple sub-admins. Initially the chat is initiated with admin only, but if the admin is offline I need to route the message to sub-admins.
offline_message_hook hook serves the purpose. I'll check if the To is admin, then I need to route the Packet to one of the sub-admins. How do I route/send the packet to other user within offline_message_hook. In short how do I change the To from the packet so that the packet is re-directed to the new sub-admin?
Here is what I've tried:-
offline_message_hook({_Action, #message{from = Peer, to = To} = Pkt} = Acc) ->
?INFO_MSG("Inside offline", []),
ejabberd_router:route(From, To, Packet),
ok.
I'm using ejabberd 17.04.105.
Update
After following user2610053's advice, I did this:-
-spec offline_message_hook({any(), message()}) -> {any(), message()}.
offline_message_hook({_Action, Msg} = Acc) ->
ejabberd_router:route(xmpp:set_to(Msg, 'praful#localhost')),
{routed, Msg}.
Following is the error:-
15:13:12.291 [error] failed to route packet:
#message{id = <<"purple187f6502">>,type = chat,lang = <<"en">>,
from = {jid,<<"praful2">>,<<"localhost">>,<<"Prafuls-MacBook-Pro">>,
<<"praful2">>,<<"localhost">>,<<"Prafuls-MacBook-Pro">>},
to = praful#localhost,subject = [],
body = [#text{lang = <<>>,data = <<"co=umon">>}],
thread = undefined,
sub_els = [{xmlel,<<"active">>,
[{<<"xmlns">>,
<<"http://jabber.org/protocol/chatstates">>}],
[]}],
meta = #{ip => {0,0,0,0,0,0,0,1}}}
Reason = {error,{{badrecord,jid},[{ejabberd_router,do_route,1,[{file,"src/ejabberd_router.erl"},{line,343}]},{ejabberd_router,route,1,[{file,"src/ejabberd_router.erl"},{line,87}]},{mod_sunshine,offline_message_hook,1,[{file,"src/mod_sunshine.erl"},{line,24}]},{ejabberd_hooks,safe_apply,4,[{file,"src/ejabberd_hooks.erl"},{line,380}]},{ejabberd_hooks,run_fold1,4,[{file,"src/ejabberd_hooks.erl"},{line,364}]},{ejabberd_sm,route,1,[{file,"src/ejabberd_sm.erl"},{line,138}]},{ejabberd_local,route,1,[{file,"src/ejabberd_local.erl"},{line,116}]},{ejabberd_router,do_route,1,[{file,"src/ejabberd_router.erl"},{line,348}]}]}}
The user praful#localhost exist. Please advice what exactly is wrong?
Update2 - `UserReceivePacket Hook
In user_receive_packet packet hook, upon using the same function ejabberd_router:route(xmpp:set_to(Packet, jid:decode("praful#localhost"))), it throws an error saying :-
Hook user_receive_packet crashed when running mod_sunshine:user_receive_packet/1:
** Reason = {error,function_clause,[{jid,decode,[{file,"src/jid.erl"},{line,132}],["praful#localhost"]},{mod_sunshine,user_receive_packet,[{file,"src/mod_sunshine.erl"},{line,29}],1},{ejabberd_hooks,safe_apply,[{file,"src/ejabberd_hooks.erl"},{line,380}],4},{ejabberd_hooks,run_fold1,[{file,"src/ejabberd_hooks.erl"},{line,364}],4},{ejabberd_c2s,process_info,[{file,"src/ejabberd_c2s.erl"},{line,231}],2},{ejabberd_hooks,safe_apply,[{file,"src/ejabberd_hooks.erl"},{line,380}],4},{ejabberd_hooks,run_fold1,[{file,"src/ejabberd_hooks.erl"},{line,364}],4},{xmpp_stream_in,handle_info,[{file,"src/xmpp_stream_in.erl"},{line,373}],2}]}
So, I read about function_clause, but couldnt understand the same. What exactly is wrong over here?
I think you're asking about xmpp:set_to/2. Here is an example:
offline_message_hook({_Action, Msg} = Acc) ->
SubAdmins = get_sub_admins(Msg#message.to),
lists:foreach(
fun(Admin) ->
ejabberd_router:route(xmpp:set_to(Msg, Admin))
end, Admins),
{routed, Msg}.
I am using pywinusb to send/get data from Custom HID device. I can successfully send data but cant get it. Any suggestions? I tried to debug using Microsoft Message Analyzer and can see the data there but not in the script. Product/Vendor Ids, report id etc are correct.
Here the code,
from pywinusb import hid
from time import sleep
devicefilter = hid.HidDeviceFilter(vendor_id=0x0483, product_id=0x572A)
devices = devicefilter.get_devices()
print ("devices:", devices)
hid_device = devices[0]
print ("hid_device:", hid_device)
hid_device.open()
out_report = hid_device.find_output_reports()
in_report = hid_device.find_input_reports()
print("out_report:", out_report)
print("out_report[0]:",out_report[0])
print("in_report:", in_report)
print("in_report[0]:",in_report[0])
txBuffer = [0x55] * 64
txBuffer[0] = 0x01 # Report ID
rxBuffer = [0x00] * 64
rxBuffer[0] = 0x02 # Report ID
print(txBuffer)
print(rxBuffer)
out_report[0].set_raw_data(txBuffer)
in_report[0].set_raw_data(rxBuffer)
while 1:
out_report[0].send()
rxBuffer = in_report[0].get()
print("rxBuffer:", rxBuffer)
sleep(1)
hid_device.close()
I'm no expert on this my self but I have a similar sounding application Here is what I do. I don't explicitly create an input report but rather attach an input report handler to the usb receive buffer.
import pywinusb.hid as hid
# handler called when a report is received
def rx_handler(data):
print 'recv: ', data
def scan_hiddevice():
""" Scans for and returns the HID device. """
devices = hid.HidDeviceFilter( vendor_id = vendor_id).get_devices()
if not devices:
print "scan_hiddevice: No device connected."
return None
else:
device = devices[0]
#print("scan_hiddevice: found %s", device )
return device
return None
def setup_hiddevice():
"""Creates a new HID device, opens it and attaches a receive data handler"""
hid_device = scan_hiddevice()
hid_device.open()
hid_device.set_raw_data_handler(rx_handler)
return hid_device
def main(verbose=True):
hid_device = setup_hiddevice()
while (True):
#wait for data
I hope this can be of some use.
I'm trying to connect to FedEx International WebServices API for Ship Service.
I'm using WSDL of v13.
Below is my SOAP Content:
<ns:ProcessShipmentRequest xmlns:ns="http://fedex.com/ws/ship/v13">
<ns:WebAuthenticationDetail>
<ns:UserCredential>
<ns:Key>GHmnVXAyWqWUemqD</ns:Key>
<ns:Password>1VYHs6O1vhKA3xPVAExhx1vUB</ns:Password>
</ns:UserCredential>
</ns:WebAuthenticationDetail>
<ns:ClientDetail>
<ns:AccountNumber>510087666</ns:AccountNumber>
<ns:MeterNumber>100115929</ns:MeterNumber>
</ns:ClientDetail>
<ns:Version>
<ns:ServiceId>ship</ns:ServiceId>
<ns:Major>13</ns:Major>
<ns:Intermediate>0</ns:Intermediate>
<ns:Minor>0</ns:Minor>
</ns:Version>
<ns:RequestedShipment>
<ns:ShipTimestamp>2015-04-17T12:51:03.404660Z</ns:ShipTimestamp>
<ns:DropoffType>REGULAR_PICKUP</ns:DropoffType>
<ns:ServiceType>INTERNATIONAL_PRIORITY</ns:ServiceType>
<ns:PackagingType>FEDEX_25KG_BOX</ns:PackagingType>
<ns:TotalWeight>
<ns:Units>LB</ns:Units>
<ns:Value>40.0</ns:Value>
</ns:TotalWeight>
<ns:Shipper>
<ns:Contact>
<ns:CompanyName>Your Company</ns:CompanyName>
<ns:PhoneNumber>4354454365746</ns:PhoneNumber>
</ns:Contact>
<ns:Address>
<ns:StreetLines>3121 W Government Way</ns:StreetLines>
<ns:StreetLines>Seattle</ns:StreetLines>
<ns:City>Seattle</ns:City>
<ns:StateOrProvinceCode>WA</ns:StateOrProvinceCode>
<ns:PostalCode>98199</ns:PostalCode>
<ns:CountryCode>US</ns:CountryCode>
<ns:CountryName>United States</ns:CountryName>
<ns:Residential>false</ns:Residential>
</ns:Address>
</ns:Shipper>
<ns:Recipient>
<ns:Contact>
<ns:PersonName>Agrolait</ns:PersonName>
<ns:PhoneNumber>3210588558</ns:PhoneNumber>
</ns:Contact>
<ns:Address>
<ns:StreetLines>1010 EASY ST</ns:StreetLines>
<ns:StreetLines>Apt# 11</ns:StreetLines>
<ns:City>OTTAWA</ns:City>
<ns:StateOrProvinceCode>ON</ns:StateOrProvinceCode>
<ns:PostalCode>K1A0B1</ns:PostalCode>
<ns:CountryCode>CA</ns:CountryCode>
<ns:Residential>false</ns:Residential>
</ns:Address>
</ns:Recipient>
<ns:ShippingChargesPayment>
<ns:PaymentType>SENDER</ns:PaymentType>
<ns:Payor>
<ns:ResponsibleParty>
<ns:AccountNumber>510087666</ns:AccountNumber>
<ns:Contact>
<ns:PersonName>Your Company</ns:PersonName>
<ns:CompanyName>Your Company</ns:CompanyName>
<ns:PhoneNumber>4354454365746</ns:PhoneNumber>
</ns:Contact>
<ns:Address>
<ns:CountryCode>US</ns:CountryCode>
</ns:Address>
</ns:ResponsibleParty>
</ns:Payor>
</ns:ShippingChargesPayment>
<ns:CustomsClearanceDetail>
<ns:ClearanceBrokerage>BROKER_UNASSIGNED</ns:ClearanceBrokerage>
<ns:DutiesPayment>
<ns:PaymentType>SENDER</ns:PaymentType>
<ns:Payor>
<ns:ResponsibleParty>
<ns:AccountNumber>510087666</ns:AccountNumber>
<ns:Contact>
<ns:PersonName>Your Company</ns:PersonName>
<ns:CompanyName>Your Company</ns:CompanyName>
<ns:PhoneNumber>4354454365746</ns:PhoneNumber>
</ns:Contact>
</ns:ResponsibleParty>
</ns:Payor>
</ns:DutiesPayment>
<ns:DocumentContent>NON_DOCUMENTS</ns:DocumentContent>
<ns:CustomsValue>
<ns:Currency>USD</ns:Currency>
<ns:Amount>100.0</ns:Amount>
</ns:CustomsValue>
<ns:FreightOnValue>OWN_RISK</ns:FreightOnValue>
<ns:CommercialInvoice>
<ns:TaxesOrMiscellaneousChargeType>TAXES</ns:TaxesOrMiscellaneousChargeType>
<ns:Purpose>SOLD</ns:Purpose>
<ns:TermsOfSale>FOB_OR_FCA</ns:TermsOfSale>
</ns:CommercialInvoice>
<ns:Commodities>
<ns:NumberOfPieces>1</ns:NumberOfPieces>
<ns:Description>[CARD] Graphics Card</ns:Description>
<ns:CountryOfManufacture>US</ns:CountryOfManufacture>
<ns:Weight>
<ns:Units>LB</ns:Units>
<ns:Value>10.0</ns:Value>
</ns:Weight>
<ns:Quantity>1</ns:Quantity>
<ns:QuantityUnits>Unit(s)</ns:QuantityUnits>
<ns:UnitPrice>
<ns:Currency>USD</ns:Currency>
<ns:Amount>100.0</ns:Amount>
</ns:UnitPrice>
<ns:CustomsValue>
<ns:Currency>USD</ns:Currency>
<ns:Amount>100.0</ns:Amount>
</ns:CustomsValue>
</ns:Commodities>
</ns:CustomsClearanceDetail>
<ns:LabelSpecification>
<ns:LabelFormatType>COMMON2D</ns:LabelFormatType>
<ns:ImageType>PNG</ns:ImageType>
<ns:LabelStockType>PAPER_4X6</ns:LabelStockType>
<ns:LabelPrintingOrientation>BOTTOM_EDGE_OF_TEXT_FIRST</ns:LabelPrintingOrientation>
</ns:LabelSpecification>
<ns:ShippingDocumentSpecification>
<ns:ShippingDocumentTypes>CERTIFICATE_OF_ORIGIN</ns:ShippingDocumentTypes>
</ns:ShippingDocumentSpecification>
<ns:RateRequestTypes>ACCOUNT</ns:RateRequestTypes>
<ns:EdtRequestType>ALL</ns:EdtRequestType>
<ns:PackageCount>1</ns:PackageCount>
<ns:RequestedPackageLineItems>
<ns:SequenceNumber>1</ns:SequenceNumber>
<ns:Weight>
<ns:Units>LB</ns:Units>
<ns:Value>40.0</ns:Value>
</ns:Weight>
<ns:Dimensions>
<ns:Length>17</ns:Length>
<ns:Width>12</ns:Width>
<ns:Height>3</ns:Height>
<ns:Units>IN</ns:Units>
</ns:Dimensions>
<ns:PhysicalPackaging>BOX</ns:PhysicalPackaging>
</ns:RequestedPackageLineItems>
</ns:RequestedShipment>
</ns:ProcessShipmentRequest>
When I send the request I get Below Response:
(reply){
HighestSeverity = "ERROR"
Notifications[] =
(Notification){
Severity = "ERROR"
Source = "ship"
Code = "8200"
Message = "Special service is invalid."
LocalizedMessage = "Special service is invalid."
},
(Notification){
Severity = "WARNING"
Source = "ship"
Code = "7037"
Message = "Harmonized code is missing or invalid for commodity (COMMODITY_INDEX}; estimated duties and taxes were not returned."
LocalizedMessage = "Harmonized code is missing or invalid for commodity (COMMODITY_INDEX}; estimated duties and taxes were not returned."
MessageParameters[] =
(NotificationParameter){
Id = "COMMODITY_INDEX"
Value = "1"
},
},
Version =
(VersionId){
ServiceId = "ship"
Major = 13
Intermediate = 0
Minor = 0
}
}
Warning I can have fixed but the Special Service Invalid Error Persists. Please let me know If I'm passing some wrong value or if I'm missing some Value.
Note: I tried adding the special services like COD, but the issue is same.
Since you don't have a special service defined, this error is really odd. You need to email websupport at fedex dot com for resolution. FedEx error responses are terrible.
I'm trying to send sms using kannel & smppsim.
I use docker as container.
I use this kannel.conf:
group = core
admin-port = 13000
smsbox-port = 13001
admin-password = bar
admin-allow-ip = "127.0.0.1;192.168.59.103"
box-allow-ip = "127.0.0.1;192.168.59.103"
group = smsc
smsc = smpp
smsc-id = SMPPSim
host = 192.168.59.103
port = 2775
transceiver-mode = 1
smsc-username = smppclient1
smsc-password = password
system-type = 'VMA'
#service-type = 'test'
interface-version = 34
#system-id = smppclient
preferred-smsc-id = SMPPSim
connect-allow-ip = 192.168.59.103
group = smsbox
bearerbox-host = bearerbox
sendsms-port = 13013
global-sender = 13013
group = sendsms-user
username = tester
password = foobar
group = sms-service
keyword = default
text = "No service specified"
when sending a request to send sms I get "0: Accepted for delivery"
I'm seeing these errors in smsbox log:
2015-03-21 20:20:52 [1] [3] DEBUG: Status: 202 Answer: <Sent.>
2015-03-21 20:20:52 [1] [3] DEBUG: Delayed reply - wait for bearerbox
2015-03-21 20:20:52 [1] [0] DEBUG: Got ACK (0) of 74f9cefe-db95-4b7d-aa99-f07395d32915
2015-03-21 20:20:52 [1] [0] DEBUG: HTTP: Resetting HTTPClient for `192.168.59.3'.
2015-03-21 20:20:52 [1] [1] ERROR: Error reading from fd 24:
2015-03-21 20:20:52 [1] [1] ERROR: System error 104: Connection reset by peer
2015-03-21 20:20:52 [1] [1] DEBUG: HTTP: Destroying HTTPClient area 0x7fe8d0000ad0.
Bearbox doesn't present any errors and seem to pass the message to smppsim, smppsim shows this in log:
21 Assessing state of 1 messages in the OutboundQueue
21 Message:2 state=DELIVERED
The sms is not sent, what could be wrong?
I think its a problem with your Kannel configuration file, specially with smsbox and later parts. I used following as smsbox
group = smsbox
bearerbox-host = 127.0.0.1
sendsms-port = 13013
global-sender = your sim number which you use in USB modem
sendsms-chars = "0123456789 +-"
log-file = "/var/log/kannel/smsbox.log"
log-level = 0
access-log = "/var/log/kannel/access.log"
and you can get my full configuration file from here. This worked fine for me.
This might be a problem of lоѕѕ оf thе соnnесtіоn оn thе rеmоtе ѕосkеt due tо а tіmеоut.
And SMPPSim is just a testing tool for kannel. It won't really send a message to your or mentioned mobile number. To send real messages you need to add either gsm modems or SMS operator details.
You can refer to userGuide from kannel.org.
To check your kannel status simply go to http://localhost:13000/status?password=password(password of your kannel)
I have a piece of code that works fine when deployed via Xcode directly onto the device but if I install the application via an adhoc archive it fails miserably.
This is the code, it is full of log statements as I wasn't able to utilise the debugger so I had to rely on the console output to work out what was happening.
var status: ShipmentStatus = ShipmentStatus.NOT_READY
let stopOrders = getStopOrders(true)
for order in stopOrders{
NSLog("Beginning Loop Shipment Status = %d", status.toRaw())
let stopStatus = order.getStopOrderStatus()
NSLog("%d Stop Status = %d", order.salesOrderHeader.salesOrderNo, stopStatus.toRaw())
if(stopStatus == StopOrderStatus.READY_FOR_PICKING || stopStatus == StopOrderStatus.PARTIALLY_PICKED){
return ShipmentStatus.READY_FOR_PICKING
} else if(stopStatus == StopOrderStatus.PICKING_COMPLETE){
status = ShipmentStatus.PICKING_COMPLETE
NSLog("Shipment Status = %d", status.toRaw())
} else if(stopStatus == StopOrderStatus.READY_FOR_DELIVERY || stopStatus == StopOrderStatus.PARTIALLY_DELIVERED){
if(status != ShipmentStatus.PICKING_COMPLETE){
status = ShipmentStatus.READY_FOR_DELIVERY
NSLog("Shipment Status = %d", status.toRaw())
} else {
NSLog("Shipment Status is not changed")
}
} else if(stopStatus == StopOrderStatus.DELIVERY_COMPLETE){
if(status != ShipmentStatus.PICKING_COMPLETE && status != ShipmentStatus.READY_FOR_DELIVERY){
status = ShipmentStatus.DELIVERY_COMPLETE
NSLog("Shipment Status = %d", status.toRaw())
} else {
NSLog("Shipment Status is not changed")
}
}
}
NSLog("Return Shipment Status = %d", status.toRaw())
return status
The issue is that unless the first condition is matched (ie it returns the value as part of the loop) the variable status is always equal to ShipmentStatus.NOT_READY. If I check the logs I can see that at every loop iteration status is also equal to ShipmentStatus.NOT_READY but I can also see in the console that it is being set correctly during the iteration. So it seems to be treating the variable as if it has been declared inside the loop and creating a new copy for every iteration.
As I mentioned this only occurs if the project is bundled up into an archive and deployed over the air. When deployed directly onto the device the code works as expected. This happens on both iOS 7.1.2 and iOS 8. I have just tested using Xcode 6 GM and the issue still exists.
Has anyone seen behaviour like this in their code? The strange thing is I have other code which follows a similar pattern and it appears to be returning the expected value.
================
Just for clarification, this is the log output that I see when deployed using Xcode
[7454:60b] Beginning Loop Shipment Status = 0
[7454:60b] 10000221 Stop Status = 70
[7454:60b] Shipment Status = 60
[7454:60b] Beginning Loop Shipment Status = 60
[7454:60b] 10000222 Stop Status = 70
[7454:60b] Shipment Status = 60
[7454:60b] Beginning Loop Shipment Status = 60
[7454:60b] 10000223 Stop Status = 70
[7454:60b] Shipment Status = 60
[7454:60b] Return Shipment Status = 60
And when it is deployed via an archive the result is
<Warning>: Beginning Loop Shipment Status = 0
<Warning>: 10000221 Stop Status = 70
<Warning>: Shipment Status = 60
<Warning>: Beginning Loop Shipment Status = 0
<Warning>: 10000222 Stop Status = 70
<Warning>: Shipment Status = 60
<Warning>: Beginning Loop Shipment Status = 0
<Warning>: 10000223 Stop Status = 70
<Warning>: Shipment Status = 60
<Warning>: Return Shipment Status = 0
OK, problem resolved but using what I would consider a workaround as I assume that because of the nature of the issue and the fact that it doesn't cause an issue when the app is deployed via Xcode that this a bug in the package builder.
The enum definition for ShipmentStatus was defined in the same Swift file as this function. So I moved the enum into a separate file and hey presto, the issue goes away.