signalstickers / signalstickers-client

⚙️🐍 A Python client for the Signal stickers API
https://pypi.org/project/signalstickers-client/
GNU Lesser General Public License v3.0
54 stars 9 forks source link

Uploaded stickers are missing #7

Closed Jeanno closed 3 years ago

Jeanno commented 3 years ago

See this published sticker pack. It is registered on signal.art but when you try to add it to sticker it fails. https://signal.art/addstickers/#pack_id=6ebed7d80414898943fab25b618165cb&pack_key=d5278059a0b61bcd38e1fd505ce8d05ecd9d935da8a0bf813e265e043657d872

romainricard commented 3 years ago

I can't really help you without context. It seems that your pack contains 2 stickers with the emoji 🤪, but the image data are empty.

> for sticker in pack.stickers:
>        print(sticker.image_data)

None
None

Can you check that the path to the image file is correct? My guess is that you give your script a wrong path for your images, thus leading to adding empty stickers.

When facing this kind of problem, please use the download script to check that what you sent is correct

Jeanno commented 3 years ago

I double-checked and the paths are correct. I also tried moving them to /tmp and gave them 777 permissions. Still no luck.

I guess I will start tracing the upload process and see what happened. At this point I'm thinking it's some sort of weird file permission problem.

Kozova1 commented 3 years ago

I know it doesn't help that much, but I also have the same problem. Interestingly enough, I get a 403 forbidden when using the download script (with pack_id and pack_key updated accordingly).

see trace here: https://pastebin.com/qEencHva

Jeanno commented 3 years ago

I did some tracing with the upload function and the encrypted data is not empty at the payload.

Right now I suspect there's something to do with API response from signal.

romainricard commented 3 years ago

Can you share the script you used to upload stickers? I've just tested with python 3.9 (like @Kozova1) and a fresh pipenv and I can't reproduce.

Tested script (from examples )

import os

import anyio
from signalstickers_client import StickersClient
from signalstickers_client.models import LocalStickerPack, Sticker

async def main():
    def add_sticker(path, emoji):

        stick = Sticker()
        stick.id = pack.nb_stickers
        stick.emoji = emoji

        with open(path, "rb") as f_in:
            stick.image_data = f_in.read()

        pack._addsticker(stick)

    pack = LocalStickerPack()
    pack.title = 'Hello world!'
    pack.author = "Romain Ricard"

    add_sticker("/tmp/hello.png", "🤪")

    async with StickersClient(os.environ['SIGNAL_USERNAME'], os.environ['SIGNAL_PASSWORD']) as client:
        pack_id, pack_key = await client.upload_pack(pack)

    print("Pack uploaded!\n\nhttps://signal.art/addstickers/#pack_id={}&pack_key={}".format(pack_id, pack_key))
if __name__ == '__main__':
    anyio.run(main)
Kozova1 commented 3 years ago

I used this script:

import os

import anyio
from signalstickers_client import StickersClient
from signalstickers_client.models import LocalStickerPack, Sticker

async def main():
    def add_sticker(path, emoji):

        stick = Sticker()
        stick.id = pack.nb_stickers
        stick.emoji = emoji

        with open(path, "rb") as f_in:
            stick.image_data = f_in.read()

        pack._addsticker(stick)

    pack = LocalStickerPack()

    # Set here the pack title and author
    pack.title = 'dancing cockroach'
    pack.author = "Dav"

    # Add the stickers here, with their emoji
    # Accepted format:
    # - Non-animated webp
    # - PNG
    # - GIF <100kb for animated stickers

    add_sticker("./dancing_cockroach.gif", "🤪")

    # Specifying a cover is optionnal
    # By default, the first sticker is the cover
    cover = Sticker()
    cover.id = pack.nb_stickers
    # Set the cover file here
    with open("./cover.webp", "rb") as f_in:
        cover.image_data = f_in.read()
    pack.cover = cover

    for sticker in pack.stickers:
        print(sticker.image_data)

    # Instanciate the client with your Signal crendentials
    async with StickersClient(os.environ['SIGNAL_USERNAME'], os.environ['SIGNAL_PASSWORD']) as client:
        # Upload the pack
        pack_id, pack_key = await client.upload_pack(pack)

    print("Pack uploaded!\n\nhttps://signal.art/addstickers/#pack_id={}&pack_key={}".format(pack_id, pack_key))

dancing_cockroach.gif and cover.webp are both accessible to the script.

Kozova1 commented 3 years ago

seems like my gif is way larger than 100KB, will try it with a smaller one.

Kozova1 commented 3 years ago

the problem was the gif size, now it works fine.

Jeanno commented 3 years ago

So I took a look at the response body

<Error><Code>EntityTooLarge</Code><Message>Your proposed upload exceeds the maximum allowed size</Message><ProposedSize>309535</ProposedSize><MaxSizeAllowed>307200</MaxSizeAllowed><RequestId>872173856B2B70A6</RequestId><HostId>t+zBQ7TfcwgTTElO5HEqbcScyFOyMmPuNJ9N2cMrjbOqbJ0FnY4VH182ruw7aYM0sTFu5yBPxtY=</HostId></Error>
Jeanno commented 3 years ago

I will probably try python 3.9 and start a fresh pipenv. Right now I'm on 3.8.

Jeanno commented 3 years ago

Python 3.9 gave me the same result. I searched a bit with the error message and seems like it's some AWS S3 error. Next step probably requires a good study at their API spec.

romainricard commented 3 years ago

So I took a look at the response body

Signal stickers max size are 300kb, so it seems that this was the problem in the first place :smiley: I'm going to close the Issue for now, feel free to reopen it if needed. You can read stickers internals for a basic presentation of how stickers are uploaded.